Implémenter SVM et Kernel SVM avec Scikit-Learn de Python

Implémenter SVM et Kernel SVM avec Scikit-Learn de Python

Introduction

Ce guide est la première partie de trois guides sur les machines à vecteurs de support (SVM). Dans cette série, nous allons travailler sur un cas d'utilisation de faux billets de banque, découvrir les SVM simples, puis les hyperparamètres SVM et, enfin, apprendre un concept appelé le astuce du noyau et explorez d'autres types de SVM.

Si vous souhaitez lire tous les guides ou voir lesquels vous intéressent le plus, voici le tableau des sujets abordés dans chaque guide :

1. Implémenter SVM et Kernel SVM avec Scikit-Learn de Python

  • Cas d'utilisation : oubliez les billets de banque
  • Contexte des SVM
  • Modèle SVM simple (linéaire)
    • À propos de l'ensemble de données
    • Importation du jeu de données
    • Exploration de l'ensemble de données
  • Implémentation de SVM avec Scikit-Learn
    • Diviser les données en ensembles d'apprentissage/test
    • Entraîner le modèle
    • Faire des prédictions
    • Évaluation du modèle
    • Interprétation des résultats

2. Comprendre les hyperparamètres SVM (Bientôt disponible!)

  • L'hyperparamètre C
  • L'hyperparamètre gamma

3. Implémenter d'autres saveurs SVM avec Scikit-Learn de Python (Bientôt disponible!)

  • L'idée générale des SVM (un récapitulatif)
  • Noyau (astuce) SVM
  • Implémentation d'un noyau SVM non linéaire avec Scikit-Learn
  • Importer des bibliothèques
    • Importer l'ensemble de données
    • Diviser les données en fonctionnalités (X) et cible (y)
    • Diviser les données en ensembles d'apprentissage/test
    • Entraînement de l'algorithme
  • Noyau polynomial
    • Faire des prédictions
    • Évaluation de l'algorithme
  • Noyau gaussien
    • Prédiction et évaluation
  • Noyau sigmoïde
    • Prédiction et évaluation
  • Comparaison des performances du noyau non linéaire

Cas d'utilisation : Billets de banque contrefaits

Parfois, les gens trouvent un moyen de falsifier des billets de banque. S'il y a une personne qui regarde ces notes et vérifie leur validité, il peut être difficile d'être trompé par elles.

Mais que se passe-t-il lorsqu'il n'y a personne pour regarder chaque note ? Existe-t-il un moyen de savoir automatiquement si les billets de banque sont faux ou authentiques ?

Il existe de nombreuses façons de répondre à ces questions. Une réponse consiste à photographier chaque billet reçu, à comparer son image avec l'image d'un faux billet, puis à le classer comme réel ou contrefait. Dès lors qu'il peut être fastidieux ou critique d'attendre la validation de la note, il serait également intéressant de faire cette comparaison rapidement.

Puisque des images sont utilisées, elles peuvent être compactées, réduites en niveaux de gris et voir leurs mesures extraites ou quantifiées. De cette façon, la comparaison se ferait entre les mesures des images, au lieu du pixel de chaque image.

Jusqu'à présent, nous avons trouvé un moyen de traiter et de comparer les billets de banque, mais comment seront-ils classés en vrais ou contrefaits ? Nous pouvons utiliser l'apprentissage automatique pour effectuer cette classification. Il existe un algorithme de classification appelé Soutenir la machine vectorielle, principalement connu sous sa forme abrégée : SVM.

Contexte des SVM

Les SVM ont été introduits initialement en 1968, par Vladmir Vapnik et Alexey Chervonenkis. A cette époque, leur algorithme se limitait à classer des données pouvant être séparées par une seule ligne droite, ou des données linéairement séparable. Nous pouvons voir à quoi ressemblerait cette séparation :

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Dans l'image ci-dessus, nous avons une ligne au milieu, dont certains points sont à gauche et d'autres à droite de cette ligne. Notez que les deux groupes de points sont parfaitement séparés, il n'y a pas de points intermédiaires ou même proches de la ligne. Il semble y avoir une marge entre des points similaires et la ligne qui les sépare, cette marge est appelée marge de séparation. La fonction de la marge de séparation est d'agrandir l'espace entre les points similaires et la ligne qui les sépare. SVM le fait en utilisant certains points et calcule ses vecteurs perpendiculaires pour prendre en charge la décision concernant la marge de la ligne. Ce sont les vecteurs de soutien qui font partie du nom de l'algorithme. Nous en comprendrons plus à leur sujet plus tard. Et la ligne droite que nous voyons au milieu est trouvée par des méthodes qui maximisent cet espace entre la ligne et les points, ou qui maximisent la marge de séparation. Ces méthodes sont issues du domaine de Théorie de l'optimisation.

