Pyspark错误:要求失败:列的类型必须是numeric,但实际上是字符串错误



我试图将pandas数据帧转换为PySpark格式的

mySchema = StructType([ StructField("movieId", IntegerType())
,StructField("title", StringType()),
StructField("userId", IntegerType()),
StructField("rating", FloatType())
])
movielens = spark.createDataFrame(merged_df, mySchema)
movielens.printSchema()

架构

root
|-- movieId: integer (nullable = true)
|-- title: string (nullable = true)
|-- userId: integer (nullable = true)
|-- rating: float (nullable = true)

然后为模型准备我的数据

(train_set,temp) = movielens.randomSplit([8.0,1.0],seed=1)
validation_set = (temp.join(train_set,["userId"],"left_semi").join(train_set,["movieId"],"left_semi"))
removed = (temp.join(validation_set,["movieId","userId"],"left_anti"))
train_set = train_set.union(removed)
als = ALS(
userCol = "userId",
itemCol = "movieId",
ratingCol = "rating"
)
evaluator = RegressionEvaluator(
metricName = "rmse",
labelCol = "rating", 
predictionCol = "prediction"
)
model = als.fit(train_set)
predictions = model.transform(validation_set)

犯了那个错误

IllegalArgumentException: requirement failed: Column userId must be of type numeric but was actually of type string.

这怎么可能呢,因为我在MySchema中手动编写了类型?如有任何帮助,将不胜感激

可能存在NaN/缺失值,这些值很难使用RegressionEvaluator进行评估。这意味着冷启动问题

您可以通过将下降指定为冷启动策略来继续。

als = ALS(
userCol = "userId",
itemCol = "movieId",
ratingCol = "rating",
coldStartStrategy = "drop"
)

我从spark文档中摘录了一段内容,阐述了spark如何处理这个问题。

Spark冷启动策略

使用ALSModel进行预测时,通常会遇到测试数据集中在训练模型。这通常发生在两种情况下:

在生产中,对于没有评级历史记录的新用户或项目模型尚未在其上进行训练(这是"冷启动"问题"(。在交叉验证期间,数据在训练之间进行分割以及评估集。在Spark中使用简单的随机拆分时CrossValidator或TrainValidationSplit,实际上遇到评估集中不在训练集默认情况下,Spark在ALSModel.transform,当中不存在用户和/或项目因素时模型。这在生产系统中很有用,因为指示新用户或项目,因此系统可以对一些回退用作预测。

然而,在交叉验证过程中,这是不可取的,因为任何NaN预测值将导致评估度量的NaN结果(例如使用RegissionEvaluator时(。这使得模型无法进行选择。

Spark允许用户将coldStartStrategy参数设置为"drop"以便删除预测的DataFrame中包含NaN值。然后将通过非NaN数据,并且将是有效的。该参数的用法如图所示在下面的例子中。

注:目前支持的冷启动策略为"nan"(上面提到的默认行为(和"drop"。进一步的策略可能在未来得到支持。

相关内容

最新更新