Apache spark 使用spark的ALS时,如何使RMSE(均方根误差)变小?

Apache spark 使用spark的ALS时,如何使RMSE(均方根误差)变小?,apache-spark,pyspark,apache-spark-mllib,collaborative-filtering,Apache Spark,Pyspark,Apache Spark Mllib,Collaborative Filtering,我需要一些建议来建立一个好的模型,通过spark的协同过滤来进行推荐。中有一个示例代码。我还回顾了以下几点: 来自pyspark.mllib.recommendation导入ALS、MatrixFactoryizationModel、评级 #加载并解析数据 data=sc.textFile(“data/mllib/als/test.data”) ratings=data.map(lambda l:l.split(','))\ .map(lambda l:Rating(int(l[0])、int(

我需要一些建议来建立一个好的模型,通过spark的
协同过滤
来进行推荐。中有一个示例代码。我还回顾了以下几点:

来自pyspark.mllib.recommendation导入ALS、MatrixFactoryizationModel、评级
#加载并解析数据
data=sc.textFile(“data/mllib/als/test.data”)
ratings=data.map(lambda l:l.split(','))\
.map(lambda l:Rating(int(l[0])、int(l[1])、float(l[2]))
#使用交替最小二乘法建立推荐模型
排名=10
数量=10
模型=ALS.列车(额定值、等级、数量)
#根据训练数据评估模型
testdata=ratings.map(lambdap:(p[0],p[1]))
预测=model.predictAll(testdata).map(λr:((r[0],r[1]),r[2]))
ratesAndPreds=ratings.map(lambdar:((r[0],r[1]),r[2])).join(预测)
RMSE=ratesAndPreds.map(λr:((r[1][0]-r[1][1])**2.mean())**.5)
打印(“均方根误差=“+str(RMSE))
一个好的模型需要尽可能小的RMSE

这是因为我没有将适当的参数设置为
ALS.train
方法,例如rand numIterations等等

还是因为我的数据集很小,所以RMSE变大了

所以,谁能帮我找出RMSE很大的原因以及如何修复它呢

添加:

正如@eliasah所说,我需要添加一些细节来缩小答案集。让我们考虑一下这个特殊的情况:

现在,如果我想建立一个推荐系统,向我的客户推荐音乐。我有他们的歌曲、专辑、艺术家和流派的历史比率。显然,这4个类构建了一个层次结构。曲目直接属于相册,相册直接属于艺术家,艺术家可能属于几种不同的类型。最后,我想使用所有这些信息来选择一些曲目推荐给客户


那么,为这些情况建立一个好的模型并确保RMSE尽可能小以进行预测的最佳实践是什么呢。

我对此做了一些研究,得出以下结论:

当rand和迭代增加时,RMSE将减少。然而,当数据集的大小增加时,RMSE将增加。从上述结果来看,rand size将更显著地改变RMSE值。


我知道这还不足以得到一个好的模型。希望有更多的想法

如上所述,对于相同的数据集,随着等级和数量的增加,RMSE会减少。然而,随着数据集的增加,RMSE会增加

现在,降低RMSE和其他类似措施的一种做法是将评级中的值标准化。根据我的经验,如果您事先知道最小和最大额定值,那么这种方法非常有效

此外,还应考虑使用除RMSE以外的其他措施。在进行矩阵分解时,我发现有用的是计算Frobenius评分范数-预测然后除以Frobenius评分范数。通过这样做,您可以得到预测相对于原始评分的相对误差

以下是spark中用于此方法的代码:

# Evaluate the model on training data
testdata = ratings.map(lambda p: (p[0], p[1]))
predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))

ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).join(predictions)

abs_frobenius_error = sqrt(ratesAndPreds.map(lambda r: ((r[1][0] - r[1][1])**2).sum())))

# frobenius error of original ratings
frob_error_orig = sqrt(ratings.map(lambda r: r[2]**2).sum())

# finally, the relative error
rel_error = abs_frobenius_error/frob_error_orig

print("Relative Error = " + str(rel_error))
在这个误差度量中,误差越接近于零,建模就越好


我希望这能有所帮助。

在pyspark中,使用它来查找均方根误差(rmse)


可能的答案太多了,好的答案对于这种格式来说太长了。请添加详细信息,以缩小答案集或隔离可以在几段中回答的问题。@eliasah我添加了一个给定的情况。也许更容易回答。它不应该读为“然而,随着数据集的增长,RMSE会增加”吗?
from pyspark.mllib.recommendation import ALS
from math import sqrt
from operator import add


# rank is the number of latent factors in the model.
# iterations is the number of iterations to run.
# lambda specifies the regularization parameter in ALS
rank = 8
num_iterations = 8
lmbda = 0.1

# Train model with training data and configured rank and iterations
model = ALS.train(training, rank, num_iterations, lmbda)


def compute_rmse(model, data, n):
    """
    Compute RMSE (Root Mean Squared Error), or square root of the average value
        of (actual rating - predicted rating)^2
    """
    predictions = model.predictAll(data.map(lambda x: (x[0], x[1])))
    predictions_ratings = predictions.map(lambda x: ((x[0], x[1]), x[2])) \
      .join(data.map(lambda x: ((x[0], x[1]), x[2]))) \
      .values()
    return sqrt(predictions_ratings.map(lambda x: (x[0] - x[1]) ** 2).reduce(add) / float(n))

print "The model was trained with rank = %d, lambda = %.1f, and %d iterations.\n" % \
        (rank, lmbda, num_iterations)
# Print RMSE of model
validation_rmse = compute_rmse(model, validation, num_validation)
print "Its RMSE on the validation set is %f.\n" % validation_rmse