Java Spark ML - prediction/forecast Spark ML 3.1+ 问题

Java Spark ML - prediction/forecast with Spark ML 3.1+ issue

关于 prediction/forecast 使用 Spark ML 3.1+ 的小问题。

我有一个数据集,非常简单,包含事件发生时间的时间戳。

数据集非常简单,这里是非常非常大的文件的一小部分。

        +----------+-----+
        |      time|label|
        +----------+-----+
        |1621900800|   43|
        |1619568000|   41|
        |1620432000|   41|
        |1623974400|   42|
        |1620604800|   41|
        |1622505600|   42|
       truncated
        |1624665600|   42|
        |1623715200|   41|
        |1623024000|   43|
        |1623888000|   42|
        |1621296000|   42|
        |1620691200|   44|
        |1620345600|   41|
        |1625702400|   44|
        +----------+-----+
        only showing top 20 rows

数据集实际上只是一个时间戳,代表一天,左边和右边是当天售出的香蕉数量。以上示例的前三行已翻译示例。

        +------    ----+--            ---+
        |          time|            value|
        +-------    ---+-----+
        |May   25, 2021|   banana sold 43|
        |April 28, 2021|   banana sold 41|
        |May    8, 2021|   banana sold 41|

我的目标只是建立一个预测模型,明天、后天等会卖多少“香蕉……

因此,我尝试了线性回归,但它可能不是解决这个问题的好模型:

VectorAssembler       vectorAssembler = new VectorAssembler().setInputCols(new String[]{"time", "label"}).setOutputCol("features");
        Dataset<Row>          vectorData      = vectorAssembler.transform(dataSetBanana);
        LinearRegression      lr              = new LinearRegression(); 
        LinearRegressionModel lrModel         = lr.fit(vectorData);
        System.out.println("Coefficients: " + lrModel.coefficients() + " Intercept: " + lrModel.intercept());
        LinearRegressionTrainingSummary trainingSummary = lrModel.summary();
        System.out.println("numIterations: " + trainingSummary.totalIterations());
        System.out.println("objectiveHistory: " + Vectors.dense(trainingSummary.objectiveHistory()));
        trainingSummary.residuals().show();
        System.out.println("RMSE: " + trainingSummary.rootMeanSquaredError());
        System.out.println("r2: " + trainingSummary.r2());
        System.out.println("the magical prediction: " + lrModel.predict(new DenseVector(new double[]{1.0, 1.0})));

看到打印出来的所有值,很开心。

Coefficients: [-1.5625735463489882E-19,1.0000000000000544] Intercept: 2.5338210784074846E-10
numIterations: 0
objectiveHistory: [0.0]

+--------------------+
|           residuals|
+--------------------+
|-1.11910480882215...|

RMSE: 3.0933584599870493E-13
r2: 1.0
the magical prediction: 1.0000000002534366

它没有给我任何接近预测的东西,我期待的是

|Some time in the future|   banana sold some prediction|
| 1626414043 | 38 |

请问什么样的模型可以得到像“模型预测 X 香蕉将在未来 Y 时间出售”这样的答案

一小段代码和结果会很棒。

谢谢

该模型为您提供了变量的系数。然后很容易计算输出。如果您只有一个变量 x1,您的模型将类似于:

y = a*x1 + b

那么你的模型的输出是a和b。然后就可以计算y了。

一般来说,机器学习库还实现了让您计算输出的其他方法。最好搜索如何保存、加载然后使用新输入评估模型。查看 https://spark.apache.org/docs/1.6.1/api/java/org/apache/spark/ml/regression/LinearRegressionModel.html

有一种称为预测的方法,您可以通过将输入作为 Vector 实例来调用您的模型。我认为这会奏效!

另一件事是:您正在尝试使用单变量线性回归模型解决时间序列问题。我认为您应该使用更好的算法来处理时间序列或序列问题,例如长短期记忆 (LSTM)。

希望我的回答对你有用。继续前进 ;)

线性回归可以是您在使用更复杂的模型之前熟悉 mllib 的良好开端。首先,让我们看看您到目前为止完成的时间。

您的 VectorAssembler 以这种方式转换您的数据框:

之前:

time label
1621900800 43
1620432000 41

之后:

time label features
1621900800 43 [1621900800;43]
1620432000 41 [1620432000;41]

现在,当您要求 LinearRegression 训练其模型时,它会期望您的数据集包含两列:

  • 一列名为特征并包含一个向量,其中包含可用于预测标签的所有内容。
  • 一列名为label,你要预测的是什么

回归将找到 a 和 b,它们使所有记录 i 的错误最小化,其中:

y_i = a * x_i + b + error_i

在您的特定设置中,您已将标签传递给矢量汇编器,这是错误的,这就是您想要预测的! 您的模型只是了解到标签可以完美地预测标签:

y = 0.0 * 特征[0] + 1.0 * 特征[1]

所以您应该更正您的 VectorAssembler:

val vectorAssembler = new VectorAssembler().setInputCols(new String[]{"time"}).setOutputCol("features");

现在当你做预测的时候,你已经通过了这个:

lrModel.predict(new DenseVector(new double[]{ 1.0,        1.0})));
                                             timestamp   label

根据上面的公式returned 1.0。 现在,如果您按照上面的建议更改 VectorAssembler,您应该这样调用预测:

lrModel.predict(new DenseVector(new double[]{ timeStampIWantToPredict })));

旁注:

  • 您可以将一个数据集传递给您的预测器,它会return一个带有预测的新列的数据集。
  • 你真的应该仔细看看 Mllib Pipeline documentation
  • 然后您可以尝试向线性回归中添加一些新特征:季节性、自回归特征...