監督學習中,如果預測的變量是離散的,我們稱其爲分類(如決策樹,支持向量機等),如果預測的變量是連續的,我們稱其爲迴歸。迴歸分析中,如果只包括一個自變量和一個因變量,且二者的關係可用一條直線近似表示,這種迴歸分析稱爲一元線性迴歸分析。如果迴歸分析中包括兩個或兩個以上的自變量,且因變量和自變量之間是線性關係,則稱爲多元線性迴歸分析。對於二維空間線性是一條直線;對於三維空間線性是一個平面,對於多維空間線性是一個超平面...這裏,談一談最簡單的一元線性迴歸模型。
1.一元線性迴歸模型
模型如下:
總體迴歸函數中Y與X的關係可是線性的,也可是非線性的。對線性迴歸模型的“線性”有兩種解釋:
(1)就變量而言是線性的,Y的條件均值是 X的線性函數
(2)就參數而言是線性的,Y的條件均值是參數的線性函數
線性迴歸模型主要指就參數而言是“線性”,因爲只要對參數而言是線性的,都可以用類似的方法估計其參數。
2.參數估計——最小二乘法
對於一元線性迴歸模型, 假設從總體中獲取了n組觀察值(X1,Y1),(X2,Y2), …,(Xn,Yn)。對於平面中的這n個點,可以使用無數條曲線來擬合。要求樣本回歸函數儘可能好地擬合這組值。綜合起來看,這條直線處於樣本數據的中心位置最合理。 選擇最佳擬合曲線的標準可以確定爲:使總的擬合誤差(即總殘差)達到最小。有以下三個標準可以選擇:
(1)用“殘差和最小”確定直線位置是一個途徑。但很快發現計算“殘差和”存在相互抵消的問題。
(2)用“殘差絕對值和最小”確定直線位置也是一個途徑。但絕對值的計算比較麻煩。
(3)最小二乘法的原則是以“殘差平方和最小”確定直線位置。用最小二乘法除了計算比較方便外,得到的估計量還具有優良特性。這種方法對異常值非常敏感。
最常用的是普通最小二乘法( Ordinary Least Square,OLS):所選擇的迴歸模型應該使所有觀察值的殘差平方和達到最小。(Q爲殘差平方和)
樣本回歸模型:
殘差平方和:
則通過Q最小確定這條直線,即確定,以爲變量,把它們看作是Q的函數,就變成了一個求極值的問題,可以通過求導數得到。求Q對兩個待估參數的偏導數:
解得:
3.最小二乘法c++實現
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
class LeastSquare{
double a, b;
public:
LeastSquare(const vector<double>& x, const vector<double>& y)
{
double t1=0, t2=0, t3=0, t4=0;
for(int i=0; i<x.size(); ++i)
{
t1 += x[i]*x[i];
t2 += x[i];
t3 += x[i]*y[i];
t4 += y[i];
}
a = (t3*x.size() - t2*t4) / (t1*x.size() - t2*t2);
//b = (t4 - a*t2) / x.size();
b = (t1*t4 - t2*t3) / (t1*x.size() - t2*t2);
}
double getY(const double x) const
{
return a*x + b;
}
void print() const
{
cout<<"y = "<<a<<"x + "<<b<<"\n";
}
};
int main(int argc, char *argv[])
{
if(argc != 2)
{
cout<<"Usage: DataFile.txt"<<endl;
return -1;
}
else
{
vector<double> x;
ifstream in(argv[1]);
for(double d; in>>d; )
x.push_back(d);
int sz = x.size();
vector<double> y(x.begin()+sz/2, x.end());
x.resize(sz/2);
LeastSquare ls(x, y);
ls.print();
cout<<"Input x:\n";
double x0;
while(cin>>x0)
{
cout<<"y = "<<ls.getY(x0)<<endl;
cout<<"Input x:\n";
}
}
}