【发布时间】:2021-12-09 07:22:30
【问题描述】:
在使用 Scikit-Learn 的 SVC 实现时,我注意到一个相当奇特但可能非常有用的现象。将内置 rbf 内核与 SVC 一起使用比将 自定义 rbf 函数传递给 SVC()慢数量级。
据我目前所见和了解,两个版本之间的唯一区别是在内置 rbf 的情况下,不是 sklearn 而是 libsvm 将计算内核。将专用内核函数作为超参数传递给 SVC() 会导致内核在 sklearn 中的计算,而不是在 libsvm 中。结果是相同的,但后一种情况只需要一小部分计算时间。
示例
我提供了一个示例,以便您可以复制此行为。
我创建了一个模拟我目前正在处理的数据的玩具数据集。顺便说一句,我还处理大约一千个样本但高维(约 50000 个特征)的数据。这导致几乎相同的行为。
import numpy as np
from time import time
from sklearn.svm import SVC
from sklearn.datasets import make_classification
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.metrics import accuracy_score
# create toy data
n_features = 1000
n_samples = 10000
n_informative = 10
X, y = make_classification(n_samples, n_features, n_informative=n_informative)
gamma = 1 / n_features
内置RBF
首先,让我们使用内置的“rbf”内核来适配 SVC。这可能是人们通常运行 SVC 的方式。
# fit SVC with built-in rbf kernel
svc_built_in = SVC(kernel='rbf', gamma=gamma)
np.random.seed(13)
t1 = time()
svc_built_in.fit(X, y)
acc = accuracy_score(y, svc_built_in.predict(X))
print("Fitting SVC with built-in kernel took {:.1f} seconds".format(time()-t1))
print("Accuracy: {}".format(acc))
自定义RBF函数
其次,让我们做同样的事情,只传递 sklearn 的 rbf 核函数,它应该做的完全一样。
# fit SVC with custom rbf kernel
svc_custom = SVC(kernel=rbf_kernel, gamma=gamma)
np.random.seed(13)
t1 = time()
svc_custom.fit(X, y)
acc = accuracy_score(y, svc_custom.predict(X))
print("Fitting SVC with a custom kernel took {:.1f} seconds".format(time()-t1))
print("Accuracy: {}".format(acc))
结果
这将给出以下结果。
Fitting SVC with built-in kernel took 58.6 seconds
Accuracy: 0.9846
Fitting SVC with a custom kernel took 3.2 seconds
Accuracy: 0.9846
我的问题
- 有人知道为什么传递内核函数比使用 libsvm 的内核计算要快得多吗?
- 对于我的特定用例(通常是大型数据集和较长的计算时间),这实际上非常有用,因为我可以使用第二种方法运行更多的超参数设置,因为计算时间显着减少。有什么理由不这样做?
【问题讨论】:
-
这作为sklearn中的错误报告会更有意义
-
有道理...这是我在 sklearn 的 Github 页面上创建的问题 github.com/scikit-learn/scikit-learn/issues/21410
标签: python performance scikit-learn svm