使用 Pyspark 进行超参数调优

Posted

技术标签:

【中文标题】使用 Pyspark 进行超参数调优【英文标题】:Hyperparameter tuning using Pyspark 【发布时间】:2018-02-16 12:04:02 【问题描述】:

我正在使用线性回归来拟合模型的数据集。在签署之前,我想尝试使用超参数调整来获得最佳模型。

我一直在通过管道运行数据,首先将字符串转换为数字,然后对其进行编码,然后对所有列进行矢量化,然后在应用线性回归之前对其进行缩放。我很想知道如何设置 grid 来启动超参数滚球(可以这么说)。

import pyspark.ml.feature as ft
WD_indexer = ft.StringIndexer(inputCol="Wind_Direction", outputCol="WD-num")
WD_encoder = ft.OneHotEncoder(inputCol="WD-num", outputCol='WD-vec')
featuresCreator = ft.VectorAssembler(inputCols=["Dew_Point", "Temperature",
                                            "Pressure", "WD-vec", "Wind_Speed","Hours_Snow","Hours_Rain"], outputCol='features')

from pyspark.ml.feature import StandardScaler
feature_scaler = StandardScaler(inputCol="features",outputCol="sfeatures")

from pyspark.ml.regression import LinearRegression
lr = LinearRegression(featuresCol="sfeatures",labelCol="PM_Reading")

所以管道看起来像这样:

from pyspark.ml import Pipeline
pipeline = Pipeline( stages = [WD_indexer, WD_encoder, featuresCreator, feature_scaler, lr] )

如何设置此管道的网格?

谢谢

【问题讨论】:

【参考方案1】:

我知道这个问题是两年前发布的,但让每个人都了解最新发现和问题的替代解决方案仍然没有什么坏处。正如 Frank Kane 详细解释的 here,CrossValidator 非常昂贵,因为它需要评估指定超参数值的每个可能组合。因此,建议您使用TrainValidationSplit,它只评估每个组合的单个随机训练/测试数据拆分。在处理非常大的数据集时,这可能非常有用。来自 spark 文档的示例代码(查找更多详细信息 here):

# We use a ParamGridBuilder to construct a grid of parameters to search over.
# TrainValidationSplit will try all combinations of values and determine best model using
# the evaluator.
paramGrid = ParamGridBuilder()\
    .addGrid(lr.regParam, [0.1, 0.01]) \
    .addGrid(lr.fitIntercept, [False, True])\
    .addGrid(lr.elasticNetParam, [0.0, 0.5, 1.0])\
    .build()

# In this case the estimator is simply the linear regression.
# A TrainValidationSplit requires an Estimator, a set of Estimator ParamMaps, and an Evaluator.
tvs = TrainValidationSplit(estimator=lr,
                           estimatorParamMaps=paramGrid,
                           evaluator=RegressionEvaluator(),
                           # 80% of the data will be used for training, 20% for validation.
                           trainRatio=0.8)

# Run TrainValidationSplit, and choose the best set of parameters.
model = tvs.fit(train)

【讨论】:

【参考方案2】:

您可以使用 pyspark ml.tuning 类中的参数网格构建器和使用交叉验证进行测试来设置网格。

from pyspark.ml.tuning import CrossValidator, ParamGridBuilder

然后可以决定要运行的不同参数及其值: 您需要为每个参数添加一个网格并分别为每个参数添加一个值数组 例如,对于线性回归,您可以传递 lr.regParam,lr.maxIter,lr.elasticNetParam 的值

paramGrid = ParamGridBuilder().addGrid(lr.maxIter, [10, 100, 1000]).addGrid(lr.regParam, [0.1, 0.01]).build()

您还可以使用 featuresCreator.inputCols 等从管道中更改矢量汇编器、字符串索引器和一种热编码的参数

crossval = CrossValidator(estimator=pipeline,
                      estimatorParamMaps=paramGrid,
                      evaluator=RegressionEvaluator(),
                      numFolds=2)  # use 3+ folds in practice

您可以通过交叉验证器运行训练数据以获得最佳模型,

cvModel = crossval.fit(training)

【讨论】:

非常感谢。我会试试看。如果我使用神经网络,如何为网格中的图层设置参数?

以上是关于使用 Pyspark 进行超参数调优的主要内容,如果未能解决你的问题,请参考以下文章

[Spark2.0]ML 调优:模型选择和超参数调优

[Spark2.0]ML 调优:模型选择和超参数调优

超参数调优后精度保持不变

R语言使用caret包的train函数构建多元自适应回归样条(MARS)模型模型调优自定义设置tuneGrid参数多个超参数组合调优trainControl函数自定义调优评估指标

K-Means 聚类 超参数调优

K-Means GridSearchCV 超参数调优