如何找到数据系列的趋势(增长/减少/平稳)

时间:2019-05-09 08:46:18

标签: algorithm analysis trend

我正在尝试提取制造机器的OEE趋势。我已经有一个OEE数据集,每台制造机每30秒或多或少计算一次并存储在数据库中。

我想做的是提取数据集的一个子集(例如,过去30分钟),并说明OEE是否增长,降低或稳定(具有一定阈值)。我的任务不是预测OEE的下一个值是什么,而只是知道它是否已减小(期望的返回值:-1 ),增长(期望的返回值:+1 < / em>)或稳定(期望的返回值:0 )基于数据集。我在项目中使用Java 8

以下是数据集的示例:

71.37
71.37
70.91
70.30
70.30
70.42
70.42
69.77
69.77
69.29
68.92
68.92
68.61
68.61
68.91
68.91
68.50
68.71
69.27
69.26
69.89
69.85
69.98
69.93
69.39
68.97
69.03

从该数据集中可以得出OEE一直在下降(基于阈值的原因),因此该算法将返回-1。

我一直没有在网上搜索。我找到了thisthis github projectthis stackoverflow question。但是,所有这些(或多或少)都是复杂的预测算法。我正在寻找更简单的解决方案。任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:3)

你可以去
最近n个值的滑动平均值

最近n个值的滑动中位数

这在很大程度上取决于您的应用程序。但是,这两种方法都很容易实现,而且在很多情况下还不够好。

答案 1 :(得分:0)

从数学上可以知道,人们会使用d / dt,而d / dt或多或少地使用了步长差异。

趋势应该有一定的分量。

class Trend {
    int direction;
    double probability;
}

Trend trend(double[] lastData) {
    double[] deltas = Arrays.copyOf(lastData, lastData.length - 1);
    for (int i = 0; i < deltas.length; ++i) {
       deltas[i] -= lastData[i + 1];
    }
    // Trend based on two parts:
    int parts = 2;
    int splitN = (deltas.length + 1) / parts;
    int i = 0;
    int[] trends = new int[parts];
    for (int j = 0; j < parts.length; ++j) {
        int n = Math.min(splitN, parts.length - i);
        double partAvg = DoubleStream.of(deltas).skip(i).limit(n).sum() / n;
        trends[j] = tendency(partAvg);
    }
    Trend result = new Trend();
    trend.direction = trends[parts - 1];
    double avg = IntStream.of(trends).average().orElse((double)trend.direction);
    trend.probability = ((direction - avg) + 1) / 2;
    return trends[parts - 1];
}

int tendency(double sum) {
    final double EPS = 0.0001;
    return sum < -EPS ? -1 : sum > EPS ? 1 : 0;
}

这不是很复杂。对于更详尽的治疗,数学论坛可能会有用。