<机器学习系列> 线性回归模型
前言线性回归模型是机器学习中一个基本回归模型,是许多模型的基础,学习好线性回归模型有助于我们的机器学习,这里简单介绍下线性回归模型并且提供Python代码演示。如有谬误,请联系指正。转载请注明出处。联系方式:e-mail: FesianXu@163.comQQ: 973926198github: https://github.com/FesianXu代码开源:click线性回
前言
线性回归模型是机器学习中一个基本回归模型,是许多模型的基础,学习好线性回归模型有助于我们的机器学习,这里简单介绍下线性回归模型并且提供Python代码演示。
如有谬误,请联系指正。转载请注明出处。
联系方式:
e-mail: FesianXu@163.com
QQ: 973926198
github: https://github.com/FesianXu
代码开源:click
线性回归
回归模型(Regression model)是研究一个变量关于另一个或者另一些变量的依赖关系的模型,比如房价和房子面积,地点等的关系等等,如下图所示。而**线性回归(Linear Regression)**是其中的一个基本模型。
当我们谈到线性回归模型的时候,大多指的是多元线性回归,其假设为:
y
=
θ
T
X
+
b
,
其
中
θ
T
=
(
θ
1
,
θ
2
,
⋯
,
θ
n
)
,
X
∈
R
n
y = \theta^TX+b,其中\theta^T = (\theta_1, \theta_2,\cdots,\theta_n), X \in R^n
y=θTX+b,其中θT=(θ1,θ2,⋯,θn),X∈Rn
也就是说这个假设代表了一个在n维空间的超平面,我们需要求得的就是参数
θ
T
\theta^T
θT和
b
b
b。在有了训练集的情况下,有多种方法可以求出这两个参数,我们一般采用梯度下降法求得,详见博文随机梯度下降法,批量梯度下降法和小批量梯度下降法以及代码实现。
损失函数
我们理想模型的目的是尽可能地拟合真实数据 P d a t a P_{data} Pdata,那么我们就需要一个指标,用于表示模型的预测值与真实值之间的差别,这个指标称为损失函数(loss function, cost function)有很多,如交叉熵,MSE误差, MAE误差等等,这里因为是回归任务,我们选择MSE误差作为损失函数。
MSE函数
均方误差(Mean Squared Error, MSE)也称为L2范数损失,代表了真实数据和预测数据之间的差别,在训练中一般是越小,代表模型拟合训练集的能力越好。其表达式为:
L
=
M
S
E
(
y
,
y
^
)
=
1
m
∑
i
=
1
m
∣
∣
y
i
−
y
i
^
∣
∣
2
,
m
是
样
本
数
量
L = MSE(y, \hat{y}) = \frac{1}{m}\sum_{i=1}^{m}||y_i-\hat{y_i}||^2,m是样本数量
L=MSE(y,y^)=m1i=1∑m∣∣yi−yi^∣∣2,m是样本数量
在一些模型中为了求梯度(导数)方便,常常会加上一个常数因子:
L
=
M
S
E
(
y
,
y
^
)
=
1
2
m
∑
i
=
1
m
∣
∣
y
i
−
y
i
^
∣
∣
2
L=MSE(y, \hat{y}) = \frac{1}{2m}\sum_{i=1}^{m}||y_i-\hat{y_i}||^2
L=MSE(y,y^)=2m1i=1∑m∣∣yi−yi^∣∣2
其梯度为:
∂
L
∂
θ
i
=
−
1
m
∑
i
=
1
m
[
(
y
i
−
θ
T
x
−
b
)
x
i
]
\frac{\partial{L}}{\partial{\theta_i}} = -\frac{1}{m} \sum_{i=1}^m [(y_i-\theta^Tx-b)x_i]
∂θi∂L=−m1i=1∑m[(yi−θTx−b)xi]
∂
L
∂
b
=
−
1
m
∑
i
=
1
m
(
y
i
−
θ
T
x
−
b
)
\frac{\partial{L}}{\partial{b}} = -\frac{1}{m} \sum_{i=1}^m (y_i-\theta^Tx-b)
∂b∂L=−m1i=1∑m(yi−θTx−b)
模型搭建
整个模型的最优化函数为:
min
θ
,
b
1
2
m
∑
i
=
1
m
∣
∣
y
i
−
y
i
^
∣
∣
2
\min_{\theta,b} \frac{1}{2m} \sum_{i=1}^m ||y_i-\hat{y_i}||^2
θ,bmin2m1i=1∑m∣∣yi−yi^∣∣2
y
i
^
=
θ
T
x
i
+
b
\hat{y_i} = \theta^Tx_i+b
yi^=θTxi+b
由梯度下降法可以得到参数的更新公式为:
θ
i
:
=
θ
i
−
η
∂
L
∂
θ
i
=
θ
i
+
1
m
∑
i
=
1
m
[
(
y
i
−
θ
T
x
−
b
)
x
i
]
\theta_i := \theta_i-\eta\frac{\partial{L}}{\partial{\theta_i}} = \theta_i+\frac{1}{m} \sum_{i=1}^m [(y_i-\theta^Tx-b)x_i]
θi:=θi−η∂θi∂L=θi+m1i=1∑m[(yi−θTx−b)xi]
b
:
=
b
−
η
∂
L
∂
b
=
b
+
η
1
m
∑
i
=
1
m
(
y
i
−
θ
T
x
−
b
)
b := b-\eta \frac{\partial{L}}{\partial{b}} = b+\eta \frac{1}{m} \sum_{i=1}^m (y_i-\theta^Tx-b)
b:=b−η∂b∂L=b+ηm1i=1∑m(yi−θTx−b)
根据采用的随机梯度下降法的策略,可分为SGD,BGD和MBGD,从而选择m的大小。
代码实现,基于python和numpy
数据描述
这里的数据为了突出多元回归的目的,我们这里人工产生三维点图数据(x,y作为输入向量,z作为输出向量),并且在x,y,z上加上高斯噪声,如:
x = -10:0.01:10;
y = -10:0.01:10;
x_randn = randn(1, length(x))*5;
x = x+x_randn;
y_randn = randn(1, length(y))*5;
y = y+y_randn;
z = 3*x+4*y+6;
z_randn = randn(1, length(z))*10;
z = z+z_randn;
x = x';
y = y';
z = z';
samples = [x, y, z];
save samples.mat
其图像如:
可以看出其是加入了噪声的。
代码
代码和随机梯度下降法,批量梯度下降法和小批量梯度下降法以及代码实现一文中的类似,这里做了一点小改变而已。
import numpy as np
import scipy.io as sio
import random
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
path = u'./samples.mat'
mat = sio.loadmat(path)
dataset = mat['samples']
batch_size = 128
def random_get_samples(mat, batch_size):
batch_id = random.sample(range(mat.shape[0]), batch_size)
ret_batch = mat[batch_id, 0:2]
ret_line = mat[batch_id, 2:3]
return ret_batch, ret_line
params = {
'w': np.random.normal(size=(2, 1)),
'b': np.random.normal(size=(1))
}
def predict(batch):
return np.dot(batch, params['w'])+params['b']
learning_rate = 0.0003
for i in range(10000):
batch, true_z = random_get_samples(dataset, batch_size)
z_pred = predict(batch)
delta = true_z-z_pred
params['w'] = params['w']+learning_rate*np.reshape(np.transpose(np.sum(delta*batch, axis=0)), (2, 1))/batch_size
params['b'] = params['b']+learning_rate*np.sum(delta)/batch_size
if i % 100 == 0:
print(np.sum(np.abs(delta))/batch_size)
fig = plt.figure()
ax = Axes3D(fig)
x = dataset[:, 0]
y = dataset[:, 1]
z = dataset[:, 2]
z_pred = predict(dataset[:, 0:2])
print(params['w'])
print(params['b'])
ax.scatter(x, y, z, c='b')
ax.scatter(x, y, z_pred, c='r')
plt.show()
其结果为:
w = [[ 3.03582457]
[ 4.0155888 ]]
b = [ 5.54841543]
可见和预设的参数还是很接近的。绘制出来的图像如:
可见对训练数据集进行了很好地拟合。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)