Pyspark - 获取使用 ParamGridBuilder 创建的模型的所有参数
Pyspark - Get all parameters of models created with ParamGridBuilder
我正在使用 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)))
现在我想要几样东西:
- 最佳模型的参数是什么? post 部分回答了问题:
- 所有型号的参数是什么?
- 每个模型的结果(又名召回率、准确性等...)是什么?我只发现
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
长话短说,您根本无法获取所有模型的参数,因为 、TrainValidationSplitModel
仅保留最佳模型。这些 类 专为半自动模型选择而不是探索或实验而设计。
What are the parameters of all models?
虽然您无法检索实际模型 validationMetrics
对应于输入 Params
因此您应该能够简单地 zip
两者:
from typing import Dict, Tuple, List, Any
from pyspark.ml.param import Param
from pyspark.ml.tuning import TrainValidationSplitModel
EvalParam = List[Tuple[float, Dict[Param, Any]]]
def get_metrics_and_params(model: TrainValidationSplitModel) -> EvalParam:
return list(zip(model.validationMetrics, model.getEstimatorParamMaps()))
了解指标和参数之间的关系。
如果您需要更多信息,您应该使用 。它将保留所有可用于进一步处理的模型:
models = pipeline.fit(df, params=paramGrid)
它将生成一个 PipelineModels
对应于 params
参数的列表:
zip(models, params)
我想我找到了一种方法来做到这一点。我编写了一个函数,专门为具有两个参数的逻辑回归提取超参数,使用 CrossValidator 创建:
def hyperparameter_getter(model_obj,cv_fold = 5.0):
enet_list = []
reg_list = []
## Get metrics
metrics = model_obj.avgMetrics
assert type(metrics) is list
assert len(metrics) > 0
## Get the paramMap element
for x in range(len(model_obj._paramMap.keys())):
if model_obj._paramMap.keys()[x].name=='estimatorParamMaps':
param_map_key = model_obj._paramMap.keys()[x]
params = model_obj._paramMap[param_map_key]
for i in range(len(params)):
for k in params[i].keys():
if k.name =='elasticNetParam':
enet_list.append(params[i][k])
if k.name =='regParam':
reg_list.append(params[i][k])
results_df = pd.DataFrame({'metrics':metrics,
'elasticNetParam': enet_list,
'regParam':reg_list})
# Because of [SPARK-16831][PYTHON]
# It only sums across folds, doesn't average
spark_version = [int(x) for x in sc.version.split('.')]
if spark_version[0] <= 2:
if spark_version[1] < 1:
results_df.metrics = 1.0*results_df['metrics'] / cv_fold
return results_df
我正在使用 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)))
现在我想要几样东西:
- 最佳模型的参数是什么? post 部分回答了问题:
- 所有型号的参数是什么?
- 每个模型的结果(又名召回率、准确性等...)是什么?我只发现
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
长话短说,您根本无法获取所有模型的参数,因为 TrainValidationSplitModel
仅保留最佳模型。这些 类 专为半自动模型选择而不是探索或实验而设计。
What are the parameters of all models?
虽然您无法检索实际模型 validationMetrics
对应于输入 Params
因此您应该能够简单地 zip
两者:
from typing import Dict, Tuple, List, Any
from pyspark.ml.param import Param
from pyspark.ml.tuning import TrainValidationSplitModel
EvalParam = List[Tuple[float, Dict[Param, Any]]]
def get_metrics_and_params(model: TrainValidationSplitModel) -> EvalParam:
return list(zip(model.validationMetrics, model.getEstimatorParamMaps()))
了解指标和参数之间的关系。
如果您需要更多信息,您应该使用
models = pipeline.fit(df, params=paramGrid)
它将生成一个 PipelineModels
对应于 params
参数的列表:
zip(models, params)
我想我找到了一种方法来做到这一点。我编写了一个函数,专门为具有两个参数的逻辑回归提取超参数,使用 CrossValidator 创建:
def hyperparameter_getter(model_obj,cv_fold = 5.0):
enet_list = []
reg_list = []
## Get metrics
metrics = model_obj.avgMetrics
assert type(metrics) is list
assert len(metrics) > 0
## Get the paramMap element
for x in range(len(model_obj._paramMap.keys())):
if model_obj._paramMap.keys()[x].name=='estimatorParamMaps':
param_map_key = model_obj._paramMap.keys()[x]
params = model_obj._paramMap[param_map_key]
for i in range(len(params)):
for k in params[i].keys():
if k.name =='elasticNetParam':
enet_list.append(params[i][k])
if k.name =='regParam':
reg_list.append(params[i][k])
results_df = pd.DataFrame({'metrics':metrics,
'elasticNetParam': enet_list,
'regParam':reg_list})
# Because of [SPARK-16831][PYTHON]
# It only sums across folds, doesn't average
spark_version = [int(x) for x in sc.version.split('.')]
if spark_version[0] <= 2:
if spark_version[1] < 1:
results_df.metrics = 1.0*results_df['metrics'] / cv_fold
return results_df