C’est toujours une bonne idée d’examiner nos données avant de commencer à tracer. Nous pouvons lire les données dans un dataframe pandas et afficher les 10 premières lignes :

import pandas as pd# Read in data and examine first 10 rows
flights = pd.read_csv('data/formatted_flights.csv')
flights.head(10)
Head of Dataframe

Les retards à l’arrivée des vols sont exprimés en minutes et les valeurs négatives signifient que le vol était en avance (il s’avère que les vols ont souvent tendance à arriver en avance, juste jamais lorsque nous sommes dessus !) Il y a plus de 300 000 vols avec un retard minimum de -60 minutes et un retard maximum de 120 minutes. L’autre colonne du dataframe est le nom de la compagnie aérienne que nous pouvons utiliser pour les comparaisons.

Une excellente façon de commencer à explorer une seule variable est avec l’histogramme. Un histogramme divise la variable en bacs, compte les points de données dans chaque bac, et montre les bacs sur l’axe des x et les comptes sur l’axe des y. Dans notre cas, les cases seront un intervalle de temps représentant le retard des vols et le nombre sera le nombre de vols entrant dans cet intervalle. La largeur de bac est le paramètre le plus important pour un histogramme et nous devrions toujours essayer quelques valeurs différentes de la largeur de bac pour sélectionner la meilleure pour nos données.

Pour réaliser un histogramme de base en Python, nous pouvons utiliser matplotlib ou seaborn. Le code ci-dessous montre les appels de fonction dans les deux bibliothèques qui créent des figures équivalentes. Pour les appels au tracé, nous spécifions la largeur de bin par le nombre de bins. Pour ce tracé, j’utiliserai des bacs d’une longueur de 5 minutes, ce qui signifie que le nombre de bacs sera l’étendue des données (de -60 à 120 minutes) divisée par la largeur de bac, 5 minutes ( bins = int(180/5)).

Histogramme (équivalent figuré produit à la fois par matplotlib et seaborn)

Pour les histogrammes les plus basiques, J’irais avec le code de matplotlib car il est plus simple, mais nous utiliserons la fonction seaborn distplot plus tard pour créer différentes distributions et il est bon de se familiariser avec les différentes options.

Comment en suis-je arrivé à 5 minutes pour la largeur de bin ? La seule façon de déterminer une binwidth optimale est d’essayer plusieurs valeurs ! Vous trouverez ci-dessous le code permettant de réaliser la même figure dans matplotlib avec une gamme de binwidths. En fin de compte, il n’y a pas de bonne ou de mauvaise réponse à la largeur de bin, mais je choisis 5 minutes parce que je pense qu’elle représente le mieux la distribution.

Histogrammes avec différentes largeurs de bin

Le choix de la largeur de bin affecte de manière significative le graphique résultant. Les petites largeurs de bin peuvent rendre le tracé encombré, mais les grandes largeurs de bin peuvent masquer les nuances dans les données. Matplotlib choisira automatiquement une largeur binaire raisonnable pour vous, mais j’aime spécifier moi-même la largeur binaire après avoir essayé plusieurs valeurs. Il n’y a pas de vraie bonne ou mauvaise réponse, alors essayez quelques options et voyez ce qui fonctionne le mieux pour vos données particulières.

Quand les histogrammes échouent

Les histogrammes sont un excellent moyen de commencer à explorer une seule variable tirée d’une catégorie. Cependant, lorsque nous voulons comparer les distributions d’une variable à travers plusieurs catégories, les histogrammes ont des problèmes de lisibilité. Par exemple, si nous voulons comparer les distributions des retards à l’arrivée entre les compagnies aériennes, une approche qui ne fonctionne pas bien est de créer des histogrammes pour chaque compagnie aérienne sur le même graphique :

Histogrammes superposés avec plusieurs compagnies aériennes

(Remarquez que l’axe des y a été normalisé pour tenir compte du nombre différent de vols entre les compagnies aériennes. Pour ce faire, passez l’argument norm_hist = True à l’appel de fonction sns.distplot.)

Ce graphique n’est pas très utile ! Toutes les barres qui se chevauchent font qu’il est presque impossible de faire des comparaisons entre les compagnies aériennes. Voyons quelques solutions possibles à ce problème courant.

Solution #1 : Histogrammes côte à côte

Au lieu de superposer les histogrammes des compagnies aériennes, nous pouvons les placer côte à côte. Pour ce faire, nous créons une liste des retards à l’arrivée pour chaque compagnie aérienne, puis nous la passons dans l’appel de fonction plt.hist comme une liste de listes. Nous devons spécifier différentes couleurs à utiliser pour chaque compagnie aérienne et une étiquette afin de pouvoir les distinguer. Le code, y compris la création des listes pour chaque compagnie aérienne est ci-dessous:

By default, si nous passons dans une liste de listes, matplotlib mettra les barres côte à côte. Ici, j’ai changé la binwidth à 15 minutes car sinon le tracé est trop encombré, mais même avec cette modification, ce n’est pas une figure efficace. Il y a trop d’informations à traiter en même temps, les barres ne sont pas alignées avec les étiquettes, et il est toujours difficile de comparer les distributions entre les compagnies aériennes. Lorsque nous créons un graphique, nous voulons qu’il soit aussi facile à comprendre que possible pour le spectateur, et cette figure ne répond pas à ce critère ! Examinons une deuxième solution potentielle.

