一、线性回归
1.概念
线性回归,能够用一个直线较为精确地描述数据之间的关系。这样当出现新的数据的时候,就能够预测出一个合理的值
如下图,平面中存在200个样本,需找出一条合理的直线对其进行拟合
通过线性回归,拟合直线效果如下
在上述二维平面中,需要做的就是找出一条最佳拟合直线方程,形式如下:
h ( x ) = w 0 x 0 + w 1 x 1 ( 通 常 x 0 为 1 ) ∴ 直 线 表 达 式 为 = > h ( x ) = w 0 + w 1 x 1 \begin{aligned} h(x) & = w_{0}x_{0}+w_{1}x_{1}{(通常x_{0}为1)}\\{\therefore 直线表达式为=>}h(x)& = w_{0}+w_{1}x_{1} \end{aligned} h(x)∴直线表达式为=>h(x)=w0x0+w1x1(通常x0为1)=w0+w1x1
通过不同的算法求解 w 0 , w 1 w_{0},w_{1} w0,w1得到直线方程, x 0 x_{0} x0代表第一个特征值, x 1 x_{1} x1代表第二个特征值
实际中,若舍去特征值 x 0 x_{0} x0, 则得到的直线恒过原点,而为了使直线拟合度更高,加入了常数项 w 0 w_{0} w0, 相当于 y = k x + b y=kx+b y=kx+b中的 b b b,为了方便与 w 0 , w 1 w_{0},w_{1} w0,w1相乘相加, x 0 x_{0} x0是人为添加的,且恒为1,直线可以看成 y = k x + b ∗ 1 = > h = w 0 + w 1 x 1 y=kx+b*1=>h= w_{0}+w_{1}x_{1} y=kx+b∗1=>h=w0+w1x1
由此可得,在一般情况下,样本可能具有n个特征值, x 1 , x 2 , . . . , x n x_{1},x_{2},...,x_{n} x1,x2,...,xn,加入常数项 x 0 = 1 x_{0}=1 x0=1,则需求解的超平面方程如下:
h ( x ) = w 0 x 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n ( 通 常 x 0 为 1 ) \begin{aligned} h(x)& = w_{0}x_{0}+w_{1}x_{1}+w_{2}x_{2}+...+w_{n}x_{n}{(通常x_{0}为1)} \end{aligned} h(x)=w0x0+w1x1+w2x2+...+wnxn(通常x0为1)
需求解 w 0 , w 1 x , w 2 , . . w n w_{0},w_{1}x,w_{2},..w_{n} w0,w1x,w2,..wn的值以确定该方程。
为了方便表示该方程,设w参数向量为
w
T
=
[
w
0
w
1
w
2
.
.
.
w
n
]
\mathbf{w^{T}}=\begin{bmatrix} w_{0}&w_{1} &w_{2} &...&w_{n} \end{bmatrix}
wT=[w0w1w2...wn]
样本特征值为:
x
T
=
[
x
0
x
1
x
2
.
.
.
x
n
]
(
x
0
=
1
)
\mathbf{x^{T}}=\begin{bmatrix} x_{0}&x_{1} &x_{2} &...&x_{n} \end{bmatrix}{(x_{0}=1)}
xT=[x0x1x2...xn](x0=1)
h
(
x
)
h(x)
h(x)可表示为:
h
(
x
)
=
w
T
x
h(\mathbf{x})=\mathbf{w^{T}x}
h(x)=wTx
目标: 求解 w \mathbf{w} w向量的最优解
2.损失函数
通过建立一个损失函数来衡量估计值和实际之间的误差的大小,将最小化损失函数作为一个约束条件来求出参数向量的最优解。
样本集为:
X
=
[
x
10
x
20
.
.
.
x
m
0
x
11
x
21
.
.
.
x
m
1
.
.
.
.
.
.
.
.
.
.
.
.
x
1
n
x
2
n
.
.
.
x
m
n
]
\mathbf{X} =\begin{bmatrix} x_{10}&x_{20}&...&x_{m0}\\ x_{11}&x_{21}&...&x_{m1}\\ ...&...&...&...\\ x_{1n}&x_{2n}&...&x_{mn} \end{bmatrix}
X=⎣⎢⎢⎡x10x11...x1nx20x21...x2n............xm0xm1...xmn⎦⎥⎥⎤
m
m
m为样本数量,
n
n
n为特征值数量
单个样本向量可以如下
x
1
=
[
x
10
x
11
.
.
.
x
1
n
]
,
x
2
=
[
x
20
x
21
.
.
.
x
2
n
]
,
.
.
.
,
x
m
=
[
x
m
0
x
m
1
.
.
.
x
m
n
]
\mathbf{x^{1}}=\begin{bmatrix} x_{10}\\x_{11}\\...\\x_{1n}\\ \end{bmatrix},\mathbf{x^{2}}=\begin{bmatrix} x_{20}\\x_{21}\\...\\x_{2n}\\ \end{bmatrix},...,\mathbf{x^{m}}=\begin{bmatrix} x_{m0}\\x_{m1}\\...\\x_{mn}\\ \end{bmatrix}
x1=⎣⎢⎢⎡x10x11...x1n⎦⎥⎥⎤,x2=⎣⎢⎢⎡x20x21...x2n⎦⎥⎥⎤,...,xm=⎣⎢⎢⎡xm0xm1...xmn⎦⎥⎥⎤
第i
个样本向量如下:
x
i
=
[
x
i
0
x
i
1
.
.
.
x
i
n
]
\mathbf{x^{i}}=\begin{bmatrix} x_{i0}\\x_{i1}\\...\\x_{in}\\ \end{bmatrix}
xi=⎣⎢⎢⎡xi0xi1...xin⎦⎥⎥⎤
第i
个样本的预测值为:
h
(
x
i
)
=
w
T
x
i
h(\mathbf{x^{i}})=\mathbf{w^{T}x^{i}}
h(xi)=wTxi
损失函数如下:
J
(
w
)
=
1
2
m
∑
i
=
1
m
(
w
T
x
−
y
i
)
2
=
1
2
m
∑
i
=
1
m
(
h
(
x
i
)
−
y
i
)
2
求
min
J
(
w
)
\begin{aligned} J(\mathbf{w}) &= \frac{1}{2m}\sum_{i = 1}^{m}(\mathbf{w^{T}x}-y^{i})^{2}\\ &=\frac{1}{2m}\sum_{i = 1}^{m}(h(\mathbf{x^{i}})-y^{i})^{2}\\\\{求}&\min J(\mathbf{w}) \end{aligned}
J(w)求=2m1i=1∑m(wTx−yi)2=2m1i=1∑m(h(xi)−yi)2minJ(w)
y i y^{i} yi为某一个样本的实际值, h ( x i ) h(\mathbf{x^{i}}) h(xi)为预测值, J ( w ) J(\mathbf{w}) J(w)函数即为误差的平方和,求当 J ( w ) J(\mathbf{w}) J(w)取最小时, w \mathbf{w} w(参数向量)的值, 1 2 \frac{1}{2} 21为常数项对最小值无影响,方便后续求导
二、最小二乘法
为了方便计算,对样本集特征矩阵X,参数向量w,以及y向量做以下规定:
样本集特征矩阵X
X
=
[
x
10
x
11
x
12
.
.
.
x
1
n
x
20
x
21
x
22
.
.
.
x
2
n
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
x
m
0
x
m
1
x
m
2
.
.
.
x
m
n
]
X
i
=
[
x
i
0
x
i
1
x
i
2
.
.
.
x
i
n
]
\begin{aligned} \mathbf{X} & = \begin{bmatrix} x_{10}&x_{11}&x_{12}&...&x_{1n}\\ x_{20}&x_{21}&x_{22}&...&x_{2n}\\ ...&...&...&...&...\\ x_{m0}&x_{m1}&x_{m2}&...&x_{mn}\\ \end{bmatrix}\\\\\mathbf{X^{i}} &= \begin{bmatrix} x_{i0}&x_{i1}&x_{i2}&...&x_{in} \end{bmatrix} \end{aligned}
XXi=⎣⎢⎢⎡x10x20...xm0x11x21...xm1x12x22...xm2............x1nx2n...xmn⎦⎥⎥⎤=[xi0xi1xi2...xin]
参数向量w:
W
=
[
w
0
w
1
w
2
.
.
.
w
n
]
\mathbf{W}=\begin{bmatrix} w_{0}\\w_{1} \\w_{2} \\...\\w_{n} \end{bmatrix}
W=⎣⎢⎢⎢⎢⎡w0w1w2...wn⎦⎥⎥⎥⎥⎤
XW矩阵相乘:
X
W
=
[
h
1
h
2
h
3
.
.
.
h
m
]
\mathbf{XW}= \begin{bmatrix} h_{1} \\ h_{2}\\ h_{3}\\...\\ h_{m} \end{bmatrix}
XW=⎣⎢⎢⎢⎢⎡h1h2h3...hm⎦⎥⎥⎥⎥⎤
h i h_{i} hi为第
i
个样本预测值
y向量:
Y
=
[
y
1
y
2
y
3
.
.
.
y
m
]
\mathbf{Y}=\begin{bmatrix} y_{1}\\y_{2} \\y_{3} \\...\\y_{m} \end{bmatrix}
Y=⎣⎢⎢⎢⎢⎡y1y2y3...ym⎦⎥⎥⎥⎥⎤
y i y_{i} yi为样本实际值
损失函数:
J
(
w
)
=
∑
i
=
1
m
(
h
(
x
i
)
−
y
i
)
2
\begin{aligned} J(\mathbf{w}) =\sum_{i = 1}^{m}(h(\mathbf{x^{i}})-y^{i})^{2} \end{aligned}
J(w)=i=1∑m(h(xi)−yi)2
可以表示为
:
J
(
W
)
=
(
Y
−
X
W
)
T
(
Y
−
X
W
)
:J(\mathbf{W})=(\mathbf{Y}-\mathbf{XW})^{T}(\mathbf{Y}-\mathbf{XW})
:J(W)=(Y−XW)T(Y−XW)
对 W \mathbf{W} W求导得:
∂ J ( W ) ∂ W = − 2 X T Y + 2 X T X W \frac{\partial J(\mathbf{W})}{\partial \mathbf{W}} =-2\mathbf{X^{T}Y}+2\mathbf{X^{T}XW} ∂W∂J(W)=−2XTY+2XTXW
令: ∂ J ( W ) ∂ W = − 2 X T Y + 2 X T X W = 0 \frac{\partial J(\mathbf{W})}{\partial \mathbf{W}} =-2\mathbf{X^{T}Y}+2\mathbf{X^{T}XW}=0 ∂W∂J(W)=−2XTY+2XTXW=0
相当于对J(W)中,分别对w0,w1,w2,…,wn求偏导,令偏导等于0,解出w0,w1,w2…,wn
解得: W = ( X T X ) − 1 X Y \mathbf{W}=(\mathbf{X^{T}X})^{-1}\mathbf{X}\mathbf{Y} W=(XTX)−1XY
即求得最优参数向量W
三、梯度下降法
使用最小二乘法效率可能比较低,需解出n(特征值数量)个方程,可使用梯度下降法,对w参数向量进行迭达
梯度下降:沿着增长最快的相反方向,移动
α
\alpha
α 的步长,即逐步递减值最低值,迭代公式如下
w
=
w
−
α
∇
f
\large w=w-\alpha \nabla {f}
w=w−α∇f
∇ f \nabla {f} ∇f表示
增长
最快的方向,使用减号表示递减(梯度下降),若加表示递增(梯度上升)
使用梯度下降(或上升)时,一般给定w一个初始值,再通过不断迭代得到最优值
此时即需求
J
(
w
)
J(\mathbf{w})
J(w)的梯度, 需分别对对
w
i
w_{i}
wi求偏导
∇
f
=
[
∂
J
(
w
)
∂
w
0
∂
J
(
w
)
∂
w
1
∂
J
(
w
)
∂
w
2
.
.
.
∂
J
(
w
)
∂
w
n
]
\large \nabla {f}=\begin{bmatrix} \frac{\partial\mathrm J(\mathbf{w})}{\partial w_{0}}\\ \frac{\partial\mathrm J(\mathbf{w})}{\partial w_{1}}\\ \frac{\partial\mathrm J(\mathbf{w})}{\partial w_{2}}\\ ...\\ \frac{\partial\mathrm J(\mathbf{w})}{\partial w_{n}}\\ \end{bmatrix}
∇f=⎣⎢⎢⎢⎢⎢⎢⎢⎡∂w0∂J(w)∂w1∂J(w)∂w2∂J(w)...∂wn∂J(w)⎦⎥⎥⎥⎥⎥⎥⎥⎤
通过对对损失函数 J ( w ) J(\mathbf w) J(w)求偏导后(参考梯度上升),梯度可以表示为:
∇ f = − 1 m [ ∑ i = 1 m ( y i − h ( w T x i ) ) x i 0 ∑ i = 1 m ( y i − h ( w T x i ) ) x i 1 ∑ i = 1 m ( y i − h ( w T x i ) ) x i 2 . . . . . . ∑ i = 1 m ( y i − h ( w T x i ) ) x i n ] \large \nabla {f}=-\frac{1}{m} \begin{bmatrix} \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i0}\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i1}\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i2}\\ ......\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{in}\\ \end{bmatrix} ∇f=−m1⎣⎢⎢⎢⎢⎢⎢⎡∑i=1m(yi−h(wTxi))xi0∑i=1m(yi−h(wTxi))xi1∑i=1m(yi−h(wTxi))xi2......∑i=1m(yi−h(wTxi))xin⎦⎥⎥⎥⎥⎥⎥⎤
所以代入原方程,
梯度上升算法的迭代过程:
α
\alpha
α 为步长
(
α
>
0
)
(\alpha >0)
(α>0)
w
=
w
−
α
∇
f
=
[
w
0
w
1
w
2
.
.
.
w
n
]
+
α
1
m
[
∑
i
=
1
m
(
y
i
−
h
(
w
T
x
i
)
)
x
i
0
∑
i
=
1
m
(
y
i
−
h
(
w
T
x
i
)
)
x
i
1
∑
i
=
1
m
(
y
i
−
h
(
w
T
x
i
)
)
x
i
2
.
.
.
.
.
.
∑
i
=
1
m
(
y
i
−
h
(
w
T
x
i
)
)
x
i
n
]
\begin{aligned} \mathbf{w} &=\mathbf{w} -\alpha \nabla f\\\\&=\begin{bmatrix} w_{0}\\ w_{1}\\ w_{2}\\...\\w_{n} \end{bmatrix}+\alpha \frac{1}{m}\begin{bmatrix} \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i0}\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i1}\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{i2}\\ ......\\ \sum_{i=1}^{m}(y_{i}-h(\mathbf{w^{T}x_{i}}))x_{in}\\ \end{bmatrix} \end{aligned}
w=w−α∇f=⎣⎢⎢⎢⎢⎡w0w1w2...wn⎦⎥⎥⎥⎥⎤+αm1⎣⎢⎢⎢⎢⎡∑i=1m(yi−h(wTxi))xi0∑i=1m(yi−h(wTxi))xi1∑i=1m(yi−h(wTxi))xi2......∑i=1m(yi−h(wTxi))xin⎦⎥⎥⎥⎥⎤
经过上述不断迭代的过程,最终得到一个合适的
w
\mathbf{w}
w参数
四、代码
import numpy as np
#from matplotlib import pyplot as plt
def load_datas(filename):
with open(filename, 'r') as fr:
data_mat=[]
data_labels=[]
for line in fr:
curr_line=line.strip().split('\t')
data_mat.append(list(map(float, curr_line[:-1])))
data_labels.append(float(curr_line[-1]))
return np.mat(data_mat), np.mat(data_labels)
def get_weights0(datas, labels):
"""
最小二乘法
:param datas:
:param labels:
:return:weights
"""
xTx=datas.T*datas
if(np.linalg.det(xTx)!=0.0):
weights=xTx.I*datas.T*labels.T
return weights
return None
def get_weights1(datas, y_labels, alpha=1, r=300):
"""
梯度下降法
:param datas:
:param labels:
:return:weights
"""
shape = datas.shape
weights=np.ones((shape[1], 1))
for i in range(r):
err = y_labels-datas*weights
weights=weights+(alpha/shape[0])*datas.T*err
return weights
print('最小二乘法')
data_mat, data_labels = load_datas('ex1.txt')
weights=get_weights0(data_mat, data_labels)
print(weights)
print('梯度下降法')
weights=get_weights1(data_mat, data_labels.T)
print(weights)