Dans l'exemple que nous venons de voir, les deux groupes de points peuvent être facilement séparés, puisque chaque point individuel est proche de ses points similaires, et les deux groupes sont éloignés l'un de l'autre.

Mais que se passe-t-il s'il n'existe aucun moyen de séparer les données à l'aide d'une ligne droite ? S'il y a des points désordonnés, ou si une courbe est nécessaire ?

Pour résoudre ce problème, SVM a ensuite été affiné dans les années 1990 pour pouvoir également classer les données qui avaient des points éloignés de sa tendance centrale, comme les valeurs aberrantes, ou des problèmes plus complexes qui avaient plus de deux dimensions et n'étaient pas linéairement séparables. .

Ce qui est curieux, c'est que ce n'est que ces dernières années que les SVM ont été largement adoptés, principalement en raison de leur capacité à obtenir parfois plus de 90 % de réponses correctes ou précision, pour les problèmes difficiles.

Les SVM sont implémentés d'une manière unique par rapport à d'autres algorithmes d'apprentissage automatique, une fois qu'ils sont basés sur des explications statistiques de ce qu'est l'apprentissage, ou sur Théorie de l'apprentissage statistique.

Dans cet article, nous verrons ce que sont les algorithmes des machines à vecteurs de support, la brève théorie derrière une machine à vecteurs de support et leur implémentation dans la bibliothèque Scikit-Learn de Python. On passera ensuite à un autre concept SVM, dit SVM du noyauou Truc du noyau, et l'implémentera également avec l'aide de Scikit-Learn.

Modèle SVM simple (linéaire)

À propos de l'ensemble de données

En suivant l'exemple donné dans l'introduction, nous utiliserons un jeu de données contenant des mesures d'images de billets de banque réels et falsifiés.

Lorsque nous regardons deux notes, nos yeux les parcourent généralement de gauche à droite et vérifient où il pourrait y avoir des similitudes ou des dissemblances. Nous recherchons un point noir devant un point vert, ou une marque brillante qui se trouve au-dessus d'une illustration. Cela signifie qu'il y a un ordre dans lequel nous regardons les notes. Si nous savions qu'il y avait des verts et des points noirs, mais pas si le point vert venait avant le noir, ou si le noir venait avant le vert, il serait plus difficile de faire la distinction entre les notes.

Il existe une méthode similaire à celle que nous venons de décrire pouvant être appliquée aux images des billets de banque. De manière générale, cette méthode consiste à traduire les pixels de l'image en un signal, puis à prendre en considération l'ordre dans lequel chaque signal différent apparaît dans l'image en le transformant en petites ondes, ou ondelettes. Après avoir obtenu les ondelettes, il existe un moyen de connaître l'ordre dans lequel un signal se produit avant un autre, ou le fiable, mais pas exactement quel signal. Pour le savoir, il faut obtenir les fréquences de l'image. Ils sont obtenus par une méthode qui effectue la décomposition de chaque signal, appelée Méthode de Fourier.

Une fois que la dimension temporelle est obtenue par les ondelettes et la dimension fréquentielle par la méthode de Fourier, une superposition du temps et de la fréquence est faite pour voir quand les deux ont une correspondance, c'est la convolution analyse. La convolution obtient un ajustement qui fait correspondre les ondelettes avec les fréquences de l'image et découvre quelles fréquences sont les plus importantes.

Cette méthode qui consiste à trouver les ondelettes, leurs fréquences, puis à les ajuster toutes les deux, s'appelle Transformée en ondelettes. La transformée en ondelettes a des coefficients, et ces coefficients ont été utilisés pour obtenir les mesures que nous avons dans l'ensemble de données.

Importation du jeu de données

L'ensemble de données des billets de banque que nous allons utiliser dans cette section est le même que celui utilisé dans la section de classification du didacticiel sur l'arbre de décision.

Remarque: Vous pouvez télécharger le jeu de données ici.

Importons les données dans un pandas dataframe structure, et jetez un oeil à ses cinq premières lignes avec le head() méthode.

Notez que les données sont enregistrées dans un txt format de fichier (texte), séparés par des virgules, et sans en-tête. Nous pouvons le reconstruire sous forme de tableau en le lisant comme un csv, en précisant le separator comme une virgule, et en ajoutant les noms de colonne avec le names argument.

Suivons ces trois étapes à la fois, puis examinons les cinq premières lignes de données :

import pandas as pd data_link = "https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt"
col_names = ["variance", "skewness", "curtosis", "entropy", "class"] bankdata = pd.read_csv(data_link, names=col_names, sep=",", header=None)
bankdata.head()

Cela se traduit par:

	variance skewness curtosis entropy class
