赞
踩
回归分析是一种预测性建模技术,它是研究因变量与自变量之间的关系,这种技术通常用于预测分析,时间序列模型以及发现变量之间的因果关系,通常使用直线或曲线进行拟合,目标是使曲线到目标点的距离差最小。线性回归是回归问题中的一种,线性回归假设目标值与特征之间线性相关,即满足一个多元一次方程。通过构建损失函数,来求解损失函数最小时的参数 ω \omega ω 和 b b b。
通常线性回归可以表达成以下公式: y ^ = ω x + b \widehat y = \omega x + b y =ωx+b。其中 y ^ \widehat y y 为预测值,为了构建这个函数关系,通过已知的点 ( x , y ) (x,y) (x,y)来求解参数 ω \omega ω 和 b b b。
为了评价所求参数的好与不好,需要一个标准来衡量,因此需要构建一个目标函数,使计算机通过已有数据对目标函数不断进行优化。因此,目标函数定义如下:
L = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 L = \frac{1}{n}\sum\limits_{i = 1}^n {{{({{\widehat y}_i} - {y_i})}^2}} L=n1i=1∑n(y i−yi)2 (1)
其中, y ^ i \widehat y_i y i 为模型的预测值, y i y_i yi 为真实值, n n n 为数据点的个数。该损失函数表示的意义为样本预测值与真实值之间的平均平方和,即MSE.将公式(1)带入目标函数中,求解的参数 ω \omega ω 和 b b b可以看做是函数 L L L的自变量,因此函数可以写成:
L ( ω , b ) = 1 n ∑ i = 1 n ( ω x i + b − y i ) 2 L(\omega ,b) = \frac{1}{n}\sum\limits_{i = 1}^n {{{(\omega {x_i} + b - {y_i})}^2}} L(ω,b)=n1i=1∑n(ωxi+b−yi)2
现在的主要任务为求使函数取得最小值的 ω \omega ω 和 b b b。因此,目标函数的优化公式为:
L ( ω ∗ , b ∗ ) = arg min ( ω , b ) ∑ i = 1 n ( ω x i + b − y i ) 2 L({\omega ^*},{b^*}) = \mathop {\arg \min }\limits_{(\omega ,b)} \sum\limits_{i = 1}^n {{{(\omega {x_i} + b - {y_i})}^2}} L(ω∗,b∗)=(ω,b)argmini=1∑n(ωxi+b−yi)2
(1) 最小二乘法
求解
ω
\omega
ω 和
b
b
b是使损失函数最小化的过程,将
L
(
ω
,
b
)
L(\omega ,b)
L(ω,b)分别对
ω
\omega
ω 和
b
b
b进行求偏导:
∂ L ∂ ω = 2 ( ω ∑ i = 1 n x i 2 − ∑ i = 1 n ( y i − b ) ) \frac{{\partial L}}{{\partial \omega }} = 2(\omega \sum\limits_{i = 1}^n {x_i^2 - \sum\limits_{i = 1}^n {({y_i} - b)} } ) ∂ω∂L=2(ωi=1∑nxi2−i=1∑n(yi−b))
∂ L ∂ b = 2 ( n b − ∑ i = 1 n ( y i − ω x i ) ) \frac{{\partial L}}{{\partial b}} = 2(nb - \sum\limits_{i = 1}^n {({y_i} - \omega {x_i})} ) ∂b∂L=2(nb−i=1∑n(yi−ωxi))
令上述两式等于0,可以得到 ω \omega ω 和 b b b 的封闭式最优解。
ω = ∑ i = 1 n y i ( x i − x ‾ ) ∑ i = 1 n x i 2 − 1 n ( ∑ i = 1 n x i ) 2 \omega = \frac{{\sum\nolimits_{i = 1}^n {{y_i}({x_i} - \overline x )} }}{{\sum\limits_{i = 1}^n {x_i^2 - \frac{1}{n}{{(\sum\limits_{i = 1}^n {{x_i}} )}^2}} }} ω=i=1∑nxi2−n1(i=1∑nxi)2∑i=1nyi(xi−x)
(2) 梯度下降法
梯度下降法的核心内容是对自变量进行不断的更新,使目标函数不断逼近最小值的过程。
ω ← ω − α ∂ L ∂ ω b ← b − α ∂ L ∂ b \omega \leftarrow \omega - \alpha \frac{{\partial L}}{{\partial \omega }}\\ b \leftarrow b - \alpha \frac{{\partial L}}{{\partial b}} ω←ω−α∂ω∂Lb←b−α∂b∂L
算法实现见代码文件夹,算法测试结果如下:
LinearRegression.py
import numpy as np class LinearRegression(object): def __init__(self,learning_rate=0.01,max_iter=100,seed=None): np.random.seed(seed) self.lr=learning_rate self.max_iter=max_iter self.w=np.random.normal(1,0.1) self.b=np.random.normal(1,0.1) self.loss_arr=[] def fit(self,x,y): self.x=x self.y=y for i in range(self.max_iter): self._train_step() self.loss_arr.append(self.loss()) def _f(self,x,w,b): return w*x+b def predict(self,x=None): if x is None: x=self.x y_pred=self._f(x,self.w,self.b) return y_pred def loss(self,y_true=None,y_pred=None): if y_true is None or y_pred is None: y_true=self.y y_pred=self.predict(self.x) return np.mean((y_true-y_pred)**2) def _calculate_gradient(self): d_w=np.mean((self.w*self.x+self.b-self.y)*self.x) d_b=np.mean(self.w*self.x+self.b-self.y) return d_w,d_b def _train_step(self): d_w,d_b=self._calculate_gradient() self.w=self.w-self.lr*d_w self.b=self.b-self.lr*d_b return self.w,self.b
train_test.py
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt from linear_regression import LinearRegression def show_data(x, y, w=None, b=None): plt.scatter(x, y, marker='.') if w is not None and b is not None: plt.plot(x, w*x+b, c='red') plt.show() # data generation np.random.seed(272) data_size = 100 x = np.random.uniform(low=1.0, high=10.0, size=data_size) y = x * 20 + 10 + np.random.normal(loc=0.0, scale=10.0, size=data_size) # plt.scatter(x, y, marker='.') # plt.show() # train / test split shuffled_index = np.random.permutation(data_size) x = x[shuffled_index] y = y[shuffled_index] split_index = int(data_size * 0.7) x_train = x[:split_index] y_train = y[:split_index] x_test = x[split_index:] y_test = y[split_index:] # visualize data # plt.scatter(x_train, y_train, marker='.') # plt.show() # plt.scatter(x_test, y_test, marker='.') # plt.show() # train the liner regression model regr = LinearRegression(learning_rate=0.01, max_iter=10, seed=314) regr.fit(x_train, y_train) print('cost: \t{:.3}'.format(regr.loss())) print('w: \t{:.3}'.format(regr.w)) print('b: \t{:.3}'.format(regr.b)) show_data(x, y, regr.w, regr.b) # plot the evolution of cost plt.scatter(np.arange(len(regr.loss_arr)), regr.loss_arr, marker='o', c='green') plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。