Rating Prediction 评分预测

转:https://blog.csdn.net/woshimalingyi/article/details/50801196

注: 
1. 数据集合来源自 MovieLens 
2. 末尾附上源代码

一、Introduction
现在,各大网络购物平台的购物都会有评分机制,商家要给用户推荐其满意的商品,就需要了解用户的行为,基于用户行为进行分析,从而预测并给用户推荐适合的商品,提高商品转化率。用户行为多种多样,本实验是基于用户评分的行为,来预测用户未来的评分,一次作为给用户推荐的因素之一。

二、Methodology
将已有的数据分割为两部分,一部分作为用户过去的行为集(即训练集),另一部分作为用户评分预测集(即测试集),通过用户的行为集来预测其对其他未评分商品的评分。然后将预测的评分集与测试集比较进行误差计算。 
步骤:

读取数据文件,生成用户评分矩阵(行标为用户id,列标为电影id,元素值为评分).
对评分矩阵进行分割,生成训练集和测试集并存入两个矩阵当中。
对训练集使用LFM算法,得到隐含因子模型矩阵。
通过step 3的隐含因子模型矩阵生成一个预测矩阵。
将预测矩阵集与测试集进行比较 ,得到误差数据。
三、Trading Algorithm
隐含语义模型(LFM):

隐含语义技术简介 
假设用户A的兴趣涉及侦探小说、科普图书以及一些计算机技术书,而用户B的兴趣比较集中在数学和机器学习方面。那么,如何给A和B推荐图书呢? 
除了UserCF和ItemCF,还有一种方法:对用户的兴趣和书进行分类。对于某个用户,首先得到他的兴趣分类,然后从分类中挑选他可能喜欢的物品。 
总结一下,这个基于兴趣分类的方法大概需要解决3个问题: 
(1) 如何给物品进行分类? 
(2) 如何确定用户对哪些类的物品感兴趣,以及感兴趣的程度? 
(3) 对于一个给定的类,选择哪些属于这个类的物品推荐给用户,以及如何确定这些物品在一个类中的权重? 
在推荐系统领域,提的最多的就是潜语义模型和矩阵分解模型。其实,这两个名词说的是一回事,就是如何通过降维的方法将评分矩阵补全。 
用户的评分行为可以表示为一个评分矩阵 ,其中 就是用户u对物品i的评分。但是,用户不会对所有物品评分,所以这个矩阵里很多元素都是空的,这些空元素称为缺失值。因此,评分预测从某种意义上说就是填空,如果一个用户对一个物品没有评过分,那么推荐系统就要预测这个用户是否会对这个物品评分以及会评几分。

LFM算法及其改进(此处不做具体介绍) 
LFM算法有很多种形式: 
(1) 传统的SVD分解 
(2) Simon Funk的SVD分解(对SVD的改进) 
(3) 加入偏置顶后的LFM算法 
(4) 考虑领域影响的LFM

加入偏置顶后的LFM算法 
LFM预测公式: 


这个预测公式通过隐类将用户和物品联系在了一起,但是,实际情况下,一个评分系统有些固有属性和用户物品无关,而用户也有些属性和物品无关,物品也有些属性和用户无关。因此,我们使用Netflix Prize中提出的另一种LFM,其预测公式如下:

这个模型称为BiasSVD,预测公式中引入的3项作用如下:

训练集中所有记录的评分的全局平均数。在不同网站中,因为网站定位和销售的物品不同,网站的整体评分分布也会显示出一些差异。比如,有些网站中的用户就是喜欢打高分,而另一些网站的用户就是喜欢打低分。而全局平均数可以表示网站本身对用户评分的影响。
用户偏置项。这一项表示了用户的评分习惯中和物品没有关系的那种因素。比如有些用户就是比较苛刻,对什么东西都要求很高,那么他的评分就会偏低,而有些用户比较宽容,那么他的评分就会偏高。
物品偏置项。这一项表示了物品接受的评分中和用户没有什么关系的因素,比如有些物品本身质量就很高,因此获得的评分相对比较高,而有些物品本身质量很差,因此获得的评分都会比较低。 
这样,加入偏置项的LFM模型损失函数为: 
 
增加的3个参数中,只有 和 (一般在开始时初始化为全0的向量)是要通过机器学习训练出来的,同样,根据随机梯度下降法,可以得到如下递推公式: 
 
 
 

LFM算法损失函数:

for(int i=0;i<100&&loss>0.01;i++){
   for(int j=0;j<m;j++){
      for(int k=0;k<n;k++){ 
         if(matrixR[j][k]>0){
            float h = 0.0;
            for(int l=0;l<f;l++ ){  
               h += matrixP[l][j]*matrixQ[l][k];  
            }  
            float eui = matrixR[j][k]-coverage-B_u[j]-B_i[k]-h;
            // float  eui = matrixR[j][k]-h;
            for(int h=0;h<f;h++){  
               B_u[j]+= alpha * (eui  - lambda *B_u[j] ) ;
               B_i[k]+= alpha * (eui  - lambda *B_i[k]) ;
               matrixP[h][j] += alpha * (eui * matrixQ[h][k] - lambda * matrixP[h][j])  ; //  P[user][f] += alpha * (eui * Q[f][item] - lambda * P[user][f])  
               matrixQ[h][k] += alpha * (eui * matrixP[h][j] - lambda * matrixQ[h][k]) ;    // Q[f][item] += alpha * (eui * P[user][f] - lambda * Q[f][item])   
             }   
          }  
       }         
    }
    alpha*=0.9;
}

四、Result
评分的预测结果:(此处是部分截图)

 
参数解释: 
U_id: 用户id 
M_id: 电影Id 
T_grade : 测试评分 
P_grade: 预测评分

误差数据分析:(以下是对整个预测集合的误差分析结果)

五、Conclusion
通过结果数据可以看出,大部分数据的预测值与测试值的偏差在0.7左右。少数偏差较大的数据会达到1~2分。 
从结果来看, 
数据总体的相对误差为:26.39%; 
均方差(RMSE):0.74 分 
就结果来说,存在的误差还是比较大的。

对结果的影响因素有很多,归结了以下几点:

第一, MovieLens的Rating数据集中有100万条评分。但是,用户有6000个,电影有4000部,也就是说评分矩阵的大小是2400万,比例是1:24,因此实验所用的训练集矩阵就相当稀疏。所以造成误差较大;
第二, 对数据没有进行筛选处理,有一些用户只对一两部电影进行了评价,有些电影值被一两个用户评价,这样一来,计算该用户或改电影的隐含因子的可靠性就不会很高;
第三, 训练集和测试集的分割也会影响预测的精确度。 
第四, LFM算法中的几个影响因子参数的数值也会影响预测的精确度。
总的来说,实验基本完成,在数据稀疏的情况下,评分预测结果与测试值相差符合度还算较好。

点此处下载源代码

https://pan.baidu.com/s/1eQPgDaU

猜你喜欢

转载自blog.csdn.net/m0_38002798/article/details/83791758