如何在 PySpark ALS 中使用长用户 ID

How to use long user ID in PySpark ALS

我正在尝试在 PySpark MLlib (1.3.1) 的 ALS 模型中使用长 user/product ID,并且 运行 成为一个问题。这里给出了代码的简化版本:

from pyspark import SparkContext
from pyspark.mllib.recommendation import ALS, Rating

sc = SparkContext("","test")

# Load and parse the data
d = [ "3661636574,1,1","3661636574,2,2","3661636574,3,3"]
data = sc.parallelize(d)
ratings = data.map(lambda l: l.split(',')).map(lambda l: Rating(long(l[0]), long(l[1]), float(l[2])) )

# Build the recommendation model using Alternating Least Squares
rank = 10
numIterations = 20
model = ALS.train(ratings, rank, numIterations)

运行 此代码产生 java.lang.ClassCastException 因为该代码试图将长整型转换为整数。查看源代码,ml ALS class in Spark allows for long user/product IDs but then the mllib ALS class强制使用整数。

问题:是否有在 PySpark ALS 中使用长 user/product ID 的解决方法?

这是已知问题 (https://issues.apache.org/jira/browse/SPARK-2465),但不会很快解决,因为将接口更改为长 userId 会减慢计算速度。

解决方案很少:

  • 您可以使用 hash() 函数将 userId 散列为 int,因为它在少数情况下只会导致随机行压缩,冲突不应该影响推荐系统的准确性,真的。先讨论link.

  • 您可以使用 RDD.zipWithUniqueId() 或更慢的速度生成唯一的 int userIds RDD.zipWithIndex,就像在这个线程中一样:How to assign unique contiguous numbers to elements in a Spark RDD

对于较新版本的 pyspark(从 1.4.0 开始),如果您正在使用数据帧,则可以使用 StringIndexer 将您的 ID 映射到索引中。然后你可以使用这些索引作为你的ids。