blog mail me! feed

协同过滤学习笔记: 稀疏?

上一篇里说到, 遇到稀疏的数据集的缺失数据的时候, 如何补充值的问题,
我采用的是补充一个评分均值以期减少这个引入的评分所产生的影响.

当然稀疏数据集同样面对的问题还有”cold start”, 系统越大, 这种效应越明显,
即一个新加入的项目不可避免的遇到评分人数相对的极低的现象,
按照上一篇我第一种考虑的方法, 这些新项目都会被不可避免的排除掉了.

当然这里又可以引出些讨论:
比如是不是根据评分的timestamp引入另外一个因子, 对近一段时间内的timestamp有更高的权重以期让那些低评分数的新项目出现呢?
不过我不想把这个系统改造得过于繁琐, 但是不可避免的, 如何去”揣测”和填充空缺的数据集是一个大问题.

Slope One算法可以简单的根据已有的用户的打分规则, 来推测当前用户”应该”或者”可能”的打分.
不过我把Slope One应用到我的”极其稀疏”的数据集中的后果就是, 使得结果更向那些孤立值倾斜.
我试图设立一些阈值来限制这些孤立”噪声”的出现, 但是效果很差.

我终于明白其实我这个根本不是什么稀疏不稀疏的问题 ,
是数据太少了, 还不足以通过协同过滤得到有效的结果.

我这几天也一直在考虑音乐站有关量化对于曲目, 专辑, 歌手的评分的问题,
毕竟一个量化的数值, 对于协同过滤以及其他任何算法来说, 都是一个必须的数字.
引入曲目后, 有些东西变得更微妙了,
比如A用户可能喜欢X专辑中的所有歌, 除了最后两首,
但是对喜欢的歌标记”喜欢”是非常烦琐和机械化的操作, “既然我默认喜欢, 为什么就不简单的放下去就行了呢?”

播放行为在最开始的时候, 应该是随机的, 除非用户从某个tag开始收听节目,
当然这要涉及到具体这个音乐站怎么被设计来生成播放清单了.
这样无数的行为都可能对评分产生微妙的影响,
让我的微小的脑子想得十分生涩的痛苦. 

所以, 也许所谓的”烦琐”的标注”喜欢”的动作,
是必须的, 为了你听到更好的音乐推荐, 动动鼠标吧.

协同过滤的学习笔记: 关于稀疏数据集.

最近在平面格子上做了一个测试,
豆瓣上选取了标签为indie, pop, rock的各前100张专辑组成数据集,
交给用户打分, 在这里先谢谢了帮我完成这个无趣的测试的所有人.

之所以做这个是因为MovieLens的数据集里的电影自己几乎都没看过,
也就无从得知”相关度”的问题.

不过这300张专辑的样本同样有个问题是, 很多独立音乐, 和较老的摇滚音乐,
很多人是没有听过的, 于是在进行协同过滤的时候, 我把这些”没听过”的记录都通通删除掉, 
结果问题就出来了, 项目间的相关性变得很奇怪, 甚至出现了很多1.0, 而真正”应该”相关的数据, 相关度不理想.

的确, 如果我们把每个项目来自不同用户的评分看做一个向量的话,
对于项目A我们有评分a1, a2, a3, …, am
项目B我们有评分b1, b2, b3, …, bn
理想的状况是, 这个数据集是密集的, 因而m和n应该非常接近甚至相等.

然而由于前面提到的问题, 大量的”没听过”的记录使得数据集变得异常稀疏,
假设一张冷门专辑X, 恰好有一个用户打分,
而这位用户也恰好给另一张专辑Y打了同样的分,
因此尽管 X, Y向量的维度有着巨大的差异,
但不影响我们通过余弦求出的两者夹角余弦值为1.

而正是这样类似的大量的稀疏数据所产生的随机效应和孤立因子,
使得相关性中出现了大量的这种效应引入的具有极高随机性的值,
显然, 在最开始设计算法的时候, 忽略了这个问题.

我着手改变这种因为稀疏数据集从而引入的相关性准确度大幅下降的问题,
我自己想到的两种方法是:

  1.  将每两个项目同时评分的人数, 标准化在区间[0, 1]之内 (利用所有项目对的评分人数算出的μ和σ进行), 将这个作为一个因子. 基于这个因子进行过滤也好, 或者直接把这个因子乘上相关性因子得到修正值也行.
  2. 对缺失的数据, 人为的填充数据.
在考虑第二种方法的时候, 我看到一个比较有趣的算法,
即, 通过用户已有的评分值, 来进行缺失项的评分预测.
当然我相信这个预测是非常粗糙的, 尽管我还没有看过这个算法的具体实现,
但是我一直在考虑这样的预测是否陷入了一种循环中. 

另外一种填充法相对简单, 取一个相对的中值或者和用户的评分均值最接近的因子,
这样对最后的相关性的影响是最小的, 也避免了上面的算法的复杂度和可能的预测偏差. 

进行如上的填充工作后, 最后的相关性结果就理想多了.
的确, 对于这个信息量膨胀的时代, 稀疏数据集可能远比密集数据集出现得普遍,
如何更好的消除数据稀疏性, 是一个很好的问题.

越写越乱, 索性不写了.