2.1 使用sklearn构建完整的回归项目
from sklearn import datasets
import pandas as pd
boston = datasets.load_boston() # 返回一个类似于字典的类
X = boston.data # 取出特征
y = boston.target # 取出标签
features = boston.feature_names # 取出特征名称
boston_data = pd.DataFrame(X,columns=features)
boston_data['Price'] = y # 因为预测房价背景信息,所以列名起为Price
boston_data.head() # 查看boston_data数据前几行,这个看自己的参数设置,我是5行
CRIM | ZN | INDUS | CHAS | NOX | RM | AGE | DIS | RAD | TAX | PTRATIO | B | LSTAT | Price | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0.0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1.0 | 296.0 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0.0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2.0 | 242.0 | 17.8 | 396.90 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0.0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2.0 | 242.0 | 17.8 | 392.83 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0.0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3.0 | 222.0 | 18.7 | 394.63 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0.0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3.0 | 222.0 | 18.7 | 396.90 | 5.33 | 36.2 |
线性回归模型的损失函数解释
(3) 选择具体的模型并进行训练
- 线性回归模型
回归这个概念是19世纪80年代由英国统计学家郎西斯.高尔顿在研究父子身高关系提出来的,他发现:在同一族群中,子代的平均身高介于父代的身高以及族群的平均身高之间。具体而言,高个子父亲的儿子的身高有低于其父亲身高的趋势,而矮个子父亲的儿子身高则有高于父亲的身高的趋势。也就是说,子代的身高有向族群平均身高"平均"的趋势,这就是统计学上"回归"的最初含义。回归分析是一种预测性的建模技术,它研究的是因变量(目标)和自变量(特征)之间的关系。这种技术通常用于预测分析,时间序列模型以及发现变量之间的因果关系。通常使用曲线/线来拟合数据点,目标是使曲线到数据点的距离差异最小。而线性回归就是回归问题中的一种,线性回归假设目标值与特征之间线性相关,即满足一个多元一次方程。通过构建损失函数,来求解损失函数最小时的参数w :
假设:数据集 D = { ( x 1 , y 1 ) , . . . , ( x N , y N ) } D = \{(x_1,y_1),...,(x_N,y_N) \} D={(x1,y1),...,(xN,yN)}, x i ∈ R p , y i ∈ R , i = 1 , 2 , . . . , N x_i \in R^p,y_i \in R,i = 1,2,...,N xi∈Rp,yi∈R,i=1,2,...,N, X = ( x 1 , x 2 , . . . , x N ) T , Y = ( y 1 , y 2 , . . . , y N ) T X = (x_1,x_2,...,x_N)^T,Y=(y_1,y_2,...,y_N)^T X=(x1,x2,...,xN)T,Y=(y1,y2,...,yN)T
假设X和Y之间存在线性关系,模型的具体形式为 y ^ = f ( w ) = w T x \hat{y}=f(w) =w^Tx y^=f(w)=wTx
(a) 最小二乘估计:
我们需要衡量真实值
y
i
y_i
yi与线性回归模型的预测值
w
T
x
i
w^Tx_i
wTxi之间的差距,在这里我们和使用二范数的平方和L(w)来描述这种差距,即:
L
(
w
)
=
∑
i
=
1
N
∣
∣
w
T
x
i
−
y
i
∣
∣
2
2
=
∑
i
=
1
N
(
w
T
x
i
−
y
i
)
2
=
(
w
T
X
T
−
Y
T
)
(
w
T
X
T
−
Y
T
)
T
=
w
T
X
T
X
w
−
2
w
T
X
T
Y
+
Y
Y
T
因
此
,
我
们
需
要
找
到
使
得
L
(
w
)
最
小
时
对
应
的
参
数
w
,
即
:
w
^
=
a
r
g
m
i
n
L
(
w
)
为
了
达
到
求
解
最
小
化
L
(
w
)
问
题
,
我
们
应
用
高
等
数
学
的
知
识
,
使
用
求
导
来
解
决
这
个
问
题
:
∂
L
(
w
)
∂
w
=
2
X
T
X
w
−
2
X
T
Y
=
0
,
因
此
:
w
^
=
(
X
T
X
)
−
1
X
T
Y
L(w) = \sum\limits_{i=1}^{N}||w^Tx_i-y_i||_2^2=\sum\limits_{i=1}^{N}(w^Tx_i-y_i)^2 = (w^TX^T-Y^T)(w^TX^T-Y^T)^T = w^TX^TXw - 2w^TX^TY+YY^T\\ 因此,我们需要找到使得L(w)最小时对应的参数w,即:\\ \hat{w} = argmin\;L(w)\\ 为了达到求解最小化L(w)问题,我们应用高等数学的知识,使用求导来解决这个问题: \\ \frac{\partial L(w)}{\partial w} = 2X^TXw-2X^TY = 0,因此: \\ \hat{w} = (X^TX)^{-1}X^TY
L(w)=i=1∑N∣∣wTxi−yi∣∣22=i=1∑N(wTxi−yi)2=(wTXT−YT)(wTXT−YT)T=wTXTXw−2wTXTY+YYT因此,我们需要找到使得L(w)最小时对应的参数w,即:w^=argminL(w)为了达到求解最小化L(w)问题,我们应用高等数学的知识,使用求导来解决这个问题:∂w∂L(w)=2XTXw−2XTY=0,因此:w^=(XTX)−1XTY
(b) 几何解释:
在线性代数中,我们知道两个向量a和b相互垂直可以得出:
<
a
,
b
>
=
a
.
b
=
a
T
b
=
0
<a,b> = a.b = a^Tb = 0
<a,b>=a.b=aTb=0,而平面X的法向量为Y-Xw,与平面X互相垂直,因此:
X
T
(
Y
−
X
w
)
=
0
X^T(Y-Xw) = 0
XT(Y−Xw)=0,即:
w
=
(
X
T
X
)
−
1
X
T
Y
w = (X^TX)^{-1}X^TY
w=(XTX)−1XTY
© 概率视角:
假设噪声
ϵ
∽
N
(
0
,
σ
2
)
,
y
=
f
(
w
)
+
ϵ
=
w
T
x
+
ϵ
\epsilon \backsim N(0,\sigma^2),y=f(w)+\epsilon=w^Tx+\epsilon
ϵ∽N(0,σ2),y=f(w)+ϵ=wTx+ϵ,因此:
y
∣
x
i
,
w
N
(
w
T
x
,
σ
2
)
y|x_i,w ~ N(w^Tx,\sigma^2)
y∣xi,w N(wTx,σ2)
我们使用极大似然估计MLE对参数w进行估计:
L
(
w
)
=
l
o
g
P
(
Y
∣
X
;
w
)
=
l
o
g
∏
i
=
1
N
P
(
y
i
∣
x
i
;
w
)
=
∑
i
=
1
N
l
o
g
P
(
y
i
∣
x
i
;
w
)
=
∑
i
=
1
N
l
o
g
(
1
2
π
σ
e
x
p
(
−
(
y
i
−
w
T
x
i
)
2
2
σ
2
)
)
=
∑
i
=
1
N
[
l
o
g
(
1
2
π
σ
)
−
1
2
σ
2
(
y
i
−
w
T
x
i
)
2
]
a
r
g
m
a
x
w
L
(
w
)
=
a
r
g
m
i
n
w
[
l
(
w
)
=
∑
i
=
1
N
(
y
i
−
w
T
x
i
)
2
]
因
此
:
线
性
回
归
的
最
小
二
乘
估
计
<
=
=
>
噪
声
ϵ
∽
N
(
0
,
σ
2
)
的
极
大
似
然
估
计
L(w) = log\;P(Y|X;w) = log\;\prod_{i=1}^N P(y_i|x_i;w) = \sum\limits_{i=1}^{N} log\; P(y_i|x_i;w)\\ = \sum\limits_{i=1}^{N}log(\frac{1}{\sqrt{2\pi \sigma}}exp(-\frac{(y_i-w^Tx_i)^2}{2\sigma^2})) = \sum\limits_{i=1}^{N}[log(\frac{1}{\sqrt{2\pi}\sigma})-\frac{1}{2\sigma^2}(y_i-w^Tx_i)^2] \\ argmax_w L(w) = argmin_w[l(w) = \sum\limits_{i = 1}^{N}(y_i-w^Tx_i)^2]\\ 因此:线性回归的最小二乘估计<==>噪声\epsilon\backsim N(0,\sigma^2)的极大似然估计
L(w)=logP(Y∣X;w)=logi=1∏NP(yi∣xi;w)=i=1∑NlogP(yi∣xi;w)=i=1∑Nlog(2πσ1exp(−2σ2(yi−wTxi)2))=i=1∑N[log(2πσ1)−2σ21(yi−wTxi)2]argmaxwL(w)=argminw[l(w)=i=1∑N(yi−wTxi)2]因此:线性回归的最小二乘估计<==>噪声ϵ∽N(0,σ2)的极大似然估计
小结
- 几何解释和概率解释看不懂 # 一定是我太菜了
- 这些解释和模型训练过程中出现过拟合,解决方法有L1,L2正则化的解释类似–>为什么正则项可以防止模型过拟合?–>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lJla6w9M-1616057552321)(./my_1.png)]
图像解释 - L1和L2加入后的函数图像:
贝叶斯先验概率的角度:
正则化之所以能够降低过拟合的原因在于,正则化是结构风险最小化的一种策略实现。给loss function加上正则化项,能使得新得到的优化目标函数h = f+normal,需要在f和normal中做一个权衡(trade-off),如果还像原来只优化f的情况下,那可能得到一组解比较复杂,使得正则项normal比较大,那么h就不是最优的,因此可以看出加正则项能让解更加简单,符合奥卡姆剃刀理论,同时也比较符合在偏差和方差(方差表示模型的复杂度)分析中,通过降低模型复杂度,得到更小的泛化误差,降低过拟合程度。 - L1正则化和L2正则化:
L1正则化就是在loss function后边所加正则项为L1范数,加上L1范数容易得到稀疏解(0比较多)。L2正则化就是loss function后边所加正则项为L2范数的平方,加上L2正则相比于L1正则来说,得到的解比较平滑(不是稀疏),但是同样能够保证解中接近于0(但不是等于0,所以相对平滑)的维度比较多,降低模型的复杂度。
:参考链接
- 使用sklearn的线性回归示例来演示
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression
from sklearn import linear_model # 引入线性回归方法
lin_reg = linear_model.LinearRegression() # 创建线性回归的类
lin_reg.fit(X,y) # 输入特征X和因变量y进行训练
print("模型系数:",lin_reg.coef_) # 输出模型的系数
print("模型得分:",lin_reg.score(X,y)) # 输出模型的决定系数R^2
模型系数: [-1.08011358e-01 4.64204584e-02 2.05586264e-02 2.68673382e+00
-1.77666112e+01 3.80986521e+00 6.92224640e-04 -1.47556685e+00
3.06049479e-01 -1.23345939e-02 -9.52747232e-01 9.31168327e-03
-5.24758378e-01]
模型得分: 0.7406426641094095
-
线性回归的推广
- 线性回归的推广
在线性回归中,我们假设因变量与特征之间的关系是线性关系,这样的假设使得模型很简单,但是缺点也是显然的,那就是当数据存在非线性关系时,我们使用线性回归模型进行预测会导致预测性能极其低下,因为模型的形式本身是线性的,无法表达数据中的非线性关系。我们一个很自然的想法就是去推广线性回归模型,使得推广后的模型更能表达非线性的关系。
(a) 多项式回归:
为了体现因变量和特征的非线性关系,一个很自然而然的想法就是将标准的线性回归模型:
y i = w 0 + w 1 x i + ϵ i y_i = w_0 + w_1x_i + \epsilon_i yi=w0+w1xi+ϵi
换成一个多项式函数:
y i = w 0 + w 1 x i + w 2 x i 2 + . . . + w d x i d + ϵ y_i = w_0 + w_1x_i + w_2x_i^2 + ...+w_dx_i^d + \epsilon yi=w0+w1xi+w2xi2+...+wdxid+ϵ
对于多项式的阶数d不能取过大,一般不大于3或者4,因为d越大,多项式曲线就会越光滑,在X的边界处有异常的波动。(图中的边界处的4阶多项式拟合曲线的置信区间(虚线表示置信区间)明显增大,预测效果的稳定性下降。)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2a4PeLqF-1616057552327)(./1.6.1.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34BF71lc-1616057552328)(./1.6.2.png)]
(b) 广义可加模型(GAM):
广义可加模型GAM实际上是线性模型推广至非线性模型的一个框架,在这个框架中,每一个变量都用一个非线性函数来代替,但是模型本身保持整体可加性。GAM模型不仅仅可以用在线性回归的推广,还可以将线性分类模型进行推广。具体的推广形式是:
标准的线性回归模型:
y i = w 0 + w 1 x i 1 + . . . + w p x i p + ϵ i y_i = w_0 + w_1x_{i1} +...+w_px_{ip} + \epsilon_i yi=w0+w1xi1+...+wpxip+ϵi
GAM模型框架:
y i = w 0 + ∑ j = 1 p f j ( x i j ) + ϵ i y_i = w_0 + \sum\limits_{j=1}^{p}f_{j}(x_{ij}) + \epsilon_i yi=w0+j=1∑pfj(xij)+ϵi
GAM模型的优点与不足:
- 优点:简单容易操作,能够很自然地推广线性回归模型至非线性模型,使得模型的预测精度有所上升;由于模型本身是可加的,因此GAM还是能像线性回归模型一样把其他因素控制不变的情况下单独对某个变量进行推断,极大地保留了线性回归的易于推断的性质。
- 缺点:GAM模型会经常忽略一些有意义的交互作用,比如某两个特征共同影响因变量,不过GAM还是能像线性回归一样加入交互项 x ( i ) × x ( j ) x^{(i)} \times x^{(j)} x(i)×x(j)的形式进行建模;但是GAM模型本质上还是一个可加模型,如果我们能摆脱可加性模型形式,可能还会提升模型预测精度,详情请看后面的算法。 - 线性回归的推广
(a) 多项式回归实例介绍:
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html?highlight=poly#sklearn.preprocessing.PolynomialFeatures
sklearn.preprocessing.PolynomialFeatures(degree=2, *, interaction_only=False, include_bias=True, order=‘C’):
参数:
degree:特征转换的阶数。
interaction_onlyboolean:是否只包含交互项,默认False 。
include_bias:是否包含截距项,默认True。
order:str in {‘C’, ‘F’}, default ‘C’,输出数组的顺序。
from sklearn.preprocessing import PolynomialFeatures
X_arr = np.arange(6).reshape(3, 2)
print("原始X为:\n",X_arr)
poly = PolynomialFeatures(2)
print("2次转化X:\n",poly.fit_transform(X_arr))
poly = PolynomialFeatures(interaction_only=True)
print("2次转化X:\n",poly.fit_transform(X_arr))
原始X为:
[[0 1]
[2 3]
[4 5]]
2次转化X:
[[ 1. 0. 1. 0. 0. 1.]
[ 1. 2. 3. 4. 6. 9.]
[ 1. 4. 5. 16. 20. 25.]]
2次转化X:
[[ 1. 0. 1. 0.]
[ 1. 2. 3. 6.]
[ 1. 4. 5. 20.]]
(b) GAM模型实例介绍:
安装pygam:pip install pygam
https://github.com/dswah/pyGAM/blob/master/doc/source/notebooks/quick_start.ipynb
from pygam import LinearGAM
gam = LinearGAM().fit(boston_data[boston.feature_names], y)
gam.summary()
LinearGAM
=============================================== ==========================================================
Distribution: NormalDist Effective DoF: 103.2423
Link Function: IdentityLink Log Likelihood: -1589.7653
Number of Samples: 506 AIC: 3388.0152
AICc: 3442.7649
GCV: 13.7683
Scale: 8.8269
Pseudo R-Squared: 0.9168
==========================================================================================================
Feature Function Lambda Rank EDoF P > x Sig. Code
================================= ==================== ============ ============ ============ ============
s(0) [0.6] 20 11.1 2.20e-11 ***
s(1) [0.6] 20 12.8 8.15e-02 .
s(2) [0.6] 20 13.5 2.59e-03 **
s(3) [0.6] 20 3.8 2.76e-01
s(4) [0.6] 20 11.4 1.11e-16 ***
s(5) [0.6] 20 10.1 1.11e-16 ***
s(6) [0.6] 20 10.4 8.22e-01
s(7) [0.6] 20 8.5 4.44e-16 ***
s(8) [0.6] 20 3.5 5.96e-03 **
s(9) [0.6] 20 3.4 1.33e-09 ***
s(10) [0.6] 20 1.8 3.26e-03 **
s(11) [0.6] 20 6.4 6.25e-02 .
s(12) [0.6] 20 6.5 1.11e-16 ***
intercept 1 0.0 2.23e-13 ***
==========================================================================================================
Significance codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
WARNING: Fitting splines and a linear function to a feature introduces a model identifiability problem
which can cause p-values to appear significant when they are not.
WARNING: p-values calculated in this manner behave correctly for un-penalized models or models with
known smoothing parameters, but when smoothing parameters have been estimated, the p-values
are typically lower than they should be, meaning that the tests reject the null too readily.
<ipython-input-15-bb049c74476f>:3: UserWarning: KNOWN BUG: p-values computed in this summary are likely much smaller than they should be.
Please do not make inferences based on these values!
Collaborate on a solution, and stay up to date at:
github.com/dswah/pyGAM/issues/163
gam.summary()
回归树与线性模型的比较:
- 模型形式有着本质的区别, f ( x ) = w 0 + ∑ j = 1 p w j x ( j ) f(x) = w_0 + \sum\limits_{j=1}^{p}w_jx^{(j)} f(x)=w0+j=1∑pwjx(j),而回归树则是 f ( x ) = ∑ m = 1 J c ^ m I ( x ∈ R m ) f(x) = \sum\limits_{m=1}^{J}\hat{c}_mI(x \in R_m) f(x)=m=1∑Jc^mI(x∈Rm)
- 如果特征变量与因变量的关系能很好的用线性关系来表达,那么线性回归通常有着不错的预测效果,拟合的效果优于不能揭示线性结构的回归树。反之,如果特征变量与因变量的关系呈现高度复杂的非线性,那么树方法比传统方法更优。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ftlprJ9V-1616057552330)(./1.9.1.png)]
树模型的优缺点:
优点:
- 树模型的解释强,在解释性方面可能比线性回归还要方便。
- 树模型更接近人的决策方式。
- 树模型可以用图来表示,非专业人士也可以轻松解读。
- 树模型可以做定性的特征而不需要像线性回归一样哑元化。
- 树模型能很好处理缺失值和异常值,对异常值不敏感,但是这个对线性模型来说却是致命的。
缺点: - 树模型的预测准确性一般无法达到其他回归模型的水平,但是改进的方法很多
- 决策树模型是一种“弱学习器”,即使通过调优方法进行了优化。也仍然容易产生过拟合的现象,造成最终结果误差较大,并且在处理特征关联性比较强的数据时表现得不是很好。
sklearn使用回归树的实例:
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeRegressor.html?highlight=tree#sklearn.tree.DecisionTreeRegressor
sklearn.tree.DecisionTreeRegressor(*, criterion=‘mse’, splitter=‘best’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, presort=‘deprecated’, ccp_alpha=0.0)
- 参数 (列举几个重要的,常用的,详细的可以自己看官网)
criterion: {“mse”,“friedman_mse”,“mae”} , 默认=“mse”。衡量分割标准的函数。
splitter:{“best”,“random”},default=“best”。分割方式
max_depth:树的最大深度。
min_samples_split:拆分内部节点所需的最少样本数,默认是2.
min_samples_leaf:在叶节点处需要的最小样本数.默认是2
min_weight_fraction_leaf:在所有叶节点处(所有输入样本)的权重总和中的最小加权分 数。如果未提供sample_weight,则样本的权重相等。默认是0。
from sklearn.tree import DecisionTreeRegressor
reg_tree = DecisionTreeRegressor(criterion = "mse",min_samples_leaf = 5)
reg_tree.fit(X,y)
reg_tree.score(X,y)
0.9376307599929274
sklearn中使用SVR实例:
sklearn.svm.SVR(*, kernel=‘rbf’, degree=3, gamma=‘scale’, coef0=0.0, tol=0.001, C=1.0, epsilon=0.1, shrinking=True, cache_size=200, verbose=False, max_iter=-1)
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html?highlight=svr#sklearn.svm.SVR
参数:
kernel:核函数,{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’}, 默认=’rbf’。(后面会详细介绍)
degree:多项式核函数的阶数。默认 = 3。
C:正则化参数,默认=1.0。(后面会详细介绍)
epsilon:SVR模型允许的不计算误差的邻域大小。默认0.1。
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler # 数据标准化
from sklearn.pipeline import make_pipeline # 使用管道,把预处理和模型形成一个流程
reg_svr = make_pipeline(StandardScaler(),SVR(C = 1.0,epsilon = 0.2))
reg_svr.fit(X,y)
reg_svr.score(X,y)
0.7024525421955277
小结
- 回顾了回归模型中的线性回归,多项式回归,还新了解了一个GAM模型,又熟悉了决策树的回归模型,SVM的
- 翻背了一下决策树的优缺点,和线性模型的优缺
- 复习了一下各类模型中导包使用,了解实践了一些参数
缺点:
- 那些底层的公式,几何解释,概率,SVM,核函数的,拉格朗日的之类还是感觉像天书一样
扩展一下随机森林的基本原理:
随机森林是模型中的Bagging方法的典型代表,通过对样本或者变量的n次随机采样,就可以得到n个样本集。对于每一个样本集,可以独立训练模型,对于n个决策树模型的结果,通过集合策略来得到最终的输出。需要注意的是,这n个决策树模型之间是相互独立的,训练集之间是有交集的。可以通过Bootstap Sample(有放回采样)方法实现对样本的随机采样,基于公式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DCl6UFN6-1616057552333)(./my_2.png)]
每次采样大约会有63.2%的样本被选中。该方法同样适用于对变量进行随机抽取
相比于决策树模型,随机森林模型为何能实现更好的效果?
- 实际上,这个问题的回答也适用于所有的集成方法。前面提到,模型误差包括偏差和方差两个部分,
- 假设各个决策树模型有相同的偏差和方差,通过将多个决策树模型得到的结果进行平均或者投票,
- 可以保证随机森林模型的偏差与单个决策树模型的偏差基本相同。
- 但是由于各个决策树模型之间的相对独立性,通过对结果进行平均或者加权能够大幅度减小随机森林模型的方差,最终将误差变小。