我需要一些建议来构建一个好的模型,以通过使用spark的Collaborative Filtering
提出建议。 official website中有一个示例代码。我也遵循以下原则:
from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating
# Load and parse the data
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])))
# Build the recommendation model using Alternating Least Squares
rank = 10
numIterations = 10
model = ALS.train(ratings, rank, numIterations)
# 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)
RMSE = ratesAndPreds.map(lambda r: ((r[1][0] - r[1][1])**2).mean())**.5)
print("Root Mean Squared Error = " + str(RMSE))
一个好的模型需要RMSE尽可能小。因此,谁能帮助我找出导致RMSE大的原因以及如何解决它。
添加:
就像@eliasah所说的那样,我需要添加一些细节来缩小答案范围。让我们考虑这种特殊情况:
现在,如果我想建立一个推荐系统来向我的客户推荐音乐。我有他们的轨道,专辑,艺术家和流派的历史记录。显然,这4个类构建了层次结构。轨道直接属于专辑,专辑直接属于艺术家,艺术家可能属于几种
different
流派。最后,我想使用所有这些信息来选择一些推荐给客户的轨道。因此,最佳实践是为这些情况建立一个好的模型,并确保使RMSE尽可能小以进行预测。
最佳答案
如上所述,给定相同的数据集,随着rank和numIterations的增加,增大,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))
在此误差度量中,误差越接近零,则建模效果越好。
我希望这有帮助。
关于apache-spark - 当使用 Spark ALS时,如何减小RMSE(均方根误差)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36575214/