首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >星火ALS predictAll返回空

星火ALS predictAll返回空
EN

Stack Overflow用户
提问于 2016-05-22 21:16:03
回答 1查看 3.7K关注 0票数 6

我有以下Python测试代码( ALS.train的参数在其他地方定义):

代码语言:javascript
复制
 r1 = (2, 1)
 r2 = (3, 1)
 test = sc.parallelize([r1, r2]) 
 model = ALS.train(ratings, rank, numIter, lmbda)
 predictions = model.predictAll(test)

 print test.take(1)     
 print predictions.count()
 print predictions

这是可行的,因为它对预测变量和输出的计数为1:

代码语言:javascript
复制
[(2, 1)]
1
ParallelCollectionRDD[2691] at parallelize at PythonRDD.scala:423

但是,当我尝试使用RDD时,我使用以下代码创建了自己,它似乎不再工作了:

代码语言:javascript
复制
model = ALS.train(ratings, rank, numIter, lmbda)
validation_data = validation.map(lambda xs: tuple(int(x) for x in xs))
predictions = model.predictAll(validation_data)

print validation_data.take(1)
print predictions.count()
print validation_data

其中产出:

代码语言:javascript
复制
[(61, 3864)]
0
PythonRDD[4018] at RDD at PythonRDD.scala:43

如您所见,当传递映射的predictAll时,RDD返回为空。输入的值都是相同的格式。我能看到的唯一显著区别是,第一个示例使用并行化并生成一个ParallelCollectionRDD,而第二个示例只使用生成PythonRDD的映射。predictAll只在通过某种类型的RDD时才能工作吗?如果是的话,是否可以在RDD类型之间进行转换?我不知道该怎么做。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-25 11:21:12

在两个基本条件下,MatrixFactorizationMode.predictAll可以返回一个条目数比输入少的RDD:

  • 用户在培训集中丢失。
  • 培训集中缺少产品。

您可以轻松地再现此行为,并检查它是否取决于如何创建RDD。首先,让我们使用示例数据来构建模型:

代码语言:javascript
复制
from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating

def parse(s):
    x, y, z  = s.split(",")
    return Rating(int(x), int(y), float(z))

ratings = (sc.textFile("data/mllib/als/test.data")
  .map(parse)
  .union(sc.parallelize([Rating(1, 5, 4.0)])))

model = ALS.train(ratings, 10, 10)

接下来,让我们看看培训数据中存在哪些产品和用户:

代码语言:javascript
复制
set(ratings.map(lambda r: r.product).collect())
## {1, 2, 3, 4, 5}

set(ratings.map(lambda r: r.user).collect())
## {1, 2, 3, 4}

现在让我们创建测试数据并检查预测:

代码语言:javascript
复制
valid_test = sc.parallelize([(2, 5), (1, 4), (3, 5)])
valid_test
## ParallelCollectionRDD[434] at parallelize at PythonRDD.scala:423

model.predictAll(valid_test).count()
## 3

到目前一切尚好。接下来,让我们使用与代码中相同的逻辑映射它:

代码语言:javascript
复制
valid_test_ = valid_test.map(lambda xs: tuple(int(x) for x in xs))
valid_test_
## PythonRDD[497] at RDD at PythonRDD.scala:43

model.predictAll(valid_test_).count()
## 3

还是很好。接下来,让我们创建无效的数据并重复实验:

代码语言:javascript
复制
invalid_test = sc.parallelize([
  (2, 6), # No product in the training data
  (6, 1)  # No user in the training data
])
invalid_test 
## ParallelCollectionRDD[500] at parallelize at PythonRDD.scala:423

model.predictAll(invalid_test).count()
## 0 

invalid_test_ = invalid_test.map(lambda xs: tuple(int(x) for x in xs))
model.predictAll(invalid_test_).count()
## 0

正如预期的那样,没有关于无效输入的预测。

最后,您可以通过使用完全独立于Python代码的训练/预测的ML模型来确认这一点:

代码语言:javascript
复制
from pyspark.ml.recommendation import ALS as MLALS

model_ml = MLALS(rank=10, maxIter=10).fit(
    ratings.toDF(["user", "item", "rating"])
)
model_ml.transform((valid_test + invalid_test).toDF(["user", "item"])).show()

## +----+----+----------+
## |user|item|prediction|
## +----+----+----------+
## |   6|   1|       NaN|
## |   1|   4| 1.0184212|
## |   2|   5| 4.0041084|
## |   3|   5|0.40498763|
## |   2|   6|       NaN|
## +----+----+----------+

如您所见,在培训数据中没有相应的用户/项意味着没有预测。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37379751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档