pyspark中的交叉验证

Posted

技术标签:

【中文标题】pyspark中的交叉验证【英文标题】:cross validation in pyspark 【发布时间】:2017-07-31 15:41:06 【问题描述】:

我使用以下代码使用交叉验证来训练线性回归模型:

from pyspark.ml.evaluation import RegressionEvaluator

lr = LinearRegression(maxIter=maxIteration)
modelEvaluator=RegressionEvaluator()
pipeline = Pipeline(stages=[lr])
paramGrid = ParamGridBuilder().addGrid(lr.regParam, [0.1, 0.01]).addGrid(lr.elasticNetParam, [0, 1]).build()

crossval = CrossValidator(estimator=pipeline,
                          estimatorParamMaps=paramGrid,
                          evaluator=modelEvaluator,
                          numFolds=3)

cvModel = crossval.fit(training)

现在我想绘制 roc 曲线,我使用了以下代码,但出现此错误:

'LinearRegressionTrainingSummary' 对象没有属性 'areaUnderROC'

trainingSummary = cvModel.bestModel.stages[-1].summary
trainingSummary.roc.show()
print("areaUnderROC: " + str(trainingSummary.areaUnderROC))

我也想在每次迭代时检查objectiveHistory,我知道我最后可以得到它

print("numIterations: %d" % trainingSummary.totalIterations)
print("objectiveHistory: %s" % str(trainingSummary.objectiveHistory))

但我想在每次迭代中获取它,我该怎么做?

此外,我想在测试数据上评估模型,我该怎么做?

prediction = cvModel.transform(test)

我知道我可以写的训练数据集:

print("RMSE: %f" % trainingSummary.rootMeanSquaredError)
print("r2: %f" % trainingSummary.r2)

但我怎样才能获得这些用于测试数据集的指标?

【问题讨论】:

对答案满意吗? 谢谢,您的回答很有帮助,只有一个问题,我如何了解 pyspark ml 库?除了 Spark 在线文档? 周围的资源不多,而且 API 变化非常频繁。这可能有用(Scala):jaceklaskowski.gitbooks.io/mastering-apache-spark/content/… 加上很多令人头疼的问题和未记录的反直觉功能,尤其是对于 Pyspark - 请参阅我的博客文章 nodalpoint.com/spark-classification 感谢您的帮助 【参考方案1】:

1) ROC 曲线下面积 (AUC) 为 defined 仅用于二元分类,因此您不能将其用于回归任务,就像您在此处尝试做的那样。

2) 每次迭代的objectiveHistory 仅在回归中的solver 参数为l-bfgs (documentation) 时可用;这是一个玩具示例:

spark.version
# u'2.1.1'

from pyspark.ml import Pipeline
from pyspark.ml.linalg import Vectors
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.regression import LinearRegression
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder

dataset = spark.createDataFrame(
        [(Vectors.dense([0.0]), 0.2),
         (Vectors.dense([0.4]), 1.4),
         (Vectors.dense([0.5]), 1.9),
         (Vectors.dense([0.6]), 0.9),
         (Vectors.dense([1.2]), 1.0)] * 10,
         ["features", "label"])

lr = LinearRegression(maxIter=5, solver="l-bfgs") # solver="l-bfgs" here

modelEvaluator=RegressionEvaluator()
pipeline = Pipeline(stages=[lr])
paramGrid = ParamGridBuilder().addGrid(lr.regParam, [0.1, 0.01]).addGrid(lr.elasticNetParam, [0, 1]).build()

crossval = CrossValidator(estimator=lr,
                          estimatorParamMaps=paramGrid,
                          evaluator=modelEvaluator,
                          numFolds=3)

cvModel = crossval.fit(dataset)

trainingSummary = cvModel.bestModel.summary

trainingSummary.totalIterations
# 2
trainingSummary.objectiveHistory # one value for each iteration
# [0.49, 0.4511834723904831]

3) 您已经定义了一个RegressionEvaluator,您可以使用它来评估您的测试集,但是,如果不使用参数,它会采用 RMSE 度量;这是一种定义具有不同指标的评估器并将它们应用于您的测试集的方法(继续上面的代码):

test = spark.createDataFrame(
        [(Vectors.dense([0.0]), 0.2),
         (Vectors.dense([0.4]), 1.1),
         (Vectors.dense([0.5]), 0.9),
         (Vectors.dense([0.6]), 1.0)],
        ["features", "label"])

modelEvaluator.evaluate(cvModel.transform(test))  # rmse by default, if not specified
# 0.35384585061028506

eval_rmse = RegressionEvaluator(metricName="rmse")
eval_r2 = RegressionEvaluator(metricName="r2")

eval_rmse.evaluate(cvModel.transform(test)) # same as above
# 0.35384585061028506

eval_r2.evaluate(cvModel.transform(test))
# -0.001655087952929124

【讨论】:

以上是关于pyspark中的交叉验证的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 线性回归梯度下降交叉验证

pyspark - 如何交叉验证几种 ML 算法

Pyspark交叉验证后如何获得最佳超参数值?

线性回归中的交叉验证

Weka 中的交叉验证

5倍交叉验证如何理解