Régression logistique en Python – Real Python

By | janvier 13, 2020

Formation Python

À mesure que la quantité de données disponibles, la puissance de la puissance de calcul et le nombre d'améliorations algorithmiques continuent d'augmenter, il en va de même de l'importance de la science des données et de l'apprentissage automatique. Classification fait partie des domaines les plus importants de l'apprentissage automatique, et régression logistique est l'une de ses méthodes de base. À la fin de ce didacticiel, vous aurez appris la classification en général et les principes fondamentaux de la régression logistique en particulier, ainsi que la façon d'implémenter la régression logistique en Python.

Dans ce didacticiel, vous apprendrez:

  • Qu'est-ce que la régression logistique
  • À quoi sert la régression logistique
  • Fonctionnement de la régression logistique
  • Comment implémenter la régression logistique en Python, étape par étape

Classification

La classification est un domaine très important de l'apprentissage automatique supervisé. Un grand nombre de problèmes importants d'apprentissage automatique relèvent de ce domaine. Il existe de nombreuses méthodes de classification, et la régression logistique en fait partie.

Qu'est-ce que la classification?

Les algorithmes d'apprentissage automatique supervisé définissent des modèles qui capturent les relations entre les données. Classification est un domaine d'apprentissage automatique supervisé qui essaie de prédire à quelle classe ou catégorie une entité appartient, en fonction de ses caractéristiques.

