原文地址: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
  1. package com.my.study.algorithm.leastSquareMethod;
  2. /**
  3. * Least square method class.
  4. */
  5. public class LeastSquareMethod {
  6. private double[] x;
  7. private double[] y;
  8. private double[] weight;
  9. private int n;
  10. private double[] coefficient;
  11. /**
  12. * Constructor method.
  13. *
  14. * @param x
  15. *            Array of x
  16. * @param y
  17. *            Array of y
  18. * @param n
  19. *            The order of polynomial
  20. */
  21. public LeastSquareMethod(double[] x, double[] y, int n) {
  22. if (x == null || y == null || x.length < 2 || x.length != y.length
  23. || n < 2) {
  24. throw new IllegalArgumentException(
  25. "IllegalArgumentException occurred.");
  26. }
  27. this.x = x;
  28. this.y = y;
  29. this.n = n;
  30. weight = new double[x.length];
  31. for (int i = 0; i < x.length; i++) {
  32. weight[i] = 1;
  33. }
  34. compute();
  35. }
  36. /**
  37. * Constructor method.
  38. *
  39. * @param x
  40. *            Array of x
  41. * @param y
  42. *            Array of y
  43. * @param weight
  44. *            Array of weight
  45. * @param n
  46. *            The order of polynomial
  47. */
  48. public LeastSquareMethod(double[] x, double[] y, double[] weight, int n) {
  49. if (x == null || y == null || weight == null || x.length < 2
  50. || x.length != y.length || x.length != weight.length || n < 2) {
  51. throw new IllegalArgumentException(
  52. "IllegalArgumentException occurred.");
  53. }
  54. this.x = x;
  55. this.y = y;
  56. this.n = n;
  57. this.weight = weight;
  58. compute();
  59. }
  60. /**
  61. * Get coefficient of polynomial.
  62. *
  63. * @return coefficient of polynomial
  64. */
  65. public double[] getCoefficient() {
  66. return coefficient;
  67. }
  68. /**
  69. * Used to calculate value by given x.
  70. *
  71. * @param x
  72. *            x
  73. * @return y
  74. */
  75. public double fit(double x) {
  76. if (coefficient == null) {
  77. return 0;
  78. }
  79. double sum = 0;
  80. for (int i = 0; i < coefficient.length; i++) {
  81. sum += Math.pow(x, i) * coefficient[i];
  82. }
  83. return sum;
  84. }
  85. /**
  86. * Use Newton's method to solve equation.
  87. *
  88. * @param y
  89. *            y
  90. * @return x
  91. */
  92. public double solve(double y) {
  93. return solve(y, 1.0d);
  94. }
  95. /**
  96. * Use Newton's method to solve equation.
  97. *
  98. * @param y
  99. *            y
  100. * @param startX
  101. *            The start point of x
  102. * @return x
  103. */
  104. public double solve(double y, double startX) {
  105. final double EPS = 0.0000001d;
  106. if (coefficient == null) {
  107. return 0;
  108. }
  109. double x1 = 0.0d;
  110. double x2 = startX;
  111. do {
  112. x1 = x2;
  113. x2 = x1 - (fit(x1) - y) / calcReciprocal(x1);
  114. } while (Math.abs((x1 - x2)) > EPS);
  115. return x2;
  116. }
  117. /*
  118. * Calculate the reciprocal of x.
  119. *
  120. * @param x x
  121. *
  122. * @return the reciprocal of x
  123. */
  124. private double calcReciprocal(double x) {
  125. if (coefficient == null) {
  126. return 0;
  127. }
  128. double sum = 0;
  129. for (int i = 1; i < coefficient.length; i++) {
  130. sum += i * Math.pow(x, i - 1) * coefficient[i];
  131. }
  132. return sum;
  133. }
  134. /*
  135. * This method is used to calculate each elements of augmented matrix.
  136. */
  137. private void compute() {
  138. if (x == null || y == null || x.length <= 1 || x.length != y.length
  139. || x.length < n || n < 2) {
  140. return;
  141. }
  142. double[] s = new double[(n - 1) * 2 + 1];
  143. for (int i = 0; i < s.length; i++) {
  144. for (int j = 0; j < x.length; j++) {
  145. s[i] += Math.pow(x[j], i) * weight[j];
  146. }
  147. }
  148. double[] b = new double[n];
  149. for (int i = 0; i < b.length; i++) {
  150. for (int j = 0; j < x.length; j++) {
  151. b[i] += Math.pow(x[j], i) * y[j] * weight[j];
  152. }
  153. }
  154. double[][] a = new double[n][n];
  155. for (int i = 0; i < n; i++) {
  156. for (int j = 0; j < n; j++) {
  157. a[i][j] = s[i + j];
  158. }
  159. }
  160. // Now we need to calculate each coefficients of augmented matrix
  161. coefficient = calcLinearEquation(a, b);
  162. }
  163. /*
  164. * Calculate linear equation.
  165. *
  166. * The matrix equation is like this: Ax=B
  167. *
  168. * @param a two-dimensional array
  169. *
  170. * @param b one-dimensional array
  171. *
  172. * @return x, one-dimensional array
  173. */
  174. private double[] calcLinearEquation(double[][] a, double[] b) {
  175. if (a == null || b == null || a.length == 0 || a.length != b.length) {
  176. return null;
  177. }
  178. for (double[] x : a) {
  179. if (x == null || x.length != a.length)
  180. return null;
  181. }
  182. int len = a.length - 1;
  183. double[] result = new double[a.length];
  184. if (len == 0) {
  185. result[0] = b[0] / a[0][0];
  186. return result;
  187. }
  188. double[][] aa = new double[len][len];
  189. double[] bb = new double[len];
  190. int posx = -1, posy = -1;
  191. for (int i = 0; i <= len; i++) {
  192. for (int j = 0; j <= len; j++)
  193. if (a[i][j] != 0.0d) {
  194. posy = j;
  195. break;
  196. }
  197. if (posy != -1) {
  198. posx = i;
  199. break;
  200. }
  201. }
  202. if (posx == -1) {
  203. return null;
  204. }
  205. int count = 0;
  206. for (int i = 0; i <= len; i++) {
  207. if (i == posx) {
  208. continue;
  209. }
  210. bb[count] = b[i] * a[posx][posy] - b[posx] * a[i][posy];
  211. int count2 = 0;
  212. for (int j = 0; j <= len; j++) {
  213. if (j == posy) {
  214. continue;
  215. }
  216. aa[count][count2] = a[i][j] * a[posx][posy] - a[posx][j]
  217. * a[i][posy];
  218. count2++;
  219. }
  220. count++;
  221. }
  222. // Calculate sub linear equation
  223. double[] result2 = calcLinearEquation(aa, bb);
  224. // After sub linear calculation, calculate the current coefficient
  225. double sum = b[posx];
  226. count = 0;
  227. for (int i = 0; i <= len; i++) {
  228. if (i == posy) {
  229. continue;
  230. }
  231. sum -= a[posx][i] * result2[count];
  232. result[i] = result2[count];
  233. count++;
  234. }
  235. result[posy] = sum / a[posx][posy];
  236. return result;
  237. }
  238. public static void main(String[] args) {
  239. LeastSquareMethod eastSquareMethod = new LeastSquareMethod(
  240. new double[] { 0.5, 1.0, 1.5, 2.0, 2.5, 3.0 }, new double[] {
  241. 1.75, 2.45, 3.81, 4.8, 7.0, 8.6 }, 3);
  242. /*double[] coefficients = eastSquareMethod.getCoefficient();
  243. for (double c : coefficients) {
  244. System.out.println(c);
  245. }*/
  246. System.out.println(eastSquareMethod.fit(4));
  247. LeastSquareMethod eastSquareMethod2 = new LeastSquareMethod(
  248. new double[] { 0.5, 1.0, 1.5, 2.0, 2.5, 3.0 }, new double[] {
  249. 1.75, 2.45, 3.81, 4.8, 7.0, 8.6 }, 2);
  250. System.out.println(eastSquareMethod2.solve(100));
  251. }
  252. }