0 3.62160 8.6661 -2.8073 -0.44699 0
1 4.54590 8.1674 -2.4586 -1.46210 0
2 3.86600 -2.6383 1.9242 0.10645 0
3 3.45660 9.5228 -4.0112 -3.59440 0
4 0.32924 -4.4552 4.5718 -0.98880 0

Remarque: Vous pouvez également enregistrer les données localement et remplacer data_link en data_path, et transmettez le chemin d'accès à votre fichier local.

Nous pouvons voir qu'il y a cinq colonnes dans notre ensemble de données, à savoir, variance, skewness, curtosis, entropyet une class. Dans les cinq lignes, les quatre premières colonnes sont remplies de nombres tels que 3.62160, 8.6661, -2.8073 ou continu valeurs, et la dernière class colonne a ses cinq premières lignes remplies de 0, ou un discret valeur.

Étant donné que notre objectif est de prédire si un billet de banque est authentique ou non, nous pouvons le faire en nous basant sur les quatre attributs du billet :

  • variance de l'image transformée en ondelettes. Généralement, la variance est une valeur continue qui mesure à quel point les points de données sont proches ou éloignés de la valeur moyenne des données. Si les points sont plus proches de la valeur moyenne des données, la distribution est plus proche d'une distribution normale, ce qui signifie généralement que ses valeurs sont mieux distribuées et un peu plus faciles à prédire. Dans le contexte image courant, il s'agit de la variance des coefficients résultant de la transformée en ondelettes. Moins il y a de variance, plus les coefficients sont proches de la traduction de l'image réelle.

  • skewness de l'image transformée en ondelettes. L'asymétrie est une valeur continue qui indique l'asymétrie d'une distribution. S'il y a plus de valeurs à gauche de la moyenne, la distribution est asymétrique négativement, s'il y a plus de valeurs à droite de la moyenne, la distribution est biaisé positivement, et si la moyenne, le mode et la médiane sont identiques, la distribution est symétrique. Plus une distribution est symétrique, plus elle se rapproche d'une distribution normale, ayant aussi ses valeurs mieux distribuées. Dans le présent contexte, il s'agit de l'asymétrie des coefficients résultant de la transformée en ondelettes. Plus ils sont symétriques, plus les coefficients que nousvariance, skewness, curtosis, entropyre à traduire l'image réelle.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • curtosis (ou aplatissement) de l'image transformée en ondelettes. L'aplatissement est une valeur continue qui, comme l'asymétrie, décrit également la forme d'une distribution. Selon le coefficient d'aplatissement (k), une distribution - par rapport à la distribution normale peut être plus ou moins plate - ou avoir plus ou moins de données dans ses extrémités ou ses queues. Lorsque la distribution est plus étalée et plus plate, on l'appelle platykurtique; quand elle est moins étalée et plus concentrée au milieu, mésocurtique; et lorsque la distribution est presque entièrement concentrée au milieu, on l'appelle leptokurtique. C'est le même cas que les cas antérieurs de variance et d'asymétrie, plus la distribution est mésokurtique, plus les coefficients étaient proches de la traduction de l'image réelle.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • entropy d'image. L'entropie est également une valeur continue, elle mesure généralement le caractère aléatoire ou le désordre dans un système. Dans le contexte d'une image, l'entropie mesure la différence entre un pixel et ses pixels voisins. Pour notre contexte, plus les coefficients ont d'entropie, plus il y a de perte lors de la transformation de l'image - et plus l'entropie est petite, plus la perte d'information est petite.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

La cinquième variable était la class variable, qui a probablement des valeurs 0 et 1, qui indiquent si la note était réelle ou falsifiée.

Nous pouvons vérifier si la cinquième colonne contient des zéros et des uns avec Pandas' unique() méthode:

bankdata['class'].unique()

La méthode ci-dessus renvoie :

array([0, 1]) 

La méthode ci-dessus renvoie un tableau avec les valeurs 0 et 1. Cela signifie que les seules valeurs contenues dans nos lignes de classe sont des zéros et des uns. Il est prêt à être utilisé comme l'objectif dans notre apprentissage supervisé.

  • class d'image. C'est une valeur entière, c'est 0 quand l'image est falsifiée, et 1 quand l'image est réelle.

Puisque nous avons une colonne avec les annotations des images réelles et oubliées, cela signifie que notre type d'apprentissage est supervisé.

Conseils: pour en savoir plus sur le raisonnement derrière la transformée en ondelettes sur les images des billets de banque et l'utilisation de SVM, lisez l' article publié des auteurs.

Nous pouvons également voir combien d'enregistrements, ou d'images, nous avons, en regardant le nombre de lignes dans les données via le shape propriété:

bankdata.shape

Cela produit:

(1372, 5)

La ligne ci-dessus signifie qu'il y a 1,372 5 lignes d'images de billets de banque transformés et XNUMX colonnes. Ce sont les données que nous allons analyser.

