问题描述
这些是我用于 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 的字符串索引数字。
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() 是细粒度的,我可以尝试使用 prediction
将 VectorAssembler
列转换为向量,但事实并非如此。
有人知道如何解决这个问题吗?
解决方法
您可以使用 MulticlassClassificationEvaluator
。您只有一个标签作为整数,因此使用多标签评估器没有意义。