最小二乘法通过最小化误差(真实 y i y_i yi与拟合函数生成的 y i ^ \hat{y_i} yi^的差)的平方和从而寻找拟合数据最佳的函数。
对于数据 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x i , y i ) ( i = 1 , 2 , 3 , . . , m ) {(x_1,y_1), (x_2,y_2),...,(x_i,y_i)}(i=1,2,3,..,m) (x1,y1),(x2,y2),...,(xi,yi)(i=1,2,3,..,m),拟合出函数 h ( x ) h(x) h(x)。一般来讲 h ( x ) h(x) h(x)为n次多项式, h ( x ) = w 0 + w 1 x + w 2 x 2 + . . . w n x n h(x) = w_0+w_1x+w_2x^2+...w_nx^n h(x)=w0+w1x+w2x2+...wnxn,其中 ( w 0 , w 1 , . . . , w n ) (w_0,w_1,...,w_n) (w0,w1,...,wn)是函数的参数。
最小二乘法的目的是找到一组 ( w 0 , w 1 , . . . , w n ) (w_0,w_1,...,w_n) (w0,w1,...,wn),使得 ∑ i = 1 n ( h ( x i ) − y i ) 2 \sum_{i=1}^{n}(h(x_i)-y_i)^2 ∑i=1n(h(xi)−yi)2最小。–> m i n ∑ i = 1 n ( h ( x i ) − y i ) 2 min\sum_{i=1}^{n}(h(x_i)-y_i)^2 min∑i=1n(h(xi)−yi)2
想要求的一组 ( w 0 , w 1 , . . . , w n ) (w_0,w_1,...,w_n) (w0,w1,...,wn)使得误差 ∑ i = 1 n ( h ( x i ) − y i ) 2 \sum_{i=1}^{n}(h(x_i)-y_i)^2 ∑i=1n(h(xi)−yi)2最小,及求误差函数的极小值点(偏导数为0的点)。
举个例子:
f ( x ; w ) = w 0 + w 1 x L o s s ( y , f ( x ; w ) ) = ( y − f ( x ; w ) ) 2 这里的平方是为了方便求导运算。 J n ( w ) = ∑ i = 1 n ( y i − w 0 − w 1 x i ) 2 / 2 为了求极值,则对 w 0 , w 1 分别求偏导。 f(x;w)=w_0+w_1x \\ Loss(y, f(x;w)) = (y-f(x;w))^2 \\ 这里的平方是为了方便求导运算。 \\ J_n(w)=\sum_{i=1}^{n}(y_i-w_0-w_1x_i)^2/2 \\ 为了求极值,则对w_0,w_1分别求偏导。 \\ f(x;w)=w0+w1xLoss(y,f(x;w))=(y−f(x;w))2这里的平方是为了方便求导运算。Jn(w)=i=1∑n(yi−w0−w1xi)2/2为了求极值,则对w0,w1分别求偏导。
{ ∂ ∂ w 0 J n ( w ) = − ∑ i = 1 n ( y i − w 0 − w 1 x i ) = 0 ∂ ∂ w 1 J n ( w ) = − ∑ i = 1 n ( y i − w 0 − w 1 x i ) x i = 0 \begin{cases} \frac{\partial}{\partial w_0}J_n(w)=-\sum_{i=1}^{n}(y_i-w_0-w_1x_i)=0 \\ \frac{\partial}{\partial w_1}J_n(w)=-\sum_{i=1}^{n}(y_i-w_0-w_1x_i)x_i=0 \end{cases} \\ {
∂w0∂Jn(w)=−∑i=1n(yi−w0−w1xi)=0∂w1∂Jn(w)=−∑i=1n(yi−w0−w1xi)xi=0
{ w 0 ( ∑ i = 1 n 1 ) + w 1 ( ∑ i = 1 n x i ) = ∑ i = 1 n y i w 0 ( ∑ i = 1 n x i ) + w 1 ( ∑ i = 1 n x i 2 ) = ∑ i = 1 n y i x i \begin{cases} w_0(\sum_{i=1}^{n}1)+w_1(\sum_{i=1}^{n}x_i)=\sum_{i=1}^ny_i \\ w_0(\sum_{i=1}^{n}x_i)+w_1(\sum_{i=1}^{n}x_i^2)=\sum_{i=1}^ny_ix_i \end{cases} \\ {
w0(∑i=1n1)+w1(∑i=1nxi)=∑i=1nyiw0(∑i=1nxi)+w1(∑i=1nxi2)=∑i=1nyixi
[ ∑ i = 1 n 1 ∑ i = 1 n x i ∑ i = 1 n x i ∑ i = 1 n x i 2 ] [ w 0 w 1 ] = [ ∑ i = 1 n y i ∑ i = 1 n y i x i ] \left[ \begin{matrix} \sum_{i=1}^{n}1&\sum_{i=1}^{n}x_i\\ \sum_{i=1}^{n}x_i&\sum_{i=1}^{n}x_i^2 \end{matrix} \right] \left[ \begin{matrix} w_0\\ w_1 \end{matrix} \right] = \left[ \begin{matrix} \sum_{i=1}^ny_i\\ \sum_{i=1}^ny_ix_i \end{matrix} \right] \\ [∑i=1n1∑i=1nxi∑i=1nxi∑i=1nxi2][w0w1]=[∑i=1nyi∑i=1nyixi]
要求 w ,及求 ϕ ⋅ w ^ = b 中的 w ^ 。 w ^ = ϕ − 1 ⋅ b 要求w,及求\phi \cdot \hat{w}=b中的\hat{w}。 \\\hat{w}=\phi^{-1} \cdot b 要求w,及求ϕ⋅w^=b中的w^。w^=ϕ−1⋅b
矩阵形式:
J = 1 2 ∣ ∣ Y − X w ∣ ∣ 2 = 1 2 ∣ ∣ [ y 1 y 2 . . . y n ] − [ 1 x 1 2 x 2 . . . 3 x 3 ] ⋅ [ w 0 w 1 ] ∣ ∣ 2 J=\frac{1}{2}||Y-Xw||^2= \frac{1}{2} \left| \left| \left[ \begin{matrix} y_1\\ y_2\\ ...\\ y_n \end{matrix} \right] - \left[ \begin{matrix} 1&x_1\\ 2&x_2\\ ...\\ 3&x_3 \end{matrix} \right] \cdot \left[ \begin{matrix} w_0\\ w_1\\ \end{matrix} \right] \right|\right|^2 \\ \\ J=21∣∣Y−Xw∣∣2=21∣
∣∣
∣⎣
⎡y1y2...yn⎦
⎤−⎣
⎡12...3x1x2x3⎦
⎤⋅[w0w1]∣
∣∣
∣2
∣ ∣ Y − X w ∣ ∣ 2 = ( Y − X w ) T ( Y − X w ) = Y T Y − x T X T Y − Y T X w + w T X T X w = Y T Y − 2 w T X T Y + w T X T X w \begin{aligned} ||Y-Xw||^2&=(Y-Xw)^T(Y-Xw)\\ &=Y^TY-x^TX^TY-Y^TXw+w^TX^TXw\\ &=Y^TY-2w^TX^TY+w^TX^TXw \end{aligned}\\ ∣∣Y−Xw∣∣2=(Y−Xw)T(Y−Xw)=YTY−xTXTY−YTXw+wTXTXw=YTY−2wTXTY+wTXTXw
∂ J ∂ w = − X T Y + X T X w = 0 \\ \frac{\partial J}{\partial w}=-X^TY+X^TXw=0 \\ ∂w∂J=−XTY+XTXw=0
w = ( X T X ) − 1 X T Y w=(X^TX)^{-1}X^TY w=(XTX)−1XTY
python实现最小二乘法
import numpy as np
import scipy as sp
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
%matplotlib inline
# 创建目标函数
def func(x):
return np.sin(2*np.pi*x)
# 预设一个用于拟合的多项式
def fit_func(p, x):
f = np.poly1d(p)
return f(x)
# 定义误差
def error(p, x, y):
err = fit_func(p, x) - y
return err
# 十个点
x = np.linspace(0, 1, 10)
x_points = np.linspace(0, 1, 1000)
# 加上正态分布噪音的目标函数的值
y_ = func(x)
y = [np.random.normal(0, 0.1) + y1 for y1 in y_]
def fitting(M=0):
"""
M 为 多项式的次数
"""
# 随机初始化多项式参数
p_init = np.random.rand(M + 1)
# 最小二乘法
p_lsq = leastsq(error, p_init, args=(x, y))
print('Fitting Parameters:', p_lsq[0])
# 可视化
plt.plot(x_points, func(x_points), label='real')
plt.plot(x_points, fit_func(p_lsq[0], x_points), label='fitted curve')
plt.plot(x, y, 'bo', label='noise')
plt.legend()
return p_lsq
# M=3
p_lsq_3 = fitting(M=3)
详细代码文件:python代码文件。