我试图在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的解决方法?
答案 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。