SVM utilisant scikit learn s'exécute sans fin et ne termine jamais l'exécution

76

J'essaie d'exécuter SVR à l'aide de scikit learn (python) sur un jeu de données d'apprentissage comportant 595605 lignes et 5 colonnes (entités) et sur un jeu de données test comportant 397070 lignes. Les données ont été pré-traitées et régularisées.

Je peux exécuter avec succès les exemples de test, mais lors de l'exécution de mon ensemble de données et de son exécution pendant plus d'une heure, je ne voyais toujours pas de sortie ni de fin du programme. J'ai essayé d'exécuter en utilisant un IDE différent et même depuis un terminal, mais cela ne semble pas être le problème. J'ai également essayé de changer la valeur du paramètre 'C' de 1 à 1e3.

Je suis confronté à des problèmes similaires avec toutes les implémentations svm utilisant scikit.

Est-ce que je n'attends pas assez pour que cela se termine? Combien de temps cette exécution devrait-elle prendre?

D'après mon expérience, cela ne devrait pas prendre plus de quelques minutes.

Voici la configuration de mon système: Ubuntu 14.04, 8 Go de RAM, beaucoup de mémoire disponible, processeur i7 de 4e génération

tejaskhot
la source
Pourriez-vous fournir le code? En outre, est-ce que la formation ou les tests prennent beaucoup de temps? Qu'en est-il des ensembles de données de formation / test plus petits?
ffriend
Je ne fais que lire les données d'un fichier csv dans un cadre de données pandas et les transmettre à la fonction d'apprentissage de scikit. C'est tout! Fournir le code ne serait pas vraiment utile ici
tejaskhot
6
L'implémentation SVM de sklearn implique au moins 3 étapes: 1) créer un objet SVR, 2) ajuster un modèle, 3) prédire une valeur. La première étape décrit l'utilisation du noyau, ce qui permet de mieux comprendre les processus internes. Les deuxième et troisième étapes sont très différentes et nous avons besoin de savoir au moins laquelle d’entre elles prend autant de temps. Si c'est une formation, ça peut aller, parce que l'apprentissage est parfois lent. S'il teste, il y a probablement un bogue, car les tests en SVM sont très rapides. En outre, la lecture de fichiers CSV peut prendre beaucoup de temps et pas du tout le SVM. Tous ces détails peuvent donc être importants.
ffriend
Je suis également confronté au même problème par le biais de svm, mais quelqu'un peut-il me dire combien de temps cela prendra-t-il après la normalisation?
kashyap kitchlu

Réponses:

70

O(nfeatures×nobservations2)O(nfeatures×nobservations3)

Vous pouvez augmenter ce cache en appelant SVR en tant que

model = SVR(cache_size=7000)

En général, cela ne va pas marcher. Mais tout n'est pas perdu. Vous pouvez sous-échantillonner les données et utiliser le reste comme jeu de validation, ou vous pouvez choisir un autre modèle. Au-dessus de la plage d'observation de 200 000, il est sage de choisir des apprenants linéaires.

La SVM du noyau peut être approximée en approximant la matrice du noyau et en la transmettant à un SVM linéaire. Cela vous permet de faire un compromis entre précision et performance en temps linéaire.

Un moyen courant d'y parvenir est d'utiliser une centaine de centres de grappes trouvés par kmeans / kmeans ++ comme base de la fonction de votre noyau. Les nouvelles entités dérivées sont ensuite introduites dans un modèle linéaire. Cela fonctionne très bien dans la pratique. Des outils tels que sophia-ml et vowpal wabbit permettent à Google, Yahoo et Microsoft de procéder ainsi. Les entrées / sorties deviennent le coût dominant pour les apprenants linéaires simples.

Dans l'abondance des données, les modèles non paramétriques fonctionnent à peu près de la même manière pour la plupart des problèmes. Les exceptions étant des entrées structurées, telles que du texte, des images, des séries chronologiques, de l'audio.

Lectures complémentaires

Jessica Mick
la source
16

SVM résout un problème d'optimisation d'ordre quadratique.

Je n'ai rien à ajouter qui n'a pas été dit ici. Je veux juste poster un lien vers la page de Sklearn sur le SVC, qui explique ce qui se passe:

L'implémentation est basée sur libsvm. La complexité temporelle de l'ajustement est plus que quadratique par rapport au nombre d'échantillons, ce qui rend difficile la mise à l'échelle d'un jeu de données comprenant plus de 10000 échantillons.

