使SVM在python中运行更快
在python中为svm使用下面的代码:使SVM在python中运行更快,python,scikit-learn,svm,Python,Scikit Learn,Svm,在python中为svm使用下面的代码: from sklearn import datasets from sklearn.multiclass import OneVsRestClassifier from sklearn.svm import SVC iris = datasets.load_iris() X, y = iris.data, iris.target clf = OneVsRestClassifier(SVC(kernel='linear', probability=True
from sklearn import datasets
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'))
clf.fit(X, y)
proba = clf.predict_proba(X)
但这需要花费大量的时间
实际数据维度:
train-set (1422392,29)
test-set (233081,29)
我如何加速(并行或其他方式)?请帮忙。
我已经尝试过PCA和下采样
我有6节课。
编辑:
建立
但我希望得到概率估计,而svm似乎不是这样
编辑:
from sklearn import datasets
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC,LinearSVC
from sklearn.linear_model import SGDClassifier
import joblib
import numpy as np
from sklearn import grid_search
import multiprocessing
import numpy as np
import math
def new_func(a): #converts array(x) elements to (1/(1 + e(-x)))
a=1/(1 + math.exp(-a))
return a
if __name__ == '__main__':
iris = datasets.load_iris()
cores=multiprocessing.cpu_count()-2
X, y = iris.data, iris.target #loading dataset
C_range = 10.0 ** np.arange(-4, 4); #c value range
param_grid = dict(estimator__C=C_range.tolist())
svr = OneVsRestClassifier(LinearSVC(class_weight='auto'),n_jobs=cores) ################LinearSVC Code faster
#svr = OneVsRestClassifier(SVC(kernel='linear', probability=True, ##################SVC code slow
# class_weight='auto'),n_jobs=cores)
clf = grid_search.GridSearchCV(svr, param_grid,n_jobs=cores,verbose=2) #grid search
clf.fit(X, y) #training svm model
decisions=clf.decision_function(X) #outputs decision functions
#prob=clf.predict_proba(X) #only for SVC outputs probablilites
print decisions[:5,:]
vecfunc = np.vectorize(new_func)
prob=vecfunc(decisions) #converts deicision to (1/(1 + e(-x)))
print prob[:5,:]
编辑2:
用户3914041的答案产生的概率估计很差。支持向量机分类器不容易扩展。从文档中,我们了解了
sklearn.svm.SVC
的复杂性
拟合时间复杂度大于二次型
使其难以扩展到具有多个
一万个样本
在scikit学习中,您有svm.linearSVC
,它可以更好地扩展。
显然它可以处理你的数据
或者,您可以使用另一个分类器。如果你想要概率估计,我建议逻辑回归。
逻辑回归也有不需要输出“适当”概率的优势
编辑:
from sklearn import datasets
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC,LinearSVC
from sklearn.linear_model import SGDClassifier
import joblib
import numpy as np
from sklearn import grid_search
import multiprocessing
import numpy as np
import math
def new_func(a): #converts array(x) elements to (1/(1 + e(-x)))
a=1/(1 + math.exp(-a))
return a
if __name__ == '__main__':
iris = datasets.load_iris()
cores=multiprocessing.cpu_count()-2
X, y = iris.data, iris.target #loading dataset
C_range = 10.0 ** np.arange(-4, 4); #c value range
param_grid = dict(estimator__C=C_range.tolist())
svr = OneVsRestClassifier(LinearSVC(class_weight='auto'),n_jobs=cores) ################LinearSVC Code faster
#svr = OneVsRestClassifier(SVC(kernel='linear', probability=True, ##################SVC code slow
# class_weight='auto'),n_jobs=cores)
clf = grid_search.GridSearchCV(svr, param_grid,n_jobs=cores,verbose=2) #grid search
clf.fit(X, y) #training svm model
decisions=clf.decision_function(X) #outputs decision functions
#prob=clf.predict_proba(X) #only for SVC outputs probablilites
print decisions[:5,:]
vecfunc = np.vectorize(new_func)
prob=vecfunc(decisions) #converts deicision to (1/(1 + e(-x)))
print prob[:5,:]
我不知道linearSVC
的复杂性,最后我在
还请注意,对于线性情况,LinearSVC中使用的算法
liblinear实现比它的
基于libsvm的SVC对应,几乎可以线性扩展到数百万
样本和/或特征的数量
要从linearSVC
中获取概率,请签出。它离我上面链接的概率校准指南只有几个链接,并且包含一种估计概率的方法。
即:
注意:如链接所示,如果不进行校准,估计值可能会很差。如果您希望尽可能坚持使用SVC并在完整数据集上进行训练,可以使用在数据子集上训练的SVC集合来减少每个分类器的记录数(这显然对复杂性有二次影响)。Scikit使用
BaggingClassifier
包装器支持这一点。这应该会给您提供类似的(如果不是更好的话)与单个分类器相比,精度更高,训练时间更少。也可以使用n_作业
参数将单个分类器的训练设置为并行运行
另外,我也会考虑使用一个随机森林分类器——它本身支持多类分类,它是快速的,并且在<代码> MySimSimulsPox< /Cord>被适当设置时给出了很好的概率估计。 我对iris数据集进行了快速测试,使用10个SVC组合放大了100次,每个SVC都训练了10%的数据。它比单个分类器快10倍多。以下是我在笔记本电脑上得到的数字:
单SVC:45s 集合SVC:3s 随机森林分类器:0.5s 请参见下面我用来生成数字的代码:import time
import numpy as np
from sklearn.ensemble import BaggingClassifier, RandomForestClassifier
from sklearn import datasets
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
iris = datasets.load_iris()
X, y = iris.data, iris.target
X = np.repeat(X, 100, axis=0)
y = np.repeat(y, 100, axis=0)
start = time.time()
clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'))
clf.fit(X, y)
end = time.time()
print "Single SVC", end - start, clf.score(X,y)
proba = clf.predict_proba(X)
n_estimators = 10
start = time.time()
clf = OneVsRestClassifier(BaggingClassifier(SVC(kernel='linear', probability=True, class_weight='auto'), max_samples=1.0 / n_estimators, n_estimators=n_estimators))
clf.fit(X, y)
end = time.time()
print "Bagging SVC", end - start, clf.score(X,y)
proba = clf.predict_proba(X)
start = time.time()
clf = RandomForestClassifier(min_samples_leaf=20)
clf.fit(X, y)
end = time.time()
print "Random Forest", end - start, clf.score(X,y)
proba = clf.predict_proba(X)
如果要确保每个记录仅用于
BaggingClassifier
中的培训一次,可以将引导
参数设置为False。在顶部答案中简要提到了这一点;下面是代码:最快的方法是通过:替换行
clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'))
与
这将使用计算机上所有可用的CPU,同时仍然做与以前相同的计算。
< P>可以使用这样的方法将大量的样本扩展到支持向量机中。对于大型数据集, < P>可以考虑使用线性SVC或SGD-分类器,而可能是在NestROM转换器之后。量化“大量时间”你用什么来分析你的代码?你需要所有140万个训练示例吗?根据fit-time,训练示例的数量复杂度超过二次。此外,你需要概率估计吗?这需要额外的交叉验证来生成。OneVsRestClassifier带有一个选项关于并行性,请注意,它可能会占用您的许多资源,因为安装每个模型需要花费大量时间。请尝试根据文档设置n_jobs参数。请参阅Continuum中的MKL优化。它们提供30天免费试用,费用为99美元。我不是销售代表,但我使用他们的Anaconda Python发行版但是,就像它一样-这是Spark Summit培训中推荐的。顺便说一句,Spark支持SVM,并且即使在一个小的Spark集群上运行它也会极大地提高性能,请参见。@TrisNefzger Spark不起作用,因为它不支持SVMThanks的概率估计!关于缩放@NBartley之前已经提到过。我哈我尝试过逻辑回归,它的精确度较低。谢谢你的回复!但是linearSVC没有输出概率估计的选项。你是对的。一个可能的解决方法是使用
决策函数
属性,就像我在关于概率校准的链接中使用linearSVC一样。你肯定需要校准f或者说可能性是有意义的。你能解释更多关于校准的部分吗。如果你有具体的问题,尽管问,但是对于这个概念,我不能做得比我在文章中给出的链接更好。谢谢你的惊人回答!!我不知道这些。除了速度,准确性也是我最关心的。你能告诉我吗如果可能的话,你会给出一个比较吗?我不一定要使用SVC
,如果你愿意的话,请推荐其他好的方法。你也可以查看sklearn.employe.AdaBoostClassifier
以用于随机林或决策树。如果你想要线性内核,你可以使用sklearn.svm.LinearSVC
,这基本上是同样,但是使用比sklearn.svm.SVC
更快的库来实现。RandomForestClassifier
运行速度惊人,但据我所知,它不使用线性/pol
clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'), n_jobs=-1)