加权移动平均法、改编的按增量加权移动平均算法
public double WeightedMovingAverage(double[] data, int x) {
double[] newData = data.clone();
int count = newData.length;
double forecast = 0.0;
int i = 0;
while (i <= x) {
forecast = 0.0;
int js = 0;
double cs = 0;
for (int j = 0; j < count; j++) {
forecast += (j + 1) * newData[j];
}
forecast /= (count * (count + 1) / 2);
for (int j = 0; j < count - 1; j++) {
newData[j] = newData[j + 1];
}
newData[count - 1] = forecast;
for (int j = 0; j < count - 1; j++) {
cs = newData[j];
if (newData[count - 1] == cs) {
js++;
}
}
if (js == count - 1) {
break;
}
i++;
}
return forecast;
}
for (int j = 0; j < count; j++) {
forecast += (j + 1) * newData[j];
}
forecast /= (count * (count + 1) / 2);
- 2.1加权移动平均法的奇思妙想(按增量重新分配权重)
package cn.frameworkModule;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class JunitTest2 {
public static double WeightedMovingAverage2(Double[] data, int x, int y) {
Integer z = y;
Integer id = 0;
double forecast = 0.0;
Double[] clone = data.clone();
while (id <= x) {
Integer js = 0;
Integer count = 0;
double incr = 0.0;
double incrSum = 0.0;
double cs = 0;
System.out.println(Arrays.toString(clone));
boolean flag = clone[0] > clone[1];
Double[] clone2 = clone.clone();
Arrays.sort(clone2);
List<Double> asList = Arrays.asList(clone2);
TreeSet<Double> dataSet = new TreeSet<>(asList);
Integer size = dataSet.size();
Double first = dataSet.first();
Double last = dataSet.last();
double maxIncr = last - first;
for (int i = 1; i <= maxIncr; i++) {
Integer suitNum = 0;
for (Double num : dataSet) {
double tempNum = num + i;
if (dataSet.contains(tempNum)) {
suitNum++;
}
}
if (suitNum >= (double) (size - 1) * iterationRatio(y) && suitNum >= 2) {
count++;
incrSum += i * suitNum;
}
y--;
y = (y == 1) ? z : y;
}
count = count == 0 ? 1 : count;
incr = 2 * incrSum / count / (count + 1);
for (int j = 0; j < clone.length - 1; j++) {
clone[j] = clone[j + 1];
}
incr = flag ? incr : -incr;
System.err.println("incr:" + incr + ",last:" + clone[clone.length - 1]);
clone[clone.length - 1] = clone[clone.length - 1] + getRealValue(incr, 0);
forecast = clone[clone.length - 1];
for (int j = 0; j < clone.length - 1; j++) {
cs = clone[j];
if (clone[clone.length - 1] == cs) {
js++;
}
}
if (js == clone.length - 1) {
break;
}
id++;
}
return forecast;
}
public static double iterationRatio(Integer iteration) {
if (iteration <= 0) {
throw new IllegalArgumentException("迭代次数必须大于0");
}
double source = Math.log10(iteration) - 1;
return 1.0 / (1 + Math.exp(-1 * source));
}
public static double getRealValue(double value, int resLen) {
if (resLen == 0) {
return Math.round(value * 10 + 5) / 10;
} else {
double db = Math.pow(10, resLen);
return Math.round(value * db) / db;
}
}
public static void main(String[] args) {
Double[] data = new Double[20];
for (int i = 0; i < 20; i++) {
data[i] = (int) (Math.random() * 10) + 30.0;
System.err.println(data[i]);
}
double d = WeightedMovingAverage2(data, data.length * 2, 10);
System.err.println(d);
}
}
- 2.2按增量加权
- 如数据集是:3,9,6,12,15,4,8,8
- 增量为1的有:3-4;8-9;8-9;共3个
- 增量为2的有:4-6;6-8;6-8;共3个
- 增量为3的有:3-6;6-9;9-12;12-15;共4个
- 增量为4的有:4-8;4-8;8-12;共3个
- …
- 最大增量位:15-3=12;共1个
- 最终按个数分权平均计算增量
for (int i = 1; i <= maxIncr; i++) {
Integer suitNum = 0;
for (Double num : dataSet) {
double tempNum = num + i;
if (dataSet.contains(tempNum)) {
suitNum++;
}
}
if (suitNum >= (double) (size - 1) * iterationRatio(y) && suitNum >= 2) {
count++;
incrSum += i * suitNum;
}
y--;
y = (y == 1) ? z : y;
}
- 2.3筛选增量
- iterationRatio(y)方法限定占比,函数结果限定在(0.27~1)
- ps:y值恒定最佳?
- if (suitNum >= (double) (size - 1) * iterationRatio(y) && suitNum >= 2) {
count++;
incrSum += i * suitNum;
}
y--;
y = (y == 1) ? z : y;
- 遇到问题,
- ③增量梯度目前是整数(导致8也要取整)
- ⑦增量正负号不好确定;
- 数据集较多以等比数据出现时可否换等比加权?
- iterationRatio(y)函数取恒定值