什么是回归?回归的目的是在一堆看似杂乱无章的数字中发现其内在的数学逻辑规律!回归的目的什么?预测,预测明年的房价有多高,预测明年的物价有多高,预测明年的工资水平有多高!当然,在这个大数据时代,靠人脑去对数据集建立回归模型,简直是痴人说梦; 但是在智脑+算法的帮助下,这并不是天方夜谭!现在我们由易至难一一来分析各种常见的回归模型!
一、简单线性回归模型
说到回归,大家脑海中第一反应一定是线性回归了(如果你告诉我是多项式回归,我也不会承认的,我不听……)!现在让我们先从最简单的线性模型说起吧~
我一般把一元一次方程 y = a ∗ x + b y = a*x+b y=a∗x+b作为简单线性模型,如图1所示!
如何去解决它?很简单,如果我们能够得到a 、b 的值,那么就可以对任意的X进行预测得到y了。对于这种简单的回归模型,我们可以直接通过最小二乘法来得到a、b的值。
(一)如何评价回归模型的优劣
回到最开始的问题,回归的目的是什么?预测,我们要通过回归模型预测出一个Y值 ; 在一个训练集中,每一组数据中我们是存在一个真实的Y值的,因此评价一个回归模型是否可靠,我们可以通过比较预测的Y值与真实的Y值之间的差值的平方来实现,即 均方误差:
M S E = 1 m ∑ i = 1 m ( f ( x ( i ) ) − y ( i ) ) 2 MSE = \frac{1}{m} \sum_{i=1}^{m}( f(x^{(i)}) - y^{(i)})^2 MSE=m1i=1∑m(f(x(i))−y(i))2
注:m 是数据集的数量 ; f(x) 是线性回归模型 ; y 是真实的值;
很明显可以发现,均方误差越大,则回归模型越差; 均方误差越小, 则回归模型越好!
代码:
'''均方误差(Mwan Squared Error): 用于评价回归算法的准确性'''
def Mean_Squared_Error(y_test,y_predict):
return np.sum((y_predict-y_test)**2)/len(y_test);
(二)如何优雅地解出模型系数
现在我们有了利器均方误差可以方便我们来评价回归模型的优劣,我们也明白,如果均方误差越小,那么回归模型越好!那么很简单,假设我们建立了一个简单线性回归模型 y = a ∗ x + b y = a*x + b y=a∗x+b, 那么得到一个a, b值使得均方误差值最小,就可以得到我们想要的回归模型了!
1. 最小二乘法
如何计算
m i n ∑ i = 1 m ( a ∗ x ( i ) + b − y ( i ) ) 2 min \sum_{i=1}^{m} (a*x^{(i)} + b - y^{(i)})^2 mini=1∑m(a∗x(i)+b−y(i))2
就是摆在我们面前的一道难题!数学的问题交给数学,首先,你是否发现这个式子和欧式距离的定义 ∣ X − Y ∣ 2 |X - Y|^2 ∣X−Y∣2很像,那么如果存在一条直线,使得所有数据点至直线的距离之和最短,这不就是我们的均方误差的定义嘛~好的,问题解决了,这种思路就是 “最小二乘法”!
令 E ( a , b ) = ∑ i = 1 m ( a ∗ x ( i ) + b − y ( i ) ) 2 E(a,b) = \sum_{i=1}^{m} (a*x^{(i)}+ b - y^{(i)})^2 E(a,b)=∑i=1m(a∗x(i)+b−y(i))2, 使其分别对a & b 求偏导: ∂ E ∂ a = 0 \frac{\partial E}{\partial a} = 0 ∂a∂E=0, ∂ E ∂ b = 0 \frac{\partial E}{\partial b} = 0 ∂b∂E=0
得:
a = ∑ i = 1 m ( x ( i ) − X m e a n ) ( y ( i ) − Y m e a n ) ( x ( i ) − X m e a n ) 2 a = \frac{\sum_{i=1}^{m}(x^{(i)} - X_{mean})(y^{(i)}- Y_{mean})}{(x^{(i)} - X_{mean})^2} a=(x(i)−Xmean)2∑i=1m(x(i)−Xmean)(y(i)−Ymean)
b = Y m e a n − a ∗ X m e a n b = Y_{mean} - a * X_{mean} b=Ymean−a∗Xmean
所以我们根据上式进行编码就可以很简单地通过计算得想要的简单线性回归模型了!
PS : 在这里,我想稍微提一下,在上章我们对数据进行KNN分类前,是对数据进行归一化处理过的。那么在回归问题中,数据集是否也需要进行处理呢?假设我们对房价进行预测,你觉得影响房价的各个因素是否是处于相同的数值标准下呢?好吧,如果可以的话,还是进行归一化处理一下吧,毕竟能够很好地提高你的模型准确性。
代码:
import numpy as np
from metrics import r2_score
class SimpleLinearRegression(object):
'''初始化简单线性回归模型 '''
def __init__(self):
self.a_ = None;
self.b_ = None;
#拟合过程
def fit(self,x_train,y_train):
assert x_train.shape == y_train.shape;
x_mean = np.mean(x_train);
y_mean = np.mean(y_train);
self.a_ = (x_train-x_mean).dot(y_train-y_mean)/(x_train-x_mean).dot(x_train - x_mean); #根据最小二乘法求出相应的系数a,b ; 向量化运算
self.b_ = y_mean - self.a_*x_mean;
return self;
#预测过程
def predict(self,x_test):
assert x_test.ndim==1;
y_predict = [self._predict(single) for single in x_test];
return np.array(y_predict);
#单个样本的回归预测过程
def _predict(self,x):
y = self.a_*x+self.b_;
return y;
2. 梯度下降法
其实在简单线性回归模型中使用梯度下降法,颇有点大炮打蚊子的意味!不过在这里先稍微科普一下什么是梯度下降法,好在下一章直接使用。
什么是梯度下降?这是一种求局部最优解的算法。你可以把下图当作两座山峰,你现在站在山顶上,你要到谷底去,但是你不知道下山的路怎么办?既然你在山上,你要去山底,那么你一定要往下走,所以你走出的每一步只要按照坡度最陡峭的方向向下走,你就是在逐渐靠近山底。
现在我们有一个多元可微函数 F ( x ) = 5 X 1 + 6 X 2 + 7 X 3 F(x) = 5X_1 + 6X_2 + 7X_3 F(x)=5X1+6X2+7X3,则F(x)的梯度为 ∇ F ( x ) = < ∂ F ∂ X 1 , ∂ F ∂ X 2 , ∂ F ∂ X 3 > = < 5 , 6 , 7 > \nabla F(x) = <\frac{\partial F}{\partial X_1},\frac{\partial F}{\partial X_2},\frac{\partial F}{\partial X_3}> = <5,6,7> ∇F(x)=<∂X1∂F,∂X2∂F,∂X3∂F>=<5,6,7> 。 可以看到,梯度就是分别对每一个变量进行微分处理。
- 在单变量的函数中,梯度就是函数的微分,即在某个点上的切线的斜率
- 在多变量的函数中,梯度是一个有方向的向量,即在某个点上上升的方向
那么回到下山问题,梯度的反方向就是我们在给定点上下降最快的方向,就是我们下山过程中观测到的最陡峭的地方。如果我们沿着梯度的反方向一直往下走,就能够走到局部的最低点。
OK,说了这么多,还是没介绍为什么我们可以在线性回归模型中使用梯度下降法。还记得我们建立回归模型的目标是为了尽可能地减小 E ( a , b ) = ∑ i = 1 m ( a ∗ x ( i ) + b − y ( i ) ) 2 E(a,b) = \sum_{i=1}^{m} (a*x^{(i)} + b - y^{(i)})^2 E(a,b)=∑i=1m(a∗x(i)+b−y(i))2,现在 x ( i ) , y ( i ) x^{(i)} , y^{(i)} x(i),y(i) 我们是已知的,该方程是可微的,因此我们完全可以通过梯度下降的思路找到该可微方程的局部极小解(在这里也就是它的全局最小解)!
那么我们该如何使用这种方法呢?请往下看:)
二、线性回归模型
(一) 多样性的评价标准
在上一篇神奇的k中我们提到分类模型的评价标准有准确率、查准率、查全率、F1等,那么在回归模型中,就只有简单的均方误差一种评价标准吗?老实说,分类模型的评价标准确实要远远多于回归模型,但是回归模型的评价标准也确实做到了一招鲜吃遍天(哈哈哈哈),反正你见到的很多回归模型最开始推导的时候都是会采用均方根误差。
不过在这里我想再补充几种分类模型的评价标准,供大家参考!
1. 均方根误差
R M S E = M S E = 1 m ∑ i = 1 m ( f ( x ( i ) ) − y ( i ) ) 2 RMSE = \sqrt{MSE} = \sqrt{ \frac{1}{m} \sum_{i=1}^{m}( f(x^{(i)}) - y^{(i)})^2} RMSE=MSE=m1i=1∑m(f(x(i))−y(i))2
很熟悉的感觉,它就是将之前的均方根误差开个根而已!
2.平均绝对误差
M A E = 1 m ∑ i = 1 m ∣ f ( x ( i ) ) − y ( i ) ∣ MAE = \frac{1}{m} \sum_{i=1}^{m} |f(x^{(i)}) - y^{(i)}| MAE=m1i=1∑m∣f(x(i))−y(i)∣
3.R平方
R 2 = 1 − S S r e s S S t o t = 1 − ∑ i = 1 m ( f ( x ( i ) ) − y ( i ) ) 2 ∑ i = 1 m ( Y m e a n − y ( i ) ) 2 = 1 − M S E ( Y p r e d i c t , Y T r u e ) V a r ( Y T r u e ) R^2 = 1 - \frac{SS_{res}}{SS_{tot}} = 1 - \frac{\sum_{i=1}^{m}( f(x^{(i)}) - y^{(i)})^2}{\sum_{i=1}^{m}( Y_{mean} - y^{(i)})^2} = 1 - \frac{MSE(Y_{predict},Y_{True})}{Var(Y_{True})} R2=1−SStotSSres=1−∑i=1m(Ymean−y(i))2∑i=1m(f(x(i))−y(i))2=1−Var(YTrue)MSE(Ypredi