为啥带有铰链损失的 SGDClassifier 比 scikit-learn 中的 SVC 实现更快
Posted
技术标签:
【中文标题】为啥带有铰链损失的 SGDClassifier 比 scikit-learn 中的 SVC 实现更快【英文标题】:Why SGDClassifier with hinge loss is faster than SVC implementation in scikit-learn为什么带有铰链损失的 SGDClassifier 比 scikit-learn 中的 SVC 实现更快 【发布时间】:2020-05-20 12:26:49 【问题描述】:众所周知,对于支持向量机,我们可以使用 SVC 以及带有铰链损失实现的 SGDClassifier。具有铰链损失实现的 SGDClassifier 是否比 SVC 更快。为什么?
scikit-learn 中两种 SVC 实现的链接:SVC SGDClassifier
我在 sci-kit 的文档页面上读到 SVC 使用 libsvm 库的一些算法进行优化。而 SGDClassifier 使用 SGD(显然)。
【问题讨论】:
你做过研究吗? 是的,主要问题是 SVC 使用 libsvm,而 SGDC 使用 liblinear,LinearSVC 使用 liblinear,因此执行时间将与 SGDC 相当 【参考方案1】:也许开始尝试一些实际案例并阅读代码会更好。开始吧……
首先,如果我们阅读 SGDC 的文档,它说仅使用线性 SVM:
带有 SGD 训练的线性分类器(SVM、逻辑回归、a.o.)
如果我们不使用通常的 SVC,而是使用 LinearSVC 会怎样?
与参数 kernel='linear' 的 SVC 类似,但根据 liblinear 而不是 libsvm 实现,因此它在选择惩罚和损失函数方面具有更大的灵活性,并且应该更好地扩展到大量样本。
让我们为这三种类型的算法添加一个示例:
from sklearn.svm import SVC
from sklearn.linear_model import SGDClassifier
from sklearn.svm import LinearSVC
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = np.random.rand(20000,2)
Y = np.random.choice(a=[False, True], size=(20000, 1))
# hinge is used as the default
svc = SVC(kernel='linear')
sgd = SGDClassifier(loss='hinge')
svcl = LinearSVC(loss='hinge')
使用 jupyter 和命令 %%time
我们得到执行时间(你可以在普通 python 中使用类似的方式,但我是这样做的):
%%time
svc.fit(X, Y)
持续时间:5.61 秒
%%time
sgd.fit(X, Y)
持续时间:24 毫秒
%%time
svcl.fit(X, Y)
持续时间:26.5ms
正如我们所见,它们之间存在巨大差异,但线性和 SGDC 或多或少具有相同的时间。时间总是有点不同,但这总是会发生,因为每个算法的执行不是来自相同的代码。
如果你对每个实现感兴趣,我建议你使用新的 github 阅读工具阅读 github 代码,真的很棒!
linearSVC的代码
SGDC的代码
【讨论】:
【参考方案2】:与 loss='hinge' 的 sklearn SGD 分类器相比,sklearn SVM 的计算成本更高。因此我们使用更快的 SGD 分类器。这仅适用于线性 SVM。如果我们使用 'rbf' 内核,则 SGD 不适合。
【讨论】:
【参考方案3】:我认为这是因为 SGD 中使用的批量大小,如果您使用带有 SGD 分类器的全批量,它应该与 SVM 花费相同的时间,但更改批量大小可以导致更快的收敛。
【讨论】:
以上是关于为啥带有铰链损失的 SGDClassifier 比 scikit-learn 中的 SVC 实现更快的主要内容,如果未能解决你的问题,请参考以下文章
带有 HashingVectorizer 和 TfidfTransformer 的 SGDClassifier
为啥python sgdclassifier 每次分类的结果都不一样