【问题标题】:how to make RMSE(root mean square error) small when use ALS of spark?使用火花的ALS时如何使RMSE(均方根误差)变小?
【发布时间】:2016-08-03 04:19:59
【问题描述】:

我需要一些建议来构建一个好的模型来使用 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 尽可能小。

是不是因为我没有给ALS.train方法设置合适的参数,比如rand numIterations等等?

还是因为我的数据集太小而无法使 RMSE 变大?

那么任何人都可以帮助我找出导致 RMSE 大的原因以及如何解决它。

补充:

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

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

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

【问题讨论】:

  • 有太多可能的答案,而好的答案对于这种格式来说太长了。请添加详细信息以缩小答案范围或隔离可以在几段中回答的问题。
  • @eliasah 我添加了一个给定的情况。也许更容易回答。

标签: apache-spark pyspark apache-spark-mllib collaborative-filtering


【解决方案1】:

如上所述,在给定相同数据集的情况下,随着 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))

在这个误差度量中,误差越接近于零,你的模型就越好。

我希望这会有所帮助。

【讨论】:

  • 不应该是“但是,随着数据集的增长,RMSE 增加。”?
【解决方案2】:

我研究了一下,结论如下:

当 rand 和迭代增长时,RMSE 会降低。但是,随着数据集大小的增加,RMSE会增加。从上面的结果来看,rand size会更显着地改变RMSE值。

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

【讨论】:

    【解决方案3】:

    在 pyspark 中使用它来查找均方根误差 (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
    

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-23
      • 2016-08-04
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      相关资源
      最近更新 更多