我在使用PySpark 2.0参加Kaggle竞赛。我想了解一个模型(RandomForest
)在不同参数下的表现。ParamGridBuilder()
允许为单个参数指定不同的值,然后(我猜)对整个参数集进行笛卡尔积。假设我的DataFrame
已经定义:
rdc = RandomForestClassifier()pipeline = Pipeline(stages=STAGES + [rdc])paramGrid = ParamGridBuilder().addGrid(rdc.maxDepth, [3, 10, 20]) .addGrid(rdc.minInfoGain, [0.01, 0.001]) .addGrid(rdc.numTrees, [5, 10, 20, 30]) .build()evaluator = MulticlassClassificationEvaluator()valid = TrainValidationSplit(estimator=pipeline, estimatorParamMaps=paramGrid, evaluator=evaluator, trainRatio=0.50)model = valid.fit(df)result = model.bestModel.transform(df)
好的,现在我可以使用手工编写的函数获取一些基本信息:
def evaluate(result): predictionAndLabels = result.select("prediction", "label") metrics = ["f1","weightedPrecision","weightedRecall","accuracy"] for m in metrics: evaluator = MulticlassClassificationEvaluator(metricName=m) print(str(m) + ": " + str(evaluator.evaluate(predictionAndLabels)))
现在我想知道几件事:
- 最佳模型的参数是什么?这个帖子部分回答了这个问题:如何从PySpark中的spark.ml提取模型超参数?
- 所有模型的参数是什么?
- 每个模型的结果(如召回率、准确率等)是什么?我只找到了
print(model.validationMetrics)
,它似乎显示了一个包含每个模型准确率的列表,但我无法知道它指的是哪个模型。
如果我能获取所有这些信息,我应该能够显示图表、条形图,并像使用Panda和sklearn
一样工作。
回答:
Spark 2.4+
SPARK-21088 CrossValidator, TrainValidationSplit应在拟合时收集所有模型 – 添加了收集子模型的支持。
默认情况下,此行为是禁用的,但可以使用CollectSubModels
Param
(setCollectSubModels
)来控制。
valid = TrainValidationSplit( estimator=pipeline, estimatorParamMaps=paramGrid, evaluator=evaluator, collectSubModels=True)model = valid.fit(df)model.subModels
Spark < 2.4
简而言之,你无法获取所有模型的参数,因为,类似于CrossValidator
,TrainValidationSplitModel
只保留最佳模型。这些类是为半自动模型选择设计的,而不是用于探索或实验。
所有模型的参数是什么?
虽然你无法检索实际模型,但validationMetrics
对应于输入的Params
,所以你应该能够简单地zip
两者:
from typing import Dict, Tuple, List, Anyfrom pyspark.ml.param import Paramfrom pyspark.ml.tuning import TrainValidationSplitModelEvalParam = List[Tuple[float, Dict[Param, Any]]]def get_metrics_and_params(model: TrainValidationSplitModel) -> EvalParam: return list(zip(model.validationMetrics, model.getEstimatorParamMaps()))
以获取有关指标和参数之间关系的一些信息。
如果你需要更多信息,你应该使用Pipeline Params
。它将保留所有模型,可用于进一步处理:
models = pipeline.fit(df, params=paramGrid)
它将生成一个与params
参数对应的PipelineModels
列表:
zip(models, params)