The Art of Lemon队的KDD CUP 2011 Track 2解决方案大致思路
随着KDD CUP 2011的结束,需要开始总结我们的解决方案了。我们在最终测试集Test2中排名第二,和在排行榜中测试集Test1上的排名是一致的。我先发一篇 Blog大致总结一下我们的方案,一来自己回顾和理清整个过程便于后面详细的写Solution Paper,二来与大家分享我们队的成果。
Track2的任务是这样的。给定训练集中包含许多用户对歌曲、曲集、歌手、曲风的打分,但不提供打分时间。同时也提供了歌曲、曲集等在内容上的关系,如
每个歌曲是哪个歌手唱的,属于哪个曲集。给定的测试集中包含部分用户,以及每个用户对应给出了6首歌曲。已知这6首歌曲中是包含3首实际被用户打了80分
或以上,另外3首没有被打分。任务就是在测试集中分辨出被用户打了分的歌曲。
对分数的预测在实际系统中用处并不是特别大,这可能就是Track2产生的原因。
- 制作Validation Set
由于Track 2没有给出Validation Set,所以需要自己制作用于本地测试。因为问题中已经给出了负样本的采样策略,按照实际测试集的产生方法制作即可。
- 基于内容的模型
首先根据经验和数据分析,有很大一部分人只听某个歌手的歌,还有很大一部分人只听某几个歌手的歌。因此单纯根据歌手、曲集等信息就能判断许多用户。 具体方法是判断测试集中的歌曲的歌手是否被打过分(或者他唱过的歌被打过分)、曲集是否被打过分(或者他收录的歌被打过分),然后计算这些相关打分的加权 平均分用来预测。如果一个歌没有曲集或者歌手,那么显然是不公平的,所以可以对他们指定某个非0预测值。此方法没有用到曲风,我们最后也没有找到很好的方 式利用曲风。这个模型大概能到13%左右的错误率。
- Item CF
计算测试集中的每个歌曲和该用户已经打过分的所有Item的相似度。我们对计算相似度的方法进行了改进,当然这里面经过了无数的曲折和各种模型。我
大致写一下最好的一个模型的思路。我们发现训练集中的各个打分虽然没有给出时间,但是是具有时间序的,也即每个用户的所有记录是按照时间先后排列的。这样
就有一个自然的想法,如果两个Item被同一用户打过分,但是距离很远,那么对相似度的贡献应该相对较小。
计算两个Item相似度的时候我们对于所有同时被一个用户打分的情况,在相似度的分子和分母上同时增加一个量,否则就在分母上增加一个量。前者还需要乘以
一个时间衰减系数,用来体现时间间距对相似度贡献的变化,也可以再乘以一个分数衰减系数,也即两个Item打分差别很大则降低相似度上的贡献。另外由于和
打分高的Item相似以及和打分低的Item相似的意义不同,因此还需要再乘以一个分数的某次方作为权重。最后取最相似的若干Items求平均相似度即
可。
Item CF还是倾向于推荐热门曲目,所以最后还要再除以一个打分次数的某次方作为惩罚。
这个方法大约可以达到3.8%左右的错误率。
- 矩阵分解模型
我们主要使用了SVD和NSVD模型,相比常见的模型形式做了一些修改。首先由于缺乏负样本,只用分数做SVD效果很一般,因此需要进行负样本采样。可以考虑正样本的“打分”为1,负样本的“打分”为-1,然后建立SVD模型。也可以让正样本根据分数分散在1的附近。
SVD中,我们额外增加了Item的歌手和曲集的对应Bias项,以及用户是否对相应歌手、曲集打过分的Bias项。后面的Bias项比较强,思想和基于内容的模型类似:用户倾向于给打过分的歌手、曲集包含的歌曲打分。
SVD模型可以达到大约3.5%左右的错误率,如果不使用最后两种Bias项可以达到大约6%左右的错误率。
NSVD模型使用用户打过分的Item向量来“求平均”获得用户向量。其余与SVD模型类似。可以达到大约4%的错误率。
实际求解时我们发现,最后两个Bias项非常强,可以考虑先不使用,等迭代到一定程度再加入,否则更容易陷入不是很好的局部最优解。我计算矩阵分解模型的时候,中间结果都是保存的,下次修改方法再继续迭代,这样不是很“完美”,不过常常得到更好的结果。
- 算法融合
和Track1的RMSE不同,Track2的目标函数不是连续的,性质非常不好,类似组合优化问题。因此我们使用了模拟退火求解多个模型计算结果 的线性融合系数。后来发现本地的Validation Set在我们突破2.7%的错误率以后已经逐渐开始过拟合,而我们又来不及再把所有算法在新的测试集上重新计算了。于是我们将Validation Set均分为N份,用模拟退火在某N-1份上求出最佳线性融合系数,这样得到的N个线性融合系数再求平均作为最终融合系数。这样虽然仍然不是很稳定,但是 基本上解决了测试集过拟合的问题。我们的最终模型融合的最好结果是2.5%左右,是由多个3%以上和错误率更高的模型融合而来。
- 后处理
我之前从来没听说过后处理。大致思路就是对某类用户、某类Item的预测值统一乘以一个和1距离不太大的系数,使得预测值更准确。为了不过拟合,必 须保证每次是对比较多的预测值进行统一修改,并且在本地和提交结果中均有比较明显的提高。例如对最热门的若干歌曲均乘以一个系数进一步抑制对热门歌曲的推 荐。这样可以弥补之前所有模型中的缺陷,而这些缺陷往往由于多种原因不能特别“细致”的反映在模型中,但后处理可以做的很“细致”。后处理大约可以使得融 合后的模型进一步提高0.2%至0.3%的正确率。