生活随笔
收集整理的這篇文章主要介紹了
最小二乘法多项式拟合的Java实现--转
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文地址:http://blog.csdn.net/funnyrand/article/details/46742561
背景
由于項目中需要根據磁盤的歷史使用情況預測未來一段時間的使用情況,決定采用最小二乘法做多項式擬合,這里簡單描述下:
?
假設給定的數據點和其對應的函數值為 (x1, y1), (x2, y2), ... (xm, ym),需要做的就是得到一個多項式函數
f(x) = a0 * x + a1 * pow(x, 2) + .. + an * pow(x, n),使其對所有給定x所計算出的f(x)與實際對應的y值的差的平方和最小,
也就是計算多項式的各項系數 a0, a1, ... an.
?
根據最小二乘法的原理,該問題可轉換為求以下線性方程組的解:Ga =?B,
所以從編程的角度來說需要做兩件事情,1,確定線性方程組的各個系數,2,解線性方程組
確定系數比較簡單,對給定的 (x1, y1), (x2, y2), ... (xm, ym) 做相應的計算即可,相關代碼:
private void compute() {
...
}
解線性方程組稍微復雜,這里用到了高斯消元法,基本思想是通過遞歸做矩陣轉換,逐漸減少求解的多項式系數的個數,相關代碼:
private double[] calcLinearEquation(double[][] a, double[] b) {
...
}
?
Java代碼
[java]?view plaincopy
package?com.my.study.algorithm.leastSquareMethod;????public?class?LeastSquareMethod?{????????private?double[]?x;??????private?double[]?y;??????private?double[]?weight;??????private?int?n;??????private?double[]?coefficient;????????????public?LeastSquareMethod(double[]?x,?double[]?y,?int?n)?{??????????if?(x?==?null?||?y?==?null?||?x.length?<?2?||?x.length?!=?y.length??????????????????||?n?<?2)?{??????????????throw?new?IllegalArgumentException(??????????????????????"IllegalArgumentException?occurred.");??????????}??????????this.x?=?x;??????????this.y?=?y;??????????this.n?=?n;??????????weight?=?new?double[x.length];??????????for?(int?i?=?0;?i?<?x.length;?i++)?{??????????????weight[i]?=?1;??????????}??????????compute();??????}????????????public?LeastSquareMethod(double[]?x,?double[]?y,?double[]?weight,?int?n)?{??????????if?(x?==?null?||?y?==?null?||?weight?==?null?||?x.length?<?2??????????????????||?x.length?!=?y.length?||?x.length?!=?weight.length?||?n?<?2)?{??????????????throw?new?IllegalArgumentException(??????????????????????"IllegalArgumentException?occurred.");??????????}??????????this.x?=?x;??????????this.y?=?y;??????????this.n?=?n;??????????this.weight?=?weight;??????????compute();??????}????????????public?double[]?getCoefficient()?{??????????return?coefficient;??????}????????????public?double?fit(double?x)?{??????????if?(coefficient?==?null)?{??????????????return?0;??????????}??????????double?sum?=?0;??????????for?(int?i?=?0;?i?<?coefficient.length;?i++)?{??????????????sum?+=?Math.pow(x,?i)?*?coefficient[i];??????????}??????????return?sum;??????}????????????public?double?solve(double?y)?{??????????return?solve(y,?1.0d);??????}????????????public?double?solve(double?y,?double?startX)?{??????????final?double?EPS?=?0.0000001d;??????????if?(coefficient?==?null)?{??????????????return?0;??????????}??????????double?x1?=?0.0d;??????????double?x2?=?startX;??????????do?{??????????????x1?=?x2;??????????????x2?=?x1?-?(fit(x1)?-?y)?/?calcReciprocal(x1);??????????}?while?(Math.abs((x1?-?x2))?>?EPS);??????????return?x2;??????}????????????private?double?calcReciprocal(double?x)?{??????????if?(coefficient?==?null)?{??????????????return?0;??????????}??????????double?sum?=?0;??????????for?(int?i?=?1;?i?<?coefficient.length;?i++)?{??????????????sum?+=?i?*?Math.pow(x,?i?-?1)?*?coefficient[i];??????????}??????????return?sum;??????}????????????private?void?compute()?{??????????if?(x?==?null?||?y?==?null?||?x.length?<=?1?||?x.length?!=?y.length??????????????????||?x.length?<?n?||?n?<?2)?{??????????????return;??????????}??????????double[]?s?=?new?double[(n?-?1)?*?2?+?1];??????????for?(int?i?=?0;?i?<?s.length;?i++)?{??????????????for?(int?j?=?0;?j?<?x.length;?j++)?{??????????????????s[i]?+=?Math.pow(x[j],?i)?*?weight[j];??????????????}??????????}??????????double[]?b?=?new?double[n];??????????for?(int?i?=?0;?i?<?b.length;?i++)?{??????????????for?(int?j?=?0;?j?<?x.length;?j++)?{??????????????????b[i]?+=?Math.pow(x[j],?i)?*?y[j]?*?weight[j];??????????????}??????????}??????????double[][]?a?=?new?double[n][n];??????????for?(int?i?=?0;?i?<?n;?i++)?{??????????????for?(int?j?=?0;?j?<?n;?j++)?{??????????????????a[i][j]?=?s[i?+?j];??????????????}??????????}????????????????????coefficient?=?calcLinearEquation(a,?b);??????}????????????private?double[]?calcLinearEquation(double[][]?a,?double[]?b)?{??????????if?(a?==?null?||?b?==?null?||?a.length?==?0?||?a.length?!=?b.length)?{??????????????return?null;??????????}??????????for?(double[]?x?:?a)?{??????????????if?(x?==?null?||?x.length?!=?a.length)??????????????????return?null;??????????}????????????int?len?=?a.length?-?1;??????????double[]?result?=?new?double[a.length];????????????if?(len?==?0)?{??????????????result[0]?=?b[0]?/?a[0][0];??????????????return?result;??????????}????????????double[][]?aa?=?new?double[len][len];??????????double[]?bb?=?new?double[len];??????????int?posx?=?-1,?posy?=?-1;??????????for?(int?i?=?0;?i?<=?len;?i++)?{??????????????for?(int?j?=?0;?j?<=?len;?j++)??????????????????if?(a[i][j]?!=?0.0d)?{??????????????????????posy?=?j;??????????????????????break;??????????????????}??????????????if?(posy?!=?-1)?{??????????????????posx?=?i;??????????????????break;??????????????}??????????}??????????if?(posx?==?-1)?{??????????????return?null;??????????}????????????int?count?=?0;??????????for?(int?i?=?0;?i?<=?len;?i++)?{??????????????if?(i?==?posx)?{??????????????????continue;??????????????}??????????????bb[count]?=?b[i]?*?a[posx][posy]?-?b[posx]?*?a[i][posy];??????????????int?count2?=?0;??????????????for?(int?j?=?0;?j?<=?len;?j++)?{??????????????????if?(j?==?posy)?{??????????????????????continue;??????????????????}??????????????????aa[count][count2]?=?a[i][j]?*?a[posx][posy]?-?a[posx][j]??????????????????????????*?a[i][posy];??????????????????count2++;??????????????}??????????????count++;??????????}????????????????????double[]?result2?=?calcLinearEquation(aa,?bb);????????????????????double?sum?=?b[posx];??????????count?=?0;??????????for?(int?i?=?0;?i?<=?len;?i++)?{??????????????if?(i?==?posy)?{??????????????????continue;??????????????}??????????????sum?-=?a[posx][i]?*?result2[count];??????????????result[i]?=?result2[count];??????????????count++;??????????}??????????result[posy]?=?sum?/?a[posx][posy];??????????return?result;??????}????????public?static?void?main(String[]?args)?{??????????LeastSquareMethod?eastSquareMethod?=?new?LeastSquareMethod(??????????????????new?double[]?{?0.5,?1.0,?1.5,?2.0,?2.5,?3.0?},?new?double[]?{??????????????????????????1.75,?2.45,?3.81,?4.8,?7.0,?8.6?},?3);????????????????????System.out.println(eastSquareMethod.fit(4));????????????LeastSquareMethod?eastSquareMethod2?=?new?LeastSquareMethod(??????????????????new?double[]?{?0.5,?1.0,?1.5,?2.0,?2.5,?3.0?},?new?double[]?{??????????????????????????1.75,?2.45,?3.81,?4.8,?7.0,?8.6?},?2);??????????System.out.println(eastSquareMethod2.solve(100));????????}??}?? 使用開源庫
也可使用Apache開源庫commons math,提供的功能更強大,
http://commons.apache.org/proper/commons-math/userguide/fitting.html
?
[html]?view plaincopy
<dependency>??????????????<groupId>org.apache.commons</groupId>??????????????<artifactId>commons-math3</artifactId>??????????????<version>3.5</version>??????????</dependency>??
?
?
[java]?view plaincopy
private?static?void?testLeastSquareMethodFromApache()?{??????????final?WeightedObservedPoints?obs?=?new?WeightedObservedPoints();??????????obs.add(-3,?4);??????????obs.add(-2,?2);??????????obs.add(-1,?3);??????????obs.add(0,?0);??????????obs.add(1,?-1);??????????obs.add(2,?-2);??????????obs.add(3,?-5);????????????????????final?PolynomialCurveFitter?fitter?=?PolynomialCurveFitter.create(3);????????????????????final?double[]?coeff?=?fitter.fit(obs.toList());??????????for?(double?c?:?coeff)?{??????????????System.out.println(c);??????????}??????} ? ?
轉載于:https://www.cnblogs.com/davidwang456/articles/5582752.html
總結
以上是生活随笔為你收集整理的最小二乘法多项式拟合的Java实现--转的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。