Faire des SVM courir plus vite en python
À l'aide de la code ci-dessous pour les 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)
Mais il prend une énorme quantité de temps.
Données Réelles Dimensions:
train-set (1422392,29)
test-set (233081,29)
Comment puis-je accélérer(parallèle ou d'une autre façon)? S'il vous plaît aider.
J'ai déjà essayé de l'APC et de sous-échantillonnage.
J'ai 6 classes.
Edit:
Trouvé http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html
mais je souhaite que les estimations de probabilité, et il ne semble pas tellement pour les svm.
Edit:
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,:]
Edit 2:
La réponse par user3914041 donne de très mauvaises estimations de probabilité.
- Quantifier "quantité énorme de temps." Qu'avez-vous utilisé pour le profil de votre code?
- Merci pour les commentaires. Je suis indiquant à peu près par hasard s'exécute du code. Je suis à peu près de mesure par la sortie vérifie dans le code, ce qui est une mauvaise façon de le faire. Ne fait que répondre à votre question?
- Avez-vous besoin de tous les 1,4 million d'exemples de formation? Selon le docs L'ajustement du temps de la complexité est plus quadratique dans le nombre d'exemples de formation. En outre, vous avez besoin de l'estimation des probabilités? Qui requiert une course de cross-validation de la générer.
- Merci pour l'info! Comme mentionné, je peux sous-échantillonner mais il n'est pas préférable. Oui, j'ai besoin d'estimations de probabilité délimitée par certains format de la compétition.
- Le OneVsRestClassifier livré avec une option pour le parallélisme, mais être averti qu'il peut manger beaucoup de vos ressources, car il faudra beaucoup de temps pour s'adapter à chacun des modèles. Essayez de définir le n_jobs paramètre selon les docs ici.
- Essayez MKL Optimisations de Continuum, voir magasin.continuum.io/cshop/mkl-optimisations. Ils offrent un essai gratuit de 30 jours et le coût est de $99. Je ne suis pas un représentant des ventes, mais je utiliser leurs Anaconda Python distribution et, comme il a été recommandé à l'Étincelle du Sommet de la formation. D'ailleurs Étincelle prend en charge SVM et qu'il tourne sur même une petite Étincelle cluster améliorer considérablement les performances, voir spark.apache.org/docs/1.1.0/....
- Allumage ne fonctionne pas car il ne prend pas en charge les estimations de probabilité de SVM
- Merci pour les connaissances utiles! J'ai un cluster HPC avec moi. Mais si ne pas offrir des estimations de probabilité, alors il ne serait pas d'une grande utilité.
- Je n'ai pas regardé beaucoup en elle, mais je pense que IPython Parallèle / Starcluster pourrait être utile de vérifier ainsi. Voici un résumé de l'information avec le code de démonstration à partir de l'une des sklearn des collaborateurs de tutoriels. Mais pour se développer à partir de Tris commentaire, vous allez vouloir essayer de passer sur un cluster à un certain point. Et si sklearn ne fonctionne pas facilement sur un cluster, vous pouvez envisager d'écrire votre propre code sur le dessus de ces autres bibliothèques qui vous donne les estimations de probabilité dont vous avez besoin.
- Merci pour la réponse, encore une fois! J'ai essayé d'utiliser
OneVsRestClassifier
en parallèle. J'ai été alloué 14 noyaux, mais il semblait seulement 6 d'entre eux (qui est égal au nombre de classes). Une raison à cela, vous le savez, je suis pas certain de savoir comment parallèle dégradé travaille. Si je ne peux pas courir plus vite que le nombre de classes, je ne pense pas que l'aide de cluster serait de l'aide.(Aussi, j'ai déjà plus qu'assez de RAM ~48 GB sur le bureau. Donc, il n'y a pas de problème de mémoire.) - Oui SVM prend beaucoup de temps et de manière lente dans les Processeurs. Vous aurez besoin de blanchir de l'APC de données, pour le rendre plus rapide ou essayer de trouver une bibliothèque qui s'exécute dans le GPU.
- Merci pour la réponse! Je fais blanchir les données. Je ne peux pas trouver une telle bibliothèque. Pouvez-vous mentionner les raisons pour lesquelles l'aide de GPU pourrait l'aider.
- Ce n'est pas vraiment parallèle gradient d'autant qu'il est approprié l'6 OneVsRest modèles en parallèle, il est donc logique qu'il ne sera pas paralléliser plus que cela. Si vous avez l'intention de rester avec Python et
sklearn.SVC
en raison des estimations de probabilité, alors il me semble que votre meilleur pari serait de sous-échantillonner, de l'APC, et l'utilisation OneVsRest avec 6 emplois. - Merci pour l'info! Moi je préfère Matlab sur python, mais comme la plupart des autres code en python. En outre, le temps ne permet pas le changement.
- En cours d'exécution sur GPU est 20X, et en plus, si vous exécutez natif c/c++ code, il ajoute à la vitesse. Python toujours lente (au moins pour moi!). Jetez un oeil ici: devtalk.nvidia.com/default/topic/485456/...
- Le sous-échantillonnage et de l'APC de ne pas donner de bons résultats. Si vous vous connaissez de toute autre possibilité s'il vous plaît laissez-moi savoir. Probablement à l'aide de LinearSVC à rendre les estimations de probabilité.
- Si cela ne fonctionne pas pour vous, alors je suis d'accord. LinearSVC avec calibré estimations de probabilité est alors une autre bonne option. J'imagine que vous pouvez également essayer de régulariser la Régression Logistique à nouveau avec des paramètres appropriés, même si il a donné de précision inférieure comme vous le mentionnez ci-dessous. Il est très difficile d'évaluer ce qui fonctionne le mieux pour vous, sans rien savoir d'autre sur les données. :/
- Salut, merci pour l'info! J'ai essayé un peu de code pour LinearSVC avec calibré estimations de probabilité, veuillez vérifier(Édition en Question). L'aide maximale likelohood convient sans doute mieux de ce que j'ai pu trouver.
1/1+exp(Ax+B)
, oùA
etB
sont des paramètres appris par ML estimation. Pouvez-vous aider à la façon de la mettre en œuvre. Je n'arrive pas à trouver un point de départ.
Vous devez vous connecter pour publier un commentaire.
Si vous voulez coller avec SVC autant que possible et de les former sur l'ensemble des données, vous pouvez utiliser des ensembles de Services qui sont formés sur des sous-ensembles de données pour réduire le nombre d'enregistrements par classificateur (qui a apparemment quadratique influence sur la complexité). Scikit prend en charge que les
BaggingClassifier
wrapper. Cela devrait vous donner similaire (si ce n'est mieux) précision par rapport à un seul classifieur, avec beaucoup moins de temps de formation. La formation de l'individu classificateurs peuvent également être configuré pour s'exécuter en parallèle à l'aide de lan_jobs
paramètre.Sinon, je voudrais également envisager d'utiliser une Forêt Aléatoire classificateur - il supporte le multi-classe de la classification en natif, il est rapide et donne assez de bonnes estimations de probabilité lorsque
min_samples_leaf
est réglé de manière appropriée.J'ai fait un test rapide sur l'iris dataset soufflé jusqu'à 100 fois avec un ensemble de 10 Svc, chacun formé de 10% des données. Il est plus de 10 fois plus rapide qu'un seul classifieur. Ce sont les chiffres que j'ai reçu sur mon portable:
Unique SVC: 45s
Ensemble SVC: 3s
Forêt aléatoire Classificateur: 0,5 s
Voir ci-dessous le code que j'ai utilisé pour produire les chiffres:
Si vous voulez vous assurer que chaque enregistrement est utilisé qu'une seule fois pour la formation dans le
BaggingClassifier
, vous pouvez définir labootstrap
paramètre à False.SVC
, s'il vous plaît suggérer d'autres bonnes approches aussi si vous le souhaitez.sklearn.ensemble.AdaBoostClassifier
pour une utilisation aléatoire de la forêt ou les arbres de décision.sklearn.svm.LinearSVC
qui est fondamentalement la même, mais mis en œuvre avec une plus rapide de la bibliothèque de lasklearn.svm.SVC
.RandomForestClassifier
fonctionne incroyablement rapide, mais ce que je comprends, il n'utilise pas linéaire / poly noyaux comme SVC faire, il donne de la baisse de la précision. Puis-je améliorer la précision de laRandomForestClassifier
?SVM classificateurs n'évoluent pas si facilement. De la documentation, de la complexité des
sklearn.svm.SVC
.Dans scikit-learn vous avez
svm.linearSVC
qui permet de mieux.Apparemment, il pourrait être en mesure de traiter vos données.
Sinon, vous pouvez tout simplement aller avec un autre classificateur. Si vous voulez estimations de probabilité que je vous suggère de régression logistique.
La régression logistique a également l'avantage de ne pas avoir de la probabilité d'étalonnage à la sortie de " bon " probabilités.
Edit:
Je ne savais pas à propos de
linearSVC
complexité, j'ai enfin trouvé de l'information dans le guide de l'utilisateur:Pour obtenir la probabilité d'un
linearSVC
découvrez ce lien. Il est juste un couple des liens à l'écart de la probabilité d'étalonnage guide, j'ai lié ci-dessus et contient une méthode pour estimer les probabilités.À savoir:
Note les estimations seront probablement pauvre, sans étalonnage, comme illustré dans le lien.
decision_function
attribut, comme il est fait avec LinearSVC dans le lien que j'ai donné sur la probabilité d'étalonnage. Vous aurez certainement besoin de calibrer les probabilités de faire sens.predict_proba()
similaire avec ce que vous avez mentionné?OneVsRestClassifier(LinearSVC())
. Connaissez-vous un moyen de calibrer cette façon?Il a été brièvement mentionné dans la réponse sommet, voici le code: le moyen Le plus rapide de le faire est par le
n_jobs
paramètre: remplacer la ligneavec
Cela permettra d'utiliser tous les Processeurs disponibles sur votre Ordinateur, tout en faisant le même calcul que précédemment.
Vous pouvez utiliser le
kernel_approximation
module à l'échelle des SVMs pour un grand nombre d'échantillons de ce genre.Quelques réponses mentionné à l'aide de
class_weight == 'auto'
. Pour sklearn de version supérieure de 0,17, veuillez utiliserclass_weight == 'balanced'
à la place:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html