Si vous ne voulez pas utiliser de noyaux, et qu'un SVM linéaire suffit, il existe LinearSVR qui est beaucoup plus rapide car il utilise une approche d'optimisation à la fois par régression linéaire. Vous devrez cependant normaliser vos données, au cas où vous ne le feriez pas déjà, car la régularisation applique le coefficient d'interception, ce qui n'est probablement pas ce que vous souhaitez. Cela signifie que si votre moyenne de données est loin de zéro, elle ne sera pas en mesure de la résoudre de manière satisfaisante.

Vous pouvez également utiliser une descente de gradient stochastique pour résoudre le problème d'optimisation. Sklearn propose SGDRegressor . Vous devez utiliser loss='epsilon_insensitive'pour obtenir des résultats similaires à SVM linéaire. Voir la documentation. Je n’utiliserais cependant que la descente de gradient en dernier recours, car cela impliquerait de nombreux ajustements des hyperparamètres afin d’éviter de rester bloqué dans les minima locaux. Utilisez LinearSVRsi vous le pouvez.

Ricardo Cruz
la source
J'ai eu un jeu de données avec beaucoup de lignes. SVC a commencé à prendre trop de temps pour moi, environ 150 000 lignes de données. J'ai utilisé votre suggestion avec LinearSVR et un million de lignes ne prend que quelques minutes. PS a également constaté que le classifieur LogisticRegression produit des résultats similaires à ceux de LinearSVR (dans mon cas) et est encore plus rapide.
Jeffery_the_Wind
8

Avez-vous inclus la mise à l’échelle dans votre étape de pré-traitement? J'ai eu ce problème lors de l'exécution de mon SVM. Mon jeu de données est d'environ 780 000 échantillons (ligne) avec 20 entités (col). Mon ensemble de formation est ~ 235k échantillons. Il se trouve que j'ai juste oublié de mettre mes données à l'échelle! Si c'est le cas, essayez d'ajouter ce bit à votre code:

données d'échelle à [-1,1]; augmenter la vitesse du SVM:

from sklearn.preprocessing import MinMaxScaler
scaling = MinMaxScaler (feature_range = (- 1,1)). fit (X_train)
X_train = scaling.transform (X_train)
X_test = scaling.transform (X_test)

Shelby Matlock
la source
2
Quelqu'un peut-il expliquer pourquoi cela accélère l'ajustement SVM?
Lppier
1
Y a-t-il une raison pour laquelle vous avez choisi MinMaxScaler au lieu d'un autre? StandardScaler par exemple?
Raspi
@Ippier: vous réduisez essentiellement l'espace limite possible pour chaque option de manière à réduire considérablement le niveau d'effort pour votre machine.
ike
7

Avec un tel ensemble de données, je pense que vous feriez mieux d'utiliser un réseau de neurones, un apprentissage en profondeur, une forêt aléatoire (ils sont étonnamment bons), etc.

Comme mentionné dans les réponses précédentes, le temps pris est proportionnel à la troisième puissance du nombre d'échantillons d'apprentissage. Même le temps de prédiction est polynomial en termes de nombre de vecteurs de test.

Si vous devez vraiment utiliser SVM, nous vous recommandons d’utiliser GPU speed ou de réduire la taille du jeu de données d’apprentissage. Essayez d’abord avec un échantillon (peut-être 10 000 lignes) des données pour voir si ce n’est pas un problème de format ou de distribution des données.

Comme mentionné dans d'autres réponses, les noyaux linéaires sont plus rapides.

Leela Prabhu
la source
3

J'ai récemment rencontré un problème similaire, car j'avais oublié de mettre à l'échelle des entités de mon jeu de données, utilisé auparavant pour former le type de modèle d'ensemble. L'échec de l'échelle des données peut être le coupable probable, comme l'a souligné Shelby Matlock. Vous pouvez essayer différents scalers disponibles dans sklearn, tels que RobustScaler :

from sklearn.preprocessing import RobustScaler scaler = RobustScaler() X = scaler.fit_transfrom(X)

X est maintenant transformé / mis à l'échelle et prêt à être utilisé dans le modèle souhaité.

Dutse I
la source
2

C'est logique. IIUC, la vitesse d'exécution des opérations de vecteur de support est liée au nombre d'échantillons et non à la dimensionnalité. En d'autres termes, il est limité par le temps CPU et non par la RAM. Je ne sais pas exactement combien de temps cela devrait prendre, mais je lance des tests de performance pour le savoir.