Solution #2 : barres empilées

Au lieu de tracer les barres de chaque compagnie aérienne côte à côte, nous pouvons les empiler en passant le paramètre stacked = True à l’appel de l’histogramme :

# Stacked histogram with multiple airlines
plt.hist(, bins = int(180/15), stacked=True,
normed=True, color = colors, label=names)

Eh bien, ce n’est définitivement pas mieux ! Ici, chaque compagnie aérienne est représentée comme une section de l’ensemble pour chaque bac, mais il est presque impossible de faire des comparaisons. Par exemple, pour un retard de -15 à 0 minute, United Air Lines ou JetBlue Airlines ont-elles une taille de barre plus importante ? Je ne peux pas le dire et les téléspectateurs ne le pourront pas non plus. Je ne suis généralement pas un partisan des barres empilées, car elles peuvent être difficiles à interpréter (bien qu’il existe des cas d’utilisation, comme la visualisation des proportions). Les deux solutions que nous avons essayées en utilisant les histogrammes n’ont pas été couronnées de succès, et il est donc temps de passer au tracé de densité.

Plots de densité

D’abord, qu’est-ce qu’un tracé de densité ? Un diagramme de densité est une version lissée et continue d’un histogramme estimé à partir des données. La forme d’estimation la plus courante est connue sous le nom d’estimation de la densité du noyau. Dans cette méthode, une courbe continue (le noyau) est tracée à chaque point de données individuel et toutes ces courbes sont ensuite additionnées pour obtenir une seule estimation de densité lisse. Le noyau le plus souvent utilisé est une gaussienne (qui produit une courbe en cloche gaussienne à chaque point de données). Si, comme moi, vous trouvez cette description un peu confuse, jetez un coup d’œil au graphique suivant :

Estimation de la densité par noyau (source)

Ici, chaque petite ligne verticale noire sur l’axe des x représente un point de données. Les noyaux individuels (gaussiens dans cet exemple) sont représentés dessinés en lignes rouges pointillées au-dessus de chaque point. La courbe bleue pleine est créée en additionnant les gaussiennes individuelles et forme le graphique de densité global.

L’axe des x est la valeur de la variable, tout comme dans un histogramme, mais que représente exactement l’axe des y ? L’axe des y dans un tracé de densité est la fonction de densité de probabilité pour l’estimation de la densité du noyau. Cependant, nous devons prendre soin de préciser qu’il s’agit d’une densité de probabilité et non d’une probabilité. La différence est que la densité de probabilité est la probabilité par unité sur l’axe des abscisses. Pour la convertir en une probabilité réelle, nous devons trouver l’aire sous la courbe pour un intervalle spécifique sur l’axe des x. De manière quelque peu déroutante, étant donné qu’il s’agit d’une densité de probabilité et non d’une probabilité, l’axe des y peut prendre des valeurs supérieures à un. La seule exigence du graphique de densité est que l’aire totale sous la courbe soit égale à un. J’ai généralement tendance à considérer l’axe des y sur un diagramme de densité comme une valeur uniquement pour les comparaisons relatives entre différentes catégories.

Les diagrammes de densité dans Seaborn

Pour faire des diagrammes de densité dans Seaborn, nous pouvons utiliser la fonction distplot ou kdeplot. Je vais continuer à utiliser la fonction distplot parce qu’elle nous permet de faire plusieurs distributions avec un seul appel de fonction. Par exemple, nous pouvons faire un graphique de densité montrant tous les retards d’arrivée au-dessus de l’histogramme correspondant :

# Density Plot and Histogram of all arrival delays
sns.distplot(flights, hist=True, kde=True,
bins=int(180/5), color = 'darkblue',
hist_kws={'edgecolor':'black'},
kde_kws={'linewidth': 4})

Plot de densité et histogramme utilisant seaborn

La courbe montre le graphique de densité qui est essentiellement une version lissée de l’histogramme. L’axe des y est en termes de densité, et l’histogramme est normalisé par défaut de sorte qu’il a la même échelle des y que le tracé de densité.

Analogue à la largeur de bin d’un histogramme, un tracé de densité a un paramètre appelé la largeur de bande qui change les noyaux individuels et affecte de manière significative le résultat final du tracé. La bibliothèque de traçage choisira une valeur raisonnable de la largeur de bande pour nous (en utilisant par défaut l’estimation ‘scott’), et contrairement à la largeur de bande d’un histogramme, j’utilise généralement la largeur de bande par défaut. Cependant, nous pouvons envisager d’utiliser différentes largeurs de bande pour voir s’il existe un meilleur choix. Dans le graphe, ‘scott’ est la largeur de bande par défaut, ce qui semble être la meilleure option.

Graphe de densité montrant différentes largeurs de bande

