回顾
回归分析之线性回归 中我们得到了线性回归的损失函数为:
J
(
θ
)
=
1
2
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
J(\theta) = \frac{1}{2}\sum_{i=1}^m\bigg(h_\theta(x^{(i)}) - y^{(i)}\bigg)^2
J(θ)=21i=1∑m(hθ(x(i))−y(i))2
θ \theta θ 的求解够
- 将损失函数用向量的形式表示:
J ( θ ) = 1 2 ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 = 1 2 ( X θ − Y ) T ( X θ − Y ) J(\theta) = \frac{1}{2}\sum_{i=1}^m\bigg(h_\theta(x^{(i)}) - y^{(i)}\bigg)^2 = \frac{1}{2}(X\theta-Y)^T(X\theta-Y) J(θ)=21i=1∑m(hθ(x(i))−y(i))2=21(Xθ−Y)T(Xθ−Y)
- 其中:
h θ ( x ( i ) ) = θ 1 x 1 ( i ) + θ 2 x 2 ( i ) + . . . + θ n x n ( i ) h_{\theta}(x^{(i)}) = \theta_1x_1^{(i)}+\theta_2 x_2^{(i)} + ...+\theta_nx_n^{(i)} hθ(x(i))=θ1x1(i)+θ2x2(i)+...+θnxn(i)
X = [ x 1 ( 1 ) x 2 ( 1 ) . . . x n ( 1 ) x 1 ( 2 ) x 2 ( 2 ) . . . x n ( 2 ) . . . x 1 ( m ) x 2 ( m ) . . . x n ( m ) ] X = \left [ \begin{matrix} x_1^{(1)} & x_2^{(1)} & ... & x_n^{(1)} \\ x_1^{(2)} & x_2^{(2)} & ... & x_n^{(2)} \\ && ... &\\ x_1^{(m)} & x_2^{(m)} & ... & x_n^{(m)} \\ \end{matrix} \right ] X=⎣⎢⎢⎢⎡x1(1)x1(2)x1(m)x2(1)x2(2)x2(m)............xn(1)xn(2)xn(m)⎦⎥⎥⎥⎤
θ = [ θ 1 θ 2 . . . θ n ] \theta = \left [ \begin{matrix} \theta_1 \\ \theta_2 \\ ...\\ \theta_n \end{matrix} \right ] θ=⎣⎢⎢⎡θ1θ2...θn⎦⎥⎥⎤
Y = [ y ( 1 ) y ( 2 ) . . . y ( m ) ] Y= \left [ \begin{matrix} y^{(1)} \\ y^{(2)}\\ ...\\ y^{(m)} \end{matrix} \right ] Y=⎣⎢⎢⎡y(1)y(2)...y(m)⎦⎥⎥⎤
- m 表示样本的数量,n 表示每个样本的特征数量
- ( i ) (i) (i)表示第 i 个样本
- X θ = Y ^ X\theta = \hat{Y} Xθ=Y^ 表示模型预测的结果, Y Y Y表示样本的真实值
- 损失矩阵对 θ \theta θ求导:
∇
θ
J
(
θ
)
=
∇
θ
(
1
2
(
X
θ
−
Y
)
T
(
X
θ
−
Y
)
)
\nabla_\theta J(\theta) = \nabla_\theta\Big(\frac{1}{2}(X\theta-Y)^T(X\theta-Y)\Big)
∇θJ(θ)=∇θ(21(Xθ−Y)T(Xθ−Y))
=
∇
θ
(
1
2
(
θ
T
X
T
−
Y
T
)
(
X
θ
−
Y
)
)
= \nabla_\theta\Big(\frac{1}{2}(\theta^TX^T-Y^T)(X\theta-Y)\Big)
=∇θ(21(θTXT−YT)(Xθ−Y))
=
∇
θ
(
1
2
(
θ
T
X
T
X
θ
−
θ
T
X
T
Y
−
Y
T
X
θ
+
Y
T
Y
)
)
= \nabla_\theta\Big(\frac{1}{2}(\theta^TX^TX\theta-\theta^TX^TY-Y^TX\theta+Y^TY)\Big)
=∇θ(21(θTXTXθ−θTXTY−YTXθ+YTY))
=
1
2
(
2
X
T
X
θ
−
X
T
Y
−
(
Y
T
X
)
T
)
=\frac{1}{2}\Big(2X^TX\theta-X^TY-(Y^TX)^T\Big)
=21(2XTXθ−XTY−(YTX)T)
=
X
T
X
θ
−
X
T
Y
=X^TX\theta-X^TY
=XTXθ−XTY
- 令上式为0
θ = ( X T X ) − 1 X T Y \theta = (X^TX)^{-1}X^TY θ=(XTX)−1XTY
最小二乘法
参数解析式:
θ = ( X T X ) − 1 X T Y \theta = (X^TX)^{-1}X^TY θ=(XTX)−1XTY
最小二乘法的使用要求矩阵 X T X X^TX XTX是可逆的;为了防止不可逆或者过拟合的问题存在,可以增加额外数据影响,导致最终的矩阵是可逆的:
θ = ( X T X + λ I ) − 1 X T Y \theta = (X^TX+\lambda I)^{-1}X^TY θ=(XTX+λI)−1XTY
其原因在于:
J
(
θ
)
=
1
2
(
X
θ
−
Y
)
T
(
X
θ
−
Y
)
+
λ
θ
T
θ
J(\theta) =\frac{1}{2}(X\theta-Y)^T(X\theta-Y) + \lambda\theta^T\theta
J(θ)=21(Xθ−Y)T(Xθ−Y)+λθTθ
∇
θ
J
(
θ
)
=
X
T
X
θ
−
X
T
Y
+
λ
θ
\nabla_\theta J(\theta)=X^TX\theta-X^TY+ \lambda\theta
∇θJ(θ)=XTXθ−XTY+λθ
令上式为0:
X
T
X
θ
−
X
T
Y
+
λ
θ
=
0
X^TX\theta-X^TY+ \lambda\theta = 0
XTXθ−XTY+λθ=0
X
T
X
θ
−
X
T
Y
+
λ
θ
=
0
X^TX\theta-X^TY+ \lambda\theta = 0
XTXθ−XTY+λθ=0
(
X
T
X
+
λ
I
)
θ
=
X
T
Y
(X^TX+\lambda I)\theta= X^TY
(XTX+λI)θ=XTY
θ
=
(
X
T
X
+
λ
I
)
−
1
X
T
Y
\theta = (X^TX+\lambda I)^{-1}X^TY
θ=(XTX+λI)−1XTY
上面在损失函数中加入了L2-norm
最小二乘法直接求解的难点:矩阵逆的求解是一个难处
使用最小二乘法预测家庭用电(功率与电流的关系)
# 引入所需要的全部包
from sklearn.model_selection import train_test_split # 数据划分的类
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
from pandas import DataFrame
import time
## 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False
# 加载数据
# 日期、时间、有功功率、无功功率、电压、电流、厨房用电功率、洗衣服用电功率、热水器用电功率
path1='datas/household_power_consumption_1000.txt'
df = pd.read_csv(path1, sep=';', low_memory=False)#没有混合类型的时候可以通过low_memory=F调用更多内存,加快效率)
## 功率和电流之间的关系
X = df.iloc[:,2:4]
Y2 = df.iloc[:,5]
## 数据分割
X2_train,X2_test,Y2_train,Y2_test = train_test_split(X, Y2, test_size=0.2, random_state=0)
# 将X和Y转换为矩阵的形式
X = np.mat(X2_train)
Y = np.mat(Y2_train).reshape(-1,1)
# 计算θ
theta = (X.T * X).I * X.T * Y
# 对测试集合进行测试
y_hat = np.mat(X2_test) * theta
# 画图看看
# 电流关系
t=np.arange(len(X2_test))
plt.figure(facecolor='w')
plt.plot(t, Y2_test, 'r-', linewidth=2, label=u'真实值')
plt.plot(t, y_hat, 'g-', linewidth=2, label=u'预测值')
plt.legend(loc = 'lower right')
plt.title(u"线性回归预测功率与电流之间的关系", fontsize=20)
plt.grid(b=True)
plt.show()
运行结果:
由高中物理可知,功率与电流之间存在固定的计算公式
代码可见: Github下01_最小二乘法.py