基于矩阵分解的推荐算法(java代码实现)
来源:互联网 发布:八方网络 编辑:程序博客网 时间:2024/04/25 12:06
目前推荐系统中用的最多的就是矩阵分解方法,在Netflix Prize推荐系统大赛中取得突出效果。以用户-项目评分矩阵为例,矩阵分解就是预测出评分矩阵中的缺失值,然后根据预测值以某种方式向用户推荐。常见的矩阵分解方法有基本矩阵分解(basic MF),正则化矩阵分解)(Regularized MF),基于概率的矩阵分解(PMF)等。今天以“用户-项目评分矩阵R(N×M)”说明三种分解方式的原理以及应用。
用户-项目评分矩阵
Basic MF:
Basic MF是最基础的分解方式,将评分矩阵R分解为用户矩阵U和项目矩阵S, 通过不断的迭代训练使得U和S的乘积越来越接近真实矩阵,矩阵分解过程如图:
矩阵分解过程
预测值接近真实值就是使其差最小,这是我们的目标函数,然后采用梯度下降的方式迭代计算U和S,它们收敛时就是分解出来的矩阵。我们用损失函数来表示误差(等价于目标函数):
损失函数 公式1
公式1中R_ij是评分矩阵中已打分的值,U_i和S_j相当于未知变量。为求得公式1的最小值,相当于求关于U和S二元函数的最小值(极小值或许更贴切)。通常采用梯度下降的方法:
梯度下降
学习速率是学习速率,表示迭代的步长。其值为1.5时,通常以震荡形式接近极值点;若<1迭代单调趋向极值点;若>2围绕极值逐渐发散,不会收敛到极值点。具体取什么值要根据实验经验。
Regularized MF
正则化矩阵分解是Basic MF的优化,解决MF造成的过拟合问题。其不是直接最小化损失函数,而是在损失函数基础上增加规范化因子,将整体作为损失函数。
红线表示正则化因子,在求解U和S时,仍然采用梯度下降法,此时迭代公式变为:(图片截取自相关论文,S和V等价)
梯度下降
梯度下降结束条件:f(x)的真实值和预测值小于自己设定的阈值(很小的值,之前一直理解为是变量U和V的迭代值差小于阈值就行)
Java代码实现矩阵分解
public class Test { private static int N=5;//用户的数目 private static int M=4;//产品的数目 private static int K=2;//特征的数目 private static DecimalFormat df=new DecimalFormat("###.000"); public static void main(String[] args) { double[] R=new double[N*M]; double[] P=new double[N*K]; double[] Q=new double[N*M]; R[0]=5; R[1]=3; R[2]=0; R[3]=1; R[4]=4; R[5]=0; R[6]=0; R[7]=1; R[8]=1; R[9]=1; R[10]=0; R[11]=5; R[12]=1; R[13]=0; R[14]=0; R[15]=4; R[16]=0; R[17]=1; R[18]=5; R[19]=4; System.out.println("R矩阵"); for(int i=0;i<N;++i) { for(int j=0;j<M;++j){ System.out.print(R[i*M+j]+","); } System.out.println(); } //初始化P,Q矩阵,这里简化了,通常也可以对服从正态分布的数据进行随机数生成 for(int i=0;i<N;++i) { for(int j=0;j<K;++j) { P[i*K+j]=Math.random()%9; } } for(int i=0;i<K;++i) { for(int j=0;j<M;++j) { Q[i*M+j]=Math.random()%9; } } System.out.println("矩阵分解开始"); matrix_factorization(R,P,Q,N,M,K); System.out.println("重构出来的R矩阵"); for(int i=0;i<N;++i) { for(int j=0;j<M;++j) { double temp=0; for (int k=0;k<K;++k){ temp+=P[i*K+k]*Q[k*M+j]; } System.out.print(df.format(temp)+","); } System.out.println(); } } public static void matrix_factorization(double[] R,double[] P,double[] Q,int N,int M,int K){ int steps=5000; double alpha=0.0002; double beta=0.02; for(int step =0;step<steps;++step){ for(int i=0;i<N;++i) { for(int j=0;j<M;++j){ if(R[i*M+j]>0){ double eij = R[i*M+j]; for(int k=0;k<K;++k){ eij -= P[i*K+k]*Q[k*M+j]; } for(int k=0;k<K;++k){ P[i*K+k] +=alpha * (2 * eij * Q[k*M+j] - beta * P[i*K+k]); Q[k*M+j] +=alpha * (2 * eij * P[i*K+k] - beta * Q[k*M+j]); } } } } double loss=0; for(int i=0;i<N;++i){ for(int j=0;j<M;++j) { if(R[i*M+j]>0){ double eij =0; for(int k=0;k<K;++k){ eij += P[i*K+k]*Q[k*M+j]; } loss += Math.pow(R[i*M+j]-eij,2); for(int k=0;k<K;++k){ loss += (beta/2) * (Math.pow(P[i*K+k],2) + Math.pow(Q[k*M+j],2)); } } } } if(loss<0.001){ break; } if (step%1000==0){ System.out.println("loss:"+loss); } } }}
- 基于矩阵分解的推荐算法(java代码实现)
- 基于矩阵分解推荐算法之交替最小二乘法(ALS)--附实现代码
- 基于矩阵分解的推荐算法
- 基于矩阵分解的推荐算法
- 推荐算法——基于矩阵分解的推荐算法
- 基于评分数据的推荐算法实现:slopeone和矩阵分解
- 基于矩阵分解的推荐算法,简单入门
- 基于矩阵分解的推荐算法,简单入门
- 基于Spark mllib的矩阵分解(ALS)推荐算法
- 基于随机梯度下降的矩阵分解推荐算法
- 基于SVD矩阵分解的推荐算法及其应用
- 基于大数据的推荐算法研究(4)——矩阵分解并行化
- 推荐系统---基于概率的矩阵分解(PMF)
- 基于矩阵分解的推荐系统
- 非负矩阵分解算法基于hadoop streaming的实现
- 协同过滤-矩阵分解推荐 java实现
- 基于矩阵分解的推荐算法-梯度下降算法-非并行计算[转载]
- 推荐系统系列---基于movielens数据集的KNN算法与矩阵分解算法比较
- jsp select option赋值
- Android 弹出软键盘android:windowSoftInputMode设置总结
- Android组件化设计开发模式
- android studio adb.exe停止工作问题解决
- Java中网络相关API的应用
- 基于矩阵分解的推荐算法(java代码实现)
- 源文件Arith.java
- Android 美团Robust热更新 使用入门
- 语音识别系统CMUsphinx环境安装
- mysql分库分表实战及php代码操作完整实例
- PHP类和面向对象
- bootstrap中常涉及到的属性的含义
- linux端口相关操作命令
- windows下gvim的ctrl +v