标准方程法
标准方程法就是通过一些方法直接求出权值ω的值,以往的文章已将讲过了代价函数的相关内容,这里直接给出代价函数的公式:
J(ω0,ω1,ω2,…,ωn)=∑i=1m[yi−hω(xi)]2
J(ω_0,ω_1,ω_2,\dots,ω_n)=\sum_{i=1}^m[y_i-h_ω(x_i)]^2
J(ω0,ω1,ω2,…,ωn)=i=1∑m[yi−hω(xi)]2
其中hω(x)h_ω(x)hω(x)的公式如下:
hω(x)=ω0+ω1x1+ω2x2+⋯+ωnxn
h_ω(x)=ω_0+ω_1x_1+ω_2x_2+\dots+ω_nx_n
hω(x)=ω0+ω1x1+ω2x2+⋯+ωnxn
如果数据集中只有一条数据,通过矩阵可以描述成一下形式:
X=[x0x1x2…xn],其中x0=1
X = \begin{bmatrix}
x_0 & x_1 & x_2 & \dots & x_n
\end{bmatrix},其中x_0=1
X=[x0x1x2…xn],其中x0=1
w=[ω0ω1ω2⋮ωn] w=\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} w=⎣⎢⎢⎢⎢⎢⎡ω0ω1ω2⋮ωn⎦⎥⎥⎥⎥⎥⎤
hω(x)=X∗w=[x0x1x2…xn]∗[ω0ω1ω2⋮ωn]=ω0+ω1x1+ω2x2+⋯+ωnxn \begin{aligned} h_ω(x)=X*w=\begin{bmatrix} x_0 & x_1 & x_2 & \dots & x_n \end{bmatrix} *\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} \\ =ω_0+ω_1x_1+ω_2x_2+\dots+ω_nx_n \end{aligned} hω(x)=X∗w=[x0x1x2…xn]∗⎣⎢⎢⎢⎢⎢⎡ω0ω1ω2⋮ωn⎦⎥⎥⎥⎥⎥⎤=ω0+ω1x1+ω2x2+⋯+ωnxn
一般数据集中,会有很多条数据,每一条数据通过上述公式都会得到一个hω(x)h_ω(x)hω(x),故通过矩阵可以描述成以下形式:
x0x1x2…xnX=[1a1a2…an1b1b2…bn……………1n1n2…nn]n∗(n+1)
x_0\quad x_1\quad x_2 \quad \dots \quad x_n
\\
X = \begin{bmatrix}
1 & a_1 & a_2 & \dots & a_n
\\
1 & b_1 & b_2 & \dots & b_n
\\
\dots & \dots & \dots & \dots & \dots
\\
1 & n_1 & n_2 & \dots & n_n
\end{bmatrix}_{n*(n+1)}
x0x1x2…xnX=⎣⎢⎢⎡11…1a1b1…n1a2b2…n2…………anbn…nn⎦⎥⎥⎤n∗(n+1)
w=[ω0ω1ω2⋮ωn](n+1)∗1 w=\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix}_{(n+1)*1} w=⎣⎢⎢⎢⎢⎢⎡ω0ω1ω2⋮ωn⎦⎥⎥⎥⎥⎥⎤(n+1)∗1
hω(x)=X∗w=[1a1a2…an1b1b2…bn……………1n1n2…nn]∗[ω0ω1ω2⋮ωn]=[ω0+ω1a1+ω2a2+⋯+ωnanω0+ω1b1+ω2b2+⋯+ωnbn⋮ω0+ω1n1+ω2n2+⋯+ωnnn]=[hω(x1)hω(x2)⋮hω(xn)]n∗1 \begin{aligned} h_ω(x)=X*w&=\begin{bmatrix} 1 & a_1 & a_2 & \dots & a_n \\ 1 & b_1 & b_2 & \dots & b_n \\ \dots & \dots & \dots & \dots & \dots \\ 1 & n_1 & n_2 & \dots & n_n \end{bmatrix} *\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} \\ &=\begin{bmatrix} ω_0+ω_1a_1+ω_2a_2+\dots+ω_na_n \\ ω_0+ω_1b_1+ω_2b_2+\dots+ω_nb_n \\ \vdots \\ ω_0+ω_1n_1+ω_2n_2+\dots+ω_nn_n \end{bmatrix} \\ &=\begin{bmatrix} h_ω(x_1) \\ h_ω(x_2) \\ \vdots \\ h_ω(x_n) \end{bmatrix}_{n*1} \end{aligned}hω(x)=X∗w=⎣⎢⎢⎡11…1a1b1…n1a2b2…n2…………anbn…nn⎦⎥⎥⎤∗⎣⎢⎢⎢⎢⎢⎡ω0ω1ω2⋮ωn⎦⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎡ω0+ω1a1+ω2a2+⋯+ωnanω0+ω1b1+ω2b2+⋯+ωnbn⋮ω0+ω1n1+ω2n2+⋯+ωnnn⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡hω(x1)hω(x2)⋮hω(xn)⎦⎥⎥⎥⎤n∗1
那么代价函数如何用这种形式表示呢?别急,看下面这个公式
∑i=1n[yi−hω(xi)]2=(yi−Xw)T(yi−Xw)
\sum_{i=1}^n[y_i-h_ω(x_i)]^2=(y_i-Xw)^T(y_i-Xw)
i=1∑n[yi−hω(xi)]2=(yi−Xw)T(yi−Xw)
证明如下
yi−Xw=[y1−hω(x1)y2−hω(x2)⋮yn−hω(xn)]
y_i-Xw=\begin{aligned}
\begin{bmatrix}
y_1-h_ω(x_1)
\\
y_2-h_ω(x_2)
\\
\vdots
\\
y_n-h_ω(x_n)
\end{bmatrix}
\end{aligned}
yi−Xw=⎣⎢⎢⎢⎡y1−hω(x1)y2−hω(x2)⋮yn−hω(xn)⎦⎥⎥⎥⎤
(yi−Xw)T(yi−Xw)=[y1−hω(x1)y2−hω(x2)…yn−hω(xn)]∗[y1−hω(x1)y2−hω(x2)⋮yn−hω(xn)]=(y1−hω(x1))2+(y2−hω(x2))2+(y1−hω(x1))2+⋯+(yn−hω(xn))2=∑i=1n[yi−hω(xi)]2 \begin{aligned} (y_i-Xw)^T(y_i-Xw)&=\begin{bmatrix} y_1-h_ω(x_1) & y_2-h_ω(x_2) & \dots & y_n-h_ω(x_n) \end{bmatrix}*\begin{bmatrix} y_1-h_ω(x_1) \\ y_2-h_ω(x_2) \\ \vdots \\ y_n-h_ω(x_n) \end{bmatrix} \\ &=(y_1-h_ω(x_1))^2+(y_2-h_ω(x_2))^2+(y_1-h_ω(x_1))^2+\dots+(y_n-h_ω(x_n))^2 \\ &=\sum_{i=1}^n[y_i-h_ω(x_i)]^2 \end{aligned} (yi−Xw)T(yi−Xw)=[y1−hω(x1)y2−hω(x2)…yn−hω(xn)]∗⎣⎢⎢⎢⎡y1−hω(x1)y2−hω(x2)⋮yn−hω(xn)⎦⎥⎥⎥⎤=(y1−hω(x1))2+(y2−hω(x2))2+(y1−hω(x1))2+⋯+(yn−hω(xn))2=i=1∑n[yi−hω(xi)]2
证明结束。
但是呢,到这里肯定是还没有结束的,我们知道了代价函数,接下来一步就是去求最小值。提到函数和最小值,用我为数不多的数学知识那就是求导了,我现在脑海中只剩了一顿求导,令其为零了。好了,接下来就让我们一起来求导吧!!!
∂(y−Xw)T(y−Xw)∂w=∂(yT−wTXT)(y−Xw)∂w=∂(yTy−yTXw−wTXTy+wTXTXw)∂w=∂yTy∂w−∂yTXw∂w−∂wTXTy∂w+∂wTXTXw∂w
\begin{aligned}
&\frac{∂(y-Xw)^T(y-Xw)}{∂w}
\\
&=\frac{∂(y^T-w^TX^T)(y-Xw)}{∂w}
\\
&=\frac{∂(y^Ty-y^TXw-w^TX^Ty+w^TX^TXw)}{∂w}
\\
&=\frac{∂y^Ty}{∂w}-\frac{∂y^TXw}{∂w}-\frac{∂w^TX^Ty}{∂w}+\frac{∂w^TX^TXw}{∂w}
\end{aligned}
∂w∂(y−Xw)T(y−Xw)=∂w∂(yT−wTXT)(y−Xw)=∂w∂(yTy−yTXw−wTXTy+wTXTXw)=∂w∂yTy−∂w∂yTXw−∂w∂wTXTy+∂w∂wTXTXw
对其各自求偏导得:
∂yTy∂w=0∂yTXw∂w=XTy∂wTXTy∂w=(∂wTXTy)T∂w=∂yTXw∂w=XTy∂wTXTXw∂w=2XTXw
\begin{aligned}
\frac{∂y^Ty}{∂w}&=0
\\
\frac{∂y^TXw}{∂w}&=X^Ty
\\
\frac{∂w^TX^Ty}{∂w}&=\frac{(∂w^TX^Ty)^T}{∂w}=\frac{∂y^TXw}{∂w}=X^Ty
\\
\frac{∂w^TX^TXw}{∂w}&=2X^TXw
\end{aligned}
∂w∂yTy∂w∂yTXw∂w∂wTXTy∂w∂wTXTXw=0=XTy=∂w(∂wTXTy)T=∂w∂yTXw=XTy=2XTXw
整合一下:
∂yTy∂w−∂yTXw∂w−∂wTXTy∂w+∂wTXTXw∂w=0−XTy−XTy+2XTXw
\frac{∂y^Ty}{∂w}-\frac{∂y^TXw}{∂w}-\frac{∂w^TX^Ty}{∂w}+\frac{∂w^TX^TXw}{∂w}=0-X^Ty-X^Ty+2X^TXw
∂w∂yTy−∂w∂yTXw−∂w∂wTXTy+∂w∂wTXTXw=0−XTy−XTy+2XTXw
令其为零:
−2XTy+2XTXw=0XTXw=XTy(XTX)−1XTXw=(XTX)−1XTyw=(XTX)−1XTy
\begin{aligned}
-2X^Ty+2X^TXw&=0
\\
X^TXw&=X^Ty
\\
(X^TX)^{-1}X^TXw&=(X^TX)^{-1}X^Ty
\\
w&=(X^TX)^{-1}X^Ty
\end{aligned}
−2XTy+2XTXwXTXw(XTX)−1XTXww=0=XTy=(XTX)−1XTy=(XTX)−1XTy
到这里www就是我们苦苦寻求的值了,而其中(XTX)−1(X^TX)^{-1}(XTX)−1是XTX)X^TX)XTX)的逆矩阵。
不可逆的情况
这里再给出两种不可逆的情况
- 线性相关特征(多重共线性)
- x1为房屋面积,单位是平方英尺
- x2为房屋面积,单位是平方米
- 特征数据太多(样本数m≤\le≤特征数量n)
梯度下降和标准方程的比较
| 梯度下降法 | 标准方程法 | |
|---|---|---|
| 优点 | 当特征值非常多的时候也可以很好的工作 | 不需要学习率 不需要迭代 可以得到全局最优解 |
| 缺点 | 需要选择合适的学习率 需要迭代很多个周期 最能得到最优解的近似值 | 需要计算(XTX)−1(X^TX)^{-1}(XTX)−1 时间复杂度大约是O(n3)O(n^3)O(n3) n是特征数量 |
代码实现
import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
# 载入数据
data = np.genfromtxt("data.csv", delimiter=",")
x_data = data[:,0,np.newaxis]
y_data = data[:,1,np.newaxis]
plt.scatter(x_data,y_data)
plt.show()
print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data.shape)
# 标准方程法求解回归参数
def weights(xArr, yArr):
xMat = np.mat(xArr)
yMat = np.mat(yArr)
xTx = xMat.T*xMat # 矩阵乘法
# 计算矩阵的值,如果值为0,说明该矩阵没有逆矩阵
if np.linalg.det(xTx) == 0.0:
print("This matrix cannot do inverse")
return
# xTx.I为xTx的逆矩阵
ws = xTx.I*xMat.T*yMat
return ws
#使用numpy本身函数求解
#相关函数可以点击链接查看
#https://www.numpy.org.cn/article/basics/numpy_matrices_vectors.html#%E7%94%A8numpy%E6%B1%82%E8%A7%A3%E6%96%B9%E7%A8%8B%E7%BB%84
def numpy_weights(xArr, yArr):
xMat = np.mat(xArr)
yMat = np.mat(yArr)
xT = np.transpose(xMat)#转置矩阵
xTx = np.dot(xT, xMat)#矩阵乘
if np.linalg.det(xTx) == 0.0:
print("This matrix cannot do inverse")
return
xTy = np.dot(xT, yMat)
ws = np.linalg.solve(xTx,xTy)
return ws
#调用函数
ws = weights(X_data,y_data)
ws1 = numpy_weights(X_data,y_data)
print(ws)
print(ws1)
# 画图
x_test = np.array([[20],[80]])
y_test = ws[0] + x_test*ws[1]
plt.plot(x_data, y_data, 'b.')
plt.plot(x_test, y_test, 'r')
plt.show()
2737

被折叠的 条评论
为什么被折叠?



