CrossValidator.fit() - IllegalArgumentException:列预测的类型必须等于 ... [array<double>, array<double>],但类型为 double

问题描述

这些是我用于 Python 3.9 和 Spark 3.1.1 的包:

from pyspark.ml import Pipeline
from pyspark.ml.feature import VectorAssemble,StringIndexer
from pyspark.ml.tuning import CrossValidator,ParamGridBuilder
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import MultilabelClassificationEvaluator

我正在尝试将包含具有名称的 2 列的矢量化数据集 df_vec 推送到 CrossValidator 函数中:

  • features - 来自 VectorAssembler 的向量
  • label - 来自 StringIndexer 的字符串索引数字。

这是一个6标签多项逻辑回归问题。

df_vec.printSchema()

root
 |-- features: vector (nullable = true)
 |-- label: integer (nullable = true)

运行以下步骤来设置 CrossValidator:

mlr = LogisticRegression()
mlr_evaluator = MultilabelClassificationEvaluator()
paramGrid = ParamGridBuilder() \
    .addGrid(mlr.maxIter,[200]) \
    .build()

cross_validator = CrossValidator(
    estimator=mlr,estimatorParamMaps=paramGrid,evaluator=mlr_evaluator
)

尝试使用 df_vec 拟合 CrossValidator 对象会引发异常:

cv_model = cross_validator.fit(df_vec)

pyspark.sql.utils.IllegalArgumentException: requirement Failed:
Column prediction must be of type equal to one of the following types:
[array<double>,array<double>] but was actually of type double.

我能够确认仅使用 mlr() 转换后的数据集的输出一个类型为 double 的列 prediction

x = mlr.fit(df_vec).transform(df_vec)
x.printSchema()

root
 |-- features: vector (nullable = true)
 |-- label: integer (nullable = true)
 |-- rawPrediction: vector (nullable = true)
 |-- probability: vector (nullable = true)
 |-- prediction: double (nullable = false) <---

因此,出于某种原因,CrossValidator 似乎期望采用另一种格式。如果 CrossValidator() 是细粒度的,我可以尝试使用 predictionVectorAssembler 列转换为向量,但事实并非如此。

有人知道如何解决这个问题吗?

解决方法

您可以使用 MulticlassClassificationEvaluator。您只有一个标签作为整数,因此使用多标签评估器没有意义。