4 votes

Comment tracer groupby en pourcentage dans seaborn ?

J'ai un problème de classification binaire, que je veux résoudre avec un RandomForestClassifier. Ma colonne cible est "successful", qui vaut soit 0 soit 1. Je veux étudier les données et voir à quoi elles ressemblent. Pour cela, j'ai essayé de faire des graphiques de comptage par catégorie. Mais cela ne dit pas combien en pourcentage du total sont "réussis" (c'est-à-dire réussis == 1).

Comment puis-je modifier le graphique suivant, de sorte que ces sous-points affichent le pourcentage de (succès == 1) du total de tous les messages ? (Disons que dans la catégorie Jour de la semaine, le jour 'Samedi', j'ai 10 points de données, 7 d'entre eux sont réussis ('réussi' == 1), donc je veux avoir une barre avec des points à ce jour à 0,7.

Voici le graphique actuel (chiffres :-/) :

actual count plot

Et voici une partie de mon cadre de données :

15 samples of my df

Et voici le code utilisé pour générer le graphique :

# Plot 

sns.set(style="darkgrid")

x_vals = [['page_name', 'weekday'],['type', 'industry']]
subtitles = [['by Page', 'by Weekday'],['by Content Type', 'by Industry']]

fig, ax = plt.subplots(2,2, figsize=(15,10))
#jitter = [[False, 1], [0.5, 0.2]]

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].tick_params(labelsize=15)
        ax[j][i].set_xlabel('label', fontsize=17, position=(.5,20))
        if (j == 0) :
            ax[j][i].tick_params(axis="x", rotation=50) 
        ax[j][i].set_ylabel('label', fontsize=17)
        ax[j][i] = sns.countplot(x=x_vals[j][i], hue="successful", data=mainDf, ax=ax[j][i])

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].set_xlabel('', fontsize=17)
        ax[j][i].set_ylabel('count', fontsize=17)
        ax[j][i].set_title(subtitles[j][i], fontsize=18)

fig.suptitle('Success Count by Category', position=(.5,1.05), fontsize=20)

fig.tight_layout()
fig.show()

PS : Veuillez noter que j'utilise Seaborn. La solution devrait être aussi avec Seaborn, si possible. Merci !

3voto

ayorgo Points 1180

Vous pouvez utiliser barplot ici. Je n'étais pas sûr à 100 % de ce que vous voulez réellement obtenir, alors j'ai développé plusieurs solutions.

Fréquence des succès (échecs) par rapport au total des succès (échecs)

fig, axes = plt.subplots(2, 2, figsize=(15, 10))

mainDf['frequency'] = 0 # a dummy column to refer to
for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
    counts = mainDf.groupby([col, 'successful']).count()
    freq_per_group = counts.div(counts.groupby('successful').transform('sum')).reset_index()
    sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_group, ax=ax)

enter image description here

Fréquence des succès (échecs) par groupe

fig, axes = plt.subplots(2, 2, figsize=(15, 10))

mainDf['frequency'] = 0 # a dummy column to refer to
for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
    counts = mainDf.groupby([col, 'successful']).count()
    freq_per_group = counts.div(counts.groupby(col).transform('sum')).reset_index()
    sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_group, ax=ax)

qui, sur la base des données que vous avez fournies, donne

enter image description here

Fréquence des succès (échecs) par total

fig, axes = plt.subplots(2, 2, figsize=(15, 10))

mainDf['frequency'] = 0 # a dummy column to refer to
total = len(mainDf)
for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
    counts = mainDf.groupby([col, 'successful']).count()
    freq_per_total = counts.div(total).reset_index()
    sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_total, ax=ax)

enter image description here

0voto

Arthur Gouveia Points 509

Changez la ligne ax[j][i] = sns.countplot(x=x_vals[j][i], hue="successful", data=mainDf, ax=ax[j][i]) a ax[j][i] = sns.barplot(x=x_vals[j][i], y='successful', data=mainDf, ax=ax[j][i], ci=None, estimator=lambda x: sum(x) / len(x) * 100)

Votre code serait le suivant

sns.set(style="darkgrid")

x_vals = [['page_name', 'weekday'],['type', 'industry']]
subtitles = [['by Page', 'by Weekday'],['by Content Type', 'by Industry']]

fig, ax = plt.subplots(2,2, figsize=(15,10))
#jitter = [[False, 1], [0.5, 0.2]]

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].tick_params(labelsize=15)
        ax[j][i].set_xlabel('label', fontsize=17, position=(.5,20))
        if (j == 0) :
            ax[j][i].tick_params(axis="x", rotation=50) 
        ax[j][i].set_ylabel('label', fontsize=17)
        ax[j][i] = sns.barplot(x=x_vals[j][i], y='successful', data=mainDf, ax=ax[j][i], ci=None, estimator=lambda x: sum(x) / len(x) * 100)

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].set_xlabel('', fontsize=17)
        ax[j][i].set_ylabel('percent', fontsize=17)
        ax[j][i].set_title(subtitles[j][i], fontsize=18)

fig.suptitle('Success Percentage by Category', position=(.5,1.05), fontsize=20)

fig.tight_layout()
fig.show()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X