Nous avons importé notre jeu de données et effectué quelques vérifications. Nous pouvons maintenant explorer nos données pour mieux les comprendre.

Exploration de l'ensemble de données

Nous venons de voir qu'il n'y a que des zéros et des uns dans la colonne des classes, mais on peut aussi savoir dans quelle proportion ils sont - autrement dit - s'il y a plus de zéros que de uns, plus de uns que de zéros, ou si les nombres de zéros est le même que le nombre de uns, ce qui signifie qu'ils sont balanced.

Pour connaître la proportion, nous pouvons compter chacune des valeurs zéro et un dans les données avec value_counts() méthode:

bankdata['class'].value_counts()

Cela produit:

0 762
1 610
Name: class, dtype: int64

Dans le résultat ci-dessus, nous pouvons voir qu'il y a 762 zéros et 610 uns, soit 152 zéros de plus que de uns. Cela signifie que nous avons un peu plus d'images falsifiées que réelles, et si cet écart était plus grand, par exemple, 5500 zéros et 610 uns, cela pourrait avoir un impact négatif sur nos résultats. Une fois que nous essayons d'utiliser ces exemples dans notre modèle - plus il y a d'exemples, cela signifie généralement que plus le modèle aura d'informations pour décider entre les faux ou les vrais billets - s'il y a peu d'exemples de vrais billets, le modèle est susceptible d'être trompé en essayant de les reconnaître.

Nous savons déjà qu'il existe 152 billets falsifiés supplémentaires, mais pouvons-nous être sûrs que ce sont suffisamment d'exemples pour que le modèle apprenne ? Savoir combien d'exemples sont nécessaires pour apprendre est une question très difficile à répondre, à la place, nous pouvons essayer de comprendre, en termes de pourcentage, quelle est la différence entre les classes.

La première étape consiste à utiliser des pandas value_counts() à nouveau, mais voyons maintenant le pourcentage en incluant l'argument normalize=True:

bankdata['class'].value_counts(normalize=True)

La normalize=True calcule le pourcentage des données pour chaque classe. Jusqu'à présent, le pourcentage de données falsifiées (0) et réelles (1) est :

0 0.555394
1 0.444606
Name: class, dtype: float64

Cela signifie qu'environ (~) 56 % de notre ensemble de données sont falsifiés et 44 % sont réels. Cela nous donne un rapport de 56 % à 44 %, ce qui équivaut à une différence de 12 %. Ceci est statistiquement considéré comme une petite différence, car il est juste un peu au-dessus de 10 %, de sorte que les données sont considérées comme équilibrées. Si au lieu d'une proportion de 56:44, il y avait une proportion de 80:20 ou 70:30, alors nos données seraient considérées comme déséquilibrées, et nous aurions besoin de faire un traitement de déséquilibre, mais, heureusement, ce n'est pas le cas.

Nous pouvons également voir cette différence visuellement, en jetant un œil à la distribution de la classe ou de la cible avec un histogramme imprégné de Pandas, en utilisant :

bankdata['class'].plot.hist();

Cela trace un histogramme en utilisant directement la structure de la trame de données, en combinaison avec le matplotlib bibliothèque qui est dans les coulisses.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

En regardant l'histogramme, nous pouvons être sûrs que nos valeurs cibles sont 0 ou 1 et que les données sont équilibrées.

Il s'agissait d'une analyse de la colonne que nous essayions de prédire, mais qu'en est-il de l'analyse des autres colonnes de nos données ?

On peut regarder les mesures statistiques avec le describe() méthode de trame de données. Nous pouvons également utiliser .T de transposition - pour inverser les colonnes et les lignes, ce qui rend plus directe la comparaison entre les valeurs :

Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!

bankdata.describe().T

Cela se traduit par:

 count mean std min 25% 50% 75% max
variance 1372.0 0.433735 2.842763 -7.0421 -1.773000 0.49618 2.821475 6.8248
skewness 1372.0 1.922353 5.869047 -13.7731 -1.708200 2.31965 6.814625 12.9516
curtosis 1372.0 1.397627 4.310030 -5.2861 -1.574975 0.61663 3.179250 17.9274
entropy 1372.0 -1.191657 2.101013 -8.5482 -2.413450 -0.58665 0.394810 2.4495
class 1372.0 0.444606 0.497103 0.0000 0.000000 0.00000 1.000000 1.0000

Notez que les colonnes d'asymétrie et de curtosis ont des valeurs moyennes qui sont éloignées des valeurs d'écart type, cela indique que les valeurs qui sont plus éloignées de la tendance centrale des données, ou ont une plus grande variabilité.

