Scikit Learn 随机梯度下降
在这里,我们将了解 Sklearn 中的一种优化算法,称为随机梯度下降 (SGD)。
随机梯度下降 (SGD) 是一种简单而有效的优化算法,用于找到最小化成本函数的函数参数/系数的值。换句话说,它用于在 SVM 和 Logistic 回归等凸损失函数下对线性分类器进行判别学习。它已成功应用于大规模数据集,因为系数更新是针对每个训练实例执行的,而不是在实例结束时执行。
SGD 分类器
随机梯度下降 (SGD) 分类器基本上实现了一个简单的 SGD 学习例程,支持各种损失函数和分类惩罚。
Scikit-learn 提供SGDClassifier模块来实现 SGD 分类。
参数
下表是 SGDClassifier 模块使用的参数:
序号 | 参数及说明 |
---|---|
1 | loss: str,默认 = ‘hinge’ 它表示实现时要使用的损失函数。默认值是“hinge”,它会给我们一个线性 SVM。其他可以使用的选项是:
|
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: bool, 默认=True 此参数指定应将常数(偏差或截距)添加到决策函数中。在计算中将不使用截距,如果设置为 false,则假定数据已经居中。 |
6 | tol: float 或 none,optional,默认 = 1.e-3 此参数表示迭代的停止标准。它的默认值是 False 但如果设置为 None,迭代将在 ?loss>best_loss - n_iter_no_change 的 tol连续的时代。 |
7 | shuffle: bool,optional,默认 = True 这个参数代表我们是否希望我们的训练数据在每个 epoch 之后被打乱。 |
8 | verbose:int,默认=0 它代表详细程度。其默认值为 0。 |
9 | epsilon:float,默认= 0.1 此参数指定不敏感区域的宽度。如果 loss = ‘epsilon-insensitive’,则当前预测与正确标签之间小于阈值的任何差异都将被忽略。 |
10 | max_iter: int, optional, 默认 = 1000 顾名思义,它代表了历元上的最大传递次数,即训练数据。 |
11 | warm_start : bool,optional,默认= false 将此参数设置为 True,我们可以重用之前调用 fit 作为初始化的解决方案。如果我们选择默认值,即 false,它将删除之前的解决方案。 |
12 | random_state: int, RandomState 实例或None,optional,默认= none 此参数表示在混洗数据时使用的生成的伪随机数的种子。以下是选项。
|
13 | n_jobs: int 或 none,optional,默认 = None 它表示用于 OVA(一个对所有)计算的 CPU 数量,用于多类问题。默认值为 none,表示 1。 |
14 | learning_rate: 字符串,optional,默认 = ‘最优’
|
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 为真时使用。它表示为提前终止训练数据而留出作为验证集的训练数据的比例。 |
19 | n_iter_no_change: int, 默认=5 它表示算法在提前停止之前运行时没有改进的迭代次数。 |
20 | classs_weight: dict, {class_label: weight} or “balanced”, or None, optional 此参数表示与类关联的权重。如果未提供,则类的权重应该为 1。 |
21 | average: iBoolean 或 int,optional,默认 = false 它表示用于 OVA(一个对所有)计算的 CPU 数量,用于多类问题。默认值为 none,表示 1。 |
属性
下表是 SGDClassifier 模块使用的属性:
序号 | 属性和描述 |
---|---|
1 | coef_: array, shape (1, n_features) if n_classes==2, else (n_classes, n_features) 此属性提供分配给要素的权重。 |
2 | intercept_: array, shape (1,) if n_classes==2, else (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脚本来获取intercept的值:
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_coef_ 和average_intercept_ 将在启用参数“average”为True 后起作用。
示例
以下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脚本来获取intercept的值:
SGReg.intercept_
SGReg.intercept_
我们可以借助以下python脚本获取训练阶段权重更新的次数:
SGDReg.t_
61.0
SGD 的利弊
遵循SGD的优点:
随机梯度下降 (SGD) 非常有效。
它很容易实现,因为有很多代码调整的机会。
遵循SGD的缺点:
随机梯度下降 (SGD) 需要几个超参数,如正则化参数。
它对特征缩放很敏感。