support score scikit rbf poly machine learn kernels fit example python scikit-learn svm

score - Haciendo que SVM corra más rápido en python



svm kernels (4)

Los clasificadores SVM no se escalan tan fácilmente. De los documentos, sobre la complejidad de sklearn.svm.SVC .

La complejidad del tiempo de ajuste es más que cuadrática con el número de muestras, lo que hace que sea difícil escalar al conjunto de datos con más de un par de 10000 muestras.

En scikit-learn tiene svm.linearSVC que puede escalar mejor. Aparentemente podría manejar sus datos.

Alternativamente, podrías ir con otro clasificador. Si quieres estimaciones de probabilidad, sugeriría la regresión logística. La regresión logística también tiene la ventaja de no necesitar calibración de probabilidad para generar probabilidades "apropiadas".

Editar:

No sabía acerca de la complejidad linearSVC de linearSVC , finalmente encontré información en la guía del usuario :

También tenga en cuenta que, para el caso lineal, el algoritmo utilizado en LinearSVC por la implementación liblinear es mucho más eficiente que su contraparte SVC basada en libsvm y puede escalarse casi linealmente a millones de muestras y / o características.

Para obtener la probabilidad de un linearSVC revise este enlace . Está a solo un par de enlaces de la guía de calibración de probabilidad que he vinculado anteriormente y contiene una forma de estimar las probabilidades. A saber:

prob_pos = clf.decision_function(X_test) prob_pos = (prob_pos - prob_pos.min()) / (prob_pos.max() - prob_pos.min())

Tenga en cuenta que las estimaciones probablemente serán deficientes sin calibración, como se ilustra en el enlace.

Usando el siguiente código para svm en python:

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)

Pero está tomando una gran cantidad de tiempo.

Dimensiones reales de los datos :

train-set (1422392,29) test-set (233081,29)

¿Cómo puedo acelerarlo (en paralelo o de alguna otra manera)? Por favor ayuda. Ya he probado PCA y downsampling.

Tengo 6 clases. Editar: encontrado http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html pero deseo estimaciones de probabilidad y parece que no para svm.

Editar:

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,:]

Editar 2: La respuesta del usuario3914041 arroja estimaciones de probabilidad muy pobres.


Puede usar el módulo kernel_approximation para escalar SVM a una gran cantidad de muestras como esta.


Se mencionó brevemente en la respuesta superior; aquí está el código: la forma más rápida de hacerlo es a través here : reemplazar la línea

clf = OneVsRestClassifier(SVC(kernel=''linear'', probability=True, class_weight=''auto''))

con

clf = OneVsRestClassifier(SVC(kernel=''linear'', probability=True, class_weight=''auto''), n_jobs=-1)

Esto usará todas las CPU disponibles en su computadora, mientras sigue haciendo el mismo cálculo que antes.


Si desea seguir con SVC tanto como sea posible y entrenar en el conjunto de datos completo, puede usar conjuntos de SVC que están entrenados en subconjuntos de datos para reducir el número de registros por clasificador (que aparentemente tiene una influencia cuadrática en la complejidad). Scikit lo admite con el contenedor BaggingClassifier . Eso debería darle una precisión similar (si no mejor) en comparación con un único clasificador, con mucho menos tiempo de entrenamiento. El entrenamiento de los clasificadores individuales también se puede configurar para que se ejecute en paralelo utilizando el parámetro n_jobs .

Alternativamente, también consideraría usar un clasificador Random Forest: admite la clasificación de clases múltiples de forma nativa, es rápido y proporciona estimaciones de probabilidad bastante buenas cuando min_samples_leaf se establece de forma adecuada.

Hice una prueba rápida en el conjunto de datos del iris explotado 100 veces con un conjunto de 10 SVC, cada uno entrenado en el 10% de los datos. Es más de 10 veces más rápido que un solo clasificador. Estos son los números que obtuve en mi computadora portátil:

SVC simple: 45 s

Ensemble SVC: 3s

Clasificador de bosque aleatorio: 0.5 s

Vea a continuación el código que utilicé para producir los números:

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)

Si desea asegurarse de que cada registro se use una sola vez para el entrenamiento en el BaggingClassifier , puede establecer el parámetro de bootstrap en False.