summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author何正杰 <[email protected]>2022-05-31 15:36:08 +0800
committer何正杰 <[email protected]>2022-05-31 15:36:08 +0800
commit25394f1cb818801ca4451ac1a31e9e877da03295 (patch)
treed612783a9c6d3c96533d11731a6b54c306c43573
parent3129725705cf80a91d2e149abc990360b229a958 (diff)
add docsHEADmain
-rw-r--r--docs/入口发现方案和实验.md270
-rw-r--r--docs/音视频入口数据获取.md102
2 files changed, 372 insertions, 0 deletions
diff --git a/docs/入口发现方案和实验.md b/docs/入口发现方案和实验.md
new file mode 100644
index 0000000..68123da
--- /dev/null
+++ b/docs/入口发现方案和实验.md
@@ -0,0 +1,270 @@
+[TOC]
+
+## 音视频入口关联近期工作进展
+
+思想:利用众包的思想,从历史数据中挖掘潜在的关联关系。从kafka中拉取当前的音视频数据,根据其host获取历史出现的次数,如果满足最低要求(目前设置为5),则查询 ClickHouse 的历史流量表的到历史出现的 client_ip 和 fount_time,通过 client_ip 对历史每一次出现查询时间窗口内的上下文,构造数据进行 `PrefixSpan` 挖掘频繁序列集,采用不同启发式规则对频繁规则进行抽去,得到候选集。
+
+目前方案架构:
+
+![在线视频入口检测方案](在线视频入口检测方案.jpeg)
+
+当前方案(华严小测试)已经在10.9服务器上 7*24 小时运行。
+
+### 当前遇到的问题
+
+### OOM问题
+
+在 `序列挖掘` 计算过程中,会占用很大的临时内存,在一开始开JVM内存的时候需要提前设置好较大内存。并且用 `spark` 的时候会有 executor 和 driver,需要同时设置较大内存。
+
+例如行数较大而列数较多的时候容易出现OOM:如果历史只出现了7次,而每一次的上下文共400-500个host,则会出现序列爆炸的问题,此时用序列挖掘开销过大,目前的方案是用统计替代。
+
+### 需要进行手动的参数调整
+
+为了防止`内存溢出`和`提高效果`, 目前设置了如下的多种超参数,在不同环境的时候需要进行手工的测试,以调整到最优的超参数。
+
+```
+# 时间窗口
+# interval = 23
+intervalLeft = 60
+intervalRight = 15
+
+# prefix算法的置信度
+prefixConfidence=0.3
+# 用于数据挖掘的历史时间,当前时间-最长间隔=最早使用的历史日志,注意这里的单位为天
+historyTrafficInterval=90
+# 候选集最大容量
+candidateSize=50
+# Redis候选表中的过期时间,单位为天
+ExpirationTime=1
+# 最少进行序列挖掘的记录数目
+leastHistoryNum=5
+
+# 序列挖掘的行数限制和每一行的size限制,此2参数控制了内存是否会溢出
+rawLimit = 80
+colLimit = 200
+# 当前行数和字段的长度比也会导致内存的溢出
+ratioRawCol=10
+```
+
+## 华严HTTP音视频测试结果
+
+利用华严过去3个月明文HTTP流量进行测试,在一定时间窗口且存在referer的YSP总数为1414,其中符合挖掘条件的个数为1115,prefix候选集平均长度为11.990134,结果如下:928
+
+```
+ Sorting rules Occurrences No-occurrence Index avg Prop pos=1 Prop pos<5 Prop pos<10
+ statistic 633 482 2.0421524 0.42869955 0.47623318 0.48071748
+ statistics_all 781 353 3.5652556 0.20811288 0.40652558 0.6208113
+ sta_rule1_rule2 633 482 2.5004485 0.22242153 0.4573991 0.47982064
+ rule1 633 482 1.8762332 0.21434978 0.46278027 0.54798204
+ sta_rule1 633 482 2.0 0.24932736 0.47982064 0.4852018
+ rule2 633 482 4.514798 0.12825112 0.30403587 0.42152467
+```
+
+### 结果说明
+
+`prefixSpan` 数据挖掘后将会得到频繁序列集,序列集长度从1~n不止,从这些序列集中采用不同的规则处理以得到候选集,目前采用以下4种方式进行抽去:
+
+- statistic 序列挖掘统计结果:利用 `prefixSpan` 的 `一项集` 按照出现次数进行排序。
+- statistics_all 统计结果:进行全量历史数据统计后,截取出现次数排名前 50 的数据。
+- rule1序列挖掘首部:利用 `prefixSpan` 的 `多项集` 按照在 **首部** 出现次数进行排序。
+- rule2 序列挖掘尾部:利用 `prefixSpan` 的 `多项集` 按照在 **非首部** **不出现**次数进行排序。
+
+评估指标说明:
+
+- Occurrences:采用 统计 / 众包 能返回 refer 数据
+
+- No-occurrence:采用 统计 / 众包 皆无法返回 refer 数据
+ - ⚠️ 不符合众包条件的个数为280个
+
+ - ⚠️ 符合众包条件,统计全量能找到,但是众包不能找到的个数为130个
+
+ - 其中,防止OOM策略处理的个数为19个
+
+ - ⚠️ 通过众包思想(序列挖掘 / 统计)不能找到的个数为352个
+
+ - 目前数据集受到运行商缓存 `200.200.200.200` 的影响,导致 ysp host被隐藏,同时对应的 refer 难以确定,`200.200.200.200` 共计206个
+
+ - 排除特殊情况,不能用众包思想找到的个数为147(353-206)个,去重后为如下9个不同的host。经分析,这些host入口并不唯一,一种情况是有多个不同的referer,另一种情况是可能通过APP端的时候没有referer出现(但是可以通过二级域名匹配到),如果只求“来自谁”,而不是“来自哪”,则不成问题
+
+ - > 'live-s3m.mediav.com', 'iadmusicmat.music.126.net', 'tb-video.bdstatic.com', 'ysf.nosdn.127.net', 'tbm-auth.alicdn.com', 'sgls.static.xyimg.net', 'upos-sz-mirrorkodo.bilivideo.com', 'edge.ivideo.sina.com.cn', 'vd3.bdstatic.com'
+
+ - ⚠️统计出现而入口不出现的情况为:781-633=148个
+
+- Index avg:
+
+ - Prop pos=1:返回的顺序中,refer在第1位返回的概率
+
+ - Prop pos<5:返回的顺序中,refer在前5位返回的概率
+
+ - Prop pos<10:返回的顺序中,refer在前10位返回的概率
+
+### 对当前问题的说明
+
+目前效果最好的情况是采用 `rule1` 也就是用 prefix 挖掘结果的多项集的首部进行排序的结果。目前在前 10 位出现概率最大的是 `总体统计` 的结果,为 0.61%,目前的方案 `Index avg优秀`,但是在前几位 `召回` 的结果还不够,经过分析后发现,在这些未能成功召回的样例,`200.200.200.200` 占了较大比例。
+
+### 运行时间说明
+
+- 实时性:采用机器学习算法会对在线系统的实时性造成很大的影响,目前华严的音视频速率小于 0.1条/s,暂时不会有时效性的问题,在更大流量环境测试的时候需要考虑这一问题。
+- 方案的速率对比:目前采用数据挖掘的时间远小于查询历史数据的时间,在后续上线方案设计中必须考虑这一点。
+
+## 华严网页视频流量测试结果
+
+采用如下规则过滤出网页流量:
+
+- Windows端 user_agent 包含 windows Chrome 并且 chrome 版本80以上
+- Mac端 user_agent 包含 mac OS 并且 不包含 mobile
+
+在去除爬虫特殊情况后,得到如下结果:
+
+```
+在一定时间窗口且存在referer的YSP总数为193,其中符合挖掘条件的个数为102,prefix候选集平均长度为20.529411
+ Sorting rules Occurrences No-occurrence Index avg Prop pos=1 Prop pos<5 Prop pos<10
+ statistic 83 19 4.970588 0.029411765 0.51960784 0.627451
+ statistics_all 115 6 3.7520661 0.32231405 0.8595041 0.87603307
+ sta_rule1_rule2 83 19 5.6862745 0.019607844 0.38235295 0.627451
+ rule1 83 19 2.5294118 0.05882353 0.74509805 0.8137255
+ statistic_rule1 83 19 3.235294 0.3529412 0.65686274 0.8137255
+ rule2 83 19 13.490196 0.019607844 0.039215688 0.30392158
+不符合众包条件(小于最小挖掘数目)的个数为:72
+防止OOM的个数位:19
+众包未找到的个数为:5
+```
+
+## Learning to rank
+
+引入推荐系统的思想,采用“召回”+“排序”的思路,进一步优化结果。
+
+### 多路召回
+
+- Host与视频Host的编辑距离
+- 总体统计的前X
+- 序列挖掘一项集(这里很容易被前一个包裹住呀)
+
+特征设计:
+
+```
+[当前Host总体统计的个数,
+当前Host总体统计的个数 / 候选集所有Host的上下文次数(YSP出现次数),
+当前Host总体统计的个数 / YSP出现次数,
+
+prefix统计的个数,
+prefix统计的频繁个数 / YSP出现次数,
+prefix子序列第一位出现的次数,
+prefix子序列第一位出现的次数 / 频繁次数,
+prefix子序列第一位出现的频繁次数,
+prefix子序列第一位出现的频繁次数 / YSP出现次数,
+prefix子序列第一位出现的频繁次数 / 频繁次数,
+prefix子序列第一位出现的频繁次数 / prefix子序列第一位出现的次数,
+prefix子序列在后面出现的次数,
+prefix子序列在后面出现的次数 / YSP出现次数,
+prefix子序列在后面出现的次数 / prefix统计的频繁个数,
+prefix子序列在后面出现的频繁次数,
+prefix子序列在后面出现的频繁次数 / YSP出现次数,
+prefix子序列在后面出现的频繁次数 / prefix统计的频繁个数,
+prefix子序列在后面出现的频繁次数 / prefix子序列在后面出现的次数,
+
+和该Host共现的音视频有几个,
+和该Host共现的音视频有几个 / Host出现次数,
+
+当前Host与视频资源的时间间隔求和 / 当前Host总体统计的个数
+离YSP的距离,
+离YSP的距离 / 当前Host总体统计的个数,
+
+编辑距离,
+Host向量]
+```
+
+### pointwise
+
+采用 random forest 和 svm 进行 point wise 排序。
+
+<img src="近期工作汇报/非泄漏的结果.png" alt="非泄漏的结果" style="zoom:67%;" />
+
+### pairwise
+
+采用 XGBoost 进行 pairwise 排序。
+
+对于包含入口的上下文(类别为1)进行识别,类别为1的识别为1的概率为81.82%,大于pointwise的68.69%。
+
+### 重排序进一步提升
+
+- 考虑进一步增加特征(比如同一时间),提高pairwise准确率
+- 采用更先进的pairwise方法
+
+## 特殊情况
+
+在测试结果说明中,描写了一个视频对应多个入口的例子,在真实场景中,一个视频多个入口是很常见的情况,例如web端和app端,或者盗版音视频承载在不同的盗版网站上,这种情况根据其流量大小的不同,具体有两种类型。
+
+### case1 一个入口占比较大
+
+- 入口1占比80%,入口2占比20%
+
+此时若设置序列挖掘的支持度为0.3,则入口2不会被发现,若设置支持度为0.2,则入口1的上下文会产出很多噪声。A A A 原始数据 100(80) 20
+
+特别是这种情况下,如果入口1其实没有referer字段,结果会很糟糕。
+
+此时的解决方案:序列挖掘完事儿之后,找到识别出入口概率最大的host对应的相同freq的 **频繁多项**,用此频繁多项对应原数据的上下文,剩下没有被对应到的上下文,若数目也符合序列挖掘条件,则以这一部分再进行一次召回+排序,如此类推,直到无法进行序列挖掘。
+
+### case2 多个入口占比都较小
+
+- 入口1,2,3,4,5都占比20%
+
+此时的解决方案:将支持度按照倍数减少,如设置为0.5时,挖掘不出频繁序列(除了常见的搜索引擎和cnzz流量分析),则按照0.5 0.45 0.35 0.2这样修改支持度,直到找到频繁序列。
+
+### case3 爬虫流量
+
+- 爬虫流量虽然有 referer,但是入口页面并不会出现或者很少会在时间窗口内出现
+
+**已发现华严有人在10.28.11.03爬好看视频**
+
+解决方案分两种情况,边缘网络条件和大规模线上
+
+- 边缘网络条件:判断单个 Client_IP 在一段时间内对应的音视频次数是否超过限制,超过的话则去除这个 ip 当天的 host。
+
+- 大规模线上:单个 IP 一天只对应1个不同的音视频Host
+
+Future Work:可以用机器学习来识别爬虫流量
+
+### case4 视频对应的host有别的作用
+
+- 典型:bdstatic.com 是好看视频的host,但是百度本身很多js,用于流量统计等功能的请求对应的 host 都是这个
+
+解决方法是确定历史的这条记录就是音视频,分为明文和密文进行判断,明文不用说了,密文的话需要引入加密音视频识别,从音视频表中拿到历史出现的记录。
+
+## 增量更新
+
+- 用在线排序学习,可能是存在偏见的,见 Unbiased LambdaMART: An Unbiased Pairwise Learning-to-Rank Algorithm。并且这里的反馈主要指的是用户点击了召回的结果,但是我更关心没有被召回的,并且由于加密占大多数,反馈占比较少。
+ - 反馈有以下两种方式利用:
+ - OL2R 每次根据用户的点击,学习bias,更新模型
+ - 这种方式的一个优势是根据反馈得到隐式的标注,其实我们本身就有HTTP的显式标注数据,并且无法即时反馈
+ - 做成向量,后面一部分向量就是反馈向量
+ - 不适合,因为反馈的占比很少
+
+- 采用积累-反馈-重训练的方式!
+
+反馈最重要的思想在于,对于用户的反馈,会根据流行的改变,会根据个人口味的改变而变换,但是这里视频和入口的关系是较难改变的,只需要增量更新就行了。
+
+## L2R学习资料
+
+推荐系统rank模块-Online Learning - 邁書傑的文章 - 知乎 https://zhuanlan.zhihu.com/p/65001235
+
+排序优化算法Learning to Ranking - https://www.biaodianfu.com/learning-to-ranking.html
+
+利用lightgbm做learning to rank 排序 - https://github.com/jiangnanboy/learning_to_rank
+
+推荐系统中的排序学习 - https://lumingdong.cn/learning-to-rank-in-recommendation-system.html
+
+Learning to rank基本算法小结 - felix的文章 - 知乎 https://zhuanlan.zhihu.com/p/26539920
+
+XGBoost文档 - https://xgboost.readthedocs.io/en/latest/parameter.html
+
+利用lightgbm做learning to rank - https://github.com/jiangnanboy/learning_to_rank
+
+Learning to Rank - https://github.com/shiba24/learning2rank
+
+Learning to rank with Python scikit-learn - https://towardsdatascience.com/learning-to-rank-with-python-scikit-learn-327a5cfd81f
+
+Learning to Rank using XGBoost - https://medium.com/predictly-on-tech/learning-to-rank-using-xgboost-83de0166229d
+
+从L2R开始理解一下xgboost的 'objective': 'rank:pairwise'参数 - https://blog.csdn.net/weixin_42001089/article/details/84146238
+
diff --git a/docs/音视频入口数据获取.md b/docs/音视频入口数据获取.md
new file mode 100644
index 0000000..595c880
--- /dev/null
+++ b/docs/音视频入口数据获取.md
@@ -0,0 +1,102 @@
+# 音视频入口数据获取
+
+### 背景
+
+根据视频资源的域名,从历史流量数据库中通过算法计算出视频网站的域名。
+
+### 数据需求
+
+- 在视频网站看视频时,后台请求的所有域名
+
+- (视频资源域名,视频网站域名)二者可以不唯一对应
+- 在历史数据中,**(视频资源域名,视频网站域名)出现的频次 > 10次**
+
+### 数据表字段
+
+视频表:包含字段 (common_client_ip, common_server_ip, http_url, http_referer, common_recv_time)
+
+```sql
+create table tsg_galaxy_xj.av_survey_log_local
+(
+ `common_recv_time` Int64,
+ `common_client_ip` String,
+ `common_server_ip` String,
+ `http_url` String,
+ `http_referer` String
+)
+ENGINE = MergeTree
+PARTITION BY toHour(toDateTime(common_recv_time))
+ORDER BY (common_recv_time)
+SETTINGS index_granularity = 8192
+```
+
+泛收表:包含字段 (common_client_ip, common_server_ip, http_url, http_referer, http_user_agent, ssl_sni, ssl_cn, dns_qname, common_recv_time)
+
+```sql
+create table tsg_galaxy_xj.connection_record_log_local
+(
+ `common_recv_time` Int64,
+ `common_client_ip` String,
+ `common_server_ip` String,
+ `http_url` String,
+ `http_referer` String,
+ `http_user_agent` String,
+ `http_content_type` String,
+ `ssl_sni` String,
+ `ssl_cn` String,
+ `dns_qname` String,
+ `common_schema_type` String
+)
+ENGINE = MergeTree
+ORDER BY (common_client_ip, common_recv_time)
+PARTITION BY toHour(toDateTime(common_recv_time))
+PRIMARY KEY common_client_ip
+SETTINGS index_granularity = 8192
+```
+
+### 可参考的方案
+
+#### 方案一:主动爬虫访问视频网站+后台捕包
+
+利用selenium爬虫访问视频网站,在屏幕特定位置点击,scapy抓取流量。
+
+缺点:
+
+- 访问不同网站时流量会重合
+ - 这一点其实可以通过随机组合网站列表的顺序一定程度避免
+- 部分网站利用爬虫加载缓慢,难以确定结束的时间
+- pcap包还需要进一步处理
+
+#### 方案二:主动爬虫访问视频网站+利用网关处的sapp自动捕包
+
+利用selenium爬虫访问视频网站,在屏幕特定位置点击,爬虫间隔可以大一点
+
+优点:可以直接将数据写入,无需数据清洗
+
+缺点:目前只有华严网关处有捕获的sapp
+
+#### 方案三:不主动访问网站,直接构造近似的数据
+
+主动访问网站一次,拿到该视频网站的视频资源的url,再填充噪音流量
+
+噪音流量来源:Alexa Top,广告,搜索引擎,常见的社交软件等等
+
+优点:容易构造
+
+缺点:数据不够真实
+
+### 一些小trick
+
+视频网站列表不够用怎么办?
+
+- 可以按照一个网站里面,按照不同的视频资源进行拆分
+- 按照视频资源区别数据,而不是按照列表区分数据能拓展很多数据出来,但是缺点在视频资源是加密的,要区分的话需要拿到完整的https url,而不是SNI,通过爬虫的方式不易获取
+
+因为爬虫导致不同音视频网站的流量重合怎么办?
+
+- 1: 爬虫的时间间隔大一点
+- 2: 可以重新排列视频网站的顺序,这样每次重合的流量不同,影响较小
+
+采用爬虫时,视频不自动播放怎么办?
+
+- 可以在10s后利用selenium点击浏览器页面特定的位置 \ No newline at end of file