如何在PySpark ALS

时间:2015-05-19 00:30:10

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

我试图在PySpark MLlib(1.3.1)的ALS模型中使用长用户/产品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,因为代码正在尝试将long转换为整数。浏览源代码,Spark中的ml ALS class允许长用户/产品ID,但mllib ALS class强制使用整数。

问题:PySpark ALS中是否有使用长用户/产品ID的解决方法?

2 个答案:

答案 0 :(得分:3)

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

解决方案很少:

  • 你可以使用hash()函数将userId哈希到int,因为在少数情况下它会导致随机行压缩,因此冲突不应该影响推荐器的准确性。在第一个链接讨论。

  • 您可以使用RDD.zipWithUniqueId()或更快的RDD.zipWithIndex生成唯一的int userIds,就像在此主题中一样:How to assign unique contiguous numbers to elements in a Spark RDD

答案 1 :(得分:0)

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