【问题标题】:Splitting in Recommender System推荐系统中的分裂
【发布时间】:2017-03-22 13:17:43
【问题描述】:

我有一个包含 Userid、ItemID、Ratings 的 Spark 数据框。我正在建立一个推荐系统。

数据如下:

originalDF.show(5)
+----+----+------+
|user|item|rating|
+----+----+------+
| 353|   0|     1|
| 353|   1|     1|
| 353|   2|     1|
| 354|   3|     1|
| 354|   4|     1|
+----+----+------+

它有 56K 的唯一用户和 8.5K 的唯一项目。

因此,如果您看到每个 UserID 都有每个项目的记录 (RoW) 和相应的评级。因此,每个用户 ID 有多个记录。

现在我通过随机拆分 0.6,0.2,0.2 % 将其拆分为训练、验证和测试。所以基本上 60% 的随机记录用于训练,20% 用于验证,其余 20% 用于测试,如下所示:

random_split=originalDF.randomSplit(split_perc,seed=20)

return random_split[0],random_split[1],random_split[2]

这给我留下了以下数据集计数

train,validation,test=train_test_split(split_sdf,[0.6,0.2,0.2])
​
print "Training size is {}".format(train.count())
print "Validation size is {}".format(validation.count())
print "Test size is {}".format(test.count())
'/'
print "Original Dataset Size is {}".format(split_sdf.count())
Training size is 179950
Validation size is 59828
Test size is 60223
Original Dataset Size is 300001

现在我在训练数据上训练 Spark pyspark.ml.ALS 算法。

als = ALS(rank=120, maxIter=15, regParam=0.01, implicitPrefs=True)
model = als.fit(train)

当我从模型对象中检查 userFactors 和 itemFactors 时,我得到:

itemF=model.itemFactors
itemF.toPandas().shape
Out[111]:
(7686, 2)
In [113]:

userF=model.userFactors
userF.toPandas().shape
Out[113]:
(47176, 2)

这意味着它只给了我一个预测的因子矩阵。训练数据中的唯一用户和项目。

现在我如何获得每个用户的所有项目的预测?

如果我这样做了

prediction=model.transform(originalDF)

其中 OriginalDF 是分解为训练、验证和测试的整个数据集,是否可以预测每个用户的所有项目?

我的问题是,如果我的数据集有 56K 用户 X 8.5K 项,那么我想找到相同 56K X8.5K 的预测矩阵,而不仅仅是 47K X7.6K 训练数据。

我在这里做错了什么?我了解这些数据仅适用于 47k X7.6K 训练数据,而不是原始的 56k X8.5K 评级数据。那么我是否将数据拆分为 train,val 错误?

我知道对于推荐系统,应该为每个用户随机屏蔽某些项目的一些评分,并将剩余的用于训练并在这些屏蔽值上进行测试。我在这里做了同样的事情,因为用户的每条记录都是对不同项目的评分。当我们随机拆分时,我们实际上是在掩盖用户的一些评分,而不是将它们用于训练。

请指教。

编辑:

在具有用户 X 项目矩阵(56K 用户 X 8.5 项目)的典型推荐系统中

我们基本上为每个用户屏蔽(设为 0)一些随机项目评级。然后将整个矩阵传递给推荐算法,并将其分解为两个因素矩阵的乘积。

但是在 Spark 中,我们不使用 Userx 项目矩阵。我们基本上将每个项目列评级作为每个用户的单独行,而不是拥有 8.5K 项目列。

因此,如果您在原始用户项目矩阵中看到屏蔽(将某些项目评分设为 0),则与在 spark 数据框中不为每个用户使用一些随机行相同。正确的?

这是我找到了一种将数据拆分(我也使用过)为 train 和 val 的方法

training_RDD, validation_RDD, test_RDD = small_ratings_data.randomSplit([6, 2, 2], seed=0L)
validation_for_predict_RDD = validation_RDD.map(lambda x: (x[0], x[1]))
test_for_predict_RDD = test_RDD.map(lambda x: (x[0], x[1]))

我在这里也使用了类似的 randomSplit 东西。所以我不确定这里有什么问题。

我可以理解,由于训练数据不包含所有用户和项目,项目因素矩阵也只有那么多用户和项目因素。那么我该如何克服呢?最后,我基本上需要一个针对所有用户和项目的预测矩阵。

【问题讨论】:

  • 这里有什么问题?是的,您可以使用在 train 上训练的模型来预测 testoriginalDF,但后者不能很好地估计模型性能。

标签: python apache-spark pyspark apache-spark-mllib recommendation-engine


【解决方案1】:

所有 id:

  • 用户
  • 产品

您希望预测的对象必须存在于训练集中。使用随机拆分不是一种可以用来确保的方法(它不等同于数据屏蔽)。

【讨论】:

  • 那是什么方法呢?。在推荐系统中,必须为每个用户屏蔽一些评分。这意味着我们基本上没有在训练数据中使用其中一些评级。这就是我使用 randomSplit 所做的。您认为更好的选择是什么?
  • 使用按用户(如果对所有用户的预测更重要)或按产品(如果对所有产品的预测)更重要的分层抽样可能会更好。您也可以在第一次采样后添加缺失值。
  • 恐怕您在第一条评论中描述的技术不适用于 spark 提供的实现。
  • 哪种技术?我正在使用 spark 的 ALS,因此已经在 spark 中实现了
  • 屏蔽一个用户评分的技术。拆分时出现的问题是,您需要将所有用户和所有需要学习的项目都包含在训练集中。因此,分层抽样是一种可行的方法。如果某个用户 X 或项目 Y 没有学习。 ALS 将他们视为新用户和新项目,这属于冷启动问题。
猜你喜欢
  • 2014-06-10
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多