最小二乘法(基础原理+简单推导+python模拟)
最小二乘法通过最小化误差(真实 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代码文件。
更多推荐
所有评论(0)