Jaidev Deshpande
la source
1

Laissez-le fonctionner pendant la nuit ou mieux pendant 24 heures. Quelle est votre utilisation du processeur? Si aucun des cœurs ne tourne à 100%, vous avez un problème. Probablement avec mémoire. Avez-vous vérifié si votre jeu de données correspond à 8 Go? Avez-vous essayé le SGDClassifier? C'est l'un des plus rapides là-bas. La peine d'essayer d'abord en espérant qu'il se termine dans environ une heure.

Diego
la source
SGDClassifierne supporte pas les noyaux. Si le PO veut une SVM linéaire, alors je vous recommande d'essayer d'abord LinearSVR. C'est beaucoup plus rapide que SVRparce que cela résout le problème en utilisant une bibliothèque de régression linéaire, et un minimum global est garanti (contrairement à gradient descente).
Ricardo Cruz
Appréciez votre commentaire. Pourriez-vous expliquer pourquoi le support du noyau est un problème?
Diego
De la documentation , The loss function to be used. Defaults to ‘hinge’, which gives a linear SVM.même chose pour SGDRegressor. SGDRegressorest équivalent à utiliser SVR(kernel='linear'). Si c'est ce que veut OP, c'est génial. J'avais l'impression qu'il voulait utiliser SVM avec un noyau. Si ce n'est pas le cas, je le recommanderais en premier LinearSVR.
Ricardo Cruz
1

Essayez de normaliser les données sur [-1,1]. J'ai fait face à un problème similaire et à la normalisation tout a bien fonctionné. Vous pouvez normaliser facilement les données en utilisant:

from sklearn import preprocessing X_train = preprocessing.scale(X_train) X_test = preprocessing.scale(X_test)

Sujay_K
la source
@Archie Ceci est une réponse à une question, pas une question.
timleathart
1

J'ai rencontré ce problème et cache_sizecomme d'autres le suggèrent, cela n'aide en rien. Vous pouvez voir ce post et celui-ci en tant que principal contributeur a suggéré que vous deviez modifier le code manuellement.

Comme vous le savez, SVCil SVRexiste des problèmes d’optimisation qui s’arrêtent lorsque la marge d’erreur est si faible que l’optimisation ultérieure est vaine. Il y a donc un autre paramètre dans ceux-ci, max_iterdans lequel vous pouvez définir le nombre d'itérations à effectuer.

J'ai utilisé sklearnen python et e1071en R et R, le résultat est beaucoup plus rapide sans réglage max_iteret sklearnprend 2 à 4 fois plus longtemps. La seule façon pour moi de réduire le temps de calcul de python était d'utiliser max_iter. Il est par rapport à la complexité de votre modèle, le nombre de caractéristiques, noyaux et hyperparam'etres, mais pour les petits ensemble de données I utilisé pour environ 4000 points de référence et max_itera été 10000les résultats ne sont pas différents du tout et il était acceptable.

Habib Karbasian
la source
0

Je viens d'avoir un problème similaire avec un jeu de données qui ne contient que 115 éléments et une seule fonctionnalité (données sur les compagnies aériennes internationales). La solution consistait à mettre à l'échelle les données. Ce qui m’avait manqué jusqu’à présent, c’était l’utilisation d’un pipeline:

from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler, MinMaxScaler

model = Pipeline([('scaler', StandardScaler()),
                  ('svr', SVR(kernel='linear'))])

Vous pouvez vous entraîner modelcomme un modèle de classification / régression habituel et l’évaluer de la même manière. Rien ne change, seule la définition du modèle.

Martin Thoma
la source
C'est quoi Pipeline? Vous ne l'importez pas.
Bram Vanroy le
0

Vous devez mettre à l'échelle vos données. La mise à l'échelle normalisera vos points de données dans une plage de -1 à 1, ce qui accélérera la convergence.

Essayez d'utiliser le code suivant:

# X is your numpy data array.

from sklearn import preprocessing

X = preprocessing.scale(X)
Rishabh Gupta
la source
Bienvenue dans Data Science SE! Pouvez-vous expliquer en quoi votre suggestion aidera OP? Ce que vous proposez est une mise à l'échelle d'un tableau. Il n'est pas clair comment cela peut ou non affecter l'algorithme SVR dans Scikit Learn.
Stereo