在PySpark中给出的ALS示例中(根据本文档- http://spark.apache.org/docs/latest/ml-collaborative-filtering.html),所使用的数据在一列中有显式反馈。数据是这样的:|用户|项目|评分|| --- | --- | --- |第一| A | 2 ||秒| B | 3|
然而,在我的情况下,我有隐含的反馈在多个列,像这样:|用户|物品|点击|查看|购买| --- | --- | --- | --- | --- |第一| A | 20 | 35 | 3 ||秒| B | 3| 12 | 0 |
我知道我们可以通过将implicitPrefs
设置为False
来使用隐式反馈。但是,它只接受单个列。如何使用多列?
我发现了这个问题:如何管理多个积极的隐含反馈?但是,它与Spark和交替最小二乘法无关。我是否需要根据答案手动分配一个权重方案?或者在PySpark中有更好的解决方案?
我已经彻底研究了你的问题,我没有发现在ALS中通过多个列,大多数这样的问题正在通过手动称重和创建评级列来解决。
下面是我的解决方案
- 创建索引视图,点击和购买价值如下
提取最小值(0除外)并将同一列的所有元素除以它
示例:最小值为3
所以3/3,10/3,20/3 ..等
- 现在得到这些列的索引值后计算Rating
以下是评分公式
评分= 60%的购买+ 30%的点击+ 10%的浏览量
data.show()
+------+----+------+-----+--------+
| User|Item|Clicks|Views|Purchase|
+------+----+------+-----+--------+
| First| A| 20| 35| 3|
|Second| B| 3| 12| 0|
| Three| C| 4| 15| 20|
| Four| D| 5| 16| 10|
+------+----+------+-----+--------+
df1 = data.sort('Purchase').select('Purchase')
df= df1.filter(df1.Purchase >0)
purch_index = df.first()['Purchase']
df2 = data.sort('Views').select('Views')
df2= df2.filter(df2.Views >0)
Views_index = df2.first()['Views']
f3 = data.sort('Clicks').select('Clicks')
df3= df3.filter(df3.Clicks >0)
CLicks_index = df3.first()['Clicks']
semi_rawdf = data.withColumn('Clicks',round(col('Clicks')/CLicks_index)).withColumn('Views',round(col('Views')/Views_index)).withColumn('Purchase',round(col('Purchase')/purch_index))
semi_rawdf.show()
+------+----+------+-----+--------+
| User|Item|Clicks|Views|Purchase|
+------+----+------+-----+--------+
| First| A| 7.0| 3.0| 1.0|
|Second| B| 1.0| 1.0| 0.0|
| Three| C| 1.0| 1.0| 7.0|
| Four| D| 2.0| 1.0| 3.0|
+------+----+------+-----+--------+
from pyspark.sql.types import DecimalType
from decimal import Decimal
refined_df = semi_rawdf.withColumn('Rating',((col('Clicks')*0.3)+round(col('Views')*0.1)+round(col('Purchase')*0.6)))
refined_df = refined_df.withColumn('Rating', col('Rating').cast(DecimalType(6,2)))
refined_df.select('User','Item','Rating').show()
+------+----+------+
| User|Item|Rating|
+------+----+------+
| First| A| 3.10|
|Second| B| 0.30|
| Three| C| 4.30|
| Four| D| 2.60|
+------+----+------+