Nous pouvons également jeter un coup d'œil à la distribution de chaque fonctionnalité visuellement, en traçant l'histogramme de chaque fonctionnalité à l'intérieur d'une boucle for. En plus de regarder la distribution, il serait intéressant de regarder comment les points de chaque classe sont séparés concernant chaque caractéristique. Pour ce faire, nous pouvons tracer un nuage de points en combinant les caractéristiques entre elles et attribuer des couleurs différentes à chaque point en fonction de sa classe.

Commençons par la distribution de chaque entité et traçons l'histogramme de chaque colonne de données, à l'exception de la class colonne. le class colonne ne sera pas prise en considération par sa position dans le tableau des colonnes de données bancaires. Toutes les colonnes seront sélectionnées sauf la dernière avec columns[:-1]:

import matplotlib.pyplot as plt for col in bankdata.columns[:-1]: plt.title(col) bankdata[col].plot.hist() plt.show();

Après avoir exécuté le code ci-dessus, nous pouvons voir que les deux skewness ainsi que entropy les distributions de données sont asymétriques négativement et curtosis est positivement biaisé. Toutes les distributions sont symétriques et variance est la seule distribution proche de la normale.

Nous pouvons maintenant passer à la deuxième partie et tracer le nuage de points de chaque variable. Pour ce faire, nous pouvons également sélectionner toutes les colonnes sauf la classe, avec columns[:-1], utilisez Seaborn scatterplot() et deux boucles for pour obtenir les variations d'appariement pour chacune des caractéristiques. On peut aussi exclure l'appariement d'une caractéristique avec elle-même, en testant si la première caractéristique est égale à la seconde avec un if statement.

import seaborn as sns for feature_1 in bankdata.columns[:-1]: for feature_2 in bankdata.columns[:-1]: if feature_1 != feature_2: print(feature_1, feature_2) sns.scatterplot(x=feature_1, y=feature_2, data=bankdata, hue='class') plt.show();

Notez que tous les graphiques ont à la fois des points de données réels et falsifiés qui ne sont pas clairement séparés les uns des autres, cela signifie qu'il existe une sorte de superposition de classes. Puisqu'un modèle SVM utilise une ligne pour séparer les classes, l'un de ces groupes dans les graphiques pourrait-il être séparé en utilisant une seule ligne ? Cela semble peu probable. Voici à quoi ressemblent la plupart des données réelles. Le plus proche que nous pouvons obtenir à une séparation est dans la combinaison de skewness ainsi que varianceou entropy ainsi que variance parcelles. Ceci est probablement dû à variance données ayant une forme de distribution plus proche de la normale.

Mais regarder tous ces graphiques dans l'ordre peut être un peu difficile. Nous avons l'alternative de regarder tous les graphiques de distribution et de nuage de points ensemble en utilisant Seaborn's pairplot().

Les deux boucles for précédentes que nous avions effectuées peuvent être remplacées par cette ligne :

sns.pairplot(bankdata, hue='class');

En regardant le pairplot, il semble qu'en fait, curtosis ainsi que variance serait la combinaison de fonctionnalités la plus simple, de sorte que les différentes classes pourraient être séparées par une ligne, ou linéairement séparable.

Si la plupart des données sont loin d'être linéairement séparables, on peut essayer de les prétraiter, en réduisant ses dimensions, et aussi de normaliser ses valeurs pour essayer de rendre la distribution plus proche d'une normale.

Dans ce cas, utilisons les données telles quelles, sans autre prétraitement, et plus tard, nous pouvons revenir en arrière, ajouter au prétraitement des données et comparer les résultats.

Conseils: Lorsque vous travaillez avec des données, des informations sont généralement perdues lors de leur transformation, car nous faisons des approximations au lieu de collecter davantage de données. Travailler d'abord avec les données initiales telles qu'elles sont, si possible, offre une base de référence avant d'essayer d'autres techniques de prétraitement. En suivant ce chemin, le résultat initial utilisant des données brutes peut être comparé à un autre résultat utilisant des techniques de prétraitement sur les données.

