一、簡(jiǎn)單分析
點(diǎn)的線性擬合是一般實(shí)驗(yàn)數(shù)據(jù)處理最常用的方法硬猫。下面考慮一個(gè)用n個(gè)數(shù)據(jù)點(diǎn)擬合成直線的問(wèn)題补箍,直線模型為
y(x)=ax+b
這個(gè)問(wèn)題稱為線性回歸。設(shè)變量y隨自變量x變化啸蜜,給定n組觀測(cè)數(shù)據(jù)(xi,yi)坑雅,用直線來(lái)擬合這些點(diǎn),其中a,b是直線的斜率和截距盔性,稱為回歸系數(shù)霞丧。
為確定回歸系數(shù),通常采用最小二乘法冕香,即使下式達(dá)到最小
根據(jù)極值愿意蛹尝,a,b滿足下列方程
可解得:
最終可得直線方程
y(x)=ax+b
對(duì)于任何一組數(shù)據(jù),都可以用這種方式擬合出一條直線悉尾,而數(shù)據(jù)點(diǎn)有些遠(yuǎn)離直線突那,有些接近直線,便有一個(gè)系數(shù)作為對(duì)所擬合直線的線性程度的一般判據(jù)
它可以判斷一組數(shù)據(jù)線性相關(guān)的密切程度
定義為:
r的絕對(duì)值越接近與1构眯,表示直線的線性關(guān)系越好愕难,直線關(guān)系的數(shù)據(jù)r=1。
二惫霸、代碼實(shí)現(xiàn)
#ifndef _POINT_H
#define _POINT_H_
class Point {
public:
Point(float x=0,float y=0):x(x),y(y) {};
float getX() {return x;}
float getY(){return y;}
private:
float x,y;
};
#endif
#include "Point.h"
#include<iostream>
#include<math.h>
using namespace std;
//直線線性擬合 points為點(diǎn) n為點(diǎn)的個(gè)數(shù)
void lineFit(Point points[],int n) {
float avgX,avgY=0;
float Lxx=0,Lyy=0,Lxy=0;
//計(jì)算x,y平均值
for(int i=0; i<n; i++) {
avgX+=points[i].getX()/n;
avgY+=points[i].getY()/n;
}
//計(jì)算Lxx,Lyy,Lxy
for(int i=0; i<n; i++) {
Lxy += (points[i].getX()-avgX)*(points[i].getY()-avgY);
Lxx += (points[i].getX()-avgX)*(points[i].getX()-avgX);
Lyy += (points[i].getY()-avgY)*(points[i].getY()-avgY);
}
cout<<"*--線性擬合結(jié)果如下--*"<<endl;
float a = Lxy/Lxx;
cout<<"a="<<a<<endl;
float b = avgY-a*avgX;
cout<<"b="<<avgY-a*avgX<<endl;
cout<<"相關(guān)系數(shù)r="<<Lxy/sqrt(Lxx*Lyy)<<endl;
cout<<"線性方程:"<<"y="<<a<<"+"<<b<<"x"<<endl;
}
int main() {
Point p[5] = {
Point(6,10),
Point(5,12),
Point(7,10),
Point(5,10),
Point(6,8)
};
lineFit(p,5);
cout<<endl<<"測(cè)試2"<<endl;
Point p_line[3] = {
Point(6,10),
Point(6,11),
Point(7,12)
};
lineFit(p_line,3);
return 0;
}