Skip to content

Commit

Permalink
add blog in math and rec-sys
Browse files Browse the repository at this point in the history
  • Loading branch information
sigmoidguo authored and sigmoidguo committed Jun 25, 2017
1 parent 4f80fb2 commit aadb3b0
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 0 deletions.
43 changes: 43 additions & 0 deletions math/积分系统的思考.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## 无处不在的积分系统
积分系统非常的常见,比如:
1. 基于1对1的对战打分:如围棋的对战评分,AlphaGo如何通过几场大战,排名世界第一,这个名次到底应该如何排?
2. 基于group的对战打分:如codeforces中一场比赛,该场次排名为第x位,那么总积分应该是多少?

## 1V1,积分分值和概率转换
假如有A和B进行对战,A的积分为x,B的积分为y, 积分越高能力越强,能力越强赢得概率越大(不是绝对的赢或者输,否则就没有比赛的必要了),那么如何衡量A赢B的概率呢?
1. x=y: A和B的能力相等,赢的概率各50%
2. x>y: A比B强,赢得概率比B大;x<y则相反

那么如何将x和y和概率值对接起来呢?
观察一下, x=y -> 0.5, 而且x和y比较才有意义,那么我们就取x-y,可以很容易想到sigmoid function,如下:
p(A赢B) = sigmoid(k(x-y)), 其中k是参数,用于调节sigmoid function的形状。
其中, sigmoid(x) = 1/(1+e^x)

## 1V1,获胜概率和分值更新
如果A获胜,B失败,那么A的分值必定增加,B的分值必定减少。
x-y越大,A增加的越少,B减少的越小;
x-y越小,A增加的越大,B减少的越大。
参考Elo rating system,保持群体总分值不变(除非有个体加入),那么A的增加的分值,必定等于B的减少的分值。
x_new = x_old + K * (1 - p)
y_new = y_old + K * (0 - (1-p))
K表示步长,1表示获胜,p表示A赢B的概率,该公式将预估值往真实值移动。

## Group,Group Ranking和Total Ranking
-- 待思考补充

## 冷启动
各自设置启动分值即可,比如codeforces上的1500分

## 不好的积分系统
王者荣耀的积分系统,是不好的。
积分分为几种:青铜,白银,黄金,铂金,钻石,王者。
这几种大的段位,每个段位里有N个小段位,满五颗星星晋级一段位,赢一场积攒1颗星。
但是王者有“经验机制”,即打满x盘之后,积累的经验,也可以获得一颗星。
所以其群体总积分是不断变大的,因此理论上,只要打的足够多,每个人都可以成为王者。
因此引入了赛季机制,新的赛季默认降低1-2个段位,即是在补“经验机制”的坑。
因此每到新赛季,连低端段位都很难打。
我猜测项目组这么做的意义在于,鼓励多打,多打游戏,不流弊也可以上王者。

参考资料:
http://codeforces.com/blog/entry/102
https://en.wikipedia.org/wiki/Elo_rating_system
163 changes: 163 additions & 0 deletions rec-sys/推荐系统中的相似性探讨.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

#### 1. 从购物篮到文式图
在常见的购物篮分析中,常常出现这样的数据:

|购物篮 |
|---|
|A B |
|B C |
|A B C |
|A B |
|C D |
|D E |
|C E |

