Java时间序列预测(ARIMA)

有时候我们需要在Java里对时间序列的数据进行简单地预测,通过其他语言(Python或R)来实现会极大的提高开发和运维成本.另外,很多数学模型的原理比较复杂,并且涉及到模型训练和参数调优,这些也会加大我们的时间投入.本文尝试向大家分享一个不需要了解算法、不需要参数调优就可以直接引用的实现方式.

添加依赖

当前Java可应用的第三方库非常少,通过对比后选择了下面的依赖,大家可以参考Github的文档和源码.

<dependency>
    <groupId>com.github.jrachiele</groupId>
    <artifactId>java-timeseries</artifactId>
    <version>0.2.1</version>
</dependency>

代码

如果你只想要一个可以引用的代码,你只需要在你的代码中调用下面的方法:

   TimeSeriesPredictUtil.predict(data, 7, false);

其中, data是你的历史时间序列, 7是需要未来多少个数据, false代表不绘图.

为了你上面的引用有效,你还需要将下面的TimeSeriesPredictUtil类复制到你的项目中:

package org.test;

import timeseries.TimeSeries;
import timeseries.models.Forecast;
import timeseries.models.arima.Arima;

import java.util.ArrayList;

public class TimeSeriesPredictUtil {

    private TimeSeriesPredictUtil() {
    }

    /**
     * 调用第三方库并对时间序列进行预测,输入对数据需要是有序甚至规律的时间序列。另外,不需要输入时间时间,
     * 如果你需要得到时间和预测值的键值对,你需要自己组装
     *
     * @param data  需要预测的数据
     * @param steps 你需要预测未来多少个单位的数据,比如5天,5周或者5个月。
     * @param draw  是否绘图,测试时可以通过绘图直观的翻译数据预测是否准确
     * @return 预测值数组
     */
    public static double[] predict(double[] data, int steps, boolean draw) {
        TimeSeries series = new TimeSeries(data);

        ArrayList<Integer> options = new ArrayList<>();
        int[] params = new int[]{0, 1, 2};
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();

        repeatableArrangement(3, params, options, result);

        ArrayList<Integer> bestChoice = new ArrayList<>(3);
        ArrayList<Integer> sBestChoice = new ArrayList<>(6);
        double minimalAic = Double.MAX_VALUE;
        for (ArrayList<Integer> item : result) {
            if (item.isEmpty()) {
                continue;
            }

            Arima.ModelOrder order = Arima.order(item.get(0), item.get(1), item.get(2));
            Arima model = Arima.model(series, order);
            double aic = model.aic();

            if (aic < minimalAic) {
                minimalAic = aic;
                bestChoice.clear();
                bestChoice.addAll(item);

                sBestChoice.clear();
            }

            for (ArrayList<Integer> sItem : result) {
                if (sItem.isEmpty()) {
                    continue;
                }

                Arima.ModelOrder sOrder = Arima.order(item.get(0), item.get(1), item.get(2),
                        sItem.get(0), sItem.get(1), sItem.get(2));
                Arima sModel = Arima.model(series, sOrder);
                double sAic = sModel.aic();

                if (sAic < minimalAic) {
                    minimalAic = sAic;
                    bestChoice.clear();

                    sBestChoice.clear();
                    sBestChoice.addAll(item);
                    sBestChoice.addAll(sItem);
                }
            }
        }

        Arima.ModelOrder order = sBestChoice.isEmpty()
                ? Arima.order(bestChoice.get(0), bestChoice.get(1), bestChoice.get(2))
                : Arima.order(sBestChoice.get(0), sBestChoice.get(1), sBestChoice.get(2),
                sBestChoice.get(3), sBestChoice.get(4), sBestChoice.get(5));
        Arima model = Arima.model(series, order);

        Forecast forecast = model.forecast(steps);

        if (draw) {
            forecast.plot();
        }

        return forecast.forecast().asArray();
    }

    private static void repeatableArrangement(int k, int[] arr, ArrayList<Integer> tmpArr,
                                              ArrayList<ArrayList<Integer>> result) {
        if (k == 1) {
            for (int j : arr) {
                tmpArr.add(j);
                ArrayList<Integer> tmp = new ArrayList<>(tmpArr);
                result.add(tmp);
                tmpArr.remove(tmpArr.size() - 1);
            }
        } else if (k > 1) {
            for (int j : arr) {
                tmpArr.add(j);
                repeatableArrangement(k - 1, arr, tmpArr, result);
                tmpArr.remove(tmpArr.size() - 1);
            }
        }
    }
}

结论

本文给出了使用ARIMA预测时间序列的实现方式,其中包括了参数自动生成,也支持季节性性数据的预测.如果你需要更深入的了解时间序列预测,你可以深入学习ARIMA算法原理,包括参数确定等.最后,你还可以去了解LSTM预测时间序列.

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值