Chapter 13 Linear Regression
前言
- 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记
- 学习的实战代码都放在代码压缩包中
- 实战代码的运行环境是python3.9 numpy 1.23.1 **anaconda 4.12.0 **
- 上一章:(97条消息) Machine Learning with Python Cookbook 学习笔记 第11章_五舍橘橘的博客-CSDN博客
- 代码仓库
13.0 Introduction
- 线性回归是我们工具包中最简单的监督学习算法之一。 如果你曾经在大学里上过统计学入门课程,那么你所涵盖的最后一个主题可能是线性回归。
- 事实上,当目标向量是定量值(例如房价、年龄)时,线性回归及其扩展仍然是一种常见且有用的预测方法。 在本章中,我们将介绍用于创建性能良好的预测模型的各种线性回归方法(和一些扩展)。
13.1 Fitting a Line
-
问题:特征和目标向量之间的线性关系的模型
-
scikit-learn
库 -
# 加载库 from sklearn.linear_model import LinearRegression from sklearn.datasets import fetch_california_housing # 加载加州房价 housing = fetch_california_housing() features = housing.data[:,0:2] target = housing.target # 创建线性回归模型 regression = LinearRegression() # 在线性模型中获取均值和方差 model = regression.fit(features, target) # 查看差值 print(model.intercept_) # 查看系数集合 print(model.coef_) # 进行预测 print(model.predict(features)[0])
Disscussion
线性回归假设特征和目标向量之间的关系是近似线性的。 也就是说,特征对目标向量的影响(也称为系数、权重或参数)是恒定的。 在我们的解决方案中,为了解释起见,我们只使用两个特征训练了我们的模型。 这意味着我们的线性模型将是:
y
^
=
β
^
0
+
β
^
1
x
1
+
β
^
2
x
2
+
ϵ
\hat y =\hat \beta_0 +\hat \beta_1 x_1 + \hat \beta_2 x_2 + \epsilon
y^=β^0+β^1x1+β^2x2+ϵ
-
其中 ŷ 是我们的目标,xi 是单个特征的数据,是通过拟合模型确定的系数, ϵ \epsilon ϵ是误差。 拟合模型后,我们可以查看每个参数的值。偏差或截距,可以使用intercept_ 查看
-
β ^ i \hat \beta_i β^i可以通过_coef查看
# 查看差值 print(model.intercept_) # 查看系数集合 print(model.coef_) # 进行预测 print(model.predict(features)[0])
-
优点:可解释性
关于scikit-learn的LinearRegression()的原理
1、模型公式: y ^ = X ω \hat y = X\omega y^=Xω
2、损失函数: Σ i = 1 m ( y i − y ^ i ) 2 \Sigma^m_{i=1}(y_i-\hat y_i)^2 Σi=1m(yi−y^i)2(SSE)
3、模型目标: m i n a r g ω ∣ ∣ y − X ω ∣ ∣ 2 min_{arg\ \omega} || y- X\omega||^2 minarg ω∣∣y−Xω∣∣2
4、矩阵求导: ∂ R S S ∂ ω = ∂ ( y − X ω ) T ( y − X ω ) ∂ ω = ∂ ( y T − ω T X T ) ( y − X ω ) ∂ ω = ∂ ( y T y − y T X ω − ω T X T y + ω T X T X ω ) ∂ ω = 0 − X T y − X T y + 2 X T X ω = 2 ( X T X ω − X T y ) = 0 \frac{\partial RSS}{\partial \omega}\\ =\frac{\partial(y-X\omega)^T(y-X\omega)}{\partial \omega} \\ =\frac{\partial (y^T-\omega ^TX^T)(y-X\omega)}{\partial \omega} \\=\frac{\partial (y^Ty-y^TX\omega -\omega^TX^Ty+\omega^TX^TX\omega)}{\partial \omega}\\ =0 - X^Ty-X^Ty +2X^TX\omega \\= 2(X^TX\omega -X^Ty) = 0 ∂ω∂RSS=∂ω∂(y−Xω)T(y−Xω)=∂ω∂(yT−ωTXT)(y−Xω)=∂ω∂(yTy−yTXω−ωTXTy+ωTXTXω)=0−XTy−XTy+2XTXω=2(XTXω−XTy)=0
ps.在求导处使用了如下规则:
- ∂ a ∂ t A = 0 \frac{\partial a}{\partial t A} =0 ∂tA∂a=0
- ∂ C T B A ∂ A = B T C \frac{\partial C^TBA}{\partial A} =B^TC ∂A∂CTBA=BTC
- ∂ A T B T C ∂ A = B T C \frac{\partial A^TB^TC}{\partial A} = B^TC ∂A∂ATBTC=BTC
- ∂ A T B T B A ∂ A = ( B + B T ) A \frac{\partial A^TB^TBA}{\partial A} = (B+B^T)A ∂A∂ATBTBA=(B+BT)A
5、 解方程:
X T X ω − X T y = 0 = > ω = ( X T X ) − 1 X T y X^TX\omega -X^Ty = 0 => \omega = (X^TX)^{-1}X^Ty XTXω−XTy=0=>ω=(XTX)−1XTy
前提是 X T X X^TX XTX可逆
13.2 Handling Interactive Effects
- 问题:某个特征对其他特征有依赖
- 创建一个interaction term(交互项)
# 加载库
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import PolynomialFeatures
# 加载加州房价
housing = fetch_california_housing()
features = housing.data[:, 0:2]
target = housing.target
# 创建交互项
interaction = PolynomialFeatures(
degree=3, include_bias=False, interaction_only=True)
features_interaction = interaction.fit_transform(features)
# 创建线性回归模型
regression = LinearRegression()
# Fit the linear regression
model = regression.fit(features_interaction, target)
Discussion
- 某些特征存在数据相关性,比如咖啡的甜度的因素中,搅拌和糖的量应该是相互依赖的
- 解决方案:创建一个包含交互特征的相应值的乘积的新特征来解释交互效应
y ^ = β ^ 0 + β ^ 1 x 1 + β ^ 2 x 2 + β ^ 3 x 1 x 2 + ϵ \hat y = \hat \beta_0 + \hat \beta_1x_1 + \hat\beta_2x_2+\hat\beta_3x_1x_2+\epsilon y^=β^0+β^1x1+β^2x2+β^3x1x2+ϵ
在这里 β ^ 3 x 1 x 2 \hat\beta_3x_1x_2 β^3x1x2就是新添加的交互项
-
我们一般用两个特征相乘来表达交叉项
-
PolynomialFeatures()可以创建交叉项
三个重要参数:
- interaction_only:只返回交叉项
- include_bias:是否在交叉项里计算bias
- degree:交叉项所拥有的最大特征数
13.3 Fitting a Nonlinear Relationship
- 拟合一个非线性关系
- 创建一个多项式回归
- noLinearRegression
# 加载库
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import fetch_california_housing
# 加载加州房价
housing = fetch_california_housing()
features = housing.data[:,0:2]
target = housing.target
# 多项式 x^2 and x^3
polynomial = PolynomialFeatures(degree=3, include_bias=False)
features_polynomial = polynomial.fit_transform(features)
# 创建线性关系
regression = LinearRegression()
# 拟合线性关系
model = regression.fit(features_polynomial, target)
Discussion
- y ^ = β ^ 0 + β ^ 1 x 1 + β ^ 2 x 2 2 + β ^ 3 x 3 3 + … … + β ^ d x i d + ϵ \hat y = \hat \beta_0 + \hat \beta_1x_1 + \hat\beta_2x_2^2+\hat\beta_3x_3^3+……+\hat\beta_dx_i^d+\epsilon y^=β^0+β^1x1+β^2x22+β^3x33+……+β^dxid+ϵ
- d是多项式的阶,
- 高阶的x实际上可以认为是新的特征
- 两个重要函数:
- degree多项式的阶
- include_bias:是否引入偏移
13.4 Reducing Variance with Regularization
-
减少线性模型的方差
-
Use a learning algorithm that includes a shrinkage penalty (also called regularization) like ridge regression and lasso regression(使用包含收缩惩罚(正则化)的算法,如
岭回归
和套索回归
) -
shrinkage_penalty.py
# Load libraries from sklearn.linear_model import Ridge from sklearn.datasets import fetch_california_housing from sklearn.preprocessing import StandardScaler # 加利福尼亚房价数据集 housing = fetch_california_housing() features = housing.data target = housing.target # 标准化 scaler = StandardScaler() features_standardized = scaler.fit_transform(features) # 岭回归 regression = Ridge(alpha=0.5) # 适用模型 model = regression.fit(features_standardized, target)
Discussion
-
传统线性模型的Loss函数:残差平方和: R S S = Σ i = 1 n ( y i − y ^ i ) 2 RSS=\Sigma_{i=1}^{n}(y_i-\hat y_i)^2 RSS=Σi=1n(yi−y^i)2
-
收缩惩罚(正则化)学习模型的损失函数与RSS相似,但是希望线性模型的系数可以尽可能的少。收缩惩罚的名称表示希望将模型缩小
-
有两种常用的正则化相信模型:岭回归和lasso回归。它们唯一的不同就是正则项的不同:
-
Ridge regression的损失函数: R S S + α Σ j = 1 p β ^ j 2 RSS + \alpha\Sigma_{j=1}^p \hat\beta_j^2 RSS+αΣj=1pβ^j2
β ^ j \hat\beta_j β^j是线性模型每一个变量前面的系数
-
Lasso regression的损失函数: 1 2 n R S S + α Σ j = 1 p ∣ β ^ j ∣ \frac{1}{2n}RSS+\alpha\Sigma_{j=1}^p|\hat\beta_j| 2n1RSS+αΣj=1p∣β^j∣
n是observation样本的数量
β ^ j \hat\beta_j β^j是线性模型每一个变量前面的系数
-
-
使用什么模型呢?
- 岭回归往往比lasso回归作出更好的预测
- lasso回归比岭回归更具有解释性
- 可以使用两者的结合
-
对于超参数 α \alpha α,决定了正则项的权重,在scikit包中,作为alpha参数输入模型中
-
我们可以使用scikit-learn中的
RigerCV
使用交叉检验法把 α \alpha α作为参数进行训练
# Load library
from sklearn.linear_model import RidgeCV
# 创建一系列的alpha参数,使用交叉检验法进行比较
regr_cv = RidgeCV(alphas=[0.1, 1.0, 10.0])
# 拟合模型
model_cv = regr_cv.fit(features_standardized, target)
# 查看结果
print(model_cv.coef_)
print(model_cv.alpha_)
- 最后:因为系数的值由实际特征的比例决定,所以最好在使用正则化之前进行一定的标准化
13.5 Reducing Features with Lasso Regression
- You want to simplify your linear regression model by reducing the number of features.
- 使用lasso模型:
lasso_regression.py
# 加载python库
from sklearn.linear_model import Lasso
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler
# 加利福尼亚房价数据集
housing = fetch_california_housing()
features = housing.data
target = housing.target
# 标准化数据
scaler = StandardScaler()
features_standardized = scaler.fit_transform(features)
# Create lasso regression with alpha value
regression = Lasso(alpha=0.5)
# Fit the linear regression
model = regression.fit(features_standardized, target)
Discussion
-
lasso回归模型是可以直接将系数降为0的
# 0.5的系数 print(model.coef_) # 设置一个新模型为alpha=10 regression_10 = Lasso(alpha=10) model = regression_10.fit(features_standardized, target) print(model.coef_)
-
这种效果的实际好处是,它意味着我们可以在特征矩阵中包含100个特征,然后通过调整拉索的α超参数,生成一个只使用10个(例如)最重要特征的模型。这使我们能够减少差异,同时提高模型的可解释性(因为较少的特征更容易解释)