在讨论A和B的相似性的时候,用文式图可以方便的表示:
![](http://km.oa.com/files/photos/pictures/201702/1486644989_19_w487_h299.png)

那么A和B越相似的表现是:

1. 【频繁一项集】A和B的出现次数很多,数据充足有说服力,即频繁一项集大
1.1 count(A) = 3, count(B) = 4,这两个值足够大
2. 【support】A∩B的值很大,数据充足有说服力,表现为重合面积大,即频繁二项集大或者support高
2.1 频繁二项集 = count(A∩B) = 3,这个值越大越好
2.2 support = count(A∩B) / count(ALL) = 3 / 7,这个值越大越好

3. 【jaccard】A∩B的值在A∪B的中占比很大,有A就有B,表现为jaccard相似度高
3.1 jaccard(A, B) = count(A∩B) / count(A∪B) = 3/4 ,这个值越大越好


#### 2. 从文式图到行为关联
文式图应用到推荐往往是条件概率,求在先验下(使用A)后验的概率(使用B)是多少。
![](http://km.oa.com/files/photos/pictures/201702/1486645007_47_w447_h301.png)

【置信度】
如上图,可以计算置信度,值越大越相似:
confidence(B|A) = P(B|A) = P(使用B|使用A) = P(A∩B|A) = P(黄色|黄色+浅蓝) = 1.0

同理, (confidence可称conf)
conf(A|B) = 3/4

发现,
conf(B|A)和conf(A|B)不同,说明conf是非对称的相似度;
jaccard(A, B)和jaccard(B, A)相同,说明jaccard是对称的相似度。

【置信度的痛点】
但是推荐过程中,使用会出现偏热的现象,是因为后验B太热门导致的。

![](http://km.oa.com/files/photos/pictures/201702/1486645018_15_w856_h487.png)

A是用户的先验(比如是手管的app);
B1是一款热门软件(比如微信);
B2是一款相对冷门的软件(比如同步助手);

可以发现由于B1的体量太大,导致conf(B1|A)很大;
由于B2的体量较小,导致conf(B2|A)偏小;
但是明显应该推荐B2,因为B2都快和A重合进去了,应该对B1的体量进行惩罚。


【提升度】
提升度是置信度B1体量惩罚的其中一种方法,含义为:
![](http://km.oa.com/files/photos/pictures/201702/1486645097_74_w408_h275.png)


lift(B|A) = conf(B|A) / P(B) = p(A∩B) | (P(A) * P(B)) = count(A, B) * ALL / (count(A) * count(B)) = ( 3 乘 7 ) / (3 乘 4) = 21/12

其中,
lift等于1,表示先验知识A的知道与否对B的概率没有影响。
lift大于1,表示促进作用;
lift小于1,表示抑制作用;

发现,
lift(A|B)=lift(B|A),即lift是对称的。

又发现,
lift公式和cos很相似,对比下两者:
cos(A, B) = p(A∩B) / sqrt( P(A) * P(B) );
lift(A, B) = p(A∩B) / ( P(A) * P(B) )
差别仅仅在于一个sqrt,所以cos又被称作,harmonized lift,因为化简后,
cos = count(A, B) / sqrt( count(A) * count(B) )
lift = count(A, B) * ALL / (count(A) * count(B))
所以lift和ALL相关,而cos和ALL无关,只关心A和B,不关心外界。

【KULC&IR】
因为lift对于ALL非常的敏感,如果为了消除这种null-transactions的影响,可以用cos来代替。
或者,
因为lift的错误是因为A和B的量级不同导致的,可以人为的规定【IR】必须小于多少,保证样本的平衡性,IR越小越好:
IR(A, B) = |P(A) - P(B)| / (P(A) + P(B) - P(A∩B))
或者,
因为lift的错误是因为A和B的量级不同导致的P(A|B)和P(B|A)的不同,把这两者平均一下,用KULC的指标来解决,KULC越大越好:
KULC = 0.5P(B|A) + 0.5P(A|B)

【总结】
在实际应用中,一般需要如下步骤:
1. 清洗列表数据,去掉过长、过短等明显错误的记录;
2. 设置频繁一项集数值,低于该值便过滤;
3. 设置频繁二项集数值,低于该值便过滤;
4. 求解IR,设置IR阈值,高于该值过滤;
5. 求解cos, support, conf, lift, support, KULC 并设置阈值,低于该值过滤;
6. 选择conf或者kulc或者自设一个指标排序。

其他:
【卡方值】
和lift特性非常相似的还有卡方值,其和lift指标二选一即可,此处不再介绍。
【LLR】
全称,log-likelihood ratio,是根据熵的变化计算相似度的一种方式。
对于item项A和B来说,有:
![](http://km.oa.com/files/photos/pictures/201705/1495172195_6_w527_h175.jpg)
LLR的计算公式为:
![](http://km.oa.com/files/photos/pictures/201705/1495172286_7_w372_h43.jpg)
其中,熵的计算方法为:
![](http://km.oa.com/files/photos/pictures/201705/1495172302_17_w430_h47.jpg)
由公式可知:
1. 满足交换律,LLR(a,b)=LLR(b, a)
2. 表达式恒大于0,0表示不相关,>0表示相关,可能正相关,也可能负相关。
![](http://km.oa.com/files/photos/pictures/201705/1495174122_13_w1380_h340.png)
![](http://km.oa.com/files/photos/pictures/201705/1495174132_11_w994_h1176.png)


#### 3. 从行为关联到多维度距离度量之cos
行为是一个维度,物品A和物品B可能是多维度的,比如内容维度等等。又或者把user-item矩阵(N*M)来看成有N个维度,那么A和B的相似就是A向量和B向量的相似。

【cos】
上文已经提到了cos,此处的cos和上文的不同在于,user-item矩阵可以是实数型的,而关联矩阵必须是0-1矩阵。
假设A和B是两个item,有
cos(A, B) = A * B / (|A| * |B|)

【用adjust-cos去掉user-bias】
如果考虑到每user的打分标准都不同,user1喜欢打高分,user2喜欢打低分,应该把用户的打分标准减掉,有
adjust_cos(A, B) =
![](http://km.oa.com/files/photos/pictures/201702/1486645132_67_w306_h63.png)

【用pearson去掉item-bias】
如果把A和B的向量归一化去掉bias,再做cos,即pearson的相似度:
![](http://km.oa.com/files/photos/pictures/201702/1486645141_34_w243_h66.png)

【去掉matrix的bias】
将所有的值都减去平均值,即可。

【总结】
1. 得到user-item matrix打分矩阵
2. 去掉matrix bias
3. 去掉user bias
4. 去掉item bias
5. 做cos

另外,
还有一些其他的距离,业务上用的不多,此处不再介绍:
欧式距离,编辑距离,曼哈顿距离(simhash可能有用)等等。

【多目标问题】
推荐的目标有两个的时候(比如转化率和商业价值),需要用到切比雪夫距离,通过计算pareto占优,去掉转化率和商业价值都不足的模型。


#### 4. 分布的相似性
分布的相似性目前在推荐业务中用的不多,理解还不深入。

【KL散度】
![](http://km.oa.com/files/photos/pictures/201702/1486645151_37_w543_h85.png)

【互信息】
Mutual information can also be expressed as a Kullback–Leibler divergence of the product p(x) × p(y) of the marginal distributions of the two random variables X and Y, from p(x,y) the random variables' joint distribution:
![](http://km.oa.com/files/photos/pictures/201702/1486645160_12_w382_h57.png)

0 comments on commit aadb3b0

Please sign in to comment.