开发语言:c#
在实际项目中,经常需要用到直线拟合,比如已有一些数值,需要插值出一些离散点,本文利用常见的一元线性回归算法和最小二乘法拟合直线。
调用方法:
linefitmethod.linearfit(pionts, out a, out b);
double y1 = linefitmethod.linearval(x, a, b);
dcorr1 = linefitmethod.corrcoef(dy.toarray(), listy.toarray());
(0<|corr(x,y)|<1 表示具有一定线性相关性,越接近1表示越线性相关)
using system;using system.collections.generic;using system.linq;using system.text;using system.threading.tasks;using system.drawing; namespace method.yosao{ /*=================================================== * 类名称: linefitmethod * 类描述:直线拟合及相关系数计算 * 创建人: yosao * 创建时间: 2020/6/6/星期六 11:49:28 * 修改人: * 修改时间: * 版本: @version 1.0 =====================================================*/ class linefitmethod { /// /// 一元线性回归 最小平方算法 /// 将离散点拟合为 y = a x b 型直线 /// /// /// /// /// public static bool linearfit(double[] x, double[] y, out double a, out double b) { double xsum = 0; double ysum = 0; double xysum = 0; double x2sum = 0; int size = x.length; if (size < 2) { a = 0; b = 0; return false; } for (int i = 0; i < size; i ) { xsum = xsum x[i]; ysum = ysum y[i]; xysum = xysum x[i] * y[i]; x2sum = x2sum x[i] * x[i]; } a = (size * xysum - xsum * ysum) / (size * x2sum - xsum * xsum 1e-10); b = (ysum - a * xsum) / size; return true; } /// /// 计算拟合后的值 /// /// /// /// /// public static void linearval(double[] x, double a, double b, double[] y) { for (int i = 0; i < x.length; i ) { y[i] = a * x[i] b; } } /// /// 计算拟合后的值 /// /// /// /// /// y public static double linearval(double x, double a, double b) { return a * x b; } /// /// 计算相关系数,线性相关性 /// l=线性相关 0<| corr(x,y)|<1的时候,说明两个随机变量具有一定程度的线性关系。越大线性相关性越强 /// /// /// /// public static double corrcoef(double[] y1, double[] y2) { double xy = 0, x = 0, y = 0, xsum = 0, ysum = 0; double corrc = 0; int m = y1.length; for (int i = 0; i < m; i ) { xsum = y1[i]; ysum = y2[i]; } for (int i = 0; i < m; i ) { x = x (m * y1[i] - xsum) * (m * y1[i] - xsum); y = y (m * y2[i] - ysum) * (m * y2[i] - ysum); xy = xy (m * y1[i] - xsum) * (m * y2[i] - ysum); } corrc = math.abs(xy) / (math.sqrt(x) * math.sqrt(y)); return corrc; } /// /// * 最小二乘法直线拟合(不是常见的一元线性回归算法) /// * 将离散点拟合为 a x b y c = 0 型直线 /// * 假设每个点的 x y 坐标的误差都是符合 0 均值的正态分布的。 /// * 与一元线性回归算法的区别:一元线性回归算法假定 x 是无误差的,只有 y 有误差。 /// * 最后将直线改写为 y = a x b 形式 /// /// /// /// /// /// public static bool linearfit(list points, out double a, out double b) { double c = 0; int size = points.count; if (size < 2) { a = 0; b = 0; c = 0; return false; } double x_mean = 0; double y_mean = 0; for (int i = 0; i < size; i ) { x_mean = points[i].x; y_mean = points[i].y; } x_mean /= size; y_mean /= size; //至此,计算出了 x y 的均值 double dxx = 0, dxy = 0, dyy = 0; for (int i = 0; i < size; i ) { dxx = (points[i].x - x_mean) * (points[i].x - x_mean); dxy = (points[i].x - x_mean) * (points[i].y - y_mean); dyy = (points[i].y - y_mean) * (points[i].y - y_mean); } double lambda = ((dxx dyy) - math.sqrt((dxx - dyy) * (dxx - dyy) 4 * dxy * dxy)) / 2.0; double den = math.sqrt(dxy * dxy (lambda - dxx) * (lambda - dxx)); a = dxy / den; b = (lambda - dxx) / den; c = -a * x_mean - b * y_mean; //将参数由 a x b y c = 0转换为y = a x b if (b != 0) { a = - a / b; b = - c / b; } else { //直线方程则为x=c/a; return false; } return true; } }}
欢迎关注@机器视角,我们将结合机器视觉技术、rpa技术、机器人技术,和大家一起讨论工业人工智能的新技术新方法。同时也会不定期给大家推荐分析一些好用的工具、产品和代码。
本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。e-mail:dandanxi6@qq.com