我使用以下代码通过交叉验证来训练线性回归模型:
from pyspark.ml.evaluation import RegressionEvaluatorlr = 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’ object has no attribute ‘areaUnderROC’
trainingSummary = cvModel.bestModel.stages[-1].summarytrainingSummary.roc.show()print("areaUnderROC: " + str(trainingSummary.areaUnderROC))
我还想在每次迭代时检查目标历史记录,我知道在最后可以得到它
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)
但如何获取测试数据集的这些指标呢?
回答:
1) ROC曲线下的面积(AUC)定义仅适用于二分类,因此你不能将其用于回归任务,正如你在这里尝试的那样。
2) 回归中的solver
参数为l-bfgs
时,每次迭代的objectiveHistory
才可用(文档);这是一个示例代码:
spark.version# u'2.1.1'from pyspark.ml import Pipelinefrom pyspark.ml.linalg import Vectorsfrom pyspark.ml.evaluation import RegressionEvaluatorfrom pyspark.ml.regression import LinearRegressionfrom pyspark.ml.tuning import CrossValidator, ParamGridBuilderdataset = 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" heremodelEvaluator=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.summarytrainingSummary.totalIterations# 2trainingSummary.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.35384585061028506eval_rmse = RegressionEvaluator(metricName="rmse")eval_r2 = RegressionEvaluator(metricName="r2")eval_rmse.evaluate(cvModel.transform(test)) # same as above# 0.35384585061028506eval_r2.evaluate(cvModel.transform(test))# -0.001655087952929124