机器学习之监督学习(一)线性回归、多项式回归、算法优化
- 1.监督学习定义
- 2.监督学习分类
- 2.1回归 regression
- 2.2 分类 classification
- 3.线性回归 linear regression
- 3.1 单特征线性回归
- 模块一:梯度下降
- 3.2 多特征线性回归
- 模块二:正规方程 normal equation
- 模块三: 梯度下降分类
- 3.3 特征缩放 feature scaling
- 模块四: 引入scikit-learn
- 4.多项式回归 polynomial regression
- 模块五:过拟合和欠拟合 overfit and underfit
- 模块六:正则化 regularization
- 5.回归算法优化 regression algoirthm optimization
- 超参数
- 模块七: 训练集、验证集和测试集 dataset split
- 模块八:偏差和方差 bias and variance
1.监督学习定义
监督学习(supervised learning)是一种机器学习方法,在这种方法中,算法通过训练集中的输入数据(特征)和相应的输出标签(目标)来学习映射关系,从而能够对未见过的数据进行预测或分类。
2.监督学习分类
2.1回归 regression
回归的目标是根据输入数据预测连续的数值输出,输出标签是连续的实数,例如预测房价。
2.2 分类 classification
分类的目标是根据输入数据将样本分配到不同类别中,输出标签是离散的如有限的类别。例如垃圾邮件过滤。
3.线性回归 linear regression
3.1 单特征线性回归
案例:根据房子尺寸预测房价
符号定义
x:输入向量
y:输出/目标向量
m:训练数据量
(x,y): 训练集中的一个数据
(x(i),y(i)):训练集中第i个数据
线性回归模型
y
^
=
f
w
,
b
(
x
)
=
w
x
+
b
\hat{y}=f_{w,b}(x) =wx+b
y^=fw,b(x)=wx+b
代价函数 cost function
平均平方误差函数 squared error function
J
(
w
,
b
)
=
1
2
m
∑
i
=
1
m
(
y
^
(
i
)
−
y
(
i
)
)
2
J(w,b)=\frac{1}{2m}\sum_{i=1}^{m}(\hat{y}^{(i)}-y^{(i)})^2
J(w,b)=2m1i=1∑m(y^(i)−y(i))2
说明:
1、额外乘
1
2
\frac{1}{2}
21是为了便于后续求导
2、代价函数J是关于线性系数w和b的函数
训练目标:最小化代价J
训练思路:梯度下降 gradient descent
模块一:梯度下降
何为梯度下降?
先看看单变量梯度下降:
一元函数中可以认为梯度即是导数,从下图中可以看出,我们从任意点出发,当该点导数大于0时,往左移动靠近极小值点,当该点导数小于0时,往右移动靠近极小值点。因此给出一种收敛到极小值点的方法:
w
−
w
−
α
∂
J
(
w
)
∂
w
w-w-\alpha\frac{\partial{J(w)}}{\partial{w}}
w−w−α∂w∂J(w),其中
α
\alpha
α是学习率,用来控制每一次移动步距。当学习率太小时,收敛缓慢,当学习率太大时,由于步距大,可能造成远离极值点而无法收敛,故应该选择合适的学习率进行训练。进行足够多次梯度下降后,w近似取到极小值点。
再来看多变量梯度下降,这里以方便可视化的二元函数梯度下降为例,学过高数的我们知道梯度的定义为:
∇
f
=
[
f
x
,
f
y
]
T
\nabla{f}=[f_x,f_y]^T
∇f=[fx,fy]T
即由两个偏导构成的梯度向量,当方向导数和梯度方向一致时,方向导数最大,方向相反时,方向导数最小。因此想要最快下降到山谷位置,应沿着梯度反方向走,用数学表述为(假设两个变量是w和b)
[
w
,
b
]
T
=
[
w
,
b
]
T
−
α
∇
f
[w,b]^T=[w,b]^T-\alpha\nabla{f}
[w,b]T=[w,b]T−α∇f
即
w
=
w
−
α
∂
J
∂
w
,
b
=
b
−
α
∂
J
∂
w
w=w-\alpha\frac{\partial{J}}{\partial{w}},b=b-\alpha\frac{\partial{J}}{\partial{w}}
w=w−α∂w∂J,b=b−α∂w∂J
对于多元函数,梯度下降表达式即
[
x
1
,
x
2
.
.
.
,
x
n
]
T
=
[
x
1
,
x
2
.
.
.
,
x
n
]
T
−
α
[
∂
J
∂
x
1
,
∂
J
∂
x
2
,
.
.
.
,
∂
J
∂
x
n
]
T
[x_1,x_2...,x_n]^T=[x_1,x_2...,x_n]^T-\alpha[\frac{\partial{J}}{\partial{x_1}},\frac{\partial{J}}{\partial{x_2}},...,\frac{\partial{J}}{\partial{x_n}}]^T
[x1,x2...,xn]T=[x1,x2...,xn]T−α[∂x1∂J,∂x2∂J,...,∂xn∂J]T
梯度下降算法的起始点随机确定,但收敛的极值点不一定是全局极值点,有可能陷入局部极值点,一种解决的思路是多次随机生成起点进行多次梯度下降,比较每次极值进行比较获取全局极值。
对于上面线性回归模型中提到的成本函数,其3D图像是凹函数,即只有一个极值点,因此不必考虑陷入局部极值的问题。
求偏导过程如下,注意求导和求和可以互换,即先导再求和:
∂
∂
w
J
(
w
,
b
)
=
∂
∂
w
1
2
m
∑
i
=
1
m
(
w
x
(
i
)
+
b
−
y
(
i
)
)
2
=
1
2
m
∑
i
=
1
m
2
(
w
x
(
i
)
+
b
−
y
(
i
)
)
x
(
i
)
=
1
m
∑
i
=
1
m
x
(
i
)
(
w
x
(
i
)
+
b
−
y
(
i
)
)
\frac{\partial}{\partial{w}}J(w,b)=\frac{\partial}{\partial{w}}\frac{1}{2m}\sum_{i=1}^{m}(wx^{(i)}+b-y^{(i)})^2\\=\frac{1}{2m}\sum_{i=1}^{m}2(wx^{(i)}+b-y^{(i)})x^{(i)}=\frac{1}{m}\sum_{i=1}^{m}x^{(i)}(wx^{(i)}+b-y^{(i)})
∂w∂J(w,b)=∂w∂2m1i=1∑m(wx(i)+b−y(i))2=2m1i=1∑m2(wx(i)+b−y(i))x(i)=m1i=1∑mx(i)(wx(i)+b−y(i))
∂
∂
b
J
(
w
,
b
)
=
∂
∂
b
1
2
m
∑
i
=
1
m
(
w
x
(
i
)
+
b
−
y
(
i
)
)
2
=
1
2
m
∑
i
=
1
m
2
(
w
x
(
i
)
+
b
−
y
(
i
)
)
=
1
m
∑
i
=
1
m
(
w
x
(
i
)
+
b
−
y
(
i
)
)
\frac{\partial}{\partial{b}}J(w,b)=\frac{\partial}{\partial{b}}\frac{1}{2m}\sum_{i=1}^{m}(wx^{(i)}+b-y^{(i)})^2\\=\frac{1}{2m}\sum_{i=1}^{m}2(wx^{(i)}+b-y^{(i)})=\frac{1}{m}\sum_{i=1}^{m}(wx^{(i)}+b-y^{(i)})
∂b∂J(w,b)=∂b∂2m1i=1∑m(wx(i)+b−y(i))2=2m1i=1∑m2(wx(i)+b−y(i))=m1i=1∑m(wx(i)+b−y(i))
关于学习率的选择
梯度下降算法是否有效与学习率的选择密切相关
如果学习率太小,梯度下降速率太慢
如果学习率太大,可能无法收敛(发散)/无法抵达极小值点
可以绘制学习曲线cost-iteration,发现曲线下降太慢/没达到收敛时,说明学习率太小,适当增加学习率;当曲线上升(不收敛)时,说明学习率太大,适当减小学习率
推荐的学习率尝试是…0.003、0.01、0.03、0.1…,即以3倍的公比调整
代码实现:
一元线性回归梯度下降代码实现
3.2 多特征线性回归
案例:
根据房子尺寸、房间数量、楼层数、年龄预测房价
符号定义
x
j
表示第
j
个特征,
x
⃗
(
i
)
表示第
i
个数据,
n
表示特征数量,
m
表示数据量
,
,
x
⃗
j
(
i
)
表示第
i
个数据第
j
个特征
x_j表示第j个特征,\vec{x}^{(i)}表示第i个数据,n表示特征数量,m表示数据量,,\vec{x}^{(i)}_j表示第i个数据第j个特征
xj表示第j个特征,x(i)表示第i个数据,n表示特征数量,m表示数据量,,xj(i)表示第i个数据第j个特征
多元线性回归模型
w
=
[
w
1
,
w
2
,
.
.
.
,
w
n
]
y
^
(
i
)
=
f
w
⃗
,
b
(
x
⃗
)
=
w
⃗
⋅
x
⃗
+
b
w=[w_1,w_2,...,w_n]~~~\\ \hat{y}^{(i)}=f_{\vec{w},b}(\vec{x})=\vec{w}\cdot\vec{x}+b
w=[w1,w2,...,wn] y^(i)=fw,b(x)=w⋅x+b
代价函数 cost function
平均平方误差函数 squared error function
J
(
w
⃗
,
b
)
=
1
2
m
∑
i
=
1
m
(
y
^
(
i
)
−
y
(
i
)
)
2
J(\vec{w},b)=\frac{1}{2m}\sum_{i=1}^{m}(\hat{y}^{(i)}-y^{(i)})^2
J(w,b)=2m1i=1∑m(y^(i)−y(i))2
训练目标:最小化代价J
训练思路:梯度下降 gradient descent
n个特征,即参数包含n个w和1个b,共n+1个参数
先计算偏导:
∂
∂
w
j
J
(
w
⃗
,
b
)
=
∂
∂
w
j
1
2
m
∑
i
=
1
m
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
2
=
1
2
m
∑
i
=
1
m
2
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
x
j
(
i
)
=
1
m
∑
i
=
1
m
x
j
(
i
)
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
\frac{\partial}{\partial{w_j}}J(\vec{w},b)=\frac{\partial}{\partial{w_j}}\frac{1}{2m}\sum_{i=1}^{m}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})^2\\=\frac{1}{2m}\sum_{i=1}^{m}2(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})x_j^{(i)}=\frac{1}{m}\sum_{i=1}^{m}x_j^{(i)}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})
∂wj∂J(w,b)=∂wj∂2m1i=1∑m(w⋅x(i)+b−y(i))2=2m1i=1∑m2(w⋅x(i)+b−y(i))xj(i)=m1i=1∑mxj(i)(w⋅x(i)+b−y(i))
∂
∂
b
J
(
w
⃗
,
b
)
=
∂
∂
b
1
2
m
∑
i
=
1
m
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
2
=
1
2
m
∑
i
=
1
m
2
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
=
1
m
∑
i
=
1
m
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
\frac{\partial}{\partial{b}}J(\vec{w},b)=\frac{\partial}{\partial{b}}\frac{1}{2m}\sum_{i=1}^{m}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})^2\\=\frac{1}{2m}\sum_{i=1}^{m}2(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})=\frac{1}{m}\sum_{i=1}^{m}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})
∂b∂J(w,b)=∂b∂2m1i=1∑m(w⋅x(i)+b−y(i))2=2m1i=1∑m2(w⋅x(i)+b−y(i))=m1i=1∑m(w⋅x(i)+b−y(i))
更新参数:
w
j
=
w
j
−
α
∂
∂
w
j
J
(
w
⃗
,
b
)
(
j
=
1
、
2...
、
n
)
b
=
b
−
α
∂
∂
b
J
(
w
⃗
,
b
)
w_j=w_j-\alpha\frac{\partial}{\partial{w_j}}J(\vec{w},b)(j=1、2...、n)\\b=b-\alpha\frac{\partial}{\partial{b}}J(\vec{w},b)
wj=wj−α∂wj∂J(w,b)(j=1、2...、n)b=b−α∂b∂J(w,b)
代码实现:
多元线性回归梯度下降代码实现
模块二:正规方程 normal equation
优化损失函数,除了梯度下降这种不断迭代直至收敛的算法外,从数学角度上还有一种暴力解法叫正规方程。
正规方程(Normal Equation)是用于求解线性回归模型参数的一种解析方法。它通过最小化误差平方和来找到最佳参数,不需要使用迭代优化方法如梯度下降。正规方程尤其适用于小规模数据集,因为它在大规模数据集上计算成本可能较高。
首先列出需要用到的线代知识:
①y是一维向量,则
y
T
y
=
∣
∣
y
∣
∣
2
=
y
⋅
y
y^Ty=||y||^2=y\cdot{y}
yTy=∣∣y∣∣2=y⋅y
②转置相关公式:
(
A
+
B
)
T
=
A
T
+
B
T
(
A
B
)
T
=
B
T
A
T
(A+B)^T=A^T+B^T\\(AB)^T=B^TA^T
(A+B)T=AT+BT(AB)T=BTAT
③p,q是一维列向量,则
p
⋅
q
=
p
T
q
=
q
T
p
p\cdot{q}=p^Tq=q^Tp
p⋅q=pTq=qTp
④矩阵求导公式:
∂
(
A
X
)
∂
X
=
A
T
\frac{\partial (AX)}{\partial X} = A^T
∂X∂(AX)=AT
∂
(
X
T
A
X
)
∂
X
=
(
A
+
A
T
)
X
[
A
对称时
=
2
A
X
]
\frac{\partial (X^T A X)}{\partial X} = (A + A^T) X~~[A对称时=2AX]
∂X∂(XTAX)=(A+AT)X [A对称时=2AX]
假设我们有一个线性回归模型:
y = X β + ϵ y = X\beta + \epsilon y=Xβ+ϵ
其中:
y 是目标变量向量(
M
×
1
M \times 1
M×1)
X 是特征矩阵(
M
×
(
N
+
1
)
M \times (N+1)
M×(N+1)),第一列通常为1,对应于截距项
β 是待估参数向量(
(
N
+
1
)
×
1
(N+1) \times 1
(N+1)×1)
ϵ 是误差项向量(
M
×
1
M \times 1
M×1)
则代价函数表示为
J
(
β
)
=
∣
∣
y
−
X
β
∣
∣
2
=
(
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
β
=
y
T
y
−
2
y
T
X
β
+
β
T
X
T
X
β
J(\beta)=||y-X\beta||^2=(y-X\beta)^T(y-X\beta)=(y^T-\beta^TX^T)(y-X\beta)\\=y^Ty-y^TX\beta-\beta^TX^Ty+\beta^TX^TX\beta=y^Ty-2y^TX\beta+\beta^TX^TX\beta
J(β)=∣∣y−Xβ∣∣2=(y−Xβ)T(y−Xβ)=(yT−βTXT)(y−Xβ)=yTy−yTXβ−βTXTy+βTXTXβ=yTy−2yTXβ+βTXTXβ
求导,令导数为0
∂
J
(
β
)
∂
β
=
−
2
X
T
y
+
2
X
T
X
β
=
0
→
β
=
(
X
T
X
)
−
1
X
T
y
\frac{∂J(β)}{∂\beta}=-2X^Ty+2X^TX\beta=0\rightarrow\beta=(X^TX)^{-1}X^Ty
∂β∂J(β)=−2XTy+2XTXβ=0→β=(XTX)−1XTy
从最优参数向量的表达式可以看出,但矩阵规模较大时,计算成本很大,因此我们通常会在面对大规模数据集时选择梯度下降算法进行训练。
除此之外,我们还可以顺便证明一下平均平方损失函数是凸函数,如何判定凸函数,一般采用黑塞矩阵,是由目标函数在点X处的二阶偏导数组成的对称矩阵是否是半正定的,对J求二阶导:
J
′
′
(
β
)
=
2
X
T
X
J^{''}(\beta)=2X^TX
J′′(β)=2XTX
由于XTX为半正定矩阵,因此代价函数J的确是凸函数,计算出的极值即全局最值。
除此之外,正规方程法一个缺点是只适用于线性回归问题,而梯度下降在后续的逻辑回归、神经网络中都是我们优化算法的核心。
模块三: 梯度下降分类
根据不同的损失函数和迭代方式,梯度下降可以被分为批量梯度下降(Batch Gradient Descent,BGD)、随机梯度下降(Stochastic Gradient Descent,SGD)、小批量梯度下降(Mini-batch Gradient Descent)等。
1、批量梯度下降(Batch Gradient Descent,BGD)
前面所讲的批量梯度下降(Batch Gradient Descent,BGD)通过在每一次迭代中计算所有训练样本的梯度来更新模型参数。
优点:
稳定收敛,由于每次更新都使用整个训练数据集,梯度计算精确,更新方向稳定
缺点:
①需要处理所有训练样本,计算量较大,因此不适合处理大规模数据集。
②对于比较稀疏的数据集,BGD 的计算效率较低,因为大部分数据都是无关的。
③由于每次迭代都需要处理整个数据集,因此在处理在线学习或实时学习等实时数据流问题时,BGD 的计算效率也较低。
2 、随机梯度下降(Stochastic Gradient Descent,SGD)
随机梯度下降(Stochastic Gradient Descent,SGD是一种常用的梯度下降算法,它通过在每一次迭代中计算一个训练样本的梯度来更新模型参数。
优点:
①计算效率高,每次迭代只计算一个样本的梯度,计算开销小,适合大规模数据集。
②能逃离局部最优,由于更新过程的随机性,SGD 更容易跳出局部最优。
缺点:
①收敛不稳定,由于每次更新使用的样本不同,梯度方向多变,可能导致损失值在收敛过程中不断波动
②可能无法保证收敛到全局最优解,因为更新方向是随机的。
3、批量梯度下降(Mini-batch Gradient Descent, MGD)
小批量梯度下降(Mini-batch Gradient Descent,MBGD)是一种介于批量梯度下降(Batch Gradient Descent,BGD)和随机梯度下降(Stochastic Gradient Descent,SGD)之间的梯度下降算法,它通过在每一次迭代中计算一小部分训练样本的梯度来更新模型参数。
优点:
结合了批量梯度下降和随机梯度下降的优点,每次更新使用一个小批量的数据,计算效率和收敛稳定性之间取得了平衡
实际应用中的常见选择(来自chatgpt)
深度学习:在深度学习中,越来越多的情况下选择小批量梯度下降(MGD),结合自适应学习率方法如 Adam、RMSProp 等。这是因为深度学习模型通常需要大规模数据,MGD 能够有效利用计算资源,且自适应学习率方法能够自动调整学习率,提高收敛速度和稳定性。
传统机器学习:在一些传统的机器学习任务中,如线性回归、逻辑回归等,如果数据集规模较小,批量梯度下降(BGD)仍然是一个常见选择。如果数据规模中等或较大,随机梯度下降(SGD)和小批量梯度下降(MGD)也广泛应用。
3.3 特征缩放 feature scaling
特征缩放(Feature Scaling)是数据预处理中的一个重要步骤,它涉及到调整不同特征值的尺度,使它们处于相同的量级。这样做的目的是帮助优化算法(比如梯度下降)更快、更有效地收敛。
当特征的尺度(范围)相差很大时,损失函数的等高线图(在参数空间中)将变得非常扁平和延伸。这意味着在某些方向上,损失函数的变化会非常缓慢,而在其他方向上,它可能变化得非常快。在这种情况下,梯度下降算法在尝试找到最小值的过程中,会在较扁平的方向上迈出很小的步伐,而在陡峭的方向上迈出较大的步伐。这会导致算法在参数空间中走“之字形”路径,从而减慢收敛速度。
通过特征缩放,我们可以将所有特征的范围调整到相似的尺度上。这样做的直接结果是,损失函数的等高线将变得更加接近圆形,而不是延伸的椭圆形。这意味着无论梯度下降在哪个方向上进行,步伐的大小都将更加一致,减少了在参数空间中走“之字形”路径的需要。因此,梯度下降能够更直接、更有效地朝着最小值方向前进,从而加快了收敛速度。
常见的特征缩放有:
1、Z-score 标准化 Z-score normalization
x
′
=
x
−
μ
σ
x^{'}=\frac{x-\mu}{\sigma}
x′=σx−μ
如果特征满足正态分布,则Z-标准化将其线性变换为均值为0,标准差为1的标准正态分布
特点:
1、对有异常值的数据有较强的鲁棒性(数据分析前应该先清洗异常数据)
2、对大多数机器学习算法效果好
3、对于非正态分布的数据,效果可能不明显
2、Min-Max 标准化 Min-Max normalization
x
′
=
x
−
x
m
i
n
x
m
a
x
−
x
m
i
n
x^{'}=\frac{x-x_{min}}{x_{max}-x_{min}}
x′=xmax−xminx−xmin
将数据映射到[0,1]区间内,缺点是对对于存在异常值的数据不鲁棒,异常值会显著影响缩放效果
3、最大绝对值缩放 MaxAbs scaling
x
′
=
x
m
a
x
(
a
b
s
(
x
)
)
x^{'}=\frac{x}{max(abs(x))}
x′=max(abs(x))x
将数据映射到[-1,1]区间内,特点是能保持稀疏数据的稀疏性,对于稀疏数据(如文本数据)非常有效
以上特征缩放的代码实现较为简单,读者不妨自己练手实现。
模块四: 引入scikit-learn
scikit-learn 是一个用于机器学习的开源库,基于Python编写,提供了一系列简单且高效的工具进行数据挖掘和数据分析。它建立在NumPy、SciPy和matplotlib等基础科学计算库之上,是Python生态系统中机器学习和数据科学领域的重要工具之一。
数据预处理
下面引入scikit-learn库谈谈如何利用其中的预处理模块快速实现特征缩放。
模块:sklearn.preprocessing(预处理模块)
StandardScaler->Z-score normalization
MinMaxScaler->Min-Max normalization
MaxAbsScaler->MaxAbs scaling
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler, MaxAbsScaler
# 创建示例数据
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 初始化StandardScaler(以Z-score 标准化为例)
scaler = StandardScaler()
# 使用fit_transform方法转化数据
scaled_data = scaler.fit_transform(data)
print("原始数据:")
print(data)
print("标准化后的数据:")
print(scaled_data)
线性回归
sklearn中的linear_model模块用于实现线性回归
LinearRegression:使用normal equation求解最优参数
SGDRegressor:采用随机梯度下降算法(没有现成的批量梯度下降和小批量梯度下降工具,前者可以通过手动编写代码实现,后者可以利用tensorflow中的神经网络框架辅助实现[后续讨论])
from sklearn.linear_model import LinearRegression, SGDRegressor
'''
max_iter=1000:最大迭代次数
eta0=0.01:初始学习率
learning_rate=‘invscaling’:学习率调度策略(详见下方)
penalty='l2':正则化类型
alpha:正则化系数[正则化内容详见正则化部分]
'''
#创建随机梯度下降线性回归器
gdr = SGDRegressor(max_iter=1000,learning_rate=‘adaptive’)
#使用fit方法,匹配数据集进行训练
sgdr.fit(X_norm, y_train)
#训练后查看相关属性
sgdr.n_iter_#实际迭代次数
sgdr.intercept_#回归b值->list
sgdr.coef_#回归w值->list
sgdr.predict(X_new)#模型预测
R2_score=sgdr.score(X_test,y_test)#评估模型性能,返回R^2 score
补充参数解释:
learning_rate string类型,默认’invscaling’
选项:
①’constant’,学习率不变,eta=eta0
②’optimal’:
η
t
=
1
α
t
η_t=\frac{1}{\alpha{t}}
ηt=αt1,使用 Léon Bottou 提出的理论学习率,通常能够更好地适应不同的数据规模和特性。
③’invascaling’:
η
t
=
e
t
a
0
t
p
o
w
e
r
t
η_t=\frac{eta0}{t^{power_{t}}}
ηt=tpowerteta0,其中power_t(默认0.25)是另一个函数参数。使用反向比例缩放学习率,学习率随迭代次数增加而逐渐减小。
④‘adaptive’:自适应学习率策略,当迭代过程中的损失停止改善时,学习率会动态调整。
4.多项式回归 polynomial regression
前面所说的线性回归只适用于线性拟合,对于下图中的数据,y-x函数关系非线性关系,应该使用二次函数进行拟合。
使用二次拟合,我们可以构建二次函数模型:
y
=
w
1
x
+
w
2
x
2
+
b
y=w_1x+w_2x^2+b
y=w1x+w2x2+b
从特征构建的角度,可以将x2视为构建的新特征,因此特征是[x,x2],相当于数据集新增了一列特征,模型的系数仍然是线性的,因此依然可以从线性回归的角度进行处理。
再举一个例子,根据房子的长x1和宽x2预测房价z,可以构建模型:
y
=
w
1
x
1
+
w
2
x
2
+
w
3
x
1
x
2
+
b
y=w_1x_1+w_2x_2+w_3x_1x_2+b
y=w1x1+w2x2+w3x1x2+b
这里的
x
1
x
2
x_1x_2
x1x2表示占地面积,作为构建的新特征。这个非线性模型,提升了模型的学习能力,使模型预测能力更强。
下面用代码演示如何构建高次(多项式)特征并使用线性回归模型进行训练:
下面是示例数据集,example.csv
x,y
1,2
2,-1
3,-14
(!示例中未进行标准化)
import numpy as np
import pandas as pd
from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import StandardScaler
# 读入数据
data = pd.read_csv('example.csv')
# 添加特征
data['x2'] = data['x'] ** 2
data['x3'] = data['x'] ** 3
# 提取 X 和 y
X = data.loc[:, ['x', 'x2', 'x3']].values
y = data['y'].values
# 使用 SGDRegressor 训练模型
sgd_reg = SGDRegressor(max_iter=100000, tol=1e-3, learning_rate='adaptive', eta0=0.01)
sgd_reg.fit(X, y)
# 输出回归系数和截距
print("回归系数:", sgd_reg.coef_)
print("截距:", sgd_reg.intercept_)
'''
输出:
回归系数: [ 1.13031506 1.05802601 -1.02887369]
截距: [0.84275648]
'''
在输出模型进行预测时,相应的数据也应该先计算出额外添加的特征,再使用模型表达式计算预测目标值。
如何使用scikit-learn进行多项式回归?
PolynomialFeatures 是 Scikit-learn 中的一个工具,用于生成多项式特征以及交互特征。这个工具对特征进行扩展,使得原始数据能够适应多项式回归或其他需要多项式特征的模型。以下是 PolynomialFeatures 的详细介绍及其常用方法和参数。
导入方式
from sklearn.preprocessing import PolynomialFeatures
主要参数
degree (default=2):
用于指定生成多项式特征的最高次幂。例如,degree=3 则表示生成最高为三次的多项式特征。
示例:特征
X
1
,
X
2
X_1,X_2
X1,X2,则新构建的特征包括
X
1
2
,
X
1
X
2
,
X
2
2
,
X
1
3
,
X
1
2
X
2
,
X
2
X
1
2
,
X
2
3
X_1^2,X_1X_2,X_2^2,X_1^3,X_1^2X_2,X_2X_1^2,X2^3
X12,X1X2,X22,X13,X12X2,X2X12,X23
interaction_only (default=False):
如果为 True,则生成的多项式特征只包括交互项,不包括各特征自身的多项式项。例如,
方法
X_new=fit_transform(X, y=None)
先拟合数据,再转化数据。返回扩展后的特征矩阵。
transform(X)
将已拟合的模型应用于数据,生成扩展后的特征矩阵。
示例
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
# 创建示例数据
X = np.array([[2, 3], [3, 4], [4, 5]])
# 创建 PolynomialFeatures 实例
poly = PolynomialFeatures(degree=3, include_bias=False)
# 拟合并转换数据
X_poly = poly.fit_transform(X)
print("原始特征:\n", X)
print("多项式特征:\n", X_poly)
模块五:过拟合和欠拟合 overfit and underfit
在学习了多项式回归后,我们可以构建的模型种类就丰富了,线性拟合、二次拟合、高次拟合…是否越高次的拟合(越复杂的多项式)所产生的模型性能就更优越呢?不一定!
看下图,对于相同的数据集(假设近似满足二次函数分布),图一采用线性拟合,明显在训练集中表现不佳,对于新的数据(测试集 test set),可以想到预测结果这不理想,就好比一个学生在平时日常刷题中屡屡不顺,在考试时也发挥差强人意。这种拟合情况称为欠拟合(underfit),呈现出的问题为高偏差(high bias)。
第三个图采用四次拟合,拟合曲线明显复杂了不少,训练集拟合效果比二次拟合还好。但可以想象,在数据集近似满足二次分布的假设下,面对测试集该模型的预测误差会很大。即该模型在训练集中误差很小,而在测试集中误差很大,就好比一个学生,平时练题基本百发百中,但考试面对没见过的题目就不懂变通,发挥牵强人意。这种拟合情况称为过拟合(overfit),呈现出的问题为高方差(high variance)
第二个图采用二次拟合,训练集拟合效果非常好,面对测试集也能作出准确的预测,就好比一个学霸,无论是平时训练还是考场实战,都顺风顺水。这种拟合称为正拟合(right fit),表现为低偏差(low bias),低方差(low variance)。
简而言之,欠拟合就是模型太简单了,无法捕捉数据中的复杂关系,预测能力有限;而过拟合是模型过于复杂,以至于在训练数据中表现非常好,但在新数据(测试数据)上表现很差。这通常是因为模型学习到了训练数据中的噪音和随机波动,而不是数据的真正模式,即过拟合泛化能力差。
泛化(Generalization)是指机器学习模型在新数据(即未见过的数据)上表现良好的能力。简单来说,泛化能力好意味着模型不仅能够在训练集上表现良好,还能够在测试集或实际应用中保持较高的预测准确度。
如何解决过拟合和欠拟合的问题,即如何避免高偏差和高方差,是一个很大的专题,在详细展开讨论这个专题之前,我们需要先引入正则化这一避免过拟合的重要方法。
模块六:正则化 regularization
正则化的核心思想是将多项式系数当做惩罚项引入代价函数,实现精确拟合,避免过拟合。
在上面过拟合图示中,我们使用四次函数进行拟合
y
=
w
1
x
1
+
w
2
x
2
+
w
3
x
3
+
w
4
x
4
+
b
y=w_1x_1+w_2x_2+w_3x_3+w_4x_4+b
y=w1x1+w2x2+w3x3+w4x4+b
我们知道最佳拟合应该是二次拟合,那么如果
w
3
,
w
4
→
0
w_3,w_4\rightarrow{0}
w3,w4→0,那么拟合效果就近似于二次拟合。这给我们的启示是,多项式模型应追求在减小误差的同时,在优化过程中应倾向于使高次项的系数趋近于零,从而降低模型的复杂度,引入权重平方和构成的平方项后,损失函数调整为:
J
(
w
⃗
,
b
)
=
1
2
m
∑
i
=
1
m
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
2
+
λ
2
m
∑
j
=
1
n
w
j
2
J(\vec{w},b)=\frac{1}{2m}\sum_{i=1}^{m}(\vec{w}\cdot{\vec{x}^{(i)}}+b-y^{(i)})^2+\frac{\lambda}{2m}\sum_{j=1}^{n}w_j^2
J(w,b)=2m1i=1∑m(w⋅x(i)+b−y(i))2+2mλj=1∑nwj2
这也称为L2正则化,如果将平方项改为绝对值项,则称为L1正则化,我们主要讨论前者。
其中的
λ
\lambda
λ称为正则化系数,如果
λ
\lambda
λ太小,那么正则化效果不明显,如果
λ
\lambda
λ太大,那么所有的权重都会被调整得很小,使模型过于简单,因此选取合适的
λ
\lambda
λ很重要,一般
λ
\lambda
λ设置为0.01。
引入惩罚项后,重新计算偏导:
∂
∂
w
j
J
(
w
⃗
,
b
)
=
1
m
∑
i
=
1
m
x
j
(
i
)
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
+
λ
m
w
j
\frac{\partial}{\partial{w_j}}J(\vec{w},b)=\frac{1}{m}\sum_{i=1}^{m}x_j^{(i)}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})+\frac{\lambda}{m}w_j
∂wj∂J(w,b)=m1i=1∑mxj(i)(w⋅x(i)+b−y(i))+mλwj
∂
∂
b
J
(
w
⃗
,
b
)
=
1
m
∑
i
=
1
m
(
w
⃗
⋅
x
⃗
(
i
)
+
b
−
y
(
i
)
)
\frac{\partial}{\partial{b}}J(\vec{w},b)=\frac{1}{m}\sum_{i=1}^{m}(\vec{w}\cdot\vec{x}^{(i)}+b-y^{(i)})
∂b∂J(w,b)=m1i=1∑m(w⋅x(i)+b−y(i))
将前面的线性回归代码(手动编写)略加修改,就能将线性回归模型正则化。
如果利用sckit-learn进行线性回归,引入正则化很简单,只需在创建回归器时,设置参数penalty=‘l2’,事实上不需要手动设置,因为默认参数就是’l2’,再通过alpha设置正则化系数,示例:
gdr = SGDRegressor(max_iter=1000,learning_rate=‘adaptive’,penalty='l2',alpha=0.01)
5.回归算法优化 regression algoirthm optimization
机器学习算法的迭代过程可以用下图表示:
迭代周期由三个步骤构成,循环进行,三个步骤是:
①选择数据集、构建选择模型
②训练模型
③模型评估(评估方差、偏差和误差分析)和优化
对三个步骤进行具体分析如下:
①选择数据集、构建模型:
收集并准备数据:这包括获取原始数据、清洗数据、处理缺失值、进行特征工程和选择适当的特征。
选择并构建模型:根据问题的性质(回归、分类、聚类等),选择适当的算法和模型。
②训练模型
分割数据:通常将数据分为训练集和测试集(有时还有验证集),以便评估模型性能。
训练模型:使用训练数据来拟合模型。对于监督学习,模型将学习输入特征和输出目标之间的关系。
调整超参数:在训练过程中,通过交叉验证或其他方法来调整模型的超参数,以找到最佳配置。
③模型评估和优化
评估模型:使用测试数据评估模型的性能,常用的评估指标包括准确率、精确率、召回率、F1分数、均方误差等。
分析偏差和方差:检查模型的偏差(bias)和方差(variance)。高偏差通常意味着模型过于简单,难以捕捉数据中的复杂模式;高方差则可能意味着模型过拟合训练数据。
优化模型:基于评估结果,进一步优化模型。这可能包括增加更多的数据、更改模型的架构、调整超参数或选择不同的特征。
误差分析:深入分析模型的误差,找出模型在某些特定情况下表现不佳的原因,并采取相应措施进行改进。
超参数
模型的超参数(Hyperparameters)是指在训练机器学习模型之前需要设置的参数,它们不能通过模型从数据中学习得到,而是需要在模型训练之前手动设定的。超参数的选择对模型的性能有着重要影响,因此在机器学习中通常会通过实验、交叉验证等方法来调优这些超参数。
例如在线性回归模型中,学习率 α \alpha α、正则化系数 λ \lambda λ都是模型预设的参数,属于超参数。而权重 w ⃗ \vec{w} w和偏置 b b b都是训练过程中不断调整的,不属于超参数。
模块七: 训练集、验证集和测试集 dataset split
在模型训练过程中,只有训练集是不够的,即使模型在训练过程中表现优异,但如果没有检验其在新数据集中的表现,就无法检测其泛化能力,如果直接发布应用,模型可能表现得非常一般。
因此一般获取数据集后,对数据集进行分割,分为训练集(train set)和测试集(test set)。分割的比例一般是7:3或6:4。训练集用于训练模型,例如在回归任务中,机器通过不断学习特征和目标之间的映射关系,优化参数,最终生成具备一定预测能力的模型。而测试集用于检验模型的性能,指示模型存在的问题和下一步优化的方向。如果训练误差 J t r a i n J_{train} Jtrain和测试误差 J t e s t J_{test} Jtest都较大,则说明模型存在欠拟合的情况,应想方法降低偏差;如果训练误差 J t r a i n J_{train} Jtrain较小,而测试误差 J t e s t J_{test} Jtest远大于 J t r a i n J_{train} Jtrain,则说明模型存在过拟合的情况,应想方法降低方差。
用sklearn中的model_selection模块能很快速实现将数据集分割为训练集和测试集。test_size=0.33表示测试集占1/3,。
#random_state:随机种子
from sklearn.model_selection import train_test_split
X_train, X_test, y_train,y_test=train_test_split(X,y,test_size=0.33,random_state=1)
假设现在在多项式回归中训练了两个模型A(最高次数为4)和B(最高次数为6),A模型在训练集中预测正确率为98.5%,B模型在训练集中预测正确率为98.9%,两个模型的都表现得非常优异,那如何在两个模型中进行选择呢?有人会说,用测试集进行测试吧,假设A模型测试正确率为88%,B模型测试正确率为90%,那么就说明B模型更好,这样看似合理,实际存在一定弊端。一个主要的弊端是:据test set选择了多项式次数d(超参数),又使用test set来评估模型,容易估计误差比实际偏小。
为了解决这一弊端,引入交叉验证集(cross validation set,简称cv)。暂时不管’交叉’的含义,称之为验证集。验证集的主要功能就是进行超参数调整和模型选择。sklearn中没有直接数据集分割为训练集、验证集、测试集三个部分的函数,但可以通过两次调用train_test_split函数来实现这一目的,下面是示例代码,分割比例为训练集:验证集:测试集=6:2:2:
#random_state:随机种子
from sklearn.model_selection import train_test_split
X_train, X_, y_train,y_=train_test_split(X,y,test_size=0.4,random_state=1)
X_cv,X_test,y_cv,y_test=train_test_split(X,y,test_split=0.5,random_state=1)
下面是模型选择的一个示例,验证集的作用用于选择超参数多项式系数:
模块八:偏差和方差 bias and variance
一个好的模型不能存在高偏差或高方差的问题,这一模块讨论如何从数据集、超参数等角度入手,识别模型存在的缺陷,然后设法调整模型的偏差与方差,提升模型的性能。
多项式次数
下图横轴表示多项式次数(d),纵轴表示训练集误差
J
t
r
a
i
n
J_{train}
Jtrain和验证集误差
J
c
v
J_{cv}
Jcv。首先对于同一多项式次数,验证集误差正常情况下都比训练集误差大。在d较小时,
J
c
v
J_{cv}
Jcv和
J
t
r
a
i
n
J_{train}
Jtrain都较大,高偏差,出现了欠拟合;在d取中间值时,
J
c
v
J_{cv}
Jcv和
J
t
r
a
i
n
J_{train}
Jtrain都较小,低偏差同时低方差,处于正拟合;在d较小时,
J
t
r
a
i
n
J_{train}
Jtrain极小,
J
c
v
J_{cv}
Jcv很大,高方差,出现了过拟合。因此得出结论:
①多项式回归中,出现高方差问题时,可以通过适当降低多项式次数降低方差
②多项式回归中,出现高偏差问题时,可以通过适当增加多项式次数降低偏差
正则化系数
下图横轴表示正则化系数
λ
\lambda
λ,纵轴表示训练集误差
J
t
r
a
i
n
J_{train}
Jtrain和验证集误差
J
c
v
J_{cv}
Jcv。在
λ
\lambda
λ较小时,惩罚项作用小,出现了过拟合,高偏差,
J
t
r
a
i
n
J_{train}
Jtrain极小,
J
c
v
J_{cv}
Jcv很大;在
λ
\lambda
λ取中间值时,
J
c
v
J_{cv}
Jcv和
J
t
r
a
i
n
J_{train}
Jtrain都较小,低偏差同时低方差,处于正拟合;在
λ
\lambda
λ较大时,为了使J足够小,权重次数趋近于0,出现了欠拟合,低偏差,
J
t
r
a
i
n
J_{train}
Jtrain和
J
c
v
J_{cv}
Jcv很较大。因此得出结论:
①正则化中,出现高方差问题时,可以通过适当升高正则化系数降低方差
②正则化中,出现高偏差问题时,可以通过适当降低正则化系数降低偏差
训练数据量
研究验证误差和训练误差随训练集数据量变化曲线,也称之为学习曲线。[下面的学习曲线通过程序模拟实验验证]
正拟合情况下学习曲线:
在正拟合情况下,随着数据量增大,训练集误差缓慢增大,最终趋于稳定;验证集误差一开始较大,因为有限数据量只能初步搭建简单的模型,随着数据量增大,模型逐渐完善,因此验证集误差下降,最终也趋于稳定。
欠拟合情况下学习曲线:
可以观察学习曲线得到,在欠拟合情况下,增大数据量无法改变训练误差和验证误差都很大的现象。
过拟合情况下学习曲线:
过拟合情况下,验证集误差远大于训练集误差,但随着数据量增大,验证集误差减小,训练集误差增大,两种误差最终趋近相等,由此得出结论:
增大数据量有助于解决过拟合问题,降低方差
(这一点不太好理解,附另外的解释:
①更多的数据通常代表更丰富的特征和更广泛的样本分布,这使得模型能学到更一般化的模式,而不仅仅是特定于训练集的特征。这样,模型在面对新数据时能够更好地泛化。
②当数据量较小时,模型容易将训练数据中的噪声和特异点误认为是有用的信号。增大数据量可以使这些噪声和特异点被更多的正常样本所掩盖,从而降低它们对模型的影响。)
特征选择
除了上面讨论的几个方面外,特征的正确选择也与方差和偏差密切相关。如果只用房子面积一个特征预测房价,这个预测器能力肯定是有限的,因为没能考虑与房价密切相关的更多房子特征,例如房子年龄、房间数量、房子地理位置等等,因此合理增加特征有利于降低偏差。当然特征并不是多多益善,而应恰到好处,如果冗杂了大量与目标值关系甚微甚至完全无关的特征,只会阻碍模型捕捉关键联系,构建过于复杂的模型,导致过拟合,因此适当减少特征有利于降低方差。在处理原始数据集时,如何有效地进行特征选择、特征编码等等,属于特征工程的内容,需要在机器学习探索过程中不断学习积累。
方差和偏差总结
降低偏差的方法(解决欠拟合) | 降低方差的方法(解决过拟合) |
---|---|
减小正则化系数 | 增大正则化系数 |
适当增加特征(多项式次数) | 适当减少特征(多项式次数) |
/ | 增加数据量 |