Remarque: Habituellement, en statistique, lors de la construction de modèles, il est courant de suivre une procédure en fonction du type de données (discrètes, continues, catégorielles, numériques), de leur distribution et des hypothèses du modèle. Alors qu'en informatique (CS), il y a plus de place pour les essais, les erreurs et les nouvelles itérations. Dans CS, il est courant d'avoir une ligne de base à comparer. Dans Scikit-learn, il existe une implémentation de modèles factices (ou d'estimateurs factices), certains ne valent pas mieux que de lancer une pièce de monnaie, et répondent simplement Oui (ou 1) 50% du temps. Il est intéressant d'utiliser des modèles fictifs comme référence pour le modèle réel lors de la comparaison des résultats. On s'attend à ce que les résultats réels du modèle soient meilleurs qu'une supposition aléatoire, sinon l'utilisation d'un modèle d'apprentissage automatique ne serait pas nécessaire.

Implémentation de SVM avec Scikit-Learn

Avant d'approfondir la théorie du fonctionnement de SVM, nous pouvons construire notre premier modèle de base avec les données, et Scikit-Learn's Classificateur de vecteur de soutien or SVC classe.

Notre modèle recevra les coefficients d'ondelettes et tentera de les classer en fonction de la classe. La première étape de ce processus consiste à séparer les coefficients ou Caractéristiques de la classe ou l'objectif. Après cette étape, la deuxième étape consiste à diviser davantage les données en un ensemble qui sera utilisé pour l'apprentissage du modèle ou coffret de train et un autre qui servira à l'évaluation du modèle ou ensemble d'essai.

Remarque: La nomenclature de test et d'évaluation peut être un peu déroutante, car vous pouvez également diviser vos données entre les ensembles d'entraînement, d'évaluation et de test. De cette façon, au lieu d'avoir deux ensembles, vous auriez un ensemble intermédiaire juste à utiliser et voir si les performances de votre modèle s'améliorent. Cela signifie que le modèle serait formé avec l'ensemble de train, amélioré avec l'ensemble d'évaluation et obtiendrait une métrique finale avec l'ensemble de test.

Certains diront que l'évaluation est cet ensemble intermédiaire, d'autres diront que l'ensemble de test est l'ensemble intermédiaire et que l'ensemble d'évaluation est l'ensemble final. C'est une autre façon d'essayer de garantir que le modèle ne voit en aucun cas le même exemple, ou qu'une sorte de fuite de données ne se produit pas, et qu'il y a une généralisation du modèle par l'amélioration de la dernière métrique définie. Si vous souhaitez suivre cette approche, vous pouvez encore diviser les données comme décrit dans ce Train_test_split() de Scikit-Learn – Ensembles de formation, de test et de validation guider.

Diviser les données en ensembles d'apprentissage/test

Lors de la session précédente, nous avons compris et exploré les données. Maintenant, nous pouvons diviser nos données en deux tableaux - un pour les quatre fonctionnalités et l'autre pour la cinquième, ou fonctionnalité cible. Puisque nous voulons prédire la classe en fonction des coefficients d'ondelettes, notre y sera l' class colonne et notre X sera le variance, skewness, curtosiset une entropy colonnes.

Pour séparer la cible et les fonctionnalités, nous pouvons attribuer uniquement la class colonne à y, en le supprimant plus tard du dataframe pour attribuer les colonnes restantes à X comprenant .drop() méthode:

y = bankdata['class']
X = bankdata.drop('class', axis=1) 

Une fois que les données sont divisées en attributs et étiquettes, nous pouvons ensuite les diviser en ensembles d'apprentissage et de test. Cela pourrait être fait à la main, mais le model_selection bibliothèque de Scikit-Learn contient les train_test_split() méthode qui nous permet de diviser aléatoirement les données en ensembles de train et de test.

Pour l'utiliser, nous pouvons importer la bibliothèque, appeler le train_test_split() méthode, transmettre X ainsi que y données, et définir un test_size passer pour un argument. Dans ce cas, nous le définirons comme 0.20– cela signifie que 20% des données seront utilisées pour les tests et les 80% restants pour la formation.

Cette méthode prend au hasard des échantillons en respectant le pourcentage que nous avons défini, mais respecte les paires Xy, de peur que l'échantillonnage ne perturbe totalement la relation.

Étant donné que le processus d'échantillonnage est intrinsèquement aléatoire, nous aurons toujours des résultats différents lors de l'exécution de la méthode. Pour pouvoir avoir les mêmes résultats, ou des résultats reproductibles, nous pouvons définir une constante appelée SEED avec la valeur de 42.

Vous pouvez exécuter le script suivant pour cela :

from sklearn.model_selection import train_test_split SEED = 42 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = SEED)

Notez que le train_test_split() la méthode renvoie déjà le X_train, X_test, y_train, y_test ensembles dans cet ordre. Nous pouvons imprimer le nombre d'échantillons séparés pour l'entraînement et le test en obtenant le premier (0) élément du shape la propriété a retourné le tuple :

xtrain_samples = X_train.shape[0]
xtest_samples = X_test.shape[0] print(f'There are {xtrain_samples} samples for training and {xtest_samples} samples for testing.')

Cela montre qu'il y a 1097 échantillons pour la formation et 275 pour les tests.

Entraîner le modèle

Nous avons divisé les données en ensembles d'entraînement et de test. Il est maintenant temps de créer et de former un modèle SVM sur les données du train. Pour ce faire, nous pouvons importer Scikit-Learn svm bibliothèque avec la Classificateur de vecteur de soutien classe, ou SVC classe.

Après avoir importé la classe, nous pouvons en créer une instance - puisque nous créons un modèle SVM simple, nous essayons de séparer nos données de manière linéaire, afin que nous puissions tracer une ligne pour diviser nos données - ce qui revient à utiliser un fonction linéaire – en définissant kernel='linear' comme argument pour le classifieur :

