机器学习
机器学习01——初识机器学习
机器学习02——数据与算法初步
机器学习03——数据与算法初步2
机器学习04——初识梯度下降
文章目录
一、训练策略
在梯度下降算法中我们有这三种训练策略:
- Batch Gradient Descent (BGD): 在这种情况下,每一次迭代都会使用全部的训练样本计算梯度来更新权重。这意味着每一步梯度更新都是基于整个数据集的平均梯度。这种方法的优点是每次更新的方向是最准确的,但缺点是计算量大且速度慢,尤其是在大数据集上。
- Mini-Batch Gradient Descent (MBGD): 这种方法介于批量梯度下降和随机梯度下降之间。它不是用全部样本也不是只用一个样本,而是每次迭代从数据集中随机抽取一小部分样本(例如,从500个样本中选取32个),然后基于这一小批样本的平均梯度来更新权重。这种方法在准确性和计算效率之间取得了一个平衡。
- Stochastic Gradient Descent (SGD): 在随机梯度下降中,每次迭代仅使用随机单个样本(或有时称为“例子”)来计算梯度并更新权重。这种方法能够更快地收敛,但由于每次更新都基于单个样本,所以会导致权重更新路径不稳定。

图中的椭圆为损失的等高线,带色曲线为梯度下降的方向。
1.1 批量梯度下降
在上一篇文章的例子中,我们构建损失函数时,带入的是数据集中的全部函数这就是
批量梯度下降,也叫Batch Gradient Descent (BGD)。
- 更新规则
假设我们有一个包含 ( m ) 个训练样本的数据集 { ( x ( i ) , y ( i ) ) } i = 1 m \{(x^{(i)}, y^{(i)})\}_{i=1}^{m} {(x(i),y(i))}i=1m,其中 x ( i ) x^{(i)} x(i)是输入特征, y ( i ) y^{(i)} y(i) 是对应的标签。我们的目标是最小化损失函数 J ( θ ) J(\theta) J(θ) 相对于模型参数 θ \theta θ的值。
则损失函数可以定义为: J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2 其中 h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i)) 是模型对第 i i i个样本的预测输出。
而批量梯度下降的更新规则为: θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) \cdot x_j^{(i)} θj:=θj−αm1i=1∑m(hθ(x(i))−y(i))⋅xj(i) 对于 j = 0 , 1 , … , n j= 0, 1, \ldots, n j=0,1,…,n (其中 n n n 是特征的数量),并且 α \alpha α 是学习率。
- 特点
- 准确性:由于使用了所有训练样本,所以得到的梯度是最准确的,这有助于找到全局最小值。
- 计算成本:每次更新都需要遍历整个数据集,因此计算量较大,特别是在数据集很大的情况下。
- 收敛速度:虽然每一步的更新都是准确的,但由于计算成本较高,实际收敛到最小值的速度可能不如其他方法快。
- 内存需求:需要在内存中存储整个数据集,对于大型数据集来说可能成为一个问题。
- 使用场景
- 小数据集:当数据集较小时,批量梯度下降是一个不错的选择,因为它能保证较好的收敛性和准确性。
- 不需要实时更新:如果模型不需要实时更新,例如在离线训练场景下,批量梯度下降是一个合理的选择。
- 实现注意事项
- 选择合适的学习率:选择合适的学习率对于快速且稳定的收敛至关重要。如果学习率太小,收敛速度会很慢;如果太大,则可能会导致不收敛。
- 数据预处理:对数据进行标准化或归一化,可以提高批量梯度下降的效率。
- 监控损失函数:定期检查损失函数的变化趋势,确保算法正常工作并朝着正确的方向前进。
1.2 随机梯度下降
基本步骤
初始化参数:
- 选择一个初始点作为参数向量 θ \theta θ的初始值。
选择样本:
- 随机选取一个训练样本 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))。
计算梯度:
- 使用所选样本 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))来近似计算损失函数 J ( θ ) J(\theta) J(θ)的梯度 ∇ J ( θ ) \nabla J(\theta) ∇J(θ)。
更新参数:
- 根据梯度的方向来更新参数 θ \theta θ。更新公式为:
θ = θ − α ⋅ ∇ J ( θ ) \theta = \theta - \alpha \cdot \nabla J(\theta) θ=θ−α⋅∇J(θ)- 其中 α \alpha α 是学习率,决定了每次迭代时参数更新的步长。
重复步骤 2 到 4:
- 对所有的训练样本重复此过程,直到完成一个完整的 epoch(即所有样本都被访问过一次)。
重复多个 epoch:
- 重复上述过程,直到满足某个停止条件,比如达到最大迭代次数或者梯度足够小。
输出结果:
- 输出最小化损失函数后的最优参数 θ ∗ \theta^* θ∗。
数学公式
假设我们有一个包含 (m) 个样本的数据集 { ( x ( i ) , y ( i ) ) } i = 1 m \{(x^{(i)}, y^{(i)})\}_{i=1}^m {(x(i),y(i))}i=1m,其中 x ( i ) x^{(i)} x(i)
是第 i i i 个样本的特征向量, y ( i ) y^{(i)} y(i) 是对应的标签。对于线性回归问题,损失函数 J ( θ ) J(\theta) J(θ) 可以定义为均方误差(Mean Squared Error, MSE): J ( θ ) = 1 2 ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2}(h_\theta(x^{(i)})- y^{(i)})^2 J(θ)=21(hθ(x(i))−y(i))2 其中 h θ ( x ( i ) ) = θ T x ( i ) h_\theta(x^{(i)}) = \theta^T x^{(i)} hθ(x(i))=θTx(i)是模型对第 i i i个样本的预测值。梯度 ∇ J ( θ ) \nabla J(\theta) ∇J(θ) 对于每个参数 θ j \theta_j θj 的偏导数可以表示为: ∂ J ( θ ) ∂ θ j = ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial J(\theta)}{\partial \theta_j} = (h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)} ∂θj∂J(θ)=(hθ(x(i))−y(i))xj(i)
更新规则
参数
θ
\theta
θ 的更新规则为:
θ
j
:
=
θ
j
−
α
⋅
∂
J
(
θ
)
∂
θ
j
\theta_j := \theta_j - \alpha \cdot \frac{\partial J(\theta)}{\partial \theta_j}
θj:=θj−α⋅∂θj∂J(θ)
注意事项
- 学习率 α \alpha α: 需要适当设置,太大会导致算法不收敛,太小则收敛速度慢。
- 随机性: 每次迭代都从训练集中随机选择一个样本,这有助于避免陷入局部最小值。
- 停止条件: 可以是达到预定的最大迭代次数,或者梯度的范数小于某个阈值。
随机梯度下降的一个关键优势在于它能够快速地进行迭代并适应较大的数据集。然而,由于每次只使用一个样本进行更新,梯度估计可能较为嘈杂,这可能导致更新过程中出现较大的波动。在实际应用中,可以通过减少学习率(例如采用学习率衰减策略)来解决这个问题。
1.3 小批量梯度下降
- 更新规则
假设我们有一个包含 ( m ) 个训练样本的数据集 { ( x ( i ) , y ( i ) ) } i = 1 m \{(x^{(i)}, y^{(i)})\}_{i=1}^{m} {(x(i),y(i))}i=1m,其中 $ x^{(i)} $ 是输入特征,$y^{(i)} $ 是对应的标签。我们将数据集划分为多个小批量,每个小批量包含 ( b ) 个样本,其中 ( b ) 称为批量大小(batch size),通常 ( b ) 远小于 ( m )。
损失函数可以定义为: J ( θ ) = 1 2 b ∑ i = 1 b ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2b} \sum_{i=1}^{b} (h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2b1i=1∑b(hθ(x(i))−y(i))2
其中 h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i)) 是模型对第 i i i 个样本的预测输出。
小批量梯度下降的更新规则为: θ j : = θ j − α 1 b ∑ i ∈ B ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{b} \sum_{i \in B} (h_\theta(x^{(i)}) - y^{(i)}) \cdot x_j^{(i)} θj:=θj−αb1i∈B∑(hθ(x(i))−y(i))⋅xj(i) 对于 j = 0 , 1 , … , n j = 0, 1, \ldots, n j=0,1,…,n (其中 n n n是特征的数量),并且 α \alpha α 是学习率, B B B 表示当前小批量中的样本索引集合。
- 特点
- 计算效率:相比于批量梯度下降,小批量梯度下降每次更新只需要处理一部分数据,减少了计算成本。
- 梯度估计:相比于随机梯度下降,小批量梯度下降提供了更准确的梯度估计,这有助于更稳定地接近最小值。
- 内存需求:相比批量梯度下降,小批量梯度下降降低了内存需求,但仍然比随机梯度下降要高。
- 收敛速度与稳定性:小批量梯度下降能够在保持较快的收敛速度的同时,维持相对较高的稳定性。
使用场景
- 中等规模数据集:当数据集大小适中时,小批量梯度下降是一个很好的折衷方案,既能够高效处理数据,又能够保持良好的收敛性。
- 在线学习:在数据流式到达的场景下,小批量梯度下降可以有效地处理新到来的数据批次。
- 分布式环境:在分布式计算环境中,小批量梯度下降可以更容易地在多台机器上并行执行。
实现注意事项
- 选择合适的批量大小:批量大小的选择对性能有很大影响。较大的批量可以减少迭代次数,但计算成本增加;较小的批量则相反。
- 选择合适的学习率:选择合适的学习率对于快速且稳定的收敛至关重要。如果学习率太小,收敛速度会很慢;如果太大,则可能会导致不收敛。
- 数据预处理:对数据进行标准化或归一化,可以提高小批量梯度下降的效率。
- 监控损失函数:定期检查损失函数的变化趋势,确保算法正常工作并朝着正确的方向前进。
二、梯度下降优化
2.1 欠拟合过拟合
欠拟合
欠拟合是指模型在训练数据上表现不佳,同时在新的未见过的数据上也表现不佳。这通常发生在模型过于简单,无法捕捉数据中的复杂模式时。欠拟合模型的表现特征如下:
- 训练误差较高。
- 测试误差同样较高。
- 模型可能过于简化,不能充分学习训练数据中的模式。
过拟合
过拟合是指模型在训练数据上表现得非常好,但在新的未见过的数据上表现较差。这通常发生在模型过于复杂,以至于它不仅学习了数据中的真实模式,还学习了噪声和异常值。过拟合模型的表现特征如下:
- 训练误差非常低。
- 测试误差较高。
- 模型可能过于复杂,以至于它对训练数据进行了过度拟合。
2.2 正则化
正则化就是防止过拟合,增加模型的鲁棒性,本质就是牺牲模型在训练集上的正确率来提高推广、泛化能力,W在数值上越小越好,这样能抵抗数值的扰动。同时为了保证模型的正确率W又不能极小。因此将原来的损失函数加上一个惩罚项使得计算出来的模型W相对小一些,就是正则化。
鲁棒即Robust,也就是强壮的意思。就像计算机软件在面临攻击、网络过载等情况下能够不死机不崩溃,这就是软件的鲁棒性,鲁棒性调优就是让模型拥有更好的鲁棒性,也就是让模型的泛化能力和推广能力更加的强大。
这里假设有两个方程描述同一条直线:
(
1
)
:
y
=
0.5
x
1
+
0.6
x
2
+
0.7
(1):y=0.5x_1+0.6x_2+0.7
(1):y=0.5x1+0.6x2+0.7
(
2
)
:
y
=
5
x
1
−
6
x
2
+
7
(2):y=5x_1-6x_2+7
(2):y=5x1−6x2+7
可以看到方程(2)其系数几乎是方程(1)的10倍,这意味着同一份输入同一份测试数据,方程(2)产生的误差可能远远大于方程方程(1)误差。也就是说,当 x x x有一点错误,这个错误会通过w放大。
常用的惩罚项有L1正则项或者L2正则项:
L 1 = ∣ ∣ w ∣ ∣ 1 = ∑ i = 1 n ∣ w i ∣ L1=||w||_1=\textstyle\sum_{i=1}^{n}|w_i| L1=∣∣w∣∣1=∑i=1n∣wi∣ 对应曼哈顿距离
L 2 = ∣ ∣ w ∣ ∣ 2 = ∑ i = 1 n x i p , X = ( x 1 , x 2 , . . . x n ) p L2=||w||_2=\textstyle\sqrt[p]{\sum_{i=1}^{n}x^p_i,X=(x_1,x_2,...x_n)} L2=∣∣w∣∣2=p∑i=1nxip,X=(x1,x2,...xn)
对应欧氏距离其实 L 1 L1 L1 和 L 2 L2 L2 正则的公式在数学里面的意义就是范数,代表空间中向量到原点的距离,当用于损失函数时,就表示w到原点的距离。当特征仅有2个时,其图像如下:
岭回归
当我们把多元线性回归损失函数加上 L 2 L2 L2正则的时候,就诞生了Ridge岭回归。
- 损失函数公式:
均方差除以2是因为方便求导
其中,
w
j
w_j
wj指所有的权重系数, λ指惩罚型系数,又叫正则项力度。当特征仅有2个时,将原本的损失函数与L2正则一起画出则有:
特点:
- 岭回归不会将权重压缩到零,这意味着所有特征都会保留在模型中,但它们的权重会被缩小。
- 适用于特征间存在多重共线性的情况。
- 岭回归产生的模型通常更为平滑,因为它对所有特征都有影响。
- api
具有L2正则化的线性回归-岭回归。
sklearn.linear_model.Ridge()
1 参数:
(1)alpha, default=1.0,正则项力度
(2)fit_intercept, 是否计算偏置, default=True
(3)solver, {‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’, ‘lbfgs’}, default=’auto’
当值为auto,并且数据量、特征都比较大时,内部会随机梯度下降法。
(4)normalize:,default=True, 数据进行标准化,如果特征工程中已经做过标准化,这里就该设置为False
(5)max_iterint, default=None,梯度解算器的最大迭代次数,默认为15000
2 属性
coef_ 回归后的权重系数
intercept_ 偏置
说明:SGDRegressor也可以做岭回归的事情,比如SGDRegressor(penalty='l2',loss="squared_loss"),但是其中梯度下降法有些不同。所以推荐使用Ridge实现岭回归
- 示例
housing=fetch_california_housing(data_home='./src')
x=housing.data
y=housing.target
# 数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=666)
# 标准化
scaler=StandardScaler()
scaler.fit(x_train)
x_train=scaler.transform(x_train)
x_test=scaler.transform(x_test)
# 模型
model=Ridge(alpha=0.1,max_iter=100,fit_intercept=True)
model.fit(x_train,y_train)
y_hat=model.predict(x_test)
print("w:",model.coef_,"b:",model.intercept_,"loss:",np.mean(mean_squared_error(y_test,y_hat)))
拉索回归
当我们把多元线性回归损失函数加上 L 1 L1 L1正则的时候,就孕育出来了Lasso回归。
-
损失函数公式:
J(w) = 1 2 n ∑ i = 1 n ( h w ( x i ) − y i ) 2 + λ ∑ j = 1 p ∣ w j ∣ \text{J(w)}= \frac{1}{2n}\sum_{i=1}^n (h_w(x_i)-y_i)^2 + \lambda \sum_{j=1}^p |w_j| J(w)=2n1i=1∑n(hw(xi)−yi)2+λj=1∑p∣wj∣ -
api
sklearn.linear_model.Lasso()
参数:
- alpha (float, default=1.0): 控制正则化强度;必须是非负浮点数。较大的 alpha 增加了正则化强度。
- fit_intercept (bool, default=True): 是否计算此模型的截距。如果设置为 False,则不会使用截距(即数据应该已经被居中)。
- precompute (bool or array-like, default=False): 如果为 True,则使用预计算的 Gram 矩阵来加速计算。如果为数组,则使用提供的 Gram 矩阵。
- copy_X (bool, default=True): 如果为 True,则复制数据 X,否则可能对其进行修改。
- max_iter (int, default=1000): 最大迭代次数。
- tol (float, default=1e-4): 精度阈值。如果更新后的系数向量减去之前的系数向量的无穷范数除以 1 加上更新后的系数向量的无穷范数小于 tol,则认为收敛。
- warm_start (bool, default=False): 当设置为 True 时,再次调用 fit 方法会重新使用之前调用 fit 方法的结果作为初始估计值,而不是清零它们。
- positive (bool, default=False): 当设置为 True 时,强制系数为非负。
- random_state (int, RandomState instance, default=None): 随机数生成器的状态。用于随机初始化坐标下降算法中的随机选择。
- selection ({‘cyclic’, ‘random’}, default=‘cyclic’): 如果设置为 ‘random’,则随机选择坐标进行更新。如果设置为 ‘cyclic’,则按照循环顺序选择坐标。
属性:
- coef_:系数向量或者矩阵,代表了每个特征的权重。
- intercept_:截距项(如果 fit_intercept=True)。
- n_iter_:实际使用的迭代次数。
- n_features_in_ (int):训练样本中特征的数量。
- 示例:
# 数据集
housing=fetch_california_housing(data_home='./src')
x=housing.data
y=housing.target
# 数据集划分
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=666)
# 标准化
scaler=StandardScaler()
scaler.fit(x_train)
x_train=scaler.transform(x_train)
x_test=scaler.transform(x_test)
# 模型
model=Lasso(alpha=0.1,max_iter=100,fit_intercept=True)
model.fit(x_train,y_train)
y_hat=model.predict(x_test)
print("w:",model.coef_,"b:",model.intercept_,"loss:",np.mean(mean_squared_error(y_test,y_hat)))
三、逻辑回归
逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,虽然名字中带有回归,但是它与回归之间有一定的联系。由于算法的简单和高效,在实际中应用非常广泛。逻辑回归一般用于二分类问题。
3.1 原理
逻辑回归就是在原本的线性回归的外面再套一层函数,为的是将原本线性回归的运算结果从 ( − ∞ , + ∞ ) (-\infty, +\infty) (−∞,+∞)映射到固定区间上。
这里以sigmoid激活函数
f
(
x
)
=
1
1
+
e
−
x
f(x) = \frac{1}{1 + e^{-x}}
f(x)=1+e−x1为例,将线性回归函数
h
(
w
)
=
w
1
x
1
+
w
2
x
2
+
.
.
.
.
+
b
h(w)=w_1x_1+w_2x_2+....+b
h(w)=w1x1+w2x2+....+b,作为其输入可得
f
(
w
)
=
1
1
+
e
−
h
(
w
)
f(w)=\frac{1}{1+e^{-h(w)}}
f(w)=1+e−h(w)1。sigmoid激活函数图像如下:
可得
f
(
w
)
=
1
1
+
e
−
h
(
w
)
f(w)=\frac{1}{1+e^{-h(w)}}
f(w)=1+e−h(w)1的输出范围为
(
0
,
1
)
(0,1)
(0,1),我们通常将映射到
(
0
,
1
)
(0,1)
(0,1)后的结果作为预测的概率值。
3.2 交叉熵损失函数
这里以二分类为例,下面的回归函数预测的是为1的概率。
这里的损失计算就不能再使用均方误差了,由于回归结果均在
(
0
,
1
)
(0,1)
(0,1)上,故使用均方误差得出的值通常很小不利于计算。而上面的损失计算函数我们称之为交叉熵损失函数。
对于一个二分类问题,其交叉熵损失函数通常形式如下:
其中
h
θ
(
w
)
h_θ(w)
hθ(w)是预测概率,这里为
h
θ
(
w
)
=
1
1
+
e
−
(
w
1
x
1
+
w
2
x
2
+
.
.
.
.
+
b
)
h_θ(w)=\frac{1}{1+e^{-(w_1x_1+w_2x_2+....+b)}}
hθ(w)=1+e−(w1x1+w2x2+....+b)1。
根据损失函数定义可知,
当y=1时,我们希望
h
θ
(
x
)
h_\theta(x)
hθ(x) 值越大越好;
当y=0时,我们希望
h
θ
(
x
)
h_\theta(x)
hθ(x) 值越小越好。
故我们可使用对数函数性质来辅助构建损失函数
当y=1时:
然后使用梯度下降算法,去减少损失函数的值,这样去更新逻辑回归前面对应算法的权重参数,提升原本属于1类别的概率,降低原本是0类别的概率。
而多分类预测中,损失函数计算略有差异,
如果样本属于第 i 类,则 y_i = 1。其他所有位置 y_j = 0 (其中 j ≠ i)。
例如:C = 3,样本属于第 2 类,则 y = [0, 1, 0]。
单个样本的交叉熵损失定义为:L(y, ŷ) = - Σ [y_i * log(ŷ_i)]
3.3 api与示例
- sklearn.linear_model.LogisticRegression()
参数:
- fit_intercept bool, default=True 指定是否计算截距
- max_iter int, default=100 最大迭代次数。迭代达到此数目后,即使未收敛也会停止。
模型对象:
- .coef_ 权重
- .intercept_ 偏置
- predict()预测分类
- predict_proba()预测分类(对应的概率)
- score()准确率
data=pd.read_csv('./src/titanic/titanic.csv')
# print(data.head())
print(data.columns)
y=data['survived']
# print(y.shape)
x=data[['pclass', 'age', 'sex']]
x['age'].fillna(x['age'].mean(), inplace=True)
# print(x.isnull())
dicter=DictVectorizer(sparse=False)
x=dicter.fit_transform(x.to_dict(orient='records'))
# print(dicter.get_feature_names_out())
# print(x)
scaler=StandardScaler()
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=666)
x_train=scaler.fit_transform(x_train)
x_test=scaler.transform(x_test)
model=LogisticRegression(max_iter=1000,fit_intercept=True)
model.fit(x_train,y_train)
print(model.score(x_test,y_test))
总结
本文简要介绍了机器学习中的三种训练策略,其中最常用的还是MBGD。此外海讲解了梯度下降法的一种优化策略,即针对过拟合而使用的正则化。最后还讲解了逻辑回归。