最小二乘法是一种优化方法。通过最小化误差的平方和来寻找数据的最佳函数进行匹配。
线性函数模型:
Y = B ^ 0 + B ^ 1 X Y = \hat B_0 + \hat B_1 X Y=B^0+B^1X
残差形式写为:
Y i = B ^ 0 + B ^ 1 X 1 + e i Y_i = \hat B_0 + \hat B_1 X_1+e_i Yi=B^0+B^1X1+ei
可将 e i e_i ei写为
e i = Y i − B ^ 0 − B ^ 1 X 1 e_i=Y_i -\hat B_0 - \hat B_1 X_1 ei=Yi−B^0−B^1X1
e_i为样本 ( x i , y i ) (x_i,y_i) (xi,yi)的误差。
所以,平方损失函数可以表示为
Q = ∑ i = 1 n e i 2 = ∑ i = 1 n ( Y i − Y ^ i ) 2 = ∑ i = 1 n ( Y i − B ^ 0 − B ^ 1 X i ) Q=\sum_{i=1}^{n}e_i^2=\sum_{i=1}^{n}(Y_i-\hat Y_i)^2=\sum_{i=1}^{n}(Y_i-\hat B_0- \hat B_1 X_i) Q=i=1∑nei2=i=1∑n(Yi−Y^i)2=i=1∑n(Yi−B^0−B^1Xi)
即,使Q最小确定直线,Q可看作是以 B ^ 0 \hat B_0 B^0, B ^ 1 \hat B_1 B^1为变量的Q的函数。
问题转换成一个极值问题:
再对Q求偏导。
{ ∂ Q ∂ B ^ 0 = 2 ∑ i = 1 n ( Y i − B ^ 0 − B ^ 1 X i ) ∗ ( − 1 ) = 0 ∂ Q ∂ B ^ 1 = 2 ∑ i = 1 n ( Y i − B ^ 0 − B ^ 1 X i ) ∗ ( − X i ) = 0 \begin{cases} \frac {\partial Q}{\partial \hat B_0} =2\sum_{i=1}^{n}(Y_i-\hat B_0- \hat B_1 X_i)*(-1)=0\\ \frac {\partial Q}{\partial \hat B_1} =2\sum_{i=1}^{n}(Y_i-\hat B_0- \hat B_1 X_i)*(-X_i)=0\end{cases} {∂B^0∂Q=2∑i=1n(Yi−B^0−B^1Xi)∗(−1)=0∂B^1∂Q=2∑i=1n(Yi−B^0−B^1Xi)∗(−Xi)=0
解得
{ B ^ 0 = ∑ X i 2 ∑ Y i − ∑ X i ∑ X i Y i n ∑ X i 2 − ( ∑ X i ) 2 B ^ 1 = n ∑ X i Y i − ∑ X i ∑ Y i n ∑ X i 2 − ( ∑ X i ) 2 \begin{cases} \hat B_0 = \frac {\sum X_i^2 \sum Y_i-\sum X_i \sum X_i Y_i}{n \sum X_i^2-(\sum X_i)^2}\\\hat B_1= \frac {n\sum X_i Y_i-\sum X_i \sum Y_i}{n \sum X_i^2-(\sum X_i)^2} \end{cases} ⎩⎨⎧B^0=n∑Xi2−(∑Xi)2∑Xi2∑Yi−∑Xi∑XiYiB^1=n∑Xi2−(∑Xi)2n∑XiYi−∑Xi∑Yi
Y = B ^ 0 + B ^ 1 X Y = \hat B_0 + \hat B_1 X Y=B^0+B^1X
推广到一般情况下,假如有更多的模型变量 x 1 , x 2 , . . . , x m x^1,x^2,...,x^m x1,x2,...,xm(指样本里的模型相关的变量),可以用线性函数表示如下:
y ( x 1 , . . . , x m ; B 0 , B 1 , . . . , B m ) = B 0 + B 1 x 1 + . . . + B m x m y(x^1,...,x^m;B_0,B_1,...,B_m)=B_0+B_1 x^1+...+B_m x^m y(x1,...,xm;B0,B1,...,Bm)=B0+B1x1+...+Bmxm
对于n个样本来说,可以用如下线性方程组表示:
B 0 + B 1 x 1 1 + . . . + B m x 1 m = y 1 B_0+B_1 x_1^1+...+B_m x_1^m=y_1 B0+B1x11+...+Bmx1m=y1
B 0 + B 1 x 2 1 + . . . + B m x 2 m = y 2 B_0+B_1 x_2^1+...+B_m x_2^m=y_2 B0+B1x21+...+Bmx2m=y2
. . . ... ...
B 0 + B 1 x i 1 + . . . + B m x i m = y i B_0+B_1 x_i^1+...+B_m x_i^m=y_i B0+B1xi1+...+Bmxim=yi
. . . ... ...
B 0 + B 1 x n 1 + . . . + B m x n m = y n B_0+B_1 x_n^1+...+B_m x_n^m=y_n B0+B1xn1+...+Bmxnm=yn
将上式记为矩阵形式为:
[ 1 x 1 1 . . . x 1 m 1 x 2 1 . . . x 2 m . . . . . . . . . . . . 1 x n 1 . . . x n m ] [ B 0 B 1 . . . B m ] = [ y y . . . y n ] \left[ \begin{matrix} 1 & x_1^1 & ... & x_1^m \\ 1 & x_2^1 & ... & x_2^m \\ ... & ... & ... & ...\\ 1 & x_n^1 & ... & x_n^m \end{matrix} \right] \left[ \begin{matrix} B_0 \\B_1 \\... \\B_m \end{matrix} \right]= \left[ \begin{matrix} y\\y\\...\\y_n \end{matrix} \right] ⎣⎢⎢⎡11...1x11x21...xn1............x1mx2m...xnm⎦⎥⎥⎤⎣⎢⎢⎡B0B1...Bm⎦⎥⎥⎤=⎣⎢⎢⎡yy...yn⎦⎥⎥⎤
最终形式为 A ⋅ B = Y A·B=Y A⋅B=Y
最小二乘形式,可以表示为: m i n ∣ ∣ A B − Y ∣ ∣ 2 min||AB-Y||_2 min∣∣AB−Y∣∣2
最优解为: B ^ = ( A T A ) − 1 A T Y \hat B=(A^TA)^{-1}A^TY B^=(ATA)−1ATY
/*
最小二乘法的实现
C++版
命令行输入数据文件
最后输入x得到预测的y值
*/
#include
#include
#include
using namespace std;
class LeastSquare {
double b0, b1;
public:
LeastSquare(const vector& x, const vector& y)
{
double t1 = 0, t2 = 0, t3 = 0, t4 = 0;
for (int i = 0; i=0)
cout << "y = " << b0 << "+" << b1 << 'x' << "\n";
else
cout << "y = " << b0 << "" << b1 << 'x' << "\n";
}
};
int main(int argc, char *argv[])
{
if (argc != 2)
{
cout << " data.txt don't exit " << endl;
return -1;
}
else
{
vector x;
vector y;
int count = 1;
ifstream in(argv[1]);
for (double d; in >> d; count++)
if (count % 2 == 1)
x.push_back(d);
else
y.push_back(d);
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";
}
}
int endline;
cin >> endline;
}
int main(int argc,char* argv[])
argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数 比如:
int main(int argc, char* argv[])
{
}
两种方法:
第一种,无需调试的情况:
直接用dos命令进入到.exe目录下然后输入:*.exe pra1 pra2
第二种,需要调试的情况:
先选择项目-〉右键-〉属性
调试 -〉命令行参数
在命令行参数里面输入命令行参数即可。
需要注意的是,不需要像第一种那样样输入***.exe了。只需要输入 pra1 pra2 ,中间用空格隔开。
例如:以上实现代码,需要输入一个data.txt,输入格式是(x,y)的点值。
1 0
2 1
3 2
0 1
1 2
2 3