Scikit Learn - 随机梯度下降

本文,我们将学习 Sklearn 中的一种优化算法,即随机梯度下降 (SGD)。

随机梯度下降 (SGD) 是一种简单而高效的优化算法,用于找到最小化成本函数的函数参数/系数值。换句话说,它用于在凸损失函数(例如 SVM 和 Logistic 回归)下对线性分类器进行判别学习。由于系数的更新是在每个训练实例上执行的,而不是在实例结束时执行,因此它已成功应用于大规模数据集。

SGD 分类器

随机梯度下降 (SGD) 分类器基本上实现了一个简单的 SGD 学习程序,支持各种损失函数和分类惩罚。 Scikit-learn 提供了 SGDClassifier 模块来实现 SGD 分类。

参数

下表列出了 SGDClassifier 模块使用的参数 −

Sr.No 参数及说明
1

loss − str,默认值 = 'hinge'

它表示实现时要使用的损失函数。默认值为 'hinge',它将返回一个线性 SVM。其他可用的选项包括 −

  • log − 此损失函数将返回逻辑回归,即概率分类器。

  • modified_huber − 平滑损失函数,在概率估计的同时,还能够容忍异常值。

  • squared_hinge − 与 'hinge' 损失函数类似,但受到二次惩罚。

  • perceptron −顾名思义,它是感知器算法使用的线性损失。

2

penalty − str, 'none', 'l2', 'l1', 'elasticnet'

这是模型中使用的正则化项。默认情况下,它是 L2。我们也可以使用 L1 或 'elasticnet',但两者都可能给模型带来稀疏性,因此 L2 无法实现。

3

alpha −浮点型,默认值 = 0.0001

Alpha 是与正则化项相乘的常数,它是一个调整参数,决定了我们要对模型施加多少惩罚。默认值为 0.0001。

4

l1_ratio − 浮点型,默认值 = 0.15

这被称为 ElasticNet 混合参数。其范围是 0 <= l1_ratio <= 1。如果 l1_ratio = 1,则惩罚为 L1 惩罚。如果 l1_ratio = 0,则惩罚项为 L2 惩罚项。

5

fit_intercept − 布尔值,默认值为 True

此参数指定应向决策函数添加一个常数(偏差或截距)。如果设置为 false,则计算中将不使用截距,并且假定数据已经居中。

6

tol − 浮点数或无,可选,默认值 = 1.e-3

此参数表示迭代的停止标准。其默认值为 False,但如果设置为 None,则当𝒍loss > best_loss - tol for n_iter_no_change个连续 epoch 时,迭代将停止。

7

shuffle − 布尔值,可选,默认值 = True

此参数表示我们是否希望在每个 epoch 后对训练数据进行 shuffle。

8

verbose − 整数,默认值 = 0

它表示详细程度。默认值为 0。

9

epsilon − float,默认值 = 0.1

此参数指定不敏感区域的宽度。如果 loss = 'epsilon-insensitive',则当前预测与正确标签之间任何小于阈值的差异都将被忽略。

10

max_iter − int,可选,默认值 = 1000

顾名思义,它表示在迭代次数(即训练数据)中的最大迭代次数。

11

warm_start − bool,可选,默认值 = false

将此参数设置为 True,我们可以重用上一次调用的结果进行拟合初始化。如果选择默认值,即 false,则会擦除上一次的结果。

12

random_state − int,RandomState 实例或 None,可选,默认值 = none

此参数表示生成的伪随机数的种子,用于对数据进行混洗。以下是选项。

  • int − 在本例中,random_state 是随机数生成器使用的种子。

  • RandomState 实例 − 在本例中,random_state 是随机数生成器。

  • None −在本例中,随机数生成器是 np.random 使用的 RandonState 实例。

13

n_jobs − int 或 none,可选,默认值 = None

它表示在多分类问题中进行 OVA(一对多)计算时要使用的 CPU 数量。默认值为 none,即 1。

14

learning_rate −字符串,可选,默认值 = 'optimal'

  • 如果学习率为'constant',eta = eta0;

  • 如果学习率为'optimal',eta = 1.0/(alpha*(t+t0)),其中 t0 由 Leon Bottou 选择;

  • 如果学习率为'invscalling',eta = eta0/pow(t, power_t)。

  • 如果学习率为'adaptive',eta = eta0。

15

eta0 − double,默认值 = 0.0

它表示上述学习率选项(即"constant"、"invscalling"或"adaptive")的初始学习率。

16

power_t − idouble,默认值 = 0.5

它是"incscalling"学习率的指数。

17

early_stopping − bool,默认值 = False

此参数表示当验证分数没有提高时,使用提前停止来终止训练。它的默认值为 false,但当设置为 true 时,它​​会自动将分层的训练数据部分留出作为验证,并在验证分数没有提高时停止训练。

18

validation_fraction − 浮点型,默认值 = 0.1

仅当 early_stopping 为 true 时使用。它表示在提前终止训练数据时,应预留多少比例的训练数据作为验证集。

19

n_iter_no_change − 整数,默认值 = 5

它表示在提前停止之前,算法应运行多少次没有改进的迭代。

20

classs_weight − dict,{class_label: weight} 或 "balanced",或 None,可选

此参数表示与类别相关的权重。如果未提供,则类别的权重应为 1。

20

warm_start − bool,可选,默认值 = false

将此参数设置为 True,我们可以重用上一次拟合调用的结果作为初始化结果。如果选择默认值,即 false,则会清除上一次的结果。

21

average − iBoolean 或 int,可选,默认值 = false

它表示在多分类问题中进行 OVA(一对多)计算时使用的 CPU 数量。默认值为 none,即 1。

属性

下表列出了 SGDClassifier 模块使用的属性 −

