@[TOC](线性模型)
基本形式
给定由d个属性描述的示例X = ( x1; x2; …; xd ),其中xi是X在第i个属性上的取值,线性模型试图学得一个通过属性的线性组合来进行预测的函数,即
举例:假设一个好瓜由色泽、根蒂、敲声决定,则可以假设一个预测线性函数为:
其中xs、xg、xq 依次表示为色泽,根蒂与敲声。可以看出一个好瓜根蒂是最要紧的。
线性回归
给定一个数据集
线性回归的目的是找到一个线性模型尽可能准确的预测实值输出标记。即
使得
为了确定w 与 b尽可能的拟合,减少f(x)与y之间的误差,最常用的让其均方差误差最小化,基于均方差最小化来进行模型求解的方法称为“最小二乘法”。
最小二乘法确定w、b推导:
首先,所有样本到直线上的欧氏距离表示为:
其中
y
i
y_i
yi与
x
i
x_i
xi作为参数输入,w与b作为变量,目的就是求出使得
E
(
w
,
b
)
E_{{(w,b)}}
E(w,b)最小,所以依次对w与b求偏导。
对w求偏导:
对b求偏导:
当上述两式导数均为0时,得到w和b的最优解。(再导数为零处取得极值,因为f(x) =
x
2
x^2
x2通常是凸函数,因此极值等于最值。)联立上述两式可以推出w和b关于
x
i
x_i
xi与
y
i
y_i
yi的表达式:
其中:
每一对w与b对应样本都有具体的数值(拟合样本数据的距离),将求w与b最小数值的函数称为代价函数:
代价函数的样子,等高线图,则可以看出在三维空间中存在一个使得𝐽(𝜃0,𝜃1)最小的点。
梯度下降
梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数𝐽(𝜃0,𝜃1) 的最小值。 梯度下降背后的思想是:开始时我们随机选择一个参数的组合(𝜃0,𝜃1,…,𝜃𝑛),计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。我们持续这么做直到到到一个局部最小值。(注意是局部最小值,不能确定我们得到的局部最小值是否便是全局最小值)如下图:
当起始的点不同时,得到的结果不一定相同,可以看出上方的梯度下降轨迹到达的只是局部的最优解,并不是全局的。
梯度下降法推导:
梯度就是表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在当前位置的导数。
首先我们写出f(𝜃)在
θ
0
\theta_0
θ0处的一阶泰勒展开式:
此处
其中, 𝜃 - 𝜃0是微小矢量,现用
ω
\omega
ωi表示,i是单位向量,
ω
\omega
ω是系数,因此式子化为:
移项:
因为我们希望的是每次的
θ
\theta
θ更新都会使得f(
θ
\theta
θ)值更小,因此f(
θ
\theta
θ) - f(
θ
0
\theta_0
θ0) < 0 即
ω
i
⋅
▽
f
(
θ
0
)
\omega i \cdot \bigtriangledown f(\theta_0)
ωi⋅▽f(θ0) < 0 ,设
ω
\omega
ω为正值,那么即
i
⋅
▽
f
(
θ
0
)
i \cdot \bigtriangledown f(\theta_0)
i⋅▽f(θ0) < 0 ,两个向量乘积要小于0,那么两向量之间的夹角需大于90°,因此每次更新的
θ
=
θ
0
−
ω
⋅
▽
f
(
θ
0
)
\theta = \theta_0-\omega\cdot\bigtriangledown f(\theta_0)
θ=θ0−ω⋅▽f(θ0)
下面我们引入一组数据建立模型:
数据的分布图:
计算代价函数
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))
接下来是batch gradient decent(批量梯度下降)
对每个
θ
\theta
θ进行更新
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (X * theta.T) - y
for j in range(parameters):
term = np.multiply(error, X[:,j])
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
初始化一些附加变量 - 学习速率α和要执行的迭代次数。
alpha = 0.01
iters = 1000
最终的结果:
现在我们来绘制线性模型以及数据,直观地看出它的拟合。
由于梯度方程式函数也在每个训练迭代中输出一个代价的向量,所以我们也可以绘制
请注意,代价总是降低 - 这是凸优化问题的一个例子。也说明随着迭代的次数增加,预测函数更加的拟合数据。
多变量线性回归
上述的实验只有一个变量,现在使用另外一组数据
可以看出与上面不同的是这组训练集有两个变量,size与bedrooms房间数。
特别注意的是若不同参数取值的范围差距比较大的话会呈现如下图
这样会导致需要花费更长的时间才找到一条通往全局最小的路径。
因此对数据进行特征归一化较为合适:
data2 = (data2 - data2.mean()) / data2.std()
data2.head()
归一化之后的路径减少了振荡的可能性。例如范围[-1 < x <1],[-2 < x <05]类似这种范围就较为合适,若一个变量的范围为[-100 < x <100]或者[-0.0001< x < 0.00001]的话,相比与上面两个变量的范围差距就太大了。
下面是归一化处理之后的数据:
接下来处理的过程与单变量的过程一样:
我们可以查看下他的训练过程:
正规方程法
梯度下降法是通过一步一步的迭代得到最小值的,但是对于某些线性回归问题,正规方程方法是更好的解决方案。
我们知道梯度下降是通过
逐步减少得到最优解的。正规方程是通过求解下面的方程来找出使得代价函数最小的参数的
∂
J
(
θ
j
)
∂
θ
j
=
0
\frac{\partial J(\theta_j)}{\partial \theta_j} = 0
∂θj∂J(θj)=0
正规方程解出向量 𝜃 = ( X T X^T XT𝑋)^-1 X T X^T XT𝑦
求解步骤:
梯度下降与正规方程的比较:
# 正规方程
def normalEqn(X, y):
theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等价于X.T.dot(X)
return theta
梯度下降得到的结果是matrix([[-3.24140214, 1.1272942 ]]),两个方法的结果还是有一定的差距。