Par exemple, vous pouvez analyser les employés d’une entreprise et essayer d’établir une dépendance à Caractéristiques ou les variables, comme le niveau de scolarité, le nombre d'années dans un poste actuel, l'âge, le salaire, les chances d'être promu, etc. L'ensemble des données relatives à un seul employé est un observation. Les caractéristiques ou variables peuvent prendre deux formes:

  1. Variables indépendantes, également appelés entrées ou prédicteurs, ne dépendent pas d'autres caractéristiques d'intérêt (ou du moins vous le supposez aux fins de l'analyse).
  2. Variables dépendantes, également appelés sorties ou réponses, dépendent des variables indépendantes.

Dans l'exemple ci-dessus, dans lequel vous analysez des employés, vous pouvez présumer que le niveau de formation, le temps passé dans un poste actuel et l'âge sont mutuellement indépendants et les considérer comme des entrées. Le salaire et les chances de promotion pourraient être les extrants qui dépendent des intrants.

La nature des variables dépendantes différencie les problèmes de régression et de classification. Régression les problèmes ont des sorties continues et généralement illimitées. Un exemple est lorsque vous estimez le salaire en fonction de l'expérience et du niveau d'éducation. D'autre part, classification les problèmes ont des sorties discrètes et finies appelées Des classes ou catégories. Par exemple, prédire si un employé va être promu ou non (vrai ou faux) est un problème de classification.

Il existe deux principaux types de problèmes de classification:

  1. Binaire ou classification binomiale: exactement deux classes à choisir (généralement 0 et 1, vrai et faux, ou positif et négatif)
  2. Multiclasse ou classification multinomiale: trois classes ou plus de sorties à choisir

S'il n'y a qu'une seule variable d'entrée, elle est généralement désignée par . Pour plusieurs entrées, vous verrez généralement la notation vectorielle = (₁,…, ᵣ), où est le nombre de prédicteurs (ou d'entités indépendantes). La variable de sortie est souvent notée et prend les valeurs 0 ou 1.

Quand avez-vous besoin d'une classification?

Vous pouvez appliquer la classification dans de nombreux domaines de la science et de la technologie. Par exemple, des algorithmes de classification de texte sont utilisés pour séparer les e-mails légitimes et indésirables, ainsi que les commentaires positifs et négatifs. Vous pouvez consulter la Classification pratique du texte avec Python et Keras pour obtenir un aperçu de cette rubrique. D'autres exemples concernent les applications médicales, la classification biologique, la notation du crédit, etc.

Les tâches de reconnaissance d'image sont souvent représentées comme des problèmes de classification. Par exemple, vous pouvez demander si une image représente un visage humain ou non, ou s'il s'agit d'une souris ou d'un éléphant, ou quel chiffre de zéro à neuf elle représente, et ainsi de suite. Pour en savoir plus à ce sujet, consultez la détection de visage traditionnelle avec Python et la reconnaissance de visage avec Python, dans moins de 25 lignes de code.

Présentation de la régression logistique

La régression logistique est une technique de classification fondamentale. Il appartient au groupe des classificateurs linéaires et est quelque peu similaire au polynôme et régression linéaire. La régression logistique est rapide et relativement simple, et il est pratique pour vous d'interpréter les résultats. Bien qu'il s'agisse essentiellement d'une méthode de classification binaire, elle peut également être appliquée à des problèmes multiclasses.

Prérequis mathématiques

Vous aurez besoin de comprendre la fonction sigmoïde et la fonction de logarithme naturel pour comprendre ce qu'est la régression logistique et comment elle fonctionne.

Cette image montre la fonction sigmoïde (ou courbe en S) d'une variable some:

Fonction sigmoïde

La fonction sigmoïde a des valeurs très proches de 0 ou 1 sur la plupart de son domaine. Ce fait le rend approprié pour une application dans les méthodes de classification.

Cette image représente le logarithme naturel log () d'une variable , pour des valeurs de comprises entre 0 et 1:

Un algorithme naturel

Lorsque s'approche de zéro, le logarithme naturel de chute vers l'infini négatif. Lorsque = 1, log () vaut 0. L'inverse est vrai pour log (1 – ).

Notez que vous trouverez souvent le logarithme naturel indiqué par ln au lieu de Journal. En Python, math.log (x) et numpy.log (x) représentent le logarithme naturel de X, vous suivrez donc cette notation dans ce didacticiel.

Formulation du problème

Dans ce didacticiel, vous verrez une explication pour le cas commun de régression logistique appliquée à la classification binaire. Lorsque vous implémentez la régression logistique d'une variable dépendante sur l'ensemble de variables indépendantes = (₁,…, ᵣ), où est le nombre de prédicteurs (ou entrées), vous commencez avec les valeurs connues des prédicteurs ᵢ et la réponse réelle (ou sortie) correspondante ᵢ pour chaque observation = 1,…, .

Votre objectif est de trouver le fonction de régression logistique () de telle sorte que réponses prévues (ᵢ) sont aussi proches que possible du réponse réelle ᵢ pour chaque observation = 1,…, . N'oubliez pas que la réponse réelle ne peut être que 0 ou 1 dans les problèmes de classification binaire! Cela signifie que chaque (ᵢ) doit être proche de 0 ou 1. C'est pourquoi il est pratique d'utiliser la fonction sigmoïde.

Une fois que vous avez la fonction de régression logistique (), vous pouvez l'utiliser pour prédire les sorties pour les entrées nouvelles et invisibles, en supposant que la dépendance mathématique sous-jacente est inchangée.

Méthodologie

La régression logistique est un classificateur linéaire, vous utiliserez donc une fonction linéaire () = ₀ + ₁₁ + ⋯ + ᵣᵣ, également appelée logit. Les variables ₀, ₁,…, ᵣ sont les estimateurs des coefficients de régression, également appelés poids prévus ou juste coefficients.

La fonction de régression logistique () est la fonction sigmoïde de (): () = 1 / (1 + exp (− ()). En tant que telle, elle est souvent proche de 0 ou 1. La la fonction () est souvent interprétée comme la probabilité prédite que la sortie pour un donné soit égale à 1. Par conséquent, 1 – () est la probabilité que la sortie soit 0.

La régression logistique détermine les meilleurs poids prédits ₀, ₁,…, ᵣ de sorte que la fonction () soit aussi proche que possible de toutes les réponses réelles ᵢ, = 1,…, , où est le nombre d'observations. Le processus de calcul des meilleurs poids à l'aide des observations disponibles est appelé formation de modèle ou raccord.

Pour obtenir les meilleurs poids, vous maximisez généralement fonction log-vraisemblance (LLF) pour toutes les observations = 1,…, . Cette méthode est appelée Estimation de vraisemblance maximale et est représenté par l'équation LLF = Σᵢ (ᵢ log ( (ᵢ)) + (1 – ᵢ) log (1 – (ᵢ))).

Lorsque ᵢ = 0, le LLF pour l'observation correspondante est égal à log (1 – (ᵢ)). Si (ᵢ) est proche de ᵢ = 0, alors log (1 – (ᵢ)) est proche de 0. C'est le résultat souhaité. Si (ᵢ) est loin de 0, alors log (1 – (ᵢ)) chute significativement. Vous ne voulez pas de ce résultat car votre objectif est d'obtenir le maximum de LLF. De même, lorsque ᵢ = 1, le LLF pour cette observation est ᵢ log ( (ᵢ)). Si (ᵢ) est proche de ᵢ = 1, alors log ( (ᵢ)) est proche de 0. Si (ᵢ) est loin de 1, alors log ( (ᵢ)) est un grand nombre négatif.

Il existe plusieurs approches mathématiques qui calculent les meilleurs poids qui correspondent à la LLF maximale, mais cela dépasse le cadre de ce didacticiel. Pour l'instant, vous pouvez laisser ces détails aux bibliothèques Python de régression logistique que vous apprendrez à utiliser ici!

Une fois que vous avez déterminé les meilleurs poids qui définissent la fonction (), vous pouvez obtenir les sorties prédites (ᵢ) pour n'importe quelle entrée donnée ᵢ. Pour chaque observation = 1,…, , la sortie prévue est 1 si (ᵢ)> 0,5 et 0 sinon. Le seuil ne doit pas nécessairement être de 0,5, mais il l'est généralement. Vous pouvez définir une valeur inférieure ou supérieure si cela convient mieux à votre situation.

Il existe une autre relation importante entre () et (), qui est que log ( () / (1 – ())) = (). Cette égalité explique pourquoi () est le logit. Cela implique que () = 0,5 lorsque () = 0 et que la sortie prévue est 1 si ()> 0 et 0 sinon.

Performance de classification

La classification binaire a quatre types de résultats possibles:

  1. Vrais négatifs: négatifs correctement prédits (zéros)
  2. Vrais positifs: positifs correctement prédits (uns)
  3. Faux négatifs: négatifs incorrectement prévus (zéros)
  4. Faux positifs: positifs imprévus (uns)

Vous évaluez généralement les performances de votre classificateur en comparant les sorties réelles et prévues et en comptant les prédictions correctes et incorrectes.

L'indicateur le plus simple de précision de la classification est le rapport du nombre de prédictions correctes au nombre total de prédictions (ou observations). Les autres indicateurs des classificateurs binaires sont les suivants:

  • La valeur prédictive positive est le rapport entre le nombre de vrais positifs et la somme des nombres de vrais et faux positifs.
  • La valeur prédictive négative est le rapport du nombre de vrais négatifs à la somme des nombres de vrais et de faux négatifs.
  • La sensibilité (également connu sous le nom de taux de rappel ou de vrai positif) est le rapport entre le nombre de vrais positifs et le nombre de positifs réels.
  • La spécificité (ou vrai taux négatif) est le rapport entre le nombre de vrais négatifs et le nombre de négatifs réels.

L'indicateur le plus approprié dépend du problème d'intérêt. Dans ce didacticiel, vous allez utiliser la forme la plus simple de précision de classification.

Régression logistique à une seule variable

Régression logistique à une seule variable est le cas le plus simple de régression logistique. Il n'y a qu'une seule variable (ou caractéristique) indépendante, qui est = . Cette figure illustre la régression logistique à une seule variable:

Régression logistique 1D

Ici, vous avez un ensemble donné de paires entrée-sortie (ou -), représenté par des cercles verts. Ce sont vos observations. N'oubliez pas que ne peut être que 0 ou 1. Par exemple, le cercle vert le plus à gauche a l'entrée = 0 et la sortie réelle = 0. L'observation la plus à droite a = 9 et = 1.

La régression logistique trouve les poids ₀ et ₁ qui correspondent au LLF maximum. Ces poids définissent le logit () = ₀ + ₁, qui est la ligne noire en pointillés. Ils définissent également la probabilité prédite () = 1 / (1 + exp (− ())), représentée ici comme la ligne noire complète. Dans ce cas, le seuil () = 0,5 et () = 0 correspond à la valeur de légèrement supérieure à 3. Cette valeur est la limite entre les entrées avec les sorties prévues de 0 et 1.

Régression logistique multivariée

Régression logistique multivariée a plus d'une variable d'entrée. Cette figure montre la classification avec deux variables indépendantes, ₁ et ₂:

Régression logistique 2D

Le graphique est différent du graphique à variation unique car les deux axes représentent les entrées. Les sorties diffèrent également en couleur. Les cercles blancs montrent les observations classées comme des zéros, tandis que les cercles verts sont ceux classés comme des uns.

La régression logistique détermine les poids ₀, ₁ et ₂ qui maximisent le LLF. Une fois que vous avez ₀, ₁ et ₂, vous pouvez obtenir:

  • Le logit (₁, ₂) = ₀ + ₁₁ + ₂₂
  • Les probabilités (₁, ₂) = 1 / (1 + exp (− (₁, ₂))))

La ligne noire en pointillés sépare linéairement les deux classes. Cette ligne correspond à (₁, ₂) = 0,5 et (₁, ₂) = 0.

Régularisation

Sur-ajustement est l'un des types de problèmes les plus graves liés à l'apprentissage automatique. Cela se produit lorsqu'un modèle apprend trop bien les données d'entraînement. Le modèle apprend ensuite non seulement les relations entre les données mais également le bruit dans l'ensemble de données. Les modèles surajustés ont tendance à avoir de bonnes performances avec les données utilisées pour les ajuster (les données de formation), mais ils se comportent mal avec les données invisibles (ou les données de test, qui ne sont pas utilisées pour ajuster le modèle).

Le sur-ajustement se produit généralement avec des modèles complexes. Régularisation essaie normalement de réduire ou de pénaliser la complexité du modèle. Les techniques de régularisation appliquées avec régression logistique ont le plus souvent tendance à pénaliser les coefficients importants ₀, ₁,…, ᵣ:

  • Régularisation L1 pénalise le LLF avec la somme échelonnée des valeurs absolues des poids: | ₀ | + | ₁ | + ⋯ + | ᵣ |.
  • Régularisation L2 pénalise le LLF avec la somme échelonnée des carrés des poids: ₀² + ₁² + ⋯ + ᵣ².
  • Régularisation élastique-net est une combinaison linéaire de régularisation L1 et L2.

La régularisation peut améliorer considérablement les performances du modèle sur les données invisibles.

Régression logistique en Python

Maintenant que vous comprenez les principes de base, vous êtes prêt à appliquer les packages appropriés ainsi que leurs fonctions et classes pour effectuer une régression logistique en Python. Dans cette section, vous verrez les éléments suivants:

  • Un résumé des packages Python pour la régression logistique (NumPy, scikit-learn, StatsModels et Matplotlib)
  • Deux exemples illustratifs de régression logistique résolu avec scikit-learn
  • Un exemple conceptuel résolu avec StatsModels
  • Un exemple concret de classification des chiffres manuscrits

Commençons à implémenter la régression logistique en Python!

Packages Python de régression logistique

Il existe plusieurs packages dont vous aurez besoin pour la régression logistique en Python. Tous sont gratuits et open-source, avec beaucoup de ressources disponibles. Tout d'abord, vous aurez besoin NumPy, qui est un package fondamental pour le calcul scientifique et numérique en Python. NumPy est utile et populaire car il permet des opérations hautes performances sur des baies unidimensionnelles et multidimensionnelles.

NumPy possède de nombreuses routines de tableaux utiles. Il vous permet d'écrire du code élégant et compact, et il fonctionne bien avec de nombreux packages Python. Si vous voulez apprendre NumPy, vous pouvez commencer avec le guide d'utilisation officiel. La référence NumPy fournit également une documentation complète sur ses fonctions, classes et méthodes.

Un autre package Python que vous utiliserez est scikit-learn. Il s'agit de l'une des bibliothèques de science des données et d'apprentissage automatique les plus populaires. Vous pouvez utiliser scikit-learn pour exécuter diverses fonctions:

  • Prétraitement Les données
  • Réduire la dimensionnalité des problèmes
  • Valider des modèles
  • Sélectionner le modèle le plus approprié
  • Résoudre problèmes de régression et de classification
  • Mettre en place l'analyse par grappes

Vous trouverez des informations utiles sur le site Web officiel de scikit-learn, où vous voudrez peut-être en savoir plus sur les modèles linéaires généralisés et la mise en œuvre de la régression logistique. Si vous avez besoin de fonctionnalités que scikit-learn ne peut pas offrir, vous trouverez peut-être StatsModels utile. C'est une puissante bibliothèque Python pour l'analyse statistique. Vous pouvez trouver plus d'informations sur le site officiel.

Enfin, vous utiliserez Matplotlib pour visualiser les résultats de votre classement. Il s'agit d'une bibliothèque Python complète et largement utilisée pour un traçage de haute qualité. Pour plus d'informations, vous pouvez consulter le site Web officiel et le guide de l'utilisateur. Il existe plusieurs ressources pour apprendre Matplotlib que vous pourriez trouver utiles, comme les didacticiels officiels, l'Anatomie de Matplotlib et Python Plotting With Matplotlib (Guide).

Régression logistique en Python avec scikit-learn: exemple 1

Le premier exemple est lié à un problème de classification binaire à une seule variable. Il s'agit du type de problème de classification le plus simple. Vous devez suivre plusieurs étapes générales lorsque vous préparez vos modèles de classification:

  1. Importation packages, fonctions et classes
  2. Avoir les données avec lesquelles travailler et, le cas échéant, les transformer
  3. Créer un modèle de classification et le former (ou l'ajuster) avec vos données existantes
  4. Évaluer votre modèle pour voir si ses performances sont satisfaisantes

Un modèle suffisamment bon que vous définissez peut être utilisé pour faire d'autres prédictions liées à de nouvelles données invisibles. La procédure ci-dessus est la même pour la classification et la régression.

Étape 1: importer des packages, des fonctions et des classes

Tout d'abord, vous devez importer Matplotlib pour la visualisation et NumPy pour les opérations de tableau. Vous aurez également besoin Régression logistique, classification_report (), et confusion_matrix () de scikit-learn:

importation matplotlib.pyplot comme plt
importation engourdi comme np
de sklearn.linear_model importation Régression logistique
de sklearn.metrics importation classification_report, confusion_matrix

Maintenant, vous avez importé tout ce dont vous avez besoin pour la régression logistique en Python avec scikit-learn!

Étape 2: obtenir des données

En pratique, vous aurez généralement quelques données à utiliser. Aux fins de cet exemple, créons simplement des tableaux pour les valeurs d'entrée () et de sortie ():

X = np.arange(dix).remodeler(-1, 1)
y = np.tableau([[[[0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

L'entrée et la sortie doivent être des tableaux NumPy (instances de la classe numpy.ndarray) ou des objets similaires. numpy.arange () crée un tableau de valeurs consécutives, également espacées dans une plage donnée. Pour plus d'informations sur cette fonction, consultez la documentation officielle ou NumPy arange (): Comment utiliser np.arange ().

Le tableau X doit être bidimensionnel. Il doit avoir une colonne pour chaque entrée et le nombre de lignes doit être égal au nombre d'observations. Faire X en deux dimensions, vous appliquez .reshape () avec les arguments -1 pour obtenir autant de lignes que nécessaire et 1 pour obtenir une colonne. Pour plus d'informations sur .reshape (), vous pouvez consulter la documentation officielle. Voici comment X et y regarde maintenant:

>>>

>>> X
tableau ([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> y
tableau ([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

X a deux dimensions:

  1. Une colonne pour une seule entrée
  2. Dix rangées, chacun correspondant à une observation

y est unidimensionnel avec dix éléments. Encore une fois, chaque élément correspond à une observation. Il ne contient que des zéros et des uns car il s'agit d'un problème de classification binaire.

Étape 3: créer un modèle et le former

Une fois l'entrée et la sortie préparées, vous pouvez créer et définir votre modèle de classification. Vous allez le représenter avec une instance de la classe Régression logistique:

modèle = Régression logistique(solveur=«liblinéaire», random_state=0)

L'instruction ci-dessus crée une instance de Régression logistique et lie ses références à la variable modèle. Régression logistique possède plusieurs paramètres facultatifs qui définissent le comportement du modèle et de l'approche:

  • peine est une chaîne («l2» par défaut) qui décide s'il y a régularisation et quelle approche utiliser. D'autres options sont «l1», «élastique», et 'aucun'.

  • double est un booléen (Faux par défaut) qui décide d'utiliser Primal (lorsque Faux) ou à double formulation (lorsque Vrai).

  • tol est un nombre à virgule flottante (0,0001 par défaut) qui définit la tolérance d'arrêt de la procédure.

  • C est un nombre à virgule flottante positif (1.0 par défaut) qui définit la force relative de la régularisation. Des valeurs plus petites indiquent une régularisation plus forte.

  • fit_intercept est un booléen (Vrai par défaut) qui décide s'il faut calculer l'ordonnée à l'origine when (lorsque Vrai) ou le considérer comme égal à zéro (lorsque Faux).

  • intercept_scaling est un nombre à virgule flottante (1.0 par défaut) qui définit la mise à l'échelle de l'ordonnée à l'origine ₀.

  • classe_poids est un dictionnaire, 'équilibré', ou Aucun (par défaut) qui définit les poids liés à chaque classe. Quand Aucun, toutes les classes ont le poids un.

  • random_state est un entier, une instance de numpy.RandomState, ou Aucun (par défaut) qui définit le générateur de nombres pseudo-aléatoires à utiliser.

  • solveur est une chaîne («liblinéaire» par défaut) qui décide du solveur à utiliser pour ajuster le modèle. D'autres options sont «newton-cg», «lbfgs», 'affaissement', et 'saga'.

  • max_iter est un entier (100 par défaut) qui définit le nombre maximum d'itérations par le solveur lors de l'ajustement du modèle.

  • multi_class est une chaîne («ovr» par défaut) qui décide de l'approche à utiliser pour gérer plusieurs classes. D'autres options sont «multinomial» et 'auto'.

  • verbeux est un entier non négatif (0 par défaut) qui définit la verbosité du «liblinéaire» et «lbfgs» solveurs.

  • warm_start est un booléen (Faux par défaut) qui décide de réutiliser la solution précédemment obtenue.

  • n_jobs est un entier ou Aucun (par défaut) qui définit le nombre de processus parallèles à utiliser. Aucun signifie généralement utiliser un noyau, tandis que -1 signifie utiliser tous les cœurs disponibles.

  • l1_ratio est soit un nombre à virgule flottante compris entre zéro et un ou Aucun (défaut). Il définit l'importance relative de la partie L1 dans la régularisation du filet élastique.

Vous devez faire correspondre soigneusement le solveur et la méthode de régularisation pour plusieurs raisons:

  • «liblinéaire» le solveur ne fonctionne pas sans régularisation.
  • «newton-cg», 'affaissement', 'saga', et «lbfgs» ne supporte pas la régularisation L1.
  • 'saga' est le seul solveur qui prend en charge la régularisation élastique-net.

Une fois le modèle créé, vous devez l'adapter (ou le former). L'ajustement du modèle est le processus de détermination des coefficients ₀, ₁,…, ᵣ qui correspondent à la meilleure valeur de la fonction de coût. Vous adaptez le modèle avec .en forme():

.en forme() prend X, y, et éventuellement des poids liés à l'observation. Ensuite, il s'adapte au modèle et renvoie l'instance de modèle elle-même:

LogisticRegression (C = 1.0, class_weight = None, dual = False, fit_intercept = True,
                   intercept_scaling = 1, l1_ratio = None, max_iter = 100,
                   multi_class = 'warn', n_jobs = None, penalty = 'l2',
                   random_state = 0, solver = 'liblinear', tol = 0.0001, verbose = 0,
                   warm_start = False)

Il s'agit de la représentation de chaîne obtenue du modèle ajusté.

Vous pouvez utiliser le fait que .en forme() renvoie l'instance de modèle et enchaîne les deux dernières instructions. Ils sont équivalents à la ligne de code suivante:

modèle = Régression logistique(solveur=«liblinéaire», random_state=0).en forme(X, y)

À ce stade, vous avez défini le modèle de classification.

Vous pouvez obtenir rapidement les attributs de votre modèle. Par exemple, l'attribut .Des classes_ représente le tableau de valeurs distinctes y prend:

>>>

>>> modèle.Des classes_
tableau ([0, 1])

Ceci est l'exemple de la classification binaire, et y peut être 0 ou 1, comme indiqué ci-dessus.

Vous pouvez également obtenir la valeur de la pente ₁ et l'ordonnée à l'origine ₀ de la fonction linéaire comme ceci:

>>>

>>> modèle.intercepter_
tableau ([-1.04608067])
>>> modèle.coef_
tableau ([[0.51491375]])

Comme vous pouvez le voir, ₀ est donné à l'intérieur d'un tableau unidimensionnel, tandis que ₁ est à l'intérieur d'un tableau bidimensionnel. Vous utilisez les attributs .intercepter_ et .coef_ pour obtenir ces résultats.

Étape 4: évaluer le modèle

Une fois un modèle défini, vous pouvez vérifier ses performances avec .predict_proba (), qui renvoie la matrice de probabilités que la sortie prédite soit égale à zéro ou à un:

>>>

>>> modèle.predire_proba(X)
tableau ([[0.74002157, 0.25997843],
       [0.62975524, 0.37024476],
       [0.5040632 , 0.4959368 ],
       [0.37785549, 0.62214451],
       [0.26628093, 0.73371907],
       [0.17821501, 0.82178499],
       [0.11472079, 0.88527921],
       [0.07186982, 0.92813018],
       [0.04422513, 0.95577487],
       [0.02690569, 0.97309431]])

Dans la matrice ci-dessus, chaque ligne correspond à une seule observation. La première colonne est la probabilité que la sortie prédite soit nulle, c'est-à-dire 1 – (). La deuxième colonne est la probabilité que la sortie soit un, ou ().

Vous pouvez obtenir les prédictions réelles, basées sur la matrice de probabilité et les valeurs de (), avec .prédire():

>>>

>>> modèle.prédire(X)
tableau ([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])

Cette fonction renvoie les valeurs de sortie prévues sous forme de tableau unidimensionnel.

La figure ci-dessous illustre les résultats d'entrée, de sortie et de classification:

Résultat de la régression logistique

Les cercles verts représentent les réponses réelles ainsi que les prédictions correctes. Le × rouge montre la prédiction incorrecte. La ligne noire complète est la droite de régression logistique estimée (). Les carrés gris sont les points sur cette ligne qui correspondent à et les valeurs dans la deuxième colonne de la matrice de probabilité. La ligne pointillée noire est le logit ().

La valeur de légèrement supérieure à 2 correspond au seuil () = 0,5, qui est () = 0. Cette valeur de est la frontière entre les points qui sont classés comme des zéros et ceux prédits comme des uns.

Par exemple, le premier point a une entrée = 0, une sortie réelle = 0, une probabilité = 0,26 et une valeur prédite de 0. Le deuxième point a = 1, = 0, = 0,37 et une prédiction de 0. Seul le quatrième point a la sortie réelle = 0 et la probabilité supérieure à 0,5 (à = 0,62), il est donc incorrectement classé comme 1. Toutes les autres valeurs sont prédites correctement.

Lorsque neuf observations sur dix sont correctement classées, la précision de votre modèle est égale à 9/10 = 0,9, que vous pouvez obtenir avec .But():

>>>

>>> modèle.But(X, y)
0,9

.But() prend l'entrée et la sortie comme arguments et renvoie le rapport entre le nombre de prédictions correctes et le nombre d'observations.

Vous pouvez obtenir plus d'informations sur la précision du modèle avec un matrice de confusion. Dans le cas d'une classification binaire, la matrice de confusion affiche les nombres suivants:

  • De vrais négatifs en position supérieure gauche
  • Faux négatifs en position en bas à gauche
  • Faux positifs en haut à droite
  • Vrais positifs en bas à droite

Pour créer la matrice de confusion, vous pouvez utiliser confusion_matrix () et fournir les résultats réels et prévus comme arguments:

>>>

>>> confusion_matrix(y, modèle.prédire(X))
tableau ([[3, 1],
       [0, 6]])

La matrice obtenue montre ce qui suit:

  • Trois vraies prédictions négatives: Les trois premières observations sont des zéros prédits correctement.
  • Pas de fausses prédictions négatives: Ce sont ceux qui sont prédit à tort comme des zéros.
  • Une fausse prédiction positive: La quatrième observation est un zéro qui a été incorrectement prédit comme un.
  • Six vraies prédictions positives: Les six dernières observations sont celles prédites correctement.

Il est souvent utile de visualiser la matrice de confusion. Vous pouvez le faire avec .imshow () de Matplotlib, qui accepte la matrice de confusion comme argument:

cm = confusion_matrix(y, modèle.prédire(X))

figure, hache = plt.sous-parcelles(figsize=(8, 8))
hache.imshow(cm)
hache.la grille(Faux)
hache.xaxis.ensemble(tiques=(0, 1), ticklabels=(«0 prévus», «1 prédit»))
hache.yaxis.ensemble(tiques=(0, 1), ticklabels=(«0 réels», «1s réels»))
hache.set_ylim(1,5, -0,5)
pour je dans intervalle(2):
    pour j dans intervalle(2):
        hache.texte(j, je, cm[[[[je, j], Ha='centre', Virginie='centre', Couleur='rouge')
plt.spectacle()

Le code ci-dessus crée un carte de chaleur qui représente la matrice de confusion:

Matrice de confusion de classification

Dans cette figure, différentes couleurs représentent des nombres différents et des couleurs similaires représentent des nombres similaires. Les heatmaps sont un moyen agréable et pratique de représenter une matrice. Pour en savoir plus à leur sujet, consultez la documentation Matplotlib sur la création de cartes thermiques annotées et .imshow ().

Vous pouvez obtenir un rapport plus complet sur la classification avec classification_report ():

>>>

>>> impression(classification_report(y, modèle.prédire(X)))
                                                        rappel de précision f1-score support

                                            0 1,00 0,75 0,86 4
                                            1 0,86 1,00 0,92 6

                précision 0,90 10
            macro moyenne 0,93 0,88 0,89 10
moyenne pondérée 0,91 0,90 0,90 10

Cette fonction prend également les sorties réelles et prévues comme arguments. Il renvoie un rapport sur la classification en tant que dictionnaire si vous fournissez output_dict = True ou une chaîne sinon.

Pour plus d'informations sur Régression logistique, consultez la documentation officielle. En outre, scikit-learn propose une classe similaire LogisticRegressionCV, qui convient mieux à la validation croisée. Vous pouvez également consulter la documentation officielle pour en savoir plus sur les rapports de classification et les matrices de confusion.

Améliorez le modèle

Vous pouvez améliorer votre modèle en définissant différents paramètres. Par exemple, travaillons avec la force de régularisation C égal à 10,0, au lieu de la valeur par défaut de 1.0:

modèle = Régression logistique(solveur=«liblinéaire», C=10,0, random_state=0)
modèle.en forme(X, y)

Vous avez maintenant un autre modèle avec différents paramètres. Cela va également avoir une matrice de probabilité différente et un ensemble différent de coefficients et de prévisions:

>>>

>>> modèle.intercepter_
tableau ([-3.51335372])
>>> modèle.coef_
tableau ([[1.12066084]])
>>> modèle.predire_proba(X)
tableau ([[0.97106534, 0.02893466],
       [0.9162684 , 0.0837316 ],
       [0.7810904 , 0.2189096 ],
       [0.53777071, 0.46222929],
       [0.27502212, 0.72497788],
       [0.11007743, 0.88992257],
       [0.03876835, 0.96123165],
       [0.01298011, 0.98701989],
       [0.0042697 , 0.9957303 ],
       [0.00139621, 0.99860379]])
>>> modèle.prédire(X)
tableau ([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

Comme vous pouvez le voir, les valeurs absolues de l'ordonnée à l'origine ₀ et du coefficient ₁ sont plus grandes. C'est le cas car la plus grande valeur de C signifie une régularisation plus faible ou une pénalisation plus faible liée à des valeurs élevées de ₀ et ₁.

Différentes valeurs de ₀ et ₁ impliquent un changement du logit (), différentes valeurs des probabilités (), une forme différente de la droite de régression, et éventuellement des changements dans d'autres sorties prédites et performances de classification. La valeur limite de pour laquelle () = 0,5 et () = 0 est maintenant plus élevée. Il est supérieur à 3. Dans ce cas, vous obtenez toutes les vraies prédictions, comme le montrent la précision, la matrice de confusion et le rapport de classification:

>>>

>>> modèle.But(X, y)
1.0
>>> confusion_matrix(y, modèle.prédire(X))
tableau ([[4, 0],
       [0, 6]])
>>> impression(classification_report(y, modèle.prédire(X)))
                                                        rappel de précision f1-score support

                                            0 1,00 1,00 1,00 4
                                            1 1,00 1,00 1,00 6

                précision 1,00 10
            macro moyenne 1,00 1,00 1,00 10
moyenne pondérée 1,00 1,00 1,00 10

Le score (ou la précision) de 1 et les zéros dans les champs inférieur gauche et supérieur droit de la matrice de confusion indiquent que les résultats réels et prévus sont les mêmes. Cela est également illustré par la figure ci-dessous:

Résultat de la régression logistique

Cette figure montre que la droite de régression estimée a maintenant une forme différente et que le quatrième point est correctement classé comme 0. Il n'y a pas de × rouge, il n'y a donc pas de mauvaise prédiction.

Régression logistique en Python avec scikit-learn: exemple 2

Résolvons un autre problème de classification. Elle est similaire à la précédente, sauf que la sortie diffère dans la deuxième valeur. Le code est similaire au cas précédent:

# Étape 1: importez des packages, des fonctions et des classes
importation engourdi comme np
de sklearn.linear_model importation Régression logistique
de sklearn.metrics importation classification_report, confusion_matrix

# Étape 2: obtenir des données
X = np.arange(dix).remodeler(-1, 1)
y = np.tableau([[[[0, 1, 0, 0, 1, 1, 1, 1, 1, 1])

# Étape 3: créer un modèle et le former
modèle = Régression logistique(solveur=«liblinéaire», C=10,0, random_state=0)
modèle.en forme(X, y)

# Étape 4: évaluer le modèle
p_pred = modèle.predire_proba(X)
y_pred = modèle.prédire(X)
But_ = modèle.But(X, y)
conf_m = confusion_matrix(y, y_pred)
rapport = classification_report(y, y_pred)

Cet exemple de code de classification génère les résultats suivants:

>>>

>>> impression('X:', X, SEP=" n")
X:
[[0]
 [1]
 [2]
 [3]
 [4]
 [5]
 [6]
 [7]
 [8]
 [9]]
>>> impression(«y:», y, SEP=" n", fin=" n  n")
y:
[0 1 0 0 1 1 1 1 1 1]

>>> impression('intercepter:', modèle.intercepter_)
intercepter: [-1.51632619]
>>> impression(«coef:», modèle.coef_, fin=" n  n")
coef: [[0.703457]]

>>> impression('p_pred:', p_pred, SEP=" n", fin=" n  n")
p_pred:
[[0.81999686 0.18000314]
 [0.69272057 0.30727943]
 [0.52732579 0.47267421]
 [0.35570732 0.64429268]
 [0.21458576 0.78541424]
 [0.11910229 0.88089771]
 [0.06271329 0.93728671]
 [0.03205032 0.96794968]
 [0.0161218  0.9838782 ]
 [0.00804372 0.99195628]]

>>> impression('y_pred:', y_pred, fin=" n  n")
y_pred: [0 0 0 1 1 1 1 1 1 1]

>>> impression('But_:', But_, fin=" n  n")
score_: 0,8

>>> impression('conf_m:', conf_m, SEP=" n", fin=" n  n")
conf_m:
[[2 1]
 [1 6]]

>>> impression('rapport:', rapport, SEP=" n")
rapport:
                                                        rappel de précision f1-score support

                                            0 0,67 0,67 0,67 3
                                            1 0,86 0,86 0,86 7

                précision 0,80 10
            macro moyenne 0,76 0,76 0,76 10
moyenne pondérée 0,80 0,80 0,80 10

Dans ce cas, le score (ou la précision) est de 0,8. Il y a deux observations classées incorrectement. L'un d'eux est un faux négatif, tandis que l'autre est un faux positif.

The figure below illustrates this example with eight correct and two incorrect predictions:

Result of Logistic Regression

This figure reveals one important characteristic of this example. Unlike the previous one, this problem is not linearly separable. That means you can’t find a value of and draw a straight line to separate the observations with =0 and those with =1. There is no such line. Keep in mind that logistic regression is essentially a linear classifier, so you theoretically can’t make a logistic regression model with an accuracy of 1 in this case.

Logistic Regression in Python With StatsModels: Example

You can also implement logistic regression in Python with the StatsModels package. Typically, you want this when you need more statistical details related to models and results. The procedure is similar to that of scikit-learn.

Step 1: Import Packages

All you need to import is NumPy and statsmodels.api:

import numpy comme np
import statsmodels.api comme sm

Now you have the packages you need.

Step 2: Get Data

You can get the inputs and output the same way as you did with scikit-learn. However, StatsModels doesn’t take the intercept ₀ into account, and you need to include the additional column of ones in X. You do that with add_constant():

X = np.arange(dix).reshape(-1, 1)
y = np.array([[[[0, 1, 0, 0, 1, 1, 1, 1, 1, 1])
X = sm.add_constant(X)

add_constant() takes the array X as the argument and returns a new array with the additional column of ones. This is how X et y look:

>>>

>>> X
array([[1., 0.],
       [1., 1.],
       [1., 2.],
       [1., 3.],
       [1., 4.],
       [1., 5.],
       [1., 6.],
       [1., 7.],
       [1., 8.],
       [1., 9.]])
>>> y
array([0, 1, 0, 0, 1, 1, 1, 1, 1, 1])

This is your data. The first column of X corresponds to the intercept ₀. The second column contains the original values of X.

Step 3: Create a Model and Train It

Your logistic regression model is going to be an instance of the class statsmodels.discrete.discrete_model.Logit. This is how you can create one:

>>>

>>> modèle = sm.Logit(y, X)

Note that the first argument here is y, followed by X.

Now, you’ve created your model and you should fit it with the existing data. You do that with .fit() or, if you want to apply L1 regularization, with .fit_regularized():

>>>

>>> résultat = modèle.fit(method='newton')
Optimization terminated successfully.
                                    Current function value: 0.350471
                                    Iterations 7

The model is now ready, and the variable résultat holds useful data. For example, you can obtain the values of ₀ and ₁ with .params:

>>>

>>> résultat.params
array([-1.972805  ,  0.82240094])

The first element of the obtained array is the intercept ₀, while the second is the slope ₁. For more information, you can look at the official documentation on Logit, aussi bien que .fit() et .fit_regularized().

Step 4: Evaluate the Model

You can use résultats to obtain the probabilities of the predicted outputs being equal to one:

>>>

>>> résultat.predict(X)
array([012208792024041529041872657062114189078864861[012208792024041529041872657062114189078864861[012208792024041529041872657062114189078864861[012208792024041529041872657062114189078864861
                            0.89465521, 0.95080891, 0.97777369, 0.99011108, 0.99563083])

These probabilities are calculated with .predict(). You can use their values to get the actual predicted outputs:

>>>

>>> (résultat.predict(X) >= 0,5).astype(int)
array([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])

The obtained array contains the predicted output values. As you can see, ₀, ₁, and the probabilities obtained with scikit-learn and StatsModels are different. This is the consequence of applying different iterative and approximate procedures and parameters. However, in this case, you obtain the same predicted outputs as when you used scikit-learn.

You can obtain the confusion matrix with .pred_table():

>>>

>>> résultat.pred_table()
array([[2., 1.],
       [1., 6.]])

This example is the same as when you used scikit-learn because the predicted ouptuts are equal. The confusion matrices you obtained with StatsModels and scikit-learn differ in the types of their elements (floating-point numbers and integers).

.summary() et .summary2() get output data that you might find useful in some circumstances:

>>>

>>> résultat.summary()

"""
                                                                                                            Logit Regression Results                           
==============================================================================
Dep. Variable:                      y   No. Observations:                   10
Model:                          Logit   Df Residuals:                        8
Method:                           MLE   Df Model:                            1
Date:                Sun, 23 Jun 2019   Pseudo R-squ.:                  0.4263
Time:                        21:43:49   Log-Likelihood:                -3.5047
converged:                       True   LL-Null:                       -6.1086
                                                                                                                                                                LLR p-value:                   0.02248
==============================================================================
                                                                    coef    std err          z      P>|z|      [0.025      0.975]
-------------------------------------------------- ----------------------------
const         -1.9728      1.737     -1.136      0.256      -5.377       1.431
x1             0.8224      0.528      1.557      0.119      -0.213       1.858
==============================================================================
"""
>>> résultat.summary2()

"""
                                                                                                Results: Logit
===============================================================
Model:              Logit            Pseudo R-squared: 0.426   
Dependent Variable: y                AIC:              11.0094
Date:               2019-06-23 21:43 BIC:              11.6146
No. Observations:   10               Log-Likelihood:   -3.5047
Df Model:           1                LL-Null:          -6.1086
Df Residuals:       8                LLR p-value:      0.022485
Converged:          1.0000           Scale:            1.0000  
No. Iterations:     7.0000                                     
-----------------------------------------------------------------
                                        Coef.    Std.Err.      z      P>|z|     [0.025   0.975]
-----------------------------------------------------------------
const    -1.9728     1.7366   -1.1360   0.2560   -5.3765   1.4309
x1        0.8224     0.5281    1.5572   0.1194   -0.2127   1.8575
===============================================================

"""

These are detailed reports with values that you can obtain with appropriate methods and attributes. For more information, check out the official documentation related to LogitResults.

Logistic Regression in Python: Handwriting Recognition

The previous examples illustrated the implementation of logistic regression in Python, as well as some details related to this method. The next example will show you how to use logistic regression to solve a real-world classification problem. The approach is very similar to what you’ve already seen, but with a larger dataset and several additional concerns.

This example is about image recognition. To be more precise, you’ll work on the recognition of handwritten digits. You’ll use a dataset with 1797 observations, each of which is an image of one handwritten digit. Each image has 64 px, with a width of 8 px and a height of 8 px.

le inputs () are vectors with 64 dimensions or values. Each input vector describes one image. Each of the 64 values represents one pixel of the image. The input values are the integers between 0 and 16, depending on the shade of gray for the corresponding pixel. le output () for each observation is an integer between 0 and 9, consistent with the digit on the image. There are ten classes in total, each corresponding to one image.

Step 1: Import Packages

You’ll need to import Matplotlib, NumPy, and several functions and classes from scikit-learn:

import matplotlib.pyplot comme plt
import numpy comme np
de sklearn.datasets import load_digits
de sklearn.linear_model import LogisticRegression
de sklearn.metrics import classification_report, confusion_matrix
de sklearn.model_selection import train_test_split
de sklearn.preprocessing import StandardScaler

C'est ça! You have all the functionality you need to perform classification.

Step 2a: Get Data

You can grab the dataset directly from scikit-learn with load_digits(). It returns a tuple of the inputs and output:

X, y = load_digits(return_X_y=True)

Now you have the data. This is how X et y look:

>>>

>>> X
array([[ 0.,  0.,  5., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ..., 10.,  0.,  0.],
       [ 0.,  0.,  0., ..., 16.,  9.,  0.],
                            ...,
       [ 0.,  0.,  1., ...,  6.,  0.,  0.],
       [ 0.,  0.,  2., ..., 12.,  0.,  0.],
       [ 0.,  0., 10., ..., 12.,  1.,  0.]])
>>> y
array([0, 1, 2, ..., 8, 9, 8])

That’s your data to work with. X is a multi-dimensional array with 1797 rows and 64 columns. It contains integers from 0 to 16. y is an one-dimensional array with 1797 integers between 0 and 9.

Step 2b: Split Data

It’s a good and widely-adopted practice to split the dataset you’re working with into two subsets. Voici les training set et le test set. This split is usually performed randomly. You should use the training set to fit your model. Once the model is fitted, you evaluate its performance with the test set. It’s important not to use the test set in the process of fitting the model. This approach enables an unbiased evaluation of the model.

One way to split your dataset into training and test sets is to apply train_test_split():

x_train, x_test, y_train, y_test =
    train_test_split(X, y, test_size=0,2, random_state=0)

train_test_split() accepte X et y. It also takes test_size, which determines the size of the test set, and random_state to define the state of the pseudo-random number generator, as well as other optional arguments. This function returns a list with four arrays:

  1. x_train: the part of X used to fit the model
  2. x_test: the part of X used to evaluate the model
  3. y_train: the part of y that corresponds to x_train
  4. y_test: the part of y that corresponds to x_test

Once your data is split, you can forget about x_test et y_test until you define your model.

Step 2c: Scale Data

Standardization is the process of transforming data in a way such that the mean of each column becomes equal to zero, and the standard deviation of each column is one. This way, you obtain the same scale for all columns. Take the following steps to standardize your data:

  1. Calculate the mean and standard deviation for each column.
  2. Subtract the corresponding mean from each element.
  3. Divide the obtained difference by the corresponding standard deviation.

It’s a good practice to standardize the input data that you use for logistic regression, although in many cases it’s not necessary. Standardization might improve the performance of your algorithm. It helps if you need to compare and interpret the weights. It’s important when you apply penalization because the algorithm is actually penalizing against the large values of the weights.

You can standardize your inputs by creating an instance of StandardScaler and calling .fit_transform() on it:

scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)

.fit_transform() fits the instance of StandardScaler to the array passed as the argument, transforms this array, and returns the new, standardized array. Maintenant, x_train is a standardized input array.

Step 3: Create a Model and Train It

This step is very similar to the previous examples. The only difference is that you use x_train et y_train subsets to fit the model. Again, you should create an instance of LogisticRegression and call .fit() on it:

modèle = LogisticRegression(solver='liblinear', C=0,05, multi_class='ovr',
                           random_state=0)
modèle.fit(x_train, y_train)

When you’re working with problems with more than two classes, you should specify the multi_class parameter of LogisticRegression. It determines how to solve the problem:

  • 'ovr' says to make the binary fit for each class.
  • 'multinomial' says to apply the multinomial loss fit.

The last statement yields the following output since .fit() returns the model itself:

LogisticRegression(C=0,05, class_weight=Aucun, dual=Faux, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=Aucun, max_iter=100,
                   multi_class='ovr', n_jobs=Aucun, penalty='l2', random_state=0,
                   solver='liblinear', tol=0.0001, verbose=0, warm_start=Faux)

These are the parameters of your model. It’s now defined and ready for the next step.

Step 4: Evaluate the Model

You should evaluate your model similar to what you did in the previous examples, with the difference that you’ll mostly use x_test et y_test, which are the subsets not applied for training. If you’ve decided to standardize x_train, then the obtained model relies on the scaled data, so x_test should be scaled as well with the same instance of StandardScaler:

x_test = scaler.transform(x_test)

That’s how you obtain a new, properly-scaled x_test. In this case, you use .transform(), which only transforms the argument, without fitting the scaler.

You can obtain the predicted outputs with .predict():

y_pred = modèle.predict(x_test)

The variable y_pred is now bound to an array of the predicted outputs. Note that you use x_test as the argument here.

You can obtain the accuracy with .score():

>>>

>>> modèle.score(x_train, y_train)
0.964509394572025
>>> modèle.score(x_test, y_test)
0.9416666666666667

Actually, you can get two values of the accuracy, one obtained with the training set and other with the test set. It might be a good idea to compare the two, as a situation where the training set accuracy is much higher might indicate overfitting. The test set accuracy is more relevant for evaluating the performance on unseen data since it’s not biased.

You can get the confusion matrix with confusion_matrix():

>>>

>>> confusion_matrix(y_test, y_pred)
array([[27,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0, 32,  0,  0,  0,  0,  1,  0,  1,  1],
       [ 1,  1, 33,  1,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  1, 28,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0, 29,  0,  0,  1,  0,  0],
       [ 0,  0,  0,  0,  0, 39,  0,  0,  0,  1],
       [ 0,  1,  0,  0,  0,  0, 43,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0, 39,  0,  0],
       [ 0,  2,  1,  2,  0,  0,  0,  1, 33,  0],
       [ 0,  0,  0,  1,  0,  1,  0,  2,  1, 36]])

The obtained confusion matrix is large. In this case, it has 100 numbers. This is a situation when it might be really useful to visualize it:

cm = confusion_matrix(y_test, y_pred)

fig, ax = plt.subplots(figsize=(8, 8))
ax.imshow(cm)
ax.grid(Faux)
ax.set_xlabel('Predicted outputs', fontsize=font_size, color='black')
ax.set_ylabel('Actual outputs', fontsize=font_size, color='black')
ax.xaxis.set(ticks=intervalle(dix))
ax.yaxis.set(ticks=intervalle(dix))
ax.set_ylim(9.5, -0,5)
pour i dans intervalle(dix):
    pour j dans intervalle(dix):
        ax.text(j, i, cm[[[[i, j], ha='center', va='center', color='white')
plt.spectacle()

The code above produces the following figure of the confusion matrix:

Classification Confusion Matrix

This is a heatmap that illustrates the confusion matrix with numbers and colors. You can see that the shades of purple represent small numbers (like 0, 1, or 2), while green and yellow show much larger numbers (27 and above).

The numbers on the main diagonal (27, 32, …, 36) show the number of correct predictions from the test set. For example, there are 27 images with zero, 32 images of one, and so on that are correctly classified. Other numbers correspond to the incorrect predictions. For example, the number 1 in the third row and the first column shows that there is one image with the number 2 incorrectly classified as 0.

Finally, you can get the report on classification as a string or dictionary with classification_report():

>>>

>>> impression(classification_report(y_test, y_pred))
                                                        precision    recall  f1-score   support

                                            0       0.96      1.00      0.98        27
                                            1       0.89      0.91      0.90        35
                                            2       0.94      0.92      0.93        36
                                            3       0.88      0.97      0.92        29
                                            4       1.00      0.97      0.98        30
                                            5       0.97      0.97      0.97        40
                                            6       0.98      0.98      0.98        44
                                            7       0.91      1.00      0.95        39
                                            8       0.94      0.85      0.89        39
                                            9       0.95      0.88      0.91        41

                accuracy                           0.94       360
            macro avg       0.94      0.94      0.94       360
weighted avg       0.94      0.94      0.94       360

This report shows additional information, like the support and precision of classifying each digit.

Beyond Logistic Regression in Python

Logistic regression is a fundamental classification technique. It’s a relatively uncomplicated linear classifier. Despite its simplicity and popularity, there are cases (especially with highly complex models) where logistic regression doesn’t work well. In such circumstances, you can use other classification techniques:

  • k-Nearest Neighbors
  • Naive Bayes classifiers
  • Support Vector Machines
  • Decision Trees
  • Random Forests
  • Neural Networks

Fortunately, there are several comprehensive Python libraries for machine learning that implement these techniques. For example, the package you’ve seen in action here, scikit-learn, implements all of the above-mentioned techniques, with the exception of neural networks.

For all these techniques, scikit-learn offers suitable classes with methods like model.fit(), model.predict_proba(), model.predict(), model.score(), and so on. You can combine them with train_test_split(), confusion_matrix(), classification_report(), and others.

Neural networks (including deep neural networks) have become very popular for classification problems. Libraries like TensorFlow, PyTorch, or Keras offer suitable, performant, and powerful support for these kinds of models.

Conclusion

You now know what logistic regression is and how you can implement it for classification with Python. You’ve used many open-source packages, including NumPy, to work with arrays and Matplotlib to visualize the results. You also used both scikit-learn and StatsModels to create, fit, evaluate, and apply models.

Generally, logistic regression in Python has a straightforward and user-friendly implementation. It usually consists of these steps:

  1. Importation packages, functions, and classes
  2. Avoir data to work with and, if appropriate, transform it
  3. Créer a classification model and train (or fit) it with existing data
  4. Evaluate your model to see if its performance is satisfactory
  5. Appliquer your model to make predictions

You’ve come a long way in understanding one of the most important areas of machine learning! If you have questions or comments, then please put them in the comments section below.