scikit-learn 线性回归 原理与使用

一、 普通线性回归

原理:最小二乘法
假定输人数据存放在矩阵X中,而回归系数存放在向量W中。那么对于给定的数据X1, 预测结果将会通过Y=X*W给出。有一些X和对应的Y,怎样才能找到W呢?一个常用的方法就是找出使误差最小的W。这里的误差是指预测Y值和真实Y值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以我 们采用平方误差。

(y - w*x)^2     
y^2 - 2*w*x*y + x^2*w^2
-2xy + 2x^2*w = 0
-y + wx = 0
xw = y
xTxw = xTy         # 两边乘以xT 转置矩阵
w = (xTx)^-1(xTy) # 平方和最小的情况:w在求导时为0 

import numpy as np
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
import sklearn.datasets as datasets
from sklearn.metrics import r2_score
diabetes = datasets.load_diabetes()
data = diabetes.data
target = diabetes.target
feature_names = diabetes.feature_names
samples = DataFrame(data = data, columns = feature_names)       # 将ndarray数据转成DataFrame (442, 10)

X_train = samples[:400]       # (400, 10)
y_train = target[:400]        # (400,)
X_test = samples[400:]        # (42, 10)
y_test = target[400:]         # (42,)

linear = LinearRegression()       # 创建数学模型
linear.fit(X_train,y_train)       # 训练数据
y_ = linear_predict(X_test)       # 进行预测
plt.plot(y_test)                  # 绘制图像
plt.plot(y_)            
r2_score(y_test,y_)               # 给线性模型打分 
linear.score(X_test,y_test)

#另一种构造X_test的方法
xmin,xmax = X_train.min(), X_train.max()
X_test = np.linspace(xmin,xmax,100).reshape(-1,1)     # (100,1)
y_ = linear_predict(X_test)    
plt.plot(X_test,y_,color = "red")
plt.scatter(X_train,y_train,alpha = 0.6)

二、 岭回归
原理:加了二阶正则项(lambdaI)的最小二乘
由于非满秩矩阵在求逆时会出现问题,岭回归在矩阵xTx上加一个λI从而使得矩阵非奇异(其中矩阵I是一个m
m的单位矩阵,对角线上元素全为1,其他元素全为0),进而能对xTx+λI求逆。
linear和ridge在处理不存在过拟合的情况下或者是共线性的情况下,效果是一样的(如果岭回归的参数不是alpha = 0的情况下, 线性回归和领回归的系数一样的,就证明数据不存在过拟合)

实现方法:缩减系数(通过引入λ来限制所有w之和,通过引入该惩罚项,能够减少不重要的参数。)

使用场景:过拟合严重或各变量之间存在多重共线性的情况(数据特征比样本点多的情况)。

f(x) = wx +b
x1w1 + x2w2+ x3w3 = y1
1*w1 + 2*w2 + 3*w3 = 5
3*w1 + 1*w2 + 5*w3 = 11
2*w1 + 4*w2 + 6*w3 = 10

1   2   3       1  0  0       1+0.1  2     3
3   1   5 + 0.1*0  1  0 == >  3      1+0.1 5
2   4   6       0  0  1       2      4     6+0.1

from sklearn.linear_model import Ridge
# 一个简单的栗子:
ridge = Ridge(alpha=0,1)    # alpha参数就是缩进系数的λ,alpha=0时就是一个普通的线性回归
ridge.fit(X_train,y_train)
ridge.score(X_test,y_test)
ridge.coef_                 # 查看岭回归的模型系数,coef_用来获取机器学习中各个特征的系数  比如,有4列数据将获得4个系数
# 获取最优的训练模型系数:
X_train = 1/(np.arange(1,11,1) + np.arange(0,10,1).reshape(-1,1))           # 创建一个数据集合  (10,10)
alphas = np.logspace(-10,-2,100)          # 返回以对数刻度均匀间隔的数字

coefs = []            # 创建一个coefs数组,保存所有训练模型的系数
for alpha in alphas:
    ridge.set_params(alpha = alpha)      # 设置岭回归lambda系数
    ridge.fit(X_train,y_train)           # 训练模型
    coefs.append(ridge.coef_)            # 获取训练模型的系数

#绘图查看alphas和coefs的关系,从而选取最优系数区间
%matplotlib inline
plt.figure(figsize=(10,10))
axes = plt.subplot(111)           
axes.plot(alphas, coefs)
axes.set_xscale("log")             # 设置x轴单位
#设置一下x轴的刻度

三、 lasso回归
原理:拉格朗日乘数法
对于参数w增加一个限定条件,能到达和岭回归一样的效果,在λ足够小的时候,一些系数会被迫缩减到0。

使用场景:同岭回归(lasso回归具有更强的缩减系数的能力)

from sklearn.linear_model import Lasso

使用较少,此处不做介绍,参考下面三种线性回归比较


四、 普通线性回归、岭回归与lasso回归比较
具体操作:使用numpy创建数据X,创建系数,对系数进行处理,对部分系数进行归零化操作,然后根据系数进行矩阵操作求得目标值

data = np.random.randint(0,10,size=(10,10))            # 创建数据
coef = np.random.random(size=10).reshape(-1,1)         # 创建真实系数 (10, 1)
coef[::2] = 0            # 对系数进行处理
target = np.dot(data, coef)         # 目标值
noise = (0.5-np.random.random(size=10))*10        # 添加噪声
target += noise.reshape(-1,1)

linear = LinearRegression()
ridge = Ridge(alpha = 0.001)
lasso = Lasso(alpha = 10)

# 绘图
plt.plot(coef,label = 'True')       # 真实系数

linear.fit(data,target)
linear_coef = linear.coef_           # (1, 10)
plt.plot(linear_coef[0],label='linear')

ridge.fit(data,target)
ridge_coef = ridge.coef_
plt.plot(ridge_coef[0],label='ridge')

lasso.fit(data,target)
lasso_coef = lasso.coef_
plt.plot(lasso_coef,label='lasso')
plt.legend()                     # 在轴上放一个图例。

猜你喜欢

转载自blog.csdn.net/qq_37212752/article/details/83151495