[PYTHON] Visualisation de corrélation entre la quantité de caractéristiques et la variable objective

introduction

Avant de modéliser dans des compétitions business ou d'analyse, nous avons permis de voir rapidement la corrélation entre les fonctionnalités créées et la variable objectif. Ici, en particulier, la modélisation est ciblée lorsque la variable objective telle que la prévision des ventes est une valeur continue.

Le code ci-dessous utilise les données de prévision de la demande de déjeuner de Signate. (Données: https://signate.jp/competitions/24/data)

Ces données sont la tâche de créer un modèle qui prédit le nombre de déjeuners vendus dans la colonne y.

colonne Nom de l'en-tête Type de données La description
0 datetid datetime Date à utiliser comme index (aaaa-m-d)
1 y int Nombre de ventes (variable objective)
2 week char Dimanche (du lundi au vendredi)
3 soldout boolean Drapeau épuisé (0:Pas en rupture de stock, 1:épuisé)
4 name varchar Menu principal
5 kcal int Il y a une carence en calories (kcal) dans le plat d'accompagnement
6 remarks varchar Remarques
7 event varchar Commencez à 13h00 Événement en interne où vous pouvez apporter votre propre déjeuner
8 payday boolean Drapeau de paie (1:Payday)
9 weather varchar Météo
10 precipitation float Précipitation. Si non"--"
11 temperature float Température

Bibliothèque à utiliser

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
%matplotlib inline

Confirmation des données

df = pd.read_csv('./signate/train.csv')
# df.shape >> (207, 12)
df.head(2)
datetime y week soldout name kcal remarks event payday weather precipitation temperature
0 2013-11-18 90 mois 0 Calmar tranché épais NaN NaN NaN NaN Ensoleillé -- 19.8
1 2013-11-19 101 Mar 1 Côtelette à nageoires artisanale NaN NaN NaN NaN Ensoleillé -- 17.0

Prétraitement des données

df['precipitation'] = df.precipitation.replace({'--' : '0'}).astype(float)
df = pd.get_dummies(df[['y', 'week', 'soldout', 'kcal', 'payday', 'weather', 'precipitation', 'temperature']])
df['payday'] = df.payday.fillna(0).astype(str)
df.head()
y soldout kcal payday precipitation temperature week_month week_Thursday week_Wed week_mar week_Fri weather_fine weather weather_sunny weather_cloudy weather_light nuageux weather_rain weather_snow weather_Raiden
0 90 0 NaN 0.0 0.0 19.8 1 0 0 0 0 1 0 0 0 0 0 0
1 101 1 NaN 0.0 0.0 17.0 0 0 0 1 0 1 0 0 0 0 0 0
2 118 0 NaN 0.0 0.0 15.5 0 0 1 0 0 1 0 0 0 0 0 0
3 120 1 NaN 0.0 0.0 15.2 0 1 0 0 0 1 0 0 0 0 0 0
4 130 1 NaN 0.0 0.0 16.1 0 0 0 0 1 1 0 0 0 0 0 0

Confirmation des statistiques

df.describe()
y soldout kcal precipitation temperature week_month week_Thursday week_Wed week_mar week_Fri weather_fine weather weather_sunny weather_cloudy weather_light nuageux weather_rain weather_snow weather_Raiden
count 207.000000 207.000000 166.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000 207.000000
mean 86.623188 0.449275 404.409639 0.113527 19.252174 0.188406 0.207729 0.207729 0.198068 0.198068 0.256039 0.241546 0.256039 0.120773 0.115942 0.004831 0.004831
std 32.882448 0.498626 29.884641 0.659443 8.611365 0.391984 0.406666 0.406666 0.399510 0.399510 0.437501 0.429058 0.437501 0.326653 0.320932 0.069505 0.069505
min 29.000000 0.000000 315.000000 0.000000 1.200000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
25% 57.000000 0.000000 386.000000 0.000000 11.550000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
50% 78.000000 0.000000 408.500000 0.000000 19.800000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
75% 113.000000 1.000000 426.000000 0.000000 26.100000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000
max 171.000000 1.000000 462.000000 6.500000 34.600000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000

Une fonction qui visualise les caractéristiques et les variables objectives

argument

--df: trame de données à visualiser --target: nom de colonne de la variable objectif

def make_plot(df, target):
    plt_col = sorted([c for c in df.columns if  c != target and len(df[c].unique()) > 1])
    
    col_num = len(plt_col)
    row_num = col_num // 2 + col_num % 2
    col_num = 2

    fig, ax = plt.subplots(row_num, col_num, figsize=(18, 3*row_num), sharex=False, sharey=False)
    fig.subplots_adjust(left=0.1, right=0.95, hspace=0.7, wspace=0.4)

    for i,col in enumerate(plt_col):
        tmp = df[[target, col]]
        tmp = tmp[~pd.isna(tmp[col])].reset_index(drop=True)
        if len(tmp[col].unique()) == 1:
            continue

        p = ((i+1) // 2) + ((i+1) % 2) -1
        q = abs(((i+1) % 2) - 1)
        if len(tmp[col].unique()) > 2:
            percentile095 = tmp[col].quantile(0.95)
            over_tmp = tmp[tmp[col] >= percentile095].reset_index(drop=True)
            over_tmp[col] = percentile095

            if tmp[col].min() < 0:
                percentile005 = tmp[col].quantile(0.05)
                under_tmp = tmp[tmp[col] <= percentile005].reset_index(drop=True)
                under_tmp[col] = percentile005

                outof_percentile = tmp[(percentile005 < tmp[col]) & ( tmp[col] < percentile095)].reset_index(drop=True)
                new_tmp = pd.concat([outof_percentile, under_tmp, over_tmp], axis=0)
                if percentile095 == percentile005:
                    new_tmp = tmp.copy()
            else:
                percentile095 = tmp[col].quantile(0.95)
                over_tmp = tmp[tmp[col] >= percentile095].reset_index(drop=True)
                over_tmp[col] = percentile095

                outof_percentile = tmp[tmp[col] < percentile095].reset_index(drop=True)
                new_tmp = pd.concat([outof_percentile, over_tmp], axis=0)
                if percentile095 == 0:
                    new_tmp = tmp.copy()
            ax1 = ax[p,q]
            ax2 = ax1.twinx()
            n, bins, pathces = ax1.hist(new_tmp[col], bins='auto', label='Valeur de la fonctionnalité: {}'.format(col), ec='black')

            new_tmp['bins'] = pd.cut(new_tmp[col], bins.tolist(), right=False).values.astype(str)
            if len([f for f in new_tmp[col].unique() if bins[-2] <= f and f < bins[-1]]) > 0:
                new_tmp['bins_start'] = [float(b.split(',')[0].replace('[', '')) for b in new_tmp['bins']]
                bins_max = new_tmp['bins_start'].max()
                nan_value = new_tmp.query('bins_start == @bins_max').bins.unique()[0]
                new_tmp['bins'] = new_tmp['bins'].replace({'nan' : nan_value})
            else:
                new_tmp['bins'] = new_tmp['bins'].replace({'nan' : '[{}, {}]'.format(bins[-2], bins[-1])})

            num_bin = new_tmp.groupby('bins').size().reset_index(name='cnt')
            mean_target_bin = new_tmp.groupby('bins')[target].mean().reset_index().rename(columns={target : '{}_mean'.format(target)})
            center_feature_bin = new_tmp.groupby('bins').agg({col : {np.max, np.min}}).reset_index()
            center_feature_bin.columns = ['bins', 'feature_max', 'feature_min']
            center_feature_bin['feature_center'] = center_feature_bin.apply(lambda x : (x['feature_max'] + x['feature_min']) / 2, axis=1)
            plt_data = mean_target_bin.merge(center_feature_bin, on='bins', how='inner').merge(num_bin, on='bins', how='inner').sort_values('feature_center', ascending=True).reset_index(drop=True)
            ax2.plot(plt_data['feature_center'], plt_data['{}_mean'.format(target)], label='Valeur moyenne de la variable objectif (pour chaque case)', marker='.', color='orange')

        else:
            new_tmp = tmp.copy()
            ax1 = ax[p,q]
            ax2 = ax1.twinx()
            bins_list = sorted(new_tmp[col].unique().tolist())
            a = new_tmp.groupby([col]).agg({col : len, target : np.mean}).rename(columns={col : 'count', target : '{}_mean'.format(target)}).reset_index().astype({col : str})
            ax1.bar(a[col], a['count'], label='Valeur de la fonctionnalité: {}'.format(col), ec='black')
            ax2.plot(a[col], a['{}_mean'.format(target)], label='Valeur moyenne de la variable objectif (pour chaque case)', marker='.', color='orange')

        ax2.hlines([new_tmp[target].mean()], new_tmp[col].min(), new_tmp[col].max(), color="darkred", linestyles='dashed', label='Valeur moyenne de la variable objective (données complètes)')

        handler1, label1 = ax1.get_legend_handles_labels()
        handler2, label2 = ax2.get_legend_handles_labels()
        ax1.legend(handler1 + handler2, label1 + label2, borderaxespad=0., bbox_to_anchor=(0, 1.45), loc='upper left', fontsize=9)
        ax1.set_ylabel('count', fontsize=12)
        ax2.set_ylabel('Variable objective', fontsize=12)
        ax1.set_title('{}'.format(col), loc='right', fontsize=12)

    plt.show()
target = 'y'  #Spécification de la variable objectif
make_plot(df, target)  #terrain

Résultat de la visualisation

Éléments à visualiser ** 1. histogramme ou graphique à barres (bleu) **

—— Si la quantité d'entités est une valeur continue, un histogramme

** 2. Valeur moyenne de la variable objectif pour chaque case (jaune) **

--Graphe de ligne de rupture de la valeur moyenne de la variable objectif pour chaque bac (pour chaque valeur dans le cas de deux valeurs)

** 3. Valeur moyenne des variables objectives pour l'ensemble des données (rouge) **

output_7_0.png

Recommended Posts

Visualisation de corrélation entre la quantité de caractéristiques et la variable objective
Comment visualiser les données par variable explicative et variable objective
Caractéristiques du lien symbolique et dur
Agrégation et visualisation des nombres accumulés
Exemple d'utilisation de variables de classe et de méthodes de classe
Visualisation des cartes et des filtres des fonctionnalités CNN (Tensorflow 2.0)
Comment créer des variables explicatives et des fonctions objectives
[Python] Chapitre 02-01 Bases des programmes Python (opérations et variables)
Analyse des données financières par pandas et leur visualisation (2)
Calcul de l'écart type et du coefficient de corrélation en Python
Analyse des données financières par pandas et leur visualisation (1)
Différence entre Ruby et Python en termes de variables
[Ingénierie de contrôle] Visualisation et analyse du contrôle PID et de la réponse par étapes
Visualisation de la connexion entre le malware et le serveur de rappel
[Python] Types de valeurs statistiques (caractéristiques) et méthodes de calcul
Variables globales et locales 2
Caractéristiques du langage Go
Principales caractéristiques de ChainMap
Variables globales et locales 1
Ordre de référence des variables de classe et des variables d'instance dans "self. Variables de classe" en Python
Jugement négatif / positif des phrases et visualisation des motifs par Transformer
Utilisation de MLflow avec Databricks ② --Visualisation des paramètres expérimentaux et des métriques -
Jugement négatif / positif des phrases par BERT et visualisation des motifs
Je veux connaître la nature de Python et pip
[Python] Que faites-vous avec la visualisation de 4 variables ou plus?