使用开源库

也可使用Apache开源库commons math,提供的功能更强大,

http://commons.apache.org/proper/commons-math/userguide/fitting.html

[html] view plaincopy
  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-math3</artifactId>
  4. <version>3.5</version>
  5. </dependency>
[java] view plaincopy
  1. private static void testLeastSquareMethodFromApache() {
  2. final WeightedObservedPoints obs = new WeightedObservedPoints();
  3. obs.add(-3, 4);
  4. obs.add(-2, 2);
  5. obs.add(-1, 3);
  6. obs.add(0, 0);
  7. obs.add(1, -1);
  8. obs.add(2, -2);
  9. obs.add(3, -5);
  10. // Instantiate a third-degree polynomial fitter.
  11. final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(3);
  12. // Retrieve fitted parameters (coefficients of the polynomial function).
  13. final double[] coeff = fitter.fit(obs.toList());
  14. for (double c : coeff) {
  15. System.out.println(c);
  16. }
  17. }

转载于:https://www.cnblogs.com/davidwang456/articles/5582752.html

最小二乘法多项式拟合的Java实现--转相关推荐

  1. 多项式拟合 java_最小二乘法多项式拟合的Java实现

    背景由于项目中需要根据磁盘的历史使用情况预测未来一段时间的使用情况,决定采用最小二乘法做多项式拟合,这里简单描述下: 假设给定的数据点和其对应的函数值为 (x1, y1), (x2, y2), ... ...

  2. python多项式拟合_最小二乘法—多项式拟合非线性函数

    本章涉及到的知识点清单: 1.函数的近似表示-高次多项式 2.误差函数-最小二乘法 3.引出案例函数曲线 4.目标函数 5.优化目标函数 6.优化目标函数-梯度下降法 7.优化目标函数-求解线性方程组 ...

  3. 数值计算之 拟合法,线性拟合,多项式拟合

    数值计算之 拟合法之线性拟合,多项式拟合 前言 最小二乘法 多项式拟合 线性拟合 后记 前言 拟合法是另一种由采样数据求取潜在函数的方法.插值要求函数必须经过每一个采样节点,而拟合则要求函数与全部节点 ...

  4. 最小二乘法函数拟合原理及matlab实现—数学笔记

    最小二乘法函数拟合原理及matlab实现 --数值分析数学笔记 如有纰漏,欢迎指正 文章目录 最小二乘法函数拟合原理及matlab实现 前言 一.拟合标准 1.使偏差向量满足 1 1 1 - 范数 2 ...

  5. matlab多项式拟合要求系数项大于零,matlab多项式系数

    要求一高阶多项式的根往 往须借助数值方法,所 幸MATLAB已将这些数值方法写成一函数 roots(p),我们只要输入多项式的各阶系数 (以 p 代表)即可求解到对应的根 >...... 2. ...

  6. 最小二乘法多项式曲线拟合原理与实现(错误地方已经修改底层补充自己写的java实现)

    目录(?) [-] 概念 原理 运行前提 代码 运行效果 概念 最小二乘法多项式曲线拟合,根据给定的m个点,并不要求这条曲线精确地经过这些点,而是曲线y=f(x)的近似曲线y= φ(x). 原理 [原 ...

  7. java 多项式拟合最多的项数_机器学习(1)--线性回归和多项式拟合

    机器学习(1)--线性回归和多项式拟合 机器学习(2)逻辑回归 (数学推导及代码实现) 机器学习(3)softmax实现Fashion-MNIST分类 一 线性回归 线性回归,顾名思义是利用线性模型对 ...

  8. 最小二乘多项式拟合程序matlab,最小二乘法的多项式拟合(matlab实现)

    1.用最小二乘法进行多项式拟合(matlab实现)西安交通大学 徐彬华算法分析:对给定数据 (i=0 ,1,2,3,.,m),一共m+1个数据点,取多项式P(x),使函数P(x)称为拟合函数或最小二乘 ...

  9. java 多项式拟合最多的项数_Matlab概率统计与曲线拟合

    一.二项分布 二项分布来源于伯努利试验 (事件发生概率 ) : 含义为独立重复N次试验后, 事件总共发生k次的概率 分布函数 二项分布记为 binopdf 获得事件共发生次的概率 binocdf 为事 ...

最新文章

  1. 链表问题13——删除无序单链表中值重复出现的节点(方法二)
  2. 你的生产型ML复现不了,可能是工作流程出了问题
  3. request url换成ip地址_【协议粗讲】TTP协议之URL,不能不知道的协议技术点
  4. android 手动 打包,android 手动打包apk
  5. C++11 std::bind 和 std::placeholder
  6. 页面残留数据该如何处理
  7. oracle 重复的记录数,如何确定Oracle数据库表中重复的记录
  8. 一站式WPF--依赖属性(DependencyProperty)
  9. 简书留言收费可行性评估
  10. 技术人必备的学习工具
  11. 封装条形码MaHelper
  12. 【易实战】Spring Cloud Greenwich Eureka:服务注册与发现
  13. mysql触发器报错_mysql触发器实例:莫名其妙的错误?
  14. 【知易行难】RS485组网连接示意图
  15. 计算机信息检索工作的原理,2021年湖北自考计算机信息检索课程考试大纲
  16. 【原创】使用高德 API
  17. 制作一个类“全能扫描王”的简易扫描软件(opencv)
  18. AI绘画小程序图片转漫画SaaS多开
  19. 【人工智能】人脸识别系统【实验报告与全部代码】(QDU)
  20. 实习6(持续更新)--数据分析

热门文章

  1. mysql主从复制自增_关于mysql主从复制自增长列
  2. java简述对象的组合_Java程序运行和对象创建过程简述
  3. java derby 用户安全_Java 7u51安全权限变化,运行derby server被拒,解决方法
  4. linux应用程序抢占键盘,linux 系统挂起
  5. sqlserver 指数_大盘指数大涨,牛市是否提前来了?
  6. Linux视频切片m3u8,使用ffmpeg+nginx使用视频切片播放
  7. java统计日志qps_【原创】基于日志增量,统计qps,并基于ip排序
  8. 记录webscraper的使用过程
  9. 融云php sdk下载安装,LICENSE · 融云 RongCloud/server-sdk-php-composer - Gitee.com
  10. mysql 22001_mysql ERROR 1264 (22003): Out of range value for column 'x' at row 1 错误