Java 关于“最小二乘法曲线平滑”的使用策略
作者在网上搜了一堆关于“最小二乘法”拟合的文章,大部分只是简单列出代码,描述不清,让人看了一头雾水!这里只站在巨人的肩膀上做数据处理时注意的事项,具体公式推导,不做累赘。
使用commons-math3 函数包,内容非常丰富,自行研究,下面言归正传:
- maven 添加依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.5</version>
</dependency>
- 具体调用最小二乘法代码实现:传入需要拟合的数据集List:值(y),序号(x)
/**
* 最小二乘法曲线拟合
* @param data
* @return
*/
public List<Double> polynomial(List<String> data){
final WeightedObservedPoints obs = new WeightedObservedPoints();
for (int i = 0; i < data.size(); i++) {
obs.add(i, Double.valueOf(data.get(i)));
}
/**
* 实例化一个2次多项式拟合器
*/
final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);//degree 阶数,一般为 3
/**
* 实例化检索拟合参数(多项式函数的系数)
*/
final double[] coeff = fitter.fit(obs.toList());//size 0-3 阶数
List<Double> result = new ArrayList<>();
for (int i = 0; i < data.size(); i++) {
double a = coeff[0]* Math.pow(i,0);
double b = coeff[1]* Math.pow(i,1);
double c = coeff[2]* Math.pow(i,2);
double d = coeff[3]* Math.pow(i,3);
/**
* 多项式函数f(x) = a0 * x + a1 * pow(x, 2) + .. + an * pow(x, n).
*/
double tmp = (a + b + c + d);
result.add(tmp);
}
return result;
}
- 第二步得到的结果就是曲线平滑后的结果集,后续就可以开展多个点的数据拟合成一个点,且真实反映一小段时间的合理结果;具体算法,后面整理后发布博文。