Scikit Learn - 随机梯度下降



在这里,我们将学习 Sklearn 中的一种优化算法,称为随机梯度下降 (SGD)。

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

SGD 分类器

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

参数

下表包含 **SGDClassifier** 模块使用的参数:

序号 参数及描述
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** − float,默认值 = 0.0001

Alpha,即乘以正则化项的常数,是决定我们想要对模型进行多少惩罚的调整参数。默认值为 0.0001。

4

**l1_ratio** − float,默认值 = 0.15

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

5

**fit_intercept** − 布尔值,默认值 = True

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

6

**tol** − float 或 none,可选,默认值 = 1.e-3

此参数表示迭代的停止条件。其默认值为 False,但如果设置为 None,则当连续 n_iter_no_change 个 epoch 的 𝑙𝑜𝑠𝑠 > 𝑏𝑒𝑠𝑡_𝑙𝑜𝑠𝑠 − 𝑡𝑜𝑙 时,迭代将停止。

7

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

此参数表示我们是否希望在每个 epoch 后洗牌我们的训练数据。

8

**verbose** − 整数,默认值 = 0

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

9

**epsilon** − float,默认值 = 0.1

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

10

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

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

11

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

将此参数设置为 True,我们可以重用先前对 fit 的调用的解决方案作为初始化。如果我们选择默认值 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** − string,可选,默认值 = ‘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** − float,默认值 = 0.1

仅当 early_stopping 为 true 时才使用。它表示要作为验证集留出的训练数据的比例,用于提前终止训练数据。

19

**n_iter_no_change** − int,默认值 = 5

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

20

**class_weight** − dict,{class_label: weight} 或“balanced”,或 None,可选

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

20

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

将此参数设置为 True,我们可以重用先前对 fit 的调用的解决方案作为初始化。如果我们选择默认值 false,它将清除之前的解决方案。

21

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

它表示在多类问题中 OVA(一对多)计算中要使用的 CPU 数量。默认值为 none,这意味着 1。

属性

下表包含 **SGDClassifier** 模块使用的属性:

序号 属性及描述
1

**coef_** − array,形状为 (1, n_features) 如果 n_classes==2,否则为 (n_classes, n_features)

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

2

**intercept_** − array,形状为 (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_** − array,形状为 (n_features,)

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

  • **average_intercept_** − array,形状为 (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) 需要多个超参数,例如正则化参数。

  • 它对特征缩放敏感。

广告