使用sklearn构建完整的回归项目
流程
- 明确项目任务:回归/分类
- 收集数据集并选择合适的特征。
- 选择度量模型性能的指标。
- 选择具体的模型并进行训练以优化模型。
- 评估模型的性能并调参。
1、收集数据集并选择合适的特征
在数据集上我们使用我们比较熟悉的Boston房价数据集,原因是:
- 第一个,我们通过这些简单的数据集快速让我们上手sklearn,以及掌握sklearn的相关操作。
- 第二个,我们用简单的数据集能更加清晰地介绍机器学习的相关模型,避免在处理数据上花费较大的精力。
各个特征的相关解释:
- CRIM:各城镇的人均犯罪率
- ZN:规划地段超过25,000平方英尺的住宅用地比例
- INDUS:城镇非零售商业用地比例
- CHAS:是否在查尔斯河边(=1是)
- NOX:一氧化氮浓度(/千万分之一)
- RM:每个住宅的平均房间数
- AGE:1940年以前建造的自住房屋的比例
- DIS:到波士顿五个就业中心的加权距离
- RAD:放射状公路的可达性指数
- TAX:全部价值的房产税率(每1万美元)
- PTRATIO:按城镇分配的学生与教师比例
- B:1000(Bk - 0.63)^2其中Bk是每个城镇的黑人比例
- LSTAT:较低地位人口
- Price:房价
from sklearn import datasets
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
boston_data.head()
2、选择度量模型性能的指标
- MSE均方误差: MSE ( y , y ^ ) = 1 n samples ∑ i = 0 n samples − 1 ( y i − y ^ i ) 2 . \text{MSE}(y, \hat{y}) = \frac{1}{n_\text{samples}} \sum_{i=0}^{n_\text{samples} - 1} (y_i - \hat{y}_i)^2. MSE(y,y^)=nsamples1∑i=0nsamples−1(yi−y^i)2.
- MAE平均绝对误差: MAE ( y , y ^ ) = 1 n samples ∑ i = 0 n samples − 1 ∣ y i − y ^ i ∣ \text{MAE}(y, \hat{y}) = \frac{1}{n_{\text{samples}}} \sum_{i=0}^{n_{\text{samples}}-1} \left| y_i - \hat{y}_i \right| MAE(y,y^)=nsamples1∑i=0nsamples−1∣yi−y^i∣
- R 2 R^2 R2决定系数: R 2 ( y , y ^ ) = 1 − ∑ i = 1 n ( y i − y ^ i ) 2 ∑ i = 1 n ( y i − y ˉ ) 2 R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2} R2(y,y^)=1−∑i=1n(yi−yˉ)2∑i=1n(yi−y^i)2
- 解释方差得分: e x p l a i n e d _ v a r i a n c e ( y , y ^ ) = 1 − V a r { y − y ^ } V a r { y } explained\_{}variance(y, \hat{y}) = 1 - \frac{Var\{ y - \hat{y}\}}{Var\{y\}} explained_variance(y,y^)=1−Var{y}Var{y−y^}
https://scikit-learn.org/stable/modules/model_evaluation.html#regression-metrics
在这个案例中,我们使用MSE均方误差为模型的性能度量指标。
3、选择具体的模型并进行训练
假设:数据集 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
1假设X和Y之间存在线性关系,模型的具体形式为 y ^ = f ( w ) = w T x \hat{y}=f(w) =w^Tx y^=f(w)=wTx
Tips:简单来说,就是所有的样本点到回归得到的曲线,或者平面垂直总距离最短
(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) = \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)=i=1∑N∣∣wTxi−yi∣∣22=i=1∑N(wTxi−yi)2=(wTXT−YT)(wTXT−YT)T=wTXTXw−2wTXTY+YYT
因此,我们需要找到使得L(w)最小时对应的参数w,即:
w ^ = a r g m i n L ( w ) \ \hat{w} = argmin\;L(w) w^=argminL(w)
为了达到求解最小化L(w)问题,我们应用高等数学的知识,使用求导来解决这个问题:
∂ L ( w ) ∂ w = 2 X T X w − 2 X T Y = 0 \ \frac{\partial L(w)}{\partial w} = 2X^TXw-2X^TY = 0 ∂w∂L(w)=2XTXw−2XTY=0,
因此: w ^ = ( X T X ) − 1 X T Y \ \hat{w} = (X^TX)^{-1}X^TY w^=(XTX)−1XTY
(b) 几何解释:
在线性代数中,我们知道两个向量a和b相互垂直可以得出:
< a , b > = a ⋅ b = a T b = 0 <a,b> = a\cdot 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
(c)概率视角:
假设噪声
ϵ
∽
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
]
\ 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]
L(w)=logP(Y∣X;w)=log∏i=1NP(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 ) \ \epsilon\backsim N(0,\sigma^2) ϵ∽N(0,σ2)的极大似然估计
下面,我们使用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
- 线性回归的推广
在线性回归中,我们假设因变量与特征之间的关系是线性关系,这样的假设使得模型很简单,但是缺点也是显然的,那就是当数据存在非线性关系时,我们使用线性回归模型进行预测会导致预测性能极其低下,因为模型的形式本身是线性的,无法表达数据中的非线性关系。我们一个很自然的想法就是去推广线性回归模型,使得推广后的模型更能表达非线性的关系。
变形 | 变形 |
---|---|
基础形式 | y = w 1 x + w 0 + ϵ i \ y = w_1x+w_0+\epsilon_i y=w1x+w0+ϵi |
自变量取对数 | y = w 1 l n x + w 0 + ϵ i \ y = w_1lnx+w_0+\epsilon_i y=w1lnx+w0+ϵi |
求平方 | y = w 1 x 2 + w 0 + ϵ i \ y = w_1x^2+w_0+\epsilon_i y=w1x2+w0+ϵi |
…… | …… |
在一定的取值范围 x ∈ ( x 1 , x 2 ) \ x\in(x_1,x_2) x∈(x1,x2) 内,可以近似的拟合出我们想要的效果,
Tips:有些时候,我们探寻的不止是1个自变量(特征)对因变量的影响,而是多个特征值的影响,如:y = w 1 x 1 + w 2 x 2 + … … + w n x n + w 0 + ϵ i (2) y = w_1x_1+w_2x_2+……+w_nx_n+w_0+\epsilon_i\tag{2} y=w1x1+w2x2+……+wnxn+w0+ϵi(2)
(a) 多项式回归:
再进一步,为了体现因变量和特征的非线性关系,将标准的线性回归模型:
y
i
=
w
0
+
w
1
x
i
+
ϵ
i
(1)
y_i = w_0 + w_1x_i + \epsilon_i\tag{1}
yi=w0+w1xi+ϵi(1)
换成一个多项式函数:
y
i
=
w
0
+
w
1
x
i
+
w
2
x
i
2
+
.
.
.
+
w
d
x
i
d
+
ϵ
(3)
y_i = w_0 + w_1x_i + w_2x_i^2 + ...+w_dx_i^d + \epsilon\tag{3}
yi=w0+w1xi+w2xi2+...+wdxid+ϵ(3)
对于多项式的阶数d不能取过大,一般不大于3或者4,因为d越大,多项式曲线就会越光滑,在X的边界处有异常的波动。(图中的边界处的4阶多项式拟合曲线的置信区间(虚线表示置信区间)明显增大,预测效果的稳定性下降。)
Tips:需要注意添加非线性项后,可能会出现模型内部的自相关性
不论简单线性回归、多项式回归等都是全局性的结构,如果不考虑全局,而是从局部入手,就如 上文所讲,
x
∈
(
x
1
,
x
2
)
\ x\in(x_1,x_2)
x∈(x1,x2) 时,能得到较好的拟合效果,但是离开这个区间,我们的模型就不再适用
正如分段函数一样,我们是否也可以在不同的区间用不同的回归模型,获得拟合曲线,
现在我们对样本空间 X \ X X 进行分组,假设把 X \ X X分为k段 ,用每段变量分别去拟合常量I
C
1
(
X
)
=
I
1
(
X
<
c
1
)
\ C_1(X) = I_1(X<c_1)
C1(X)=I1(X<c1)
C
2
(
X
)
=
I
1
(
c
1
<
X
<
c
2
)
\ C_2(X) = I_1(c1<X<c_2)
C2(X)=I1(c1<X<c2)
…
…
\ ……
……
C k ( X ) = I 1 ( c k − 1 < X < c k ) \ C_k(X) = I_1(c_{k-1}<X<c_k) Ck(X)=I1(ck−1<X<ck)
- 这些变量在极端条件下(值取1,0)就是我们所说的哑变量
然后,我们再对这k+1个变量进行拟合,得到:
y
i
=
w
1
C
(
x
i
)
+
w
2
C
(
x
i
)
+
…
…
+
w
k
C
(
x
i
)
+
ϵ
i
y_i = w_1C(x_i)+w_2C(x_i)+……+w_kC(x_i)+\epsilon_i
yi=w1C(xi)+w2C(xi)+……+wkC(xi)+ϵi
(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模型本质上还是一个可加模型,如果我们能摆脱可加性模型形式,可能还会提升模型预测精度,详情请看后面的算法。
sklearn.preprocessing.PolynomialFeatures(degree=2, *, interaction_only=False, include_bias=True, order=‘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))
- 参数:
degree:特征转换的阶数。
interaction_onlyboolean:是否只包含交互项,默认False 。
include_bias:是否包含截距项,默认True。
order:str in {‘C’, ‘F’}, default ‘C’,输出数组的顺序。
特征转换其实就是一个为基础回归模型增加特征数的过程,特征由基础特征和基础特征的交互项产生,如果我有a,b,两个基础特征,当特征转换阶数为2,那么特征转换后就有 1 , a , b , a b , a 2 , b 2 \ 1,a,b,ab,a^2,b^2 1,a,b,ab,a2,b2,分别产生于:
a 0 ∗ b 0 , a 0 ∗ b 1 , a 1 ∗ b 0 , a 1 ∗ b 1 , a 2 ∗ b 0 , a 0 ∗ b 2 a^0*b^0,a^0*b^1,a^1*b^0,a^1*b^1,a^2*b^0,a^0*b^2 a0∗b0,a0∗b1,a1∗b0,a1∗b1,a2∗b0,a0∗b2
(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()
单纯的统计量并不能直观的看出数据之间的依赖关系,我们还可以通过对数据之间进行绘图,通过图像上的直观结果辅助我们进行后续的调整
# 数据还是波士顿房价数据,之前已经导入,这里就不在代码里重新导入了
from matplotlib import pyplot as plt
fig,axs = plt.subplots(1,len(features[0:6]))
titles = features
for i,ax in enumerate(axs):
XX = gam.generate_X_grid(term=i)
ax.plot(XX[:, i], gam.partial_dependence(term=i, X=XX))
ax.plot(XX[:, i], gam.partial_dependence(term=i, X=XX, width=.95)[1], c='r', ls='--')
ax.set_title(titles[i])
plt.show()
可以看出,部分变量和目标值有很强的非线性相关性,图4又与目标值表现出简单的线性关系,通过二者在模型里的单纯相加,我们可以结合二者得出一个更具有概括性的模型,但是不同的函数在结合点不会像同一常量那样自然光滑,可能会出现跳跃,这就需要对
-
模型设置约束条件
-
对误差项进行惩罚
- 回归树:
基于树的回归方法主要是依据分层和分割的方式将特征空间划分为一系列简单的区域。
对某个给定的待预测的自变量,用他所属区域中训练集的平均数或者众数对其进行预测。
由于划分特征空间的分裂规则可以用树的形式进行概括,因此这类方法称为决策树方法。决策树由结点(node)和有向边(diredcted edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类别或者某个值。区域
R
1
,
R
2
R_1,R_2
R1,R2等称为叶节点,将特征空间分开的点
t
1
,
t
2
\ t_1,t_2
t1,t2为内部节点。
建立回归树的过程大致可以分为以下两步:
-
将自变量的特征空间(即 x ( 1 ) , x ( 2 ) , x ( 3 ) , . . . , x ( p ) x^{(1)},x^{(2)},x^{(3)},...,x^{(p)} x(1),x(2),x(3),...,x(p))的可能取值构成的集合分割成J个互不重叠的区域 R 1 , R 2 , . . . , R j R_1,R_2,...,R_j R1,R2,...,Rj。
-
对落入区域 R j R_j Rj的每个观测值作相同的预测,预测值等于 R j R_j Rj上训练集的因变量的简单算术平均。具体来说,就是:
-
a. 选择最优切分特征j以及该特征上的最优点s:
遍历特征j以及固定j后遍历切分点s,选择使得下式最小的(j,s) m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] min_{j,s}[min_{c_1}\sum\limits_{x_i\in R_1(j,s)}(y_i-c_1)^2 + min_{c_2}\sum\limits_{x_i\in R_2(j,s)}(y_i-c_2)^2 ] minj,s[minc1xi∈R1(j,s)∑(yi−c1)2+minc2xi∈R2(j,s)∑(yi−c2)2]
b. 按照(j,s)分裂特征空间:R 1 ( j , s ) = { x ∣ x j ≤ s } \ R_1(j,s) = \{x|x^{j} \le s \} R1(j,s)={x∣xj≤s}
R 2 ( j , s ) = { x ∣ x j > s } \ R_2(j,s) = \{x|x^{j} > s \} R2(j,s)={x∣xj>s},
c ^ m = 1 N m ∑ x ∈ R m ( j , s ) y i , m = 1 , 2 \ \hat{c}_m = \frac{1}{N_m}\sum\limits_{x \in R_m(j,s)}y_i,\;m=1,2 c^m=Nm1x∈Rm(j,s)∑yi,m=1,2
c. 继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5。
d. 将特征空间划分为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)
如以下生成的关于运动员在棒球大联盟数据的回归树:
回归树与线性模型的比较:
线性模型的模型形式与树模型的模型形式有着本质的区别,具体而言,线性回归对模型形式做了如下假定: 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)。那问题来了,哪种模型更优呢?这个要视具体情况而言,如果特征变量与因变量的关系能很好的用线性关系来表达,那么线性回归通常有着不错的预测效果,拟合效果则优于不能揭示线性结构的回归树。反之,如果特征变量与因变量的关系呈现高度复杂的非线性,那么树方法比传统方法更优。
树模型的优缺点:- 树模型的解释性强,在解释性方面可能比线性回归还要方便。
- 树模型更接近人的决策方式。
- 树模型可以用图来表示,非专业人士也可以轻松解读。
- 树模型可以直接做定性的特征而不需要像线性回归一样哑元化。
- 树模型能很好处理缺失值和异常值,对异常值不敏感,但是这个对线性模型来说却是致命的。
- 树模型的预测准确性一般无法达到其他回归模型的水平,但是改进的方法很多。
-
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:在叶节点处需要的最小样本数。默认是1。
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)
决策树的本质就是一堆if-else的组合
-
支持向量机回归(SVR)
在介绍支持向量回归SVR之前,我们先来了解下约束优化的相关知识:- 约束优化问题§:
m i n f ( x ) s . t . g i ( x ) ≤ 0 , i = 1 , 2 , . . . , m h j ( x ) = 0 , j = 1 , 2 , . . . , l min f(x) \\ s.t.\;\;\;g_i(x) \le 0,\; i=1,2,...,m\\ \;\;\;\;\; h_j(x) = 0,\; j=1,2,...,l minf(x)s.t.gi(x)≤0,i=1,2,...,mhj(x)=0,j=1,2,...,l
我们假设 x ∗ x^* x∗为满足以上条件的局部最优解, p ∗ = f ( x ∗ ) p^* = f(x^*) p∗=f(x∗),我们的目的就是要找到 x ∗ x^* x∗与 p ∗ p^* p∗,满足不等式和等式约束的x集合成为可行域,记作S。
- 约束优化问题§:
-
KKT条件(最优解的一阶必要条件)
因为KKT条件是最优化的相关内容,在本次开源学习中并不是重点,因此在这里我用一个更加简单的例子说明KKT条件,严格的证明请参见凸优化相关书籍。
在这个例子中,我们考虑:( x ∗ x^* x∗为我们的最优解)
m i n f ( x ) s . t . g 1 ( x ) ≤ 0 , x ∈ R n g 2 ( x ) ≤ 0 g 3 ( x ) ≤ 0 minf(x)\\ s.t.\;g_1(x) \le 0,\;x \in R^n\\ \;\;\;g_2(x) \le 0\\ \;\;\;g_3(x) \le 0 minf(x)s.t.g1(x)≤0,x∈Rng2(x)≤0g3(x)≤0
我们可以看到: − ∇ f ( x ∗ ) -\nabla f(x^*) −∇f(x∗)可以由 ∇ g 1 ( x ∗ ) \nabla g_1(x^*) ∇g1(x∗)与 ∇ g 2 ( x ∗ ) \nabla g_2(x^*) ∇g2(x∗)线性表出,因此有: − ∇ f ( x ∗ ) = λ 1 ∇ g 1 ( x ∗ ) + λ 2 ∇ g 2 ( x ∗ ) -\nabla f(x^*) = \lambda_1 \nabla g_1(x^*) + \lambda_2 \nabla g_2(x^*) −∇f(x∗)=λ1∇g1(x∗)+λ2∇g2(x∗)其中 λ 1 , λ 2 ≥ 0 \lambda_1,\lambda_2 \ge 0 λ1,λ2≥0,即:
∇ f ( x ∗ ) + λ 1 ∇ g 1 ( x ∗ ) + λ 2 ∇ g 2 ( x ∗ ) = 0 , 其 中 λ 1 , λ 2 ≥ 0 \nabla f(x^*) + \lambda_1 \nabla g_1(x^*) + \lambda_2 \nabla g_2(x^*) = 0,\;\;\;其中\lambda_1,\lambda_2 \ge 0 ∇f(x∗)+λ1∇g1(x∗)+λ2∇g2(x∗)=0,其中λ1,λ2≥0
我们把没有起作用的约束 g 3 ( x ) g_3(x) g3(x)也放到式子里面去,目的也就是为了书写方便,即要求:
∇ f ( x ∗ ) + λ 1 ∇ g 1 ( x ∗ ) + λ 2 ∇ g 2 ( x ∗ ) + λ 3 ∇ g 3 ( x ∗ ) = 0 , \nabla f(x^*) + \lambda_1 \nabla g_1(x^*) + \lambda_2 \nabla g_2(x^*) + \lambda_3 \nabla g_3(x^*)= 0,\;\;\; ∇f(x∗)+λ1∇g1(x∗)+λ2∇g2(x∗)+λ3∇g3(x∗)=0,
其 中 λ 1 , λ 2 ≥ 0 , λ 3 = 0 由 于 点 x ∗ 位 于 方 程 g 1 ( x ) = 0 与 g 2 ( x ) = 0 上 , 因 此 : 其中\lambda_1,\lambda_2 \ge 0,\lambda_3 = 0由于点x^*位于方程g_1(x)=0与g_2(x)=0上,因此: 其中λ1,λ2≥0,λ3=0由于点x∗位于方程g1(x)=0与g2(x)=0上,因此:
λ 1 g 1 ( x ∗ ) = 0 , λ 2 g 2 ( x ∗ ) = 0 , λ 3 g 3 ( x ∗ ) = 0 \lambda_1 g_1(x^*) = 0,\lambda_2 g_2(x^*) = 0 , \lambda_3 g_3(x^*)= 0 λ1g1(x∗)=0,λ2g2(x∗)=0,λ3g3(x∗)=0
因此,KKT条件就是:假设
x
∗
x^*
x∗为最优化问题§的局部最优解,且
x
∗
x^*
x∗ 在某个适当的条件下 ,有:
∇
f
(
x
∗
)
+
∑
i
=
1
m
λ
i
∇
g
(
x
∗
)
+
∑
j
=
1
l
μ
j
∇
h
j
(
x
∗
)
=
0
(
对
偶
条
件
)
λ
i
≥
0
,
i
=
1
,
2
,
.
.
.
,
m
(
对
偶
条
件
)
g
i
(
x
∗
)
≤
0
(
原
问
题
条
件
)
h
j
(
x
∗
)
=
0
(
原
问
题
条
件
)
λ
i
g
(
x
∗
)
=
0
(
互
补
松
弛
定
理
)
\nabla f(x^*) + \sum\limits_{i=1}^{m}\lambda_i \nabla g(x^*) + \sum\limits_{j=1}^{l}\mu_j \nabla h_j(x^*) = 0(对偶条件)\\ \lambda_i \ge 0,\;i = 1,2,...,m(对偶条件)\\ g_i(x^*) \le 0(原问题条件)\\ h_j(x^*) = 0(原问题条件)\\ \lambda_i g(x^*) = 0(互补松弛定理)
∇f(x∗)+i=1∑mλi∇g(x∗)+j=1∑lμj∇hj(x∗)=0(对偶条件)λi≥0,i=1,2,...,m(对偶条件)gi(x∗)≤0(原问题条件)hj(x∗)=0(原问题条件)λig(x∗)=0(互补松弛定理)
- 对偶理论:
为什么要引入对偶问题呢?是因为原问题与对偶问题就像是一个问题两个角度去看,如利润最大与成本最低等。有时侯原问题上难以解决,但是在对偶问题上就会变得很简单。再者,任何一个原问题在变成对偶问题后都会变成一个凸优化的问题,这点我们后面会有介绍。下面我们来引入对偶问题:
首先,我们的原问题§是:
m i n f ( x ) s . t . g i ( x ) ≤ 0 , i = 1 , 2 , . . . , m h j ( x ) = 0 , j = 1 , 2 , . . . , l min f(x) \\ s.t.\;\;\;g_i(x) \le 0,\; i=1,2,...,m\\ \;\;\;\;\; h_j(x) = 0,\; j=1,2,...,l minf(x)s.t.gi(x)≤0,i=1,2,...,mhj(x)=0,j=1,2,...,l
引入拉格朗日函数: L ( x , λ , μ ) = f ( x ) + ∑ i = 1 m λ i g i ( x ) + ∑ j = 1 l μ j h j ( x ) L(x,\lambda,\mu) = f(x) + \sum\limits_{i=1}^{m}\lambda_i g_i(x) + \sum\limits_{j=1}^{l}\mu_j h_j(x) L(x,λ,μ)=f(x)+i=1∑mλigi(x)+j=1∑lμjhj(x)
拉格朗日对偶函数:
d ( λ , μ ) = m i n x ∈ X { f ( x ) + ∑ i = 1 m λ i g i ( x ) + ∑ j = 1 l μ j h j ( x ) } d(\lambda,\mu) = min_{x\in X}\{ f(x) + \sum\limits_{i=1}^{m}\lambda_i g_i(x) +\sum\limits_{j=1}^{l}\mu_j h_j(x)\} d(λ,μ)=minx∈X{f(x)+i=1∑mλigi(x)+j=1∑lμjhj(x)}
其 中 X 为 满 足 条 件 的 x 其中X为满足条件的x 其中X为满足条件的x
变 量 ≤ m i n x ∈ S { f ( x ) + ∑ i = 1 m λ i g i ( x ) + ∑ j = 1 l μ j h j ( x ) } 变量\le min_{x\in S}\{ f(x) + \sum\limits_{i=1}^{m}\lambda_i g_i(x) + \sum\limits_{j=1}^{l}\mu_j h_j(x) \} 变量≤minx∈S{f(x)+i=1∑mλigi(x)+j=1∑lμjhj(x)}
由 于 由于 由于: g i ( x ) ≤ 0 , h j ( x ) = 0 , λ i ≥ 0 g_i(x) \le 0,h_j(x) = 0,\lambda_i \ge 0 gi(x)≤0,hj(x)=0,λi≥0
其 中 其中 其中 S 为 可 行 域 b ≤ m i n x ∈ S { f ( x ) } S为可行域b\le min_{x\in S}\{f(x) \} S为可行域b≤minx∈S{f(x)}
因 此 : 拉 格 朗 日 对 偶 函 数 d ( λ , μ ) 是 原 问 题 最 优 解 的 函 数 值 p ∗ 的 下 界 因此:拉格朗日对偶函数d(\lambda,\mu)是原问题最优解的函数值p^* 的下界 因此:拉格朗日对偶函数d(λ,μ)是原问题最优解的函数值p∗的下界,
即 每 个 不 同 的 λ 与 μ 确 定 的 d ( λ , μ ) 都 是 p ∗ 的 下 界 , 但 是 我 们 希 望 下 界 越 大 越 好 , 即每个不同的\lambda与\mu确定的d(\lambda,\mu)都是p^* 的下界,但是我们希望下界越大越好, 即每个不同的λ与μ确定的d(λ,μ)都是p∗的下界,但是我们希望下界越大越好,
因 为 越 大 就 更 能 接 近 真 实 的 p ∗ 。 因 此 拉 格 朗 日 对 偶 问 题 ( D ) 转 化 为 因为越大就更能接近真实的p^*。因此拉格朗日对偶问题(D)转化为 因为越大就更能接近真实的p∗。因此拉格朗日对偶问题(D)转化为:
m a x λ , μ d ( λ , μ ) s . t . λ i ≥ 0 , i = 1 , 2 , . . . , m max_{\lambda,\mu}d(\lambda,\mu)\\ s.t. \lambda_i \ge 0,i = 1,2,...,m maxλ,μd(λ,μ)s.t.λi≥0,i=1,2,...,m
也就是:
m a x λ ≥ 0 , μ m i n x ∈ S L ( x , λ , μ ) max_{\lambda \ge 0,\mu}\;min_{x \in S} L(x,\lambda,\mu) maxλ≥0,μminx∈SL(x,λ,μ)
我们可以观察到,对偶问题是关于 λ \lambda λ和 μ \mu μ的线性函数,因此对偶问题是一个凸优化问题,凸优化问题在最优化理论较为简单。
弱对偶定理:对偶问题(D)的最优解 D ∗ D^* D∗一定小于原问题最优解 P ∗ P^* P∗,这点在刚刚的讨论得到了充分的证明,一定成立。
强对偶定理:对偶问题(D)的最优解 D ∗ D^* D∗在一定的条件下等于原问题最优解 P ∗ P^* P∗,条件非常多样化且不是唯一的,也就是说这是个开放性的问题,在这里我给出一个最简单的条件,即: f ( x ) f(x) f(x)与 g i ( x ) g_i(x) gi(x)为凸函数, h j ( x ) h_j(x) hj(x)为线性函数,X是凸集, x ∗ x^* x∗满足KKT条件,那么 D ∗ = P ∗ D^* = P^* D∗=P∗。
sklearn中使用SVR实例:
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html?highlight=svr#sklearn.svm.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)
- 参数:
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)
W T \ W^T WT:向量的转置 ↩︎