我使用SGD算法实现了矩阵分解,但是在运行预测矩阵时经常得到NaN。当我在非常小的(6 x 7)矩阵上运行算法时,错误出现的次数很少。当我移至“电影镜头”数据集时,每次运行算法时,所有单元格中都会出现错误。只有在某些单元格中错误消失的唯一时间是当我将优化步骤(迭代次数)设置为1时。
private static Matrix matrixFactorizationLarge (Matrix realRatingMatrix,Matrix factor_1,Matrix factor_2)
{
int features = (int) factor_1.getcolumnCount();
double learningRate = 0.02;
double regularization = 0.02;
int optimizationSteps = 10;
Matrix predictedRatingMatrix = SparseMatrix.Factory.zeros(realRatingMatrix.getRowCount(),realRatingMatrix.getcolumnCount());
for (int step = 0; step < optimizationSteps; step++)
{
for (int row = 0; row < predictedRatingMatrix.getRowCount(); row++)
{
for (int col = 0; col < predictedRatingMatrix.getcolumnCount(); col++)
{
if (realRatingMatrix.getasInt(row,col) > 0)
{
Matrix vector_1 = getRow(factor_1,row);
Matrix vector_2 = getcolumn(factor_2,col);
predictedRatingMatrix.setasDouble( ( Math.floor ( dotProduct(vector_1,vector_2) * 100 ) ) / 100,row,col);
for (int f = 0; f < features; f++)
{
factor_1.setasDouble( ( Math.floor ( ( factor_1.getasDouble(row,f) + ( learningRate * ( ( calculateDerivative(realRatingMatrix.getasDouble(row,col),predictedRatingMatrix.getasDouble(row,factor_2.getasDouble(f,col) ) ) - ( regularization * factor_1.getasDouble(row,f) ) ) ) ) * 100 ) / 100),f);
factor_2.setasDouble( ( Math.floor ( ( factor_2.getasDouble(f,col) + ( learningRate * ( ( calculateDerivative(realRatingMatrix.getasDouble(row,factor_1.getasDouble(row,f) ) ) - ( regularization * factor_2.getasDouble(f,col) ) ) ) ) * 100 ) / 100),f,col);
}
}
}
}
}
return predictedRatingMatrix;
}
相关方法如下:
private static double dotProduct (Matrix vector_A,Matrix vector_B)
{
double dotProduct = 0.0;
for (int index = 0; index < vector_A.getcolumnCount(); index++)
{
dotProduct = dotProduct + ( vector_A.getasDouble(0,index) * vector_B.getasDouble(0,index) );
}
return dotProduct;
}
private static double errorOfDotProduct (double original,double dotProduct)
{
double error = 0.0;
error = Math.pow( ( original - dotProduct ),2 );
return error;
}
private static double calculateDerivative(double realValue,double predictedValue,double value)
{
return ( 2 * (realValue - predictedValue) * (value) );
}
private static double calculateRMSE (Matrix realRatingMatrix,Matrix predictedRatingMatrix)
{
double rmse = 0.0;
double summation = 0.0;
for (int row = 0; row < realRatingMatrix.getRowCount(); row++)
{
for (int col = 0; col < realRatingMatrix.getcolumnCount(); col++)
{
if (realRatingMatrix.getasDouble(row,col) != 0)
{
summation = summation + errorOfDotProduct(realRatingMatrix.getasDouble(row,col));
}
}
}
rmse = Math.sqrt(summation);
return rmse;
}
private static Matrix csvToMatrixLarge (File csvFile)
{
Scanner inputStream;
Matrix realRatingMatrix = SparseMatrix.Factory.zeros(610,17000);
// Matrix realRatingMatrix = SparseMatrix.Factory.zeros(6,7);
try
{
inputStream = new Scanner(csvFile);
while (inputStream.hasnext()) {
String ln = inputStream.next();
String[] values = ln.split(",");
double rating = Double.parseDouble(values[2]);
int row = Integer.parseInt(values[0])-1;
int col = Integer.parseInt(values[1])-1;
if (col < 1000)
{
realRatingMatrix.setasDouble(rating,col);
}
}
inputStream.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
return realRatingMatrix;
}
private static Matrix createFactorLarge (long rows,long features)
{
Matrix factor = DenseMatrix.Factory.zeros(rows,features);
return factor;
}
private static void fillInmatrixLarge (Matrix matrix)
{
for (int row = 0; row < matrix.getRowCount() ; row++)
{
for (int col = 0; col < matrix.getcolumnCount(); col++)
{
double random = ThreadLocalRandom.current().nextDouble(5.1);
matrix.setasDouble( (Math.floor (random * 10 ) / 10),col);
}
}
// return matrix;
}
private static Matrix getRow (Matrix matrix,int rowOfIntresst)
{
Matrix row = Matrix.Factory.zeros(1,matrix.getcolumnCount());
for (int col = 0; col < matrix.getcolumnCount(); col++)
{
row.setasDouble(matrix.getasDouble(rowOfIntresst,col);
}
return row;
}
private static Matrix getcolumn (Matrix matrix,int colOfInteresst)
{
Matrix column = Matrix.Factory.zeros(1,matrix.getRowCount());
for (int index = 0; index < matrix.getRowCount(); index++)
{
column.setasDouble(matrix.getasDouble(index,colOfInteresst),index); //column[row] = matrix[row][colOfInteresst];
}
return column;
}
是什么导致错误,因为我在算法中未除以零?而我该如何解决呢?
P.S。我正在使用通用矩阵库软件包