Sr.No 属性和说明
1

coef_ −数组,形状为 (1, n_features),如果 n_classes==2,则为 (n_classes, n_features)

此属性提供分配给特征的权重。

2

intercept_ − 数组,形状为 (1,),如果 n_classes==2,则为 (n_classes,)

它表示决策函数中的独立项。

3

n_iter_ − int

它给出了达到停止标准的迭代次数。

实现示例

与其他分类器一样,随机梯度下降 (SGD) 必须使用以下两个数组 − 进行拟合。

  • 一个包含训练样本的数组 X。其大小为 [n_samples, n_features]。

  • 数组 Y 保存目标值,即训练样本的类标签。其大小为 [n_samples]。

示例

以下 Python 脚本使用 SGDClassifier 线性模型 −

import numpy as np
from sklearn import linear_model
X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
Y = np.array([1, 1, 2, 2])
SGDClf = linear_model.SGDClassifier(max_iter = 1000, tol=1e-3,penalty = "elasticnet")
SGDClf.fit(X, Y)

输出

SGDClassifier(
   alpha = 0.0001, average = False, class_weight = None,
   early_stopping = False, epsilon = 0.1, eta0 = 0.0, fit_intercept = True,
   l1_ratio = 0.15, learning_rate = 'optimal', loss = 'hinge', max_iter = 1000,
   n_iter = None, n_iter_no_change = 5, n_jobs = None, penalty = 'elasticnet',
   power_t = 0.5, random_state = None, shuffle = True, tol = 0.001,
   validation_fraction = 0.1, verbose = 0, warm_start = False
)

示例

现在,一旦拟合完成,模型就可以预测新的值,如下所示: −

SGDClf.predict([[2.,2.]])

输出

array([2])

示例

对于上述示例,我们可以借助以下 Python 脚本获取权重向量 −

SGDClf.coef_

输出

array([[19.54811198, 9.77200712]])

示例

类似地,我们可以借助以下 Python 脚本获取截距的值 −

SGDClf.intercept_

输出

array([10.])

示例

我们可以使用 SGDClassifier.decision_function 获取到超平面的有符号距离,如以下 Python 脚本 −

所示。
SGDClf.decision_function([[2., 2.]])

输出

array([68.6402382])

SGD 回归器

随机梯度下降 (SGD) 回归器基本上实现了一个简单的 SGD 学习程序,支持各种损失函数和惩罚项,以拟合线性回归模型。 Scikit-learn 提供了 SGDRegressor 模块来实现 SGD 回归。

参数

SGDRegressor 使用的参数与 SGDClassifier 模块中使用的参数几乎相同。区别在于"loss"参数。SGDRegressor 模块的loss参数的正值如下:−

  • squared_loss − 指的是普通最小二乘拟合。

  • huber: SGDRegressor − 通过将平方损失转换为线性损失(超过 epsilon 距离)来校正异常值。 "huber" 的作用是修改"squared_loss",使算法减少对异常值的校正。

  • epsilon_insensitive − 实际上,它会忽略小于 epsilon 的误差。

  • squared_epsilon_insensitive − 它与 epsilon_insensitive 相同。唯一的区别是,当超过 epsilon 的容差时,它会变成平方损失。

另一个区别是,名为"power_t"的参数的默认值为 0.25,而不是像 SGDClassifier 中的 0.5。此外,它没有"class_weight"和"n_jobs"参数。

属性

SGDRegressor 的属性也与 SGDClassifier 模块的属性相同。相反,它有三个额外的属性,如下所示 −

  • average_coef_ − 数组,shape(n_features,)

顾名思义,它提供分配给特征的平均权重。

  • average_intercept_ − 数组,shape(1,)

顾名思义,它提供平均截距项。

  • t_ − int

它提供在训练阶段执行的权重更新次数。

注意 −将参数"average"设置为 True 后,average_coef_ 和 average_intercept_ 属性将生效。

实现示例

以下 Python 脚本使用 SGDRegressor 线性模型 −

import numpy as np
from sklearn import linear_model
n_samples, n_features = 10, 5
rng = np.random.RandomState(0)
y = rng.randn(n_samples)
X = rng.randn(n_samples, n_features)
SGDReg =linear_model.SGDRegressor(
   max_iter = 1000,penalty = "elasticnet",loss = 'huber',tol = 1e-3, average = True
)
SGDReg.fit(X, y)

输出

SGDRegressor(
   alpha = 0.0001, average = True, early_stopping = False, epsilon = 0.1,
   eta0 = 0.01, fit_intercept = True, l1_ratio = 0.15,
   learning_rate = 'invscaling', loss = 'huber', max_iter = 1000,
   n_iter = None, n_iter_no_change = 5, penalty = 'elasticnet', power_t = 0.25,
   random_state = None, shuffle = True, tol = 0.001, validation_fraction = 0.1,
   verbose = 0, warm_start = False
)

示例

拟合完成后,我们可以使用以下 Python 脚本 − 来获取权重向量。

SGDReg.coef_

输出

array([-0.00423314, 0.00362922, -0.00380136, 0.00585455, 0.00396787])

示例

类似地,我们可以使用以下 Python 脚本 − 来获取截距的值。

SGReg.intercept_

输出

SGReg.intercept_

示例

我们可以借助以下 Python 脚本获取训练阶段的权重更新次数 −

SGDReg.t_

输出

61.0

SGD 的优缺点

以下是 SGD 的优点 −

  • 随机梯度下降 (SGD) 非常高效。

  • 它非常容易实现,因为有很多代码机会调优。

遵循 SGD 的缺点 −

  • 随机梯度下降 (SGD) 需要多个超参数,例如正则化参数。

  • 它对特征缩放很敏感。