sklearn 线性回归
1 多元线性回归LinearRegression原理建模评估指标2 岭回归建模Ridge专门的选择最好alpha的交叉验证3 Lasso 的核心作用:特征选择4 多项式回归多项式回归提升模型表现1 多元线性回归LinearRegression原理线性回归是机器学习中最简单的回归算法,多元线性回归指的就是一个样本有多个特征的线性回归问题。对于一个n有 i 个特征的样本 而言,它的回归结果可以写作一个
1 多元线性回归LinearRegression
原理
线性回归是机器学习中最简单的回归算法,多元线性回归指的就是一个样本有多个特征的线性回归问题。对于一个n有 i 个特征的样本 而言,它的回归结果可以写作一个几乎人人熟悉的方程:
在多元线性回归中,我们的损失函数如下定义:
我们的损失函数是L2范式,即欧式距离的平方结果,在sklearn所有官方文档和网页上,我们都称之为RSS残差平方和
最小二乘法求解多元线性回归的参数 :
现在问题转换成了求解让RSS最小化的参数向量 ,这种通过最小化真实值和预测值之间的RSS来求解参数的方法叫做最小二乘法。
最小二乘法的过程非常简单。求解极值的第一步往往是求解一阶导数并让一阶导数等于0,最小二乘法也不能免俗。因此,我们现在残差平方和RSS上对参数向量w求导:
建模
class sklearn.linear_model.LinearRegression
(fit_intercept=True, normalize=False, copy_X=True,n_jobs=None)
没有对我们的模型有不可替代作用的参数,这说明,线性回归的性能,往往取决于数据本身,而并非是我们的调参能力,线性回归也因此对数据有着很高的要求
- 导入需要的模块和库
from sklearn.linear_model import LinearRegression as LR
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch #加利福尼亚房屋价值数据集
import pandas as pd
housevalue = fch() #会需要下载,大家可以提前运行试试看
X = pd.DataFrame(housevalue.data) #放入DataFrame中便于查看
y = housevalue.target
- 导入数据,探索数据
X.shape
y.shape
X.head()
housevalue.feature_names
X.columns = housevalue.feature_names
X.head()
- 分训练集和测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
# 恢复索引
for i in [Xtrain, Xtest]:
i.index = range(i.shape[0])
Xtrain.shape
- 建模
reg = LR().fit(Xtrain, Ytrain)
- 探索建好的模型
yhat = reg.predict(Xtest)
yhat
reg.coef_
[*zip(Xtrain.columns,reg.coef_)]
reg.intercept_
评估指标
MSE :
sklearn中使用RSS的变体,均方误差MSE(mean squared error)来衡量我们的预测值和真实值的差异:
注意没有
cross_val_score(reg,X,y,cv=10,scoring=“mean_squared_error”)
只有:
cross_val_score(reg,X,y,cv=10,scoring=“neg_mean_squared_error”)
#查看都有哪些参数
import sklearn
sorted(sklearn.metrics.SCORERS.keys())
两种方法调用:
# 1
from sklearn.metrics import mean_squared_error as MSE
MSE(yhat,Ytest)
y.max()
y.min()
# 2
cross_val_score(reg,X,y,cv=10,scoring="neg_mean_squared_error")
均方误差MSE为负?
sklearn中的参数scoring下,均方误差作为评判标准时,是计算”负均方误差“(neg_mean_squared_error),真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字
对于某些拟合模型,如果我们使用MSE来对它进行判断,它的MSE会很小,当大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦我的新样本是处于拟合曲线的后半段的,我的预测结果必然会有巨大的偏差,而这不是我们希望看到的。所以,我们希望找到新的指标,除了判断预测的数值是否正确之外,还能够判断我们的模型是否拟合了足够多的,数值之外的信息
R^2:
和可解释性方差分数(explained_variance_score,EVS)
r2_score(真实值,预测值) # 顺序不可颠倒
from sklearn.metrics import r2_score
r2_score(Ytest,yhat)
#或者直接指定参数
r2_score(y_true = Ytest,y_pred = yhat)
score 的值是测试的x和y
r2 = reg.score(Xtest,Ytest)
我们观察到,虽然我们在加利福尼亚房子价值数据集上的MSE相当小,但我们的 却不高,这证明我们的模型比较好地拟合了数据的数值,却没有能正确拟合数据的分布。让我们与绘图来看看,究竟是不是这样一回事。我们可以绘制一张图上的两条曲线,一条曲线是我们的真实标签Ytest,另一条曲线是我们的预测结果yhat,两条曲线的交叠越多,我们的模型拟合就越好
import matplotlib.pyplot as plt
# sorted(Ytest)
plt.plot(range(len(Ytest)),sorted(Ytest),c="black",label= "Data")
plt.plot(range(len(yhat)),sorted(yhat),c="red",label = "Predict")
plt.legend()
plt.show()
可见,虽然我们的大部分数据被拟合得比较好,但是图像的开头和结尾处却又着较大的拟合误差。如果我们在图像右侧分布着更多的数据,我们的模型就会越来越偏离我们真正的标签。这种结果类似于我们前面提到的,虽然在有限的数据集上将数值预测正确了,但却没有正确拟合数据的分布,如果有更多的数据进入我们的模型,那数据标签被预测错误的可能性是非常大的。
r2 显示为负?
当我们的r2 显示为负的时候,这证明我们的模型对我们的数据的拟合非常糟糕,模型完全不能使用。所有,一个负的是合理的。当然了,现实应用中,如果你发现你的线性回归模型出现了负的 ,不代表你就要接受他了,首先检查你的建模过程和数据处理过程是否正确,也许你已经伤害了数据本身,也许你的建模过程是存在bug的。如果你检查了所有的代码,也确定了你的预处理没有问题,但你的 也还是负的,那这就证明,线性回归模型不适合你的数据,试试看其他的算法吧。
2 岭回归
这算法不是为了提升模型表现,而是为而设计的(实际上,我们使用岭回归或者Lasso,模型的效果往往会下降一些,因为我们删除了一小部分特征
建模
岭回归的损失函数:
求导之后
多重共线性可以被控制住了︰最小二乘法一定有解,并且这个解可以通过α来进行调节,以确保不会偏离太多。当然了,α挤占了w中由原始的特征矩阵贡献的空间,因此α如果太大,也会导致w的估计出现较大的偏移,无法正确拟合数据的真实面貌。我们在使用中,需要找出α让模型效果变好的最佳取值。
在sklearn中,岭回归由线性模型库中的Ridge类来调用:
class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,
normalize=False, copy_X=True,max_iter=None, tol=0.001, solver=auto’ ,
random_state=None)
重新导入数据后
from sklearn.linear_model import Ridge
reg = Ridge(alpha=1).fit(Xtrain, Ytrain)
reg.score(Xtest,Ytest)
#交叉验证下,与线性回归相比,岭回归的结果如何变化?
import numpy as np
alpharange =np.arange(1,1001,100)
ridge ,lr=[],[]
for alpha in alpharange:
reg=Ridge(alpha=alpha)
linear=LR()
regs=cross_val_score(reg,X,y,cv=5,scoring='r2').mean()
linears=cross_val_score( linear,X,y,cv=5,scoring='r2').mean()
ridge.append(regs)
lr.append(linears)
plt.plot(alpharange,ridge,color="red",label="Ridge")
plt.plot(alpharange,lr,color="blue",label="LR")
plt.legend()
plt.show()
可以逐渐逼近最高点,但在本数据中即使找到最高的alpha,模型也没有提升
看看方差:
import numpy as np
alpharange =np.arange(1,1001,100)
ridge ,lr=[],[]
for alpha in alpharange:
reg=Ridge(alpha=alpha)
linear=LR()
regs=cross_val_score(reg,X,y,cv=5,scoring='r2').var()
linears=cross_val_score( linear,X,y,cv=5,scoring='r2').var()
ridge.append(regs)
lr.append(linears)
plt.plot(alpharange,ridge,color="red",label="Ridge")
plt.plot(alpharange,lr,color="blue",label="LR")
plt.legend()
plt.show()
Ridge专门的选择最好alpha的交叉验证
class sklearn. linear_model. Ridgecv(alphas=(0.1,1.0,10.0), fit
intercept=True, normalize=False,scoring=None,cv=None,store_cv _values=False)
from sklearn.linear_model import RidgeCV
Ridge_=RidgeCV(alphas=np. arange(1,1001,100)
#, scoring="neg_mean_squared_error"
, store_cv_values=True
#, cv=5
). fit(X,y)
#不交叉验证的结果
Ridge_.score(X,y)
#每个alpha下的结果
Ridge_.cv_values_.mean(axis=0)
# 选择的最佳值
Ridge_.alpha_
3 Lasso 的核心作用:特征选择
这里不详细说了
4 多项式回归
普遍的用于解决"线性回归只能处理线性数据"问题的手段
class sklearn.preprocessing.Po1ynomialFeatures(degree=2,
interaction_only=False, include_bias=True)
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
X=np.arange(1,4).reshape(-1,1)
x=PolynomialFeatures(degree=3,include_bias).fit_transform(X)
rnd = np.random.RandomState(42)#设置随机数种子
y=rnd.randn(3)
y
#LR().fit(x,y).coef_
#LR().fit(x,y).intercept_
LR(fit_intercept=False).fit(x,y).coef_
LR(fit_intercept=False).fit(x,y).intercept_
多项式回归提升模型表现
from sklearn.preprocessing import PolynomialFeatures as PF
from sklearn.linear_model import LinearRegression
import numpy as np
rnd =np.random.RandomState(42)#设置随机数种子
X=rnd.uniform(-3,3,size=100)
X=X.reshape(-1,1)#将X升维,准备好放入skLearn中
y=np.sin(X)+rnd.normal(size=len(X))/3
line=np.linspace(-3,3,1000,endpoint=False).reshape(-1,1) #测试数据
reg=LinearRegression().fit(X,y)
reg.score(X,y)
#进行高次项转换
poly = PF(degree=4)
X_= poly.fit_transform(X)
line_ = poly.transform(line)
#拟合
LinearR_ = LinearRegression( ).fit(X_, y)
#打分
LinearR_.score(X_,y)
LinearR_.score(line_,np.sin(line))
更多推荐
所有评论(0)