ItemCF优化点见解

xlvector大牛在他文章里说:

ItemCF这个算法肯定很多人用过,这里我不谈在线优化ItemCF的问题,仅仅讨论离线的ItemCF算法。我这里谈到的这三个优化方法在我目前遇到的所有数据集上都是有效的,包括最近举行的KDD Cup。

ItemCF算法包含了两个部分:1)算出item的相似度矩阵 2)计算推荐结果

那么,三种优化方式就是

1. 在计算item相似度的时候,对于每一个用户,我们往往是将他看过的item两两加一。但是用户的活跃度不同,如果一个用户看了10000个电影,另一个只看了10部电影,那么看10000部电影的用户对他看的电影的相似度的贡献应该要小于看10部电影的。所以,每次应该不是将用户看过的item两两加一,而是加上一个 1 / log(3 + nu),nu是这个用户看过的电影的数目。

2. 对于算完的相似度,要做归一化。即如果w(i,j)是i,j的相似度,我们需要将w(i,j)做行归一化。

3. 最后的优化方法当然是选择邻域的数目,就是那个K。

除了这三个部分,itemcf能发掘的就不多了。

在认为发掘部分除了这三部分,其他挖掘点不过, 觉得不敢苟同。
其实在建模本身挖掘点还是很多的,比如:
建模本身 在建立关系矩阵的时候是否把用户观看电影的次数加进去,或者时长(针对看电影场景),比如在AppStore上用户玩过某款应用的次数和对改应用的兴趣度至少是正相关的。 或者建模本身不用关系矩阵,而是用欧几里德或者皮尔逊相关系数、余弦相似度?
计算w(i,j)的相似度对应公式的优化 对于w(i,j)=|N(i) 交 N(j)| / (|N(i)|^(1-a) *|N(j)|^a) 其中1-a本身是不一定合理的,我在没学习ItemCF之前是用的5-a ,其中a=4,效果远比1-a的任何a取值来的理想。 因为在选择1-a还是5-a的问题上,是对单个i相似度之间距离放大还是收敛,放大意味着希望TopN里包含的i的推荐j都有一定占比。(会有一种穿插排序的效果),而缩小则是相反。

自然

最近在做推荐系统,起初没有看任何资料自己想了一套出来,然后不断优化。 而前几天看了下业界作法,既然看到一个几乎一模一样的模型…而我只是在他的基础上加下优化。 不禁问自己什么是算法呢,算法就是找到合适的方法解决实际问题

一种开放地址方法解决Hash冲突

今天在用共享内存做cache的时候发现之前简单用id mod p的方法并不能满足条件,有太多了Hash冲突,导致一些数据不能有效cache。那么怎么解决冲突呢?

首相说下数据特点,每个key存1kb左右的信息。 共享内存要开辟key的个数打算控制在1w左右的级别。毕竟能少用就尽量少用。  而实际有效key的个数在3k以内。id大小在32位整数以内。要做hash的目的无非想直接寻址。 所以现在说说怎么有效用1w的空间有效对id做Hash,并友好地解决冲突。由于一些通用的开放地址方法对数据删除或者更新等操作比较麻烦。或者从算法的优美角度来说,比较蹩脚。下面就尝试一些自以为比较好的方法。

最开始尝试的是有冲突就继续用不通的质数p取模,直到所有冲突解决。这样我允许对数据做删除等操作,只要在查找操作的时候对所有使用过的质数取模查找一遍才判定是否成功。但是从实际实践上来看,到底要多少次Hash才会解决冲突呢,这个数值没办法估量。虽然实际实践中4次左右基本所有冲突都解决了,但是理论上还是会存在尝试n个p之后还是有冲突,而且这个n不好估量,甚至造成Hash查找是线性的。  所以这个想法最终放弃。  也想过给每个Hash值做一个桶,但是这个桶的代价比较大,整个空间的大小成倍增长,而且桶的长度也是不可估量的。所以继续放弃这个念头。

不经意间想:为何不让所有冲突的Key统一解决呢,并且给他开辟更小的空间。 浮现在脑海一个念头,将空间分成两块,每次以2倍左右的速度缩小空间,这样就能保证空间大小不变,而且很好的控制了冲突的次数,最坏情况需要log(n)的查找次数。 而且如果Hash的空间比id的个数来的大,并且在5倍左右的话,这个完全冲突的概率是非常小的。而且20%左右的Hash利用率已经是不错了。从实际数据来看这个策略冲突次数非常少,基本冲突只有两次。

至于如果真有经过log n次Hash之后还是冲突可以复制同样一份大小的空间,同样的策略走下去。不过对我这个应用场景来说没必要这么做,最后舍弃也OK。

大概的思路就如图所示,冲突之后就“折半”空间继续Hash。每次Hash空间都是一个质数。  至于如何证明这个冲突概率到底多小的问题还在研究中。继续完成这个策略

智能推荐——聚类

问题本身的目的是:根据用户在玩游戏信息,构造一些具有相同用户兴趣游戏的聚类。即如果用户P1、P2、…Pn 绝大多数都同时玩A1、A2…An  ,然后从Ai 组成的集合算出聚类。这样就可以根据用户Pi在玩的游戏信息,结合相关聚类信息给他推荐其它认为他喜欢的游戏。

目前我的处理方法是先构造一个带权无向图: 将每个游戏看成单独的结点,如果Pi用户同时玩了游戏A和B,就将连接结点A和结点B边的权重加1,同时将结点本身的出现次数加1。这样形成的带权无向图特点就是连接N(i)和N(j)边( 记为E(i,j) )的权重越高,说明同时在玩N(i)和N(j)的人越多。而 E(i,j)权重 / N(i)次数 就是玩游戏i同时再玩游戏j的概率。

原本打算根据图的连通性来构造聚类。但是从应用场景来看没必要这么做。只要根据用户热玩游戏作为根结点,然后遍历和根结点相关联结点。形成一个聚类,再给这个聚类游戏做排序。具体排序规则就不便透露了,就当商业机密 哈哈

 

Hello World

一点生活一点阅读一点代码
刚刚开始,有建议请留言