from sklearn.svm import SVC
svc = SVC(kernel='linear')

De cette façon, le classificateur essaiera de trouver une fonction linéaire qui sépare nos données. Après avoir créé le modèle, entraînons-le, ou s'adapter il, avec les données du train, employant le fit() méthode et donnant la X_train caractéristiques et y_train cibles comme arguments.

Nous pouvons exécuter le code suivant afin de former le modèle :

svc.fit(X_train, y_train)

Juste comme ça, le modèle est formé. Jusqu'à présent, nous avons compris les données, les avons divisées, créé un modèle SVM simple et adapté le modèle aux données du train.

La prochaine étape consiste à comprendre dans quelle mesure cet ajustement a réussi à décrire nos données. En d'autres termes, pour répondre si un SVM linéaire était un choix adéquat.

Faire des prédictions

Une façon de répondre si le modèle a réussi à décrire les données est de calculer et d'examiner une classification métrique.

Considérant que l'apprentissage est supervisé, on peut faire des prédictions avec X_test et comparer ces résultats de prédiction - que nous pourrions appeler y_pred – avec le réel y_testou vérité sur le terrain.

Pour prédire certaines données, le modèle predict() méthode peut être employée. Cette méthode reçoit les fonctionnalités de test, X_test, en tant qu'argument et renvoie une prédiction, 0 ou 1, pour chacun des X_test's rangées.

Après avoir prédit le X_test données, les résultats sont stockés dans un y_pred variable. Ainsi, chacune des classes prédites avec le modèle SVM linéaire simple est maintenant dans le y_pred variable.

Voici le code de prédiction :

y_pred = svc.predict(X_test)

Considérant que nous avons les prédictions, nous pouvons maintenant les comparer aux résultats réels.

Évaluation du modèle

Il existe plusieurs façons de comparer les prédictions aux résultats réels, et elles mesurent différents aspects d'une classification. Certaines mesures de classification les plus utilisées sont :

  1. Matrice de confusion: lorsque nous avons besoin de savoir pour combien d'échantillons nous avons eu raison ou tort chaque classe. Les valeurs qui étaient correctes et correctement prédites sont appelées vrais positifs, ceux qui ont été prédits comme positifs mais qui n'étaient pas positifs sont appelés faux positifs. La même nomenclature de vrais négatifs ainsi que faux négatifs est utilisé pour les valeurs négatives ;

  2. La précision: lorsque notre objectif est de comprendre quelles valeurs de prédiction correctes ont été considérées comme correctes par notre classifieur. La précision divisera ces vraies valeurs positives par les échantillons qui ont été prédits comme positifs ;

$$
précision = frac{texte{vrais positifs}}{texte{vrais positifs} + texte{faux positifs}}
$$

  1. Rappeler: généralement calculé avec précision pour comprendre combien de vrais positifs ont été identifiés par notre classificateur. Le rappel est calculé en divisant les vrais positifs par tout ce qui aurait dû être prédit comme positif.

$$
rappel = frac{texte{vrais positifs}}{texte{vrais positifs} + texte{faux négatifs}}
$$

  1. Score F1: est l'équilibré ou moyenne harmonique de précision et de rappel. La valeur la plus basse est 0 et la plus élevée est 1. Lorsque f1-score est égal à 1, cela signifie que toutes les classes ont été correctement prédites - c'est un score très difficile à obtenir avec des données réelles (des exceptions existent presque toujours).

$$
texte{f1-score} = 2* frac{texte{précision} * texte{rappel}}{texte{précision} + texte{rappel}}
$$

Nous avons déjà été familiarisés avec la matrice de confusion, la précision, le rappel et les mesures du score F1. Pour les calculer, nous pouvons importer les fichiers de Scikit-Learn metrics bibliothèque. Cette bibliothèque contient les classification_report ainsi que confusion_matrix méthodes, la méthode de rapport de classification renvoie la précision, le rappel et le score f1. Les deux classification_report ainsi que confusion_matrix peut être facilement utilisé pour connaître les valeurs de toutes ces métriques importantes.

Pour calculer les métriques, on importe les méthodes, on les appelle et on passe en arguments les classifications prédites, y_test, et les étiquettes de classification, ou y_true.

Pour une meilleure visualisation de la matrice de confusion, nous pouvons la tracer dans un Seaborn's heatmap ainsi que les annotations de quantité, et pour le rapport de classification, il est préférable d'imprimer son résultat, de sorte que ses résultats soient formatés. C'est le code suivant :

