Spark mllib线性回归给出了非常糟糕的结果
我一直在收到真的很差的结果当尝试使用Spark mllib的LinearRegressionWithSGD使用Python进行线性回归时。Spark mllib线性回归给出了非常糟糕的结果
我看着similiar问题,如下所示:
- Spark - MLlib linear regression intercept and weight NaN
- https://*.com/questions/34940225/spark-mllib-python-linear-regression-with-sgd-not-getting-accurate-weights-for-s
- Spark MlLib linear regression (Linear least squares) giving random results
我清楚地知道,关键是调整参数恰到好处。
我也明白,随机梯度下降不一定会找到一个最佳的解决方案(如交替最小二乘),因为有机会陷入局部极小值。但至少我会期望找到一个OK模型。
这是我的设置,我选择使用统计学杂志的this example和相应的dataset。我从这篇论文中得知(并且从JMP中复制结果),如果仅使用数字字段,我应该得到类似于以下等式的东西(R^2约为44%,RMSE约为7400):
价格= 7323 - 0.171里程+ 3200油缸 - 1463门+ 6206克鲁斯 - 2024音响+ 3327皮革
因为我不知道如何设置参数恰到好处,我跑了以下暴力方式:
from collections import Iterable
from pyspark import SparkContext
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.regression import LinearRegressionWithSGD
from pyspark.mllib.evaluation import RegressionMetrics
def f(n):
return float(n)
if __name__ == "__main__":
sc = SparkContext(appName="LinearRegressionExample")
# CSV file format:
# 0 1 2 3 4 5 6 7 8 9 10 11
# Price, Mileage, Make, Model, Trim, Type, Cylinder, Liter, Doors, Cruise, Sound, Leather
raw_data = sc.textFile('file:///home/ccastroh/training/pyspark/kuiper.csv')
# Grabbing numerical values only (for now)
data = raw_data \
.map(lambda x : x.split(',')) \
.map(lambda x : [f(x[0]), f(x[1]), f(x[6]), f(x[8]), f(x[9]), f(x[10]), f(x[11])])
points = data.map(lambda x : LabeledPoint(x[0], x[1:])).cache()
print "Num, Iterations, Step, MiniBatch, RegParam, RegType, Intercept?, Validation?, " + \
"RMSE, R2, EXPLAINED VARIANCE, INTERCEPT, WEIGHTS..."
i = 0
for ite in [10, 100, 1000]:
for stp in [1, 1e-01, 1e-02, 1e-03, 1e-04, 1e-05, 1e-06, 1e-07, 1e-08, 1e-09, 1e-10]:
for mini in [0.2, 0.4, 0.6, 0.8, 1.0]:
for regP in [0.0, 0.1, 0.01, 0.001]:
for regT in [None, 'l1', 'l2']:
for intr in [True]:
for vald in [False, True]:
i += 1
message = str(i) + \
"," + str(ite) + \
"," + str(stp) + \
"," + str(mini) + \
"," + str(regP) + \
"," + str(regT) + \
"," + str(intr) + \
"," + str(vald)
model = LinearRegressionWithSGD.train(points, iterations=ite, step=stp, \
miniBatchFraction=mini, regParam=regP, regType=regT, intercept=intr, \
validateData=vald)
predictions_observations = points \
.map(lambda p : (float(model.predict(p.features)), p.label)).cache()
metrics = RegressionMetrics(predictions_observations)
message += "," + str(metrics.rootMeanSquaredError) \
+ "," + str(metrics.r2) \
+ "," + str(metrics.explainedVariance)
message += "," + str(model.intercept)
for weight in model.weights:
message += "," + str(weight)
print message
sc.stop()
正如你可以se e,我基本上跑了3960个不同的变化。我没有收到任何与论文或JMP中的公式类似的东西。这里有一些亮点:
- 在很多我得到NaN的截距的奔跑和重量
- 最高的R^2,我得到的是-0.89。我甚至不知道你会得到一个负面的R^2。原来一个负值表示所选的型号为fits worse than a horizontal line。
- ,我得到了最低的RMSE为13600,这比预期的7400
我也试过normalizing the values,以便有在[0,1]区间的方式更糟,而没有帮助要么
有没有人有任何想法如何得到一个体面的线性回归模型?我错过了什么吗?
也有类似的问题。 使用DecisionTree和RandomForest回归工作正常,如果你想有一个相当准确的解决方案,生产连续标签并不是很好。
然后测试线性回归,就像您对每个参数使用多个值一样,也使用多个数据集,并且没有得到远离真实值的任何解决方案。 还试图在训练模型之前使用StandardScaler进行特征缩放,但也不尽如人意。 :-(
编辑:设置截距为true可能会解决问题。