【问题标题】:ALS model - predicted full_u * v^t * v ratings are very highALS 模型 - 预测的 full_u * v^t * v 评分非常高
【发布时间】:2017-05-24 22:49:35
【问题描述】:

我正在预测批量训练模型的进程之间的评分。我正在使用此处概述的方法:ALS model - how to generate full_u * v^t * v?

! rm -rf ml-1m.zip ml-1m
! wget --quiet http://files.grouplens.org/datasets/movielens/ml-1m.zip
! unzip ml-1m.zip
! mv ml-1m/ratings.dat .

from pyspark.mllib.recommendation import Rating

ratingsRDD = sc.textFile('ratings.dat') \
               .map(lambda l: l.split("::")) \
               .map(lambda p: Rating(
                                  user = int(p[0]), 
                                  product = int(p[1]),
                                  rating = float(p[2]), 
                                  )).cache()

from pyspark.mllib.recommendation import ALS

rank = 50
numIterations = 20
lambdaParam = 0.1
model = ALS.train(ratingsRDD, rank, numIterations, lambdaParam)

然后提取产品特征...

import json
import numpy as np

pf = model.productFeatures()

pf_vals = pf.sortByKey().values().collect()
pf_keys = pf.sortByKey().keys().collect()

Vt = np.matrix(np.asarray(pf_vals))

full_u = np.zeros(len(pf_keys))

def set_rating(pf_keys, full_u, key, val):
    try:
        idx = pf_keys.index(key)
        full_u.itemset(idx, val)
    except:
        pass

set_rating(pf_keys, full_u, 260, 9),   # Star Wars (1977)
set_rating(pf_keys, full_u, 1,   8),   # Toy Story (1995)
set_rating(pf_keys, full_u, 16,  7),   # Casino (1995)
set_rating(pf_keys, full_u, 25,  8),   # Leaving Las Vegas (1995)
set_rating(pf_keys, full_u, 32,  9),   # Twelve Monkeys (a.k.a. 12 Monkeys) (1995)
set_rating(pf_keys, full_u, 335, 4),   # Flintstones, The (1994)
set_rating(pf_keys, full_u, 379, 3),   # Timecop (1994)
set_rating(pf_keys, full_u, 296, 7),   # Pulp Fiction (1994)
set_rating(pf_keys, full_u, 858, 10),  # Godfather, The (1972)
set_rating(pf_keys, full_u, 50,  8)    # Usual Suspects, The (1995)

recommendations = full_u*Vt*Vt.T

top_ten_ratings = list(np.sort(recommendations)[:,-10:].flat)

print("predicted rating value", top_ten_ratings)

top_ten_recommended_product_ids = np.where(recommendations >= np.sort(recommendations)[:,-10:].min())[1]
top_ten_recommended_product_ids = list(np.array(top_ten_recommended_product_ids))

print("predict rating prod_id", top_ten_recommended_product_ids)

但是预测的收视率似乎太高了:

('predicted rating value', [313.67320347694897, 315.30874327316576, 317.1563289268388, 317.45475214423948, 318.19788673744563, 319.93044594688428, 323.92448427140653, 324.12553531632761, 325.41052886977582, 327.12199687047649])
('predict rating prod_id', [49, 287, 309, 558, 744, 802, 1839, 2117, 2698, 3111])

这似乎是不正确的。任何提示表示赞赏。

【问题讨论】:

  • 我使用这个确实得到了很好的结果,但这是带有隐式反馈的,评分为 0 表示负面或未知,1 表示正面。我确实得到了介于 0 和 1 之间的预测,并且我使用排名作为指标,即不太关注分数。
  • 啊,有趣。我还没有研究隐式反馈。如果您将评论作为答案发布,如果没有其他人回答,您将默认获得赏金;)
  • @yoh.lej 啊,这就解释了为什么我的收视率像克里斯一样被夸大了!所以假设评级是二元的。 Yohan,你能简要解释一下这个公式的依据吗?我尝试用谷歌搜索相似性度量,但没有看到。我们在计算什么相似度?很感兴趣,因为我目前正在上线性代数课。从逻辑上讲,似乎我们也想确定这个新用户最相似的现有用户,并使用他们的因素来预测评级——这种方法更复杂吗?谢谢! (克里斯 - 查看 ALS.trainImplicit)
  • 当然,我会在回答中详细说明
  • @yoh.lej- 你是如何使用排名作为衡量标准的?你能分享更多细节吗?

标签: apache-spark apache-spark-mllib apache-spark-ml


【解决方案1】:

如果您只关心电影的排名,我认为上述方法会起作用。如果您想获得实际评级,似乎有一些维度/缩放方面的东西。

这里的想法是猜测新用户的潜在表示。通常,对于已经在分解中的用户,用户 i,您有他的潜在表示 u_i(model.userFeatures() 中的第 i 行),并且您使用 model.predict 获得他对给定电影(电影 j)的评分,这基本上是相乘的u_i 由产品 v_j 的潜在表示。如果你乘以整个 v:u_i*v,你可以一次得到所有的预测评分。

对于新用户,您必须从full_u_new 猜测他的潜在表示u_new 是什么。 基本上,您需要 50 个系数来代表您对每个潜在产品因素的新用户亲和力。 为简单起见,因为对于我的隐式反馈用例来说已经足够了,我只使用了点积,基本上将新用户投射到产品潜在因子上:full_u_new*V^t 给你 50 系数,系数 i 是你的新用户看起来多少像产品潜在因子 i。它特别适用于隐式反馈。 所以,使用点积会给你这个,但它不会被缩放,它解释了你看到的高分。 要获得可用的分数,您需要更准确地缩放 u_new,我认为您可以使用余弦相似度来获得它,就像他们在 [这里]https://github.com/apache/incubator-predictionio/blob/release/0.10.0/examples/scala-parallel-recommendation/custom-query/src/main/scala/ALSAlgorithm.scala

@ScottEdwards2000 在评论中提到的方法也很有趣,但完全不同。您确实可以在您的训练集中寻找最相似的用户。如果有多个,您可以获得平均值。我认为它不会做得太糟糕,但它是一种非常不同的方法,您需要完整的评级矩阵(以找到最相似的用户)。获得一位亲密的用户绝对应该解决缩放问题。如果您设法使这两种方法都起作用,您可以比较结果!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-14
    • 2020-08-18
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    相关资源
    最近更新 更多