线性回归
【关键词】最小二乘法,线性
一、普通线性回归
1、原理
分类的目标变量是标称型数据,而回归将会对连续型的数据做出预测。
应当怎样从一大堆数据里求出回归方程呢?
假定输人数据存放在矩阵X中,而回归系数存放在向量W中。那么对于给定的数据X1, 预测结果将会通过
Y=X*W
给出。现在的问题是,手里有一些X和对应的Y,怎样才能找到W呢?
一个常用的方法就是找出使误差最小的W。这里的误差是指预测Y值和真实Y值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以我 们采用平方误差。
最小二乘法
平方误差可以写做:
对W求导,当导数为零时,平方误差最小,此时W等于:
例如有下面一张图片:
求回归曲线,得到:
矩阵乘法
矩阵相乘:行和列相同,行乘列。
#导包
import numpy as np
from IPython.display import display
# 创建两个二维数组
a = np.random.randint(0,10,size = (2,3))
b = np.random.randint(0,10,size = (3,4))
display(a,b)
#矩阵点乘:行乘列:8*0+4*8+4*4 = 48
np.dot(a,b)
# 矩阵转置
a.T
#单元矩阵:a_T*a
unit_a = np.dot(a_T,a)
# 逆矩阵的求解:
nverse_matrix = np.linalg.inv(unit_a)
nverse_matrix
2、实例(比较不同模型对同一样本集的预测效果)
注意:以下命令都是在浏览器中输入。
cmd命令窗口输入:jupyter notebook
打开浏览器输入网址http://localhost:8888/
2.1 导包
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
# 获取糖尿病信息
from sklearn.datasets import load_diabetes
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
2.2 获取数据
#获取糖尿病数据
data=load_diabetes()
2.3 数据建模
#数据建模
features=data.data
target=data.target
2.4 模型选择
2.4.1 使用普通线性回归模型算法进行线性回归
1) 拆分数据
#拆分数据
x_train,x_test,y_train,y_test=train_test_split(features,
target,
test_size=0.3,
random_state=1)
2) 导入线性回归模型包
from sklearn.linear_model import LinearRegression
3)创建模型对象
#创建模型对象
linear=LinearRegression()
4)模型训练
#模型训练
linear.fit(x_train,y_train)
5)预测
#求出预测值(将测试的特征数据代入predict中)
y_pred=linear.predict(x_test)
6)模型评估
#使用r2.score对线性回归模型进行评分
from sklearn.metrics import r2_score
r2_score(y_test,y_pred)
7)绘图
#画出真实值和模型求出的预测值得线形图,进行比对
plt.plot(y_pred,color='r')
plt.plot(y_test,color='y')
8)求累差和(越低越好)
#查看真实值和预测值之间的累差和
((y_test + 2) - (y_pred + 2)).sum()
9)绘制残差直方图
可以求出真实值和预测值之间差的一个累和,该累和值越小表示模型越好。
result_=(y_test + 2) - (y_pred + 2)
plt.hist(result_,bins=20)
2.4.2 使用Knn算法模型处理回归问题
1) 导入Knn算法模型包
from sklearn.neighbors import KNeighborsRegressor
3)创建模型对象
#创建模型对象
knn=KNeighborsRegressor(n_neighbors=5)
4)模型训练
#模型训练
knn.fit(x_train,y_train)
5)预测
#求出预测值(将测试的特征数据代入predict中)
knn_y_pred=knn.predict(x_test)
6)模型评估
#使用r2.score对线性回归模型进行评分
from sklearn.metrics import r2_score
r2_score(y_test,y_pred)
7)模型调优
调整k参数,进行模型调优。
knn=KNeighborsRegressor(n_neighbors=28)
knn.fit(x_train,y_train)
knn_y_pred=knn.predict(x_test)
r2_score(y_test,knn_y_pred)
8)绘图
#画出真实值和模型求出的预测值得线形图,进行比对
plt.plot(knn_y_pred,color='r')
plt.plot(y_test,color='y')
8)求累差和(越低越好)
#查看真实值和预测值之间的累差和
((y_test + 2) - (knn_y_pred + 2)).sum()
9)绘制残差直方图
可以求出真实值和预测值之间差的一个累和,该累和值越小表示模型越好。
#绘制残差直方图
#Knn
result=(y_test + 2) - (knn_y_pred + 2)
plt.hist(result,bins=20)
从上面的对比可以看出,针对“糖尿病信息”这个样本集,使用普通的线性回归模型比使用knn算法模型做预测要好。
3、研究一个特征对结果的影响
#取样本集中的一列
new_features=features[:,3]
target=target
#使用普通线性回归模型
new_linear=LinearRegression()
#训练模型
new_linear.fit(new_features.reshape(-1,1),target)
#对给出的数据进行预测
x=np.linspace(new_features.min(),new_features.max(),300)
y=new_linear.predict(x.reshape(-1,1))
#绘图,绘出变化曲线
plt.scatter(new_features,target)
plt.scatter(x,y)
可以预测出,这一特征对“糖尿病”的影响是成正相关的。
二、岭回归
1、原理
缩减系数来“理解”数据 :
如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归和之前的方法来做预测?
答案是否定的,即不能再使用前面介绍的方法。这是因为输入数据的矩阵X不是满秩矩阵。非满秩矩阵在求逆时会出现问题。
为了解决这个问题,统计学家引入了岭回归(ridge regression)的概念。
缩减方法可以去掉不重要的参数,因此能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果。
岭回归是加了二阶正则项的最小二乘,主要适用于过拟合严重或各变量之间存在多重共线性的时候,岭回归是有bias的,这里的bias是为了让variance更小。
归纳总结
1.岭回归可以解决特征数量比样本量多的问题
2.岭回归作为一种缩减算法可以判断哪些特征重要或者不重要,有点类似于降维的效果
岭回归用于处理下面两类问题:
1.数据点少于变量个数
2.变量间存在共线性(最小二乘回归得到的系数不稳定,方差很大)
所谓的多重共线性是指一些自变量之间存在较强的线性关系。这种情况在实际应用中非常普遍,如研究高血压与年龄、吸烟年限、饮白酒年限等因素的关系,这些自变量通常是相关的,如果这种相关程度非常高,使用最小二乘法建立回归方程就有可能失效,引起下列不良后果 。
2、实例
岭回归一般用在样本值不够的时候 。
使用岭回归处理波士顿房价信息
2.1 获取数据
#导入波士顿的数据
from sklearn.datasets import load_boston
data=load_boston()
2.2 数据建模
#提取特征数据
features=data.data
#提取目标数据
target=data.target
2.3 特征工程(归一化处理:提高算法模型的精度)
有3种归一化处理方法。
1)普通归一化处理
普通归一化:每个特征数据在全部特征数据中占的比重。
#普通归一化处理
features / features.sum()
从图中可以看出每一列数据之间的量级差别还是比较大的,在这个实例当中,使用普通归一化处理不好。
2)区归一化
区归一化:每一个特征数据在一个区域中占的比重。
#区归一化:
features / (features.max() - features.min())
从图中可以看出每一列数据之间的量级差别还是比较大的,在这个实例当中,使用区归一化处理也不好。
3)函数归一化
使用以下三个函数进行特征数据归一化处理:
Normalizer,MinMaxScaler,StandardScaler
#导包
from sklearn.preprocessing import Normalizer,MinMaxScaler,StandardScaler
Normalizer()
Normalizer().fit_transform(features)
MinMaxScaler()
MinMaxScaler().fit_transform(features)
StandardScaler()
#该种归一化处理效果最优(特征值间的相差的量级最小)
features=StandardScaler().fit_transform(features)
features
4)模型选择
#创建普通线性回归模型对象
linear=LinearRegression()
#创建岭回归模型对象
ri=Ridge(alpha=5)
5)模型评估
拆分数据
#分割数据
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(features,target,
test_size=0.2,
random_state=2)
训练模型
#训练普通线性回归模型
linear.fit(x_train,y_train)
#训练岭回归模型
ri.fit(x_train,y_train)
使用coef_
注意:使用模型调用coef_后,可返回一个装有样本集中所有特征种类对结果的影响权重。 调整模型对象alpha参数会导致coef返回系数的变化。 系数缩减会导致对目标影响较小的特征对结果的权重值缩减到0,这样就只会留下重要的特征进行模型训练。目的:节省训练的开销 。
#普通线性回归模型的coef_
linear.coef_
#岭回归模型的coef_
ri.coef_
获取预测值并进行评分
#获取普通线性回归模型预测值
linear_y_pred=linear.predict(x_test)
#评分
r2_score(y_test,linear_y_pred)
#获取岭回归模型预测值
ri_y_pred=ri.predict(x_test)
r2_score(y_test,ri_y_pred)
两种模型的评分差不多,说明使用岭回归去除一些不重要的特征数据后做出的预测和原来的差不多。
残差直方图
#绘制普通线性回归模型的残差直方图
plt.hist(y_test-linear_y_pred,bins=20)
#绘制岭回归的残差直方图
plt.hist(y_test-ri_y_pred,bins=20)
三、lasso回归
1、原理
拉格朗日乘数法】
对于参数w增加一个限定条件,能到达和岭回归一样的效果:
2、实例
1)导包
from sklearn.linear_model import Lasso
2)创建Lasso模型
#alpha值可以根据评分高低来调整,越低评分越高
la=Lasso(alpha=5)
3)训练模型
la.fit(x_train,y_train)
4)查看coef_
#比对lasso和岭回归模型系数缩减幅度
la.coef_
ri.coef_
coef_越低说明这个特征对目标数据影响越小,从两图可以看出lasso去除不重要的特征数据更多。
5)评分
#获取预测值
la_y_pred=la.predict(x_test)
#评分
r2_score(y_test,la_y_pred)
6)模型调优
la=Lasso(alpha=1)
la.fit(x_train,y_train)
la_y_pred=la.predict(x_test)
r2_score(y_test,la_y_pred)
7)绘制残差直方图
plt.hist(y_test-la_y_pred,bins=20)
残差直方图:越接近0说明预测的值和真实的值重合度越高。