Notez qu’une largeur de bande plus large entraîne un plus grand lissage de la distribution. Nous constatons également que même si nous avons limité nos données à -60 à 120 minutes, le tracé de densité s’étend au-delà de ces limites. Il s’agit d’un problème potentiel avec un diagramme de densité : comme il calcule une distribution à chaque point de données, il peut générer des données qui dépassent les limites des données d’origine. Cela peut signifier que nous nous retrouvons avec des valeurs impossibles sur l’axe des x qui n’ont jamais été présentes dans les données d’origine ! À titre d’information, nous pouvons également modifier le noyau, ce qui change la distribution dessinée à chaque point de données et donc la distribution globale. Cependant, pour la plupart des applications, le noyau par défaut, gaussien, et l’estimation de la largeur de bande par défaut fonctionnent très bien.

Solution #3 Tracé de densité

Maintenant que nous comprenons comment un tracé de densité est fait et ce qu’il représente, voyons comment il peut résoudre notre problème de visualisation des retards d’arrivée de plusieurs compagnies aériennes. Pour montrer les distributions sur le même graphique, nous pouvons itérer à travers les compagnies aériennes, en appelant chaque fois distplot avec l’estimation de la densité du noyau définie sur True et l’histogramme défini sur False. Le code pour dessiner le graphe de densité avec plusieurs compagnies aériennes est ci-dessous:

Graphe de densité avec plusieurs compagnies aériennes

Enfin, nous sommes arrivés à une solution efficace ! Avec le graphe de densité, nous pouvons facilement faire des comparaisons entre les compagnies aériennes car le graphe est moins encombré. Maintenant que nous avons enfin le graphique que nous voulons, nous arrivons à la conclusion que toutes ces compagnies aériennes ont des distributions de retards à l’arrivée presque identiques ! Cependant, il y a d’autres compagnies aériennes dans l’ensemble de données, et nous pouvons en tracer une qui est un peu différente pour illustrer un autre paramètre optionnel pour les tracés de densité, l’ombrage du graphique.

Tracés de densité ombrés

Le remplissage du tracé de densité peut nous aider à distinguer les distributions qui se chevauchent. Bien que ce ne soit pas toujours une bonne approche, cela peut aider à souligner la différence entre les distributions. Pour ombrer les tracés de densité, nous passons shade = True à l’argument kde_kws dans l’appel distplot.

sns.distplot(subset, hist = False, kde = True,
kde_kws = {'shade': True, 'linewidth': 3},
label = airline)

Tracé de densité ombré

La décision d’ombrer ou non le tracé est, comme les autres options de tracé, une question qui dépend du problème ! Pour ce graphique, je pense que cela a du sens car l’ombrage nous aide à distinguer les tracés dans les régions où ils se chevauchent. Maintenant, nous avons enfin des informations utiles : Les vols d’Alaska Airlines ont tendance à être plus tôt que ceux d’United Airlines. La prochaine fois que vous aurez le choix, vous saurez quelle compagnie aérienne choisir !

Rug Plots

Si vous voulez montrer chaque valeur d’une distribution et pas seulement la densité lissée, vous pouvez ajouter un rug plot. Cela montre chaque point de données sur l’axe des x, ce qui nous permet de visualiser toutes les valeurs réelles. L’avantage d’utiliser le distplot de seaborn est que nous pouvons ajouter le rug plot avec un seul appel de paramètre de rug = True (avec un peu de formatage également).

Tracé de densité avec rug plot pour Alaska Airlines

Avec de nombreux points de données, le rug plot peut devenir surchargé, mais pour certains ensembles de données, il peut être utile de visualiser chaque point de données. Le rug plot nous permet également de voir comment le plot de densité « crée » des données là où il n’y en a pas, car il crée une distribution à noyau à chaque point de données. Ces distributions peuvent s’étendre sur la plage des données d’origine et donner l’impression que les retards d’Alaska Airlines sont à la fois plus courts et plus longs que ceux réellement enregistrés. Nous devons faire attention à cet artefact des diagrammes de densité et le signaler aux téléspectateurs !

Conclusions

Ce post vous a, nous l’espérons, donné une gamme d’options pour visualiser une seule variable à partir d’une ou plusieurs catégories. Il y a encore plus de tracés univariés (à une seule variable) que nous pouvons faire, comme les tracés de densité cumulative empirique et les tracés de quantile-quantile, mais pour l’instant nous en resterons aux histogrammes et aux tracés de densité (et aux tracés de tapis aussi !). Ne vous inquiétez pas si les options vous semblent écrasantes : avec la pratique, faire un bon choix deviendra plus facile, et vous pourrez toujours demander de l’aide si nécessaire. De plus, il n’y a souvent pas de choix optimal et la « bonne » décision dépendra des préférences et des objectifs de la visualisation. La bonne nouvelle est que, quel que soit le tracé que vous souhaitez réaliser, il y aura un moyen de le faire en Python ! Les visualisations sont un moyen efficace de communiquer des résultats, et connaître toutes les options disponibles nous permet de choisir la bonne figure pour nos données.

J’accueille volontiers les commentaires et les critiques constructives et je suis joignable sur Twitter @koehrsen_will.

admin

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

lg