一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

一、简单分析

  点的线性拟合是一般实验数据处理最常用的方法。下面考虑一个用n个数据点拟合成直线的问题,直线模型为

y(x)=ax+b

  这个问题称为线性回归。设变量y随自变量x变化,给定n组观测数据(xi,yi),用直线来拟合这些点,其中a,b是直线的斜率和截距,称为回归系数。

  为确定回归系数,通常采用最小二乘法,即使下式达到最小

   根据极值愿意,a,b满足下列方程

   可解得:

   最终可得直线方程

y(x)=ax+b

  对于任何一组数据,都可以用这种方式拟合出一条直线,而数据点有些远离直线,有些接近直线,便有一个系数作为对所拟合直线的线性程度的一般判据

  它可以判断一组数据线性相关的密切程度

  定义为:

  r的绝对值越接近与1,表示直线的线性关系越好,直线关系的数据r=1。

二、代码实现

 1 #ifndef _POINT_H
 2 #define _POINT_H_
 3 
 4 class Point {
 5     public:
 6         Point(float x=0,float y=0):x(x),y(y) {};
 7         float getX() {return x;}
 8         float getY(){return y;}
 9     private:
10         float x,y; 
11 };
12 
13 #endif
 1 #include "Point.h"
 2 #include<iostream>
 3 #include<math.h>
 4 
 5 using namespace std;
 6 
 7 //直线线性拟合 points为点 n为点的个数
 8 void lineFit(Point points[],int n) {
 9     float avgX,avgY=0;
10     float Lxx=0,Lyy=0,Lxy=0;
11 
12     //计算x,y平均值
13     for(int i=0; i<n; i++) {
14         avgX+=points[i].getX()/n;
15         avgY+=points[i].getY()/n;
16     }
17 
18     //计算Lxx,Lyy,Lxy
19     for(int i=0; i<n; i++) {
20         Lxy += (points[i].getX()-avgX)*(points[i].getY()-avgY);
21         Lxx += (points[i].getX()-avgX)*(points[i].getX()-avgX);
22         Lyy += (points[i].getY()-avgY)*(points[i].getY()-avgY);
23     }
24 
25     cout<<"*--线性拟合结果如下--*"<<endl;
26     float a = Lxy/Lxx;
27     cout<<"a="<<a<<endl;
28     float b = avgY-a*avgX;
29     cout<<"b="<<avgY-a*avgX<<endl;
30     cout<<"相关系数r="<<Lxy/sqrt(Lxx*Lyy)<<endl;
31     cout<<"线性方程:"<<"y="<<a<<"+"<<b<<"x"<<endl;
32 }
33 
34 int main() {
35     Point p[5] = {
36         Point(6,10),
37         Point(5,12),
38         Point(7,10),
39         Point(5,10),
40         Point(6,8)
41     };
42 
43     lineFit(p,5);
44 
45     cout<<endl<<"测试2"<<endl;
46 
47     Point p_line[3] = {
48         Point(6,10),
49         Point(6,11),
50         Point(7,12)
51     };
52 
53     lineFit(p_line,3);
54     return 0;
55 }

 

posted on 2024-02-28 13:48  一杯清酒邀明月  阅读(220)  评论(0编辑  收藏  举报