本文作者:合肥工业大学 管理学院 钱洋 email:1563178220@qq.com 。
以下内容是个人的论文阅读笔记,内容可能有不到之处,欢迎交流。
未经本人允许禁止转载。
问题背景
最近,在使用Java实现一个个性化推荐算法时,遇到了非常常见的问题。实现的算法为:
Wang C, Blei D M. Collaborative topic modeling for recommending scientific articles[C]//Proceedings of the 17th ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2011: 448-456.
该算法主要针对的是科研文章的推荐问题。
在算法的公式推理中,即:
)
其中,CiC_{i}Ci为J∗JJ*JJ∗J的对角矩阵。对角矩阵上的值为:
由于我用的数据集包含16800左右的商品,即CiC_{i}Ci的维度为16800*16800。在算法实现的过程中,我已对其他变量做了初始化。
在产生该对角阵时,我是用了下面的操作方式:
public RealMatrix matrixCEachUser(int u){
double[][] cUserNew = new double[M][M];
for (int i = 0; i < rating[u].length; i++) {
cUserNew[rating[u][i]][rating[u][i]] = 0.99;
}
for (int i = 0; i < M; i++) {
if (cUserNew[i][i] < 0.5) {
cUserNew[i][i] = 0.01;
}
}
RealMatrix mat1 = new Array2DRowRealMatrix(cUserNew).transpose();
return mat1;
}
即如果rij=1r_{ij}=1rij=1,则该对角上的值为0.99,否则为0.01。但在实际产生这个大对角阵时,却出现了内存溢出,即:
Java heap space
同时,调整VM也没有解决。
为此,需要寻找更好的解决方案。
解决方案
为了防止内存溢出,能够进行矩阵运算,我这里使用了math3中的DiagonalMatrix类。在使用时,我将二维数组变成了一维数组,之后直接产生对角阵。解决的程序如下面所示:
//get matrix C_i: a diagonal matrix
public RealMatrix matrixCEachUser(int u){
double[] cUserNew = new double[M];
for (int i = 0; i < rating[u].length; i++) {
cUserNew[rating[u][i]] = 0.99;
}
for (int i = 0; i < M; i++) {
if (cUserNew[i] < 0.5) {
cUserNew[i] = 0.01;
}
}
DiagonalMatrix matrix = new DiagonalMatrix(cUserNew);
return matrix;
}