from sklearn.metrics import classification_report, confusion_matrix cm = confusion_matrix(y_test,y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Confusion matrix of linear SVM') print(classification_report(y_test,y_pred))

Cela affiche :

 precision recall f1-score support 0 0.99 0.99 0.99 148 1 0.98 0.98 0.98 127 accuracy 0.99 275 macro avg 0.99 0.99 0.99 275
weighted avg 0.99 0.99 0.99 275

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Dans le rapport de classification, nous savons qu'il y a une précision de 0.99, un rappel de 0.99 et un score f1 de 0.99 pour les faux billets, ou classe 0. Ces mesures ont été obtenues à partir de 148 échantillons comme indiqué dans la colonne support. Pendant ce temps, pour la classe 1, ou notes réelles, le résultat était une unité en dessous, 0.98 de précision, 0.98 de rappel et le même score f1. Cette fois, 127 mesures d'images ont été utilisées pour obtenir ces résultats.

Si nous regardons la matrice de confusion, nous pouvons également voir que sur 148 échantillons de classe 0, 146 ont été correctement classés et il y a eu 2 faux positifs, tandis que pour 127 échantillons de classe 1, il y a eu 2 faux négatifs et 125 vrais positifs.

On peut lire le rapport de classement et la matrice de confusion, mais que signifient-ils ?

Interprétation des résultats

Pour en découvrir la signification, examinons toutes les mesures combinées.

Presque tous les échantillons de la classe 1 ont été correctement classés, il y avait 2 erreurs pour notre modèle lors de l'identification des billets de banque réels. C'est la même chose qu'un rappel de 0.98 ou 98 %. Quelque chose de similaire peut être dit de la classe 0, seuls 2 échantillons ont été mal classés, tandis que 148 sont de vrais négatifs, totalisant une précision de 99%.

Outre ces résultats, tous les autres marquent 0.99, ce qui est presque 1, une métrique très élevée. La plupart du temps, lorsqu'une métrique aussi élevée se produit avec des données réelles, cela peut indiquer un modèle trop ajusté aux données, ou suréquipé.

En cas de surajustement, le modèle peut bien fonctionner lors de la prédiction des données déjà connues, mais il perd la capacité de généraliser à de nouvelles données, ce qui est important dans les scénarios du monde réel.

Un test rapide pour savoir si un surajustement se produit est également avec les données du train. Si le modèle a quelque peu mémorisé les données du train, les métriques seront très proches de 1 ou 100 %. N'oubliez pas que les données de train sont plus grandes que les données de test - pour cette raison - essayez de les regarder proportionnellement, plus d'échantillons, plus de chances de faire des erreurs, à moins qu'il n'y ait eu un surajustement.

Pour prédire avec les données de train, nous pouvons répéter ce que nous avons fait pour les données de test, mais maintenant avec X_train:

y_pred_train = svc.predict(X_train) cm_train = confusion_matrix(y_train,y_pred_train)
sns.heatmap(cm_train, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with train data') print(classification_report(y_train,y_pred_train))

Cela produit:

 precision recall f1-score support 0 0.99 0.99 0.99 614 1 0.98 0.99 0.99 483 accuracy 0.99 1097 macro avg 0.99 0.99 0.99 1097
weighted avg 0.99 0.99 0.99 1097

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Il est facile de voir qu'il semble y avoir un surajustement, une fois que les métriques du train sont à 99 % avec 4 fois plus de données. Que peut-on faire dans ce scénario ?

Pour inverser le surajustement, nous pouvons ajouter plus d'observations de train, utiliser une méthode de formation avec différentes parties de l'ensemble de données, telles que validation croisée, et également modifier les paramètres par défaut qui existent déjà avant la formation, lors de la création de notre modèle, ou hyperparamètres. La plupart du temps, Scikit-learn définit certains paramètres par défaut, et cela peut se produire silencieusement s'il n'y a pas beaucoup de temps consacré à la lecture de la documentation.

Vous pouvez consulter la deuxième partie de ce guide (restez à l'écoute!) pour voir comment implémenter la validation croisée et effectuer un réglage des hyperparamètres.

Conclusion

Dans cet article, nous avons étudié le noyau linéaire simple SVM. Nous avons eu l'intuition derrière l'algorithme SVM, utilisé un jeu de données réel, exploré les données et vu comment ces données peuvent être utilisées avec SVM en les implémentant avec la bibliothèque Scikit-Learn de Python.

Pour continuer à vous entraîner, vous pouvez essayer d'autres ensembles de données du monde réel disponibles à des endroits comme Kaggle, UCI, Ensembles de données publics Big Query, des universités et des sites Web gouvernementaux.

Je suggérerais également que vous exploriez les mathématiques réelles derrière le modèle SVM. Bien que vous n'en ayez pas nécessairement besoin pour utiliser l'algorithme SVM, il est toujours très pratique de savoir ce qui se passe réellement dans les coulisses pendant que votre algorithme trouve des limites de décision.

Horodatage:

Plus de Stackabuse