Feature Transformation for Machine Learning, Guide du débutant

Lorsque je commençais à apprendre comment optimiser les modèles d’apprentissage automatique, je trouvais souvent, une fois arrivée à l’étape de la construction du modèle, que je devais revenir constamment pour revoir les données afin de mieux gérer les types d’entités présentes dans le jeu de données. Au fil du temps, j'ai constaté que l'une des premières étapes à suivre avant de créer les modèles consiste à examiner attentivement les types de variables présents dans les données et à essayer de déterminer à l'avance le meilleur processus de transformation à suivre pour obtenir les performances optimales du modèle.

Dans le post suivant, je vais décrire le processus que je prends pour identifier et transformer quatre types de variables communs. Je vais utiliser un ensemble de données tiré du concours d'échauffement “Machine Learning with a Heart” organisé sur le site Web https://www.drivendata.org/. L'ensemble de données complet peut être téléchargé ici https://www.drivendata.org/competitions/54/machine-learning-with-a-heart/data/. DrivenData héberge des défis en ligne réguliers basés sur la résolution de problèmes sociaux. J’ai récemment commencé à participer à certaines de ces compétitions dans le but d’utiliser certaines de mes compétences pour une bonne cause et pour acquérir une expérience des jeux de données et des problèmes que je ne rencontre généralement pas dans mon travail quotidien.

Identifier les types de variables

En statistique, les variables numériques peuvent être caractérisées en quatre types principaux. Lorsque vous démarrez un projet d'apprentissage automatique, il est important de déterminer le type de données contenu dans chacune de vos fonctions, car cela peut avoir un impact significatif sur les performances des modèles. J'ai essayé de donner une description simple des quatre types ci-dessous.

  • Les variables continues sont des variables pouvant avoir un nombre infini de valeurs possibles, par opposition aux variables discrètes qui ne peuvent avoir qu'une plage de valeurs spécifiée. Un exemple de variable continue serait le nombre de kilomètres parcourus par une voiture au cours de sa vie.
  • Les variables nominales sont des valeurs catégorielles ayant au moins deux valeurs possibles, mais dans lesquelles l'ordre de ces valeurs n'a aucune signification. Par exemple, nous pourrions utiliser une représentation numérique pour interpréter les types de voitures, par exemple compacte a une valeur de 1, MPV a une valeur de 2 et la voiture décapotable a une valeur de 3. Cependant, le fait que la voiture compacte a une valeur de 1 et le convertible a une valeur de 2 ne signifie pas que mathématiquement le groupe convertible est en quelque sorte plus grand que le MPV. C'est simplement une représentation numérique de la catégorie.
  • Les variables dichotomiques sont encore une fois catégoriques mais n'ont que 2 valeurs possibles, généralement 0 et 1. Par exemple, nous pouvons classer la possession d'une voiture dans les catégories 1 (signifiant oui) ou 0 (signifiant non). Lorsque nous convertissons des variables en colonnes factices (ce que nous ferons plus tard dans cet article), les nouvelles fonctionnalités produites deviennent également dichotomiques.
  • Les variables ordinales sont similaires aux valeurs nominales en ce qu’elles ont 2 valeurs possibles ou plus. La principale différence est que ces valeurs ont un ordre ou un rang significatif. Ainsi, dans notre exemple de voiture, cela pourrait être quelque chose comme la taille du moteur où ces catégories pourraient être classées en termes de puissance, 1.2, 1.6, 1.8.

Préparer les données

Je vais utiliser notre apprentissage automatique avec un jeu de données de cœur pour parcourir le processus d'identification et de transformation des types de variable. J'ai téléchargé et lu les fichiers csv dans un cahier Jupyter. Ensuite, je lance la fonction suivante pour obtenir un instantané de la composition des données.

importer des pandas en tant que pd
def quick_analysis (df):
 print (“Types de données:”)
 print (df.dtypes)
 print (“Lignes et colonnes:”)
 print (df.shape)
 print (“Noms de colonne:”)
 print (df.columns)
 print (“Null Values:”)
 print (df.apply (lambda x: sum (x.isnull ()) / len (df)))
quick_analysis (train)

Cela produit la sortie suivante.

Cela me dit que j'ai un petit ensemble de données de seulement 180 lignes et qu'il y a 15 colonnes. L'une des fonctionnalités est non numérique et devra donc être transformée avant l'application de la plupart des bibliothèques d'apprentissage automatique. Il n’existe pas de valeur NULL et je n’ai donc pas à me soucier de les traiter. Avant de traiter l'ensemble de données, je supprime également la colonne «patient_id» pour le moment, car elle est non numérique et ne sera utilisée à aucune étape de la formation ou de la prévision.

Je lance ensuite la fonction de description des pandas afin de produire des statistiques descriptives rapides.

train.describe ()

Pour classer les types de variables dans le jeu de données, exécutez le code suivant, qui génère des histogrammes de toutes les entités numériques. Vous pouvez facilement voir dans la sortie résultante quelles entités sont continues et dichotomiques. Les entités continues affichent un schéma de distribution continu alors que les entités dichotomiques ne comportent que deux barres. Les variables nominales et ordinales peuvent parfois être plus difficiles à déterminer et peuvent nécessiter une connaissance supplémentaire de l'ensemble de données ou une connaissance de domaine spécifique. Dans le cas d’un concours d’apprentissage automatique tel que celui-ci, je suggérerais de faire référence à tout dictionnaire de données pouvant être fourni. S'il n’en existe pas (comme c’est le cas ici), une combinaison d’intuition et d’essais et d’erreur peut être nécessaire.

importer matplotlib.pyplot en tant que plt
train [train.dtypes [(train.dtypes == "float64") | (train.dtypes == "int64")]
                        .index.values] .hist (figsize = [11,11])

J'ai caractérisé les caractéristiques en quatre types dans le tableau ci-dessous. Je peux maintenant prendre quelques décisions quant aux étapes de transformation que je vais suivre afin de préparer les données pour la formation et la prévision.

Variables factices

Comme mentionné précédemment dans ce message, toute valeur non numérique doit être convertie en entier ou en virgule flottante pour pouvoir être utilisée dans la plupart des bibliothèques d’apprentissage automatique. Pour les variables de faible cardinalité, la meilleure approche consiste généralement à transformer l'entité en une colonne par valeur unique, avec un 0 lorsque la valeur n'est pas présente et un 1 pour le même résultat. Celles-ci sont appelées variables nominales.

Cette technique est également généralement mieux appliquée à toutes les variables nominales. Celles-ci n’ayant pas d’ordre intrinsèque, si nous ne l’appliquions pas d’abord, l’algorithme d’apprentissage automatique risque de rechercher de manière incorrecte une relation dans l’ordre de ces valeurs.

Les pandas ont une fonction intéressante pour cela appelée get_dummies (). Dans le code ci-dessous, je l'ai utilisé pour convertir toutes les caractéristiques nominales et non numériques en nouvelles colonnes. Vous voyez dans la sortie que plusieurs nouvelles colonnes ont été créées et que les colonnes d'origine ont été supprimées.

dummy_cols = ['thal', 'chest_pain_type', 'num_major_vessels',
              'exercise_induced_angina', 'fasting_blood_sugar_gt_120_mg_per_dl',
              'resting_ekg_results', 'pente_de_peak_exercise_st_segment']
train = pd.get_dummies (train, colonnes = dummy_cols)

Mise à l'échelle des fonctionnalités

Les variables continues dans notre jeu de données sont à différentes échelles. Par exemple, si vous vous référez aux histogrammes ci-dessus, vous pouvez voir que la variable «oldpeak_eq_st_depression» va de 0 à 6, tandis que «max_heart_rate_achieved» va de 100 à 200. Cela pose un problème pour de nombreux algorithmes d'apprentissage automatique populaires qui utilisent souvent la distance euclidienne. entre les points de données pour faire les prédictions finales. La standardisation de l'échelle pour toutes les variables continues peut souvent entraîner une augmentation des performances des modèles d'apprentissage automatique.

Il existe un certain nombre de méthodes pour effectuer la mise à l'échelle des fonctionnalités en python. Ma méthode préférée consiste à utiliser la fonction Sci-Kit Learn MinMaxScaler. Ce qui transforme l'échelle de sorte que toutes les valeurs des fonctionnalités vont de 0 à 1. J'ai inclus du code qui le fait ci-dessous.

du pré-traitement d'importation sklearn
n_test = train [['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']]
cols_to_norm = ['sérum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']
x = n_test.values
min_max_scaler = pré-traitement.MinMaxScaler ()
x_scaled = min_max_scaler.fit_transform (x)
n_test = pd.DataFrame (x_scaled, columns = cols_to_norm)
l_test = train.drop (['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure'], axis = 1)
train = pd.concat ([n_test, l_test], axis = 1)
train.colonnes

Binning

D'après le code ci-dessus, vous remarquerez que je n'ai pas inclus la variable continue «age» dans la transformation de redimensionnement des entités. La raison en est que l’âge est un exemple de type d’entité susceptible de bénéficier de la transformation en une variable discrète. Dans cet exemple, nous pouvons utiliser un compartiment ou un regroupement pour transformer l'entité en une liste de catégories significatives.

Dans le code ci-dessous, j'ai spécifié des catégories intuitives basées sur la distribution dans les données. Ceci utilise la fonction de coupe pandas qui prend une liste de bacs, de noms de groupes et du cadre de données. Cette fonction renvoie le bloc de données d'origine avec une nouvelle fonctionnalité «age_categories». Cette colonne peut ensuite être transformée en un certain nombre de colonnes factices en utilisant la méthode décrite précédemment.

bacs = [30, 40, 50, 60, 70, 80]
group_names = ['30 -39 ', '40 -49', '50 -59 ', '60 -69', '70 -79 ']
age_categories = pd.cut (train ['age'], bacs, libellés = noms_groupe)
train ['age_categories'] = pd.cut (train ['age'], bacs, libellés = noms_groupe)
catégories d'age
pd.value_counts (train ['age_categories'])

Nous avons maintenant un ensemble de données où toutes les colonnes sont non numériques. Nous avons créé plusieurs nouvelles fonctionnalités et transformé les fonctionnalités existantes en formats qui devraient aider à améliorer les performances de tous les modèles d'apprentissage machine que nous pouvons maintenant utiliser. La transformation des fonctions est une première étape importante du processus d’apprentissage automatique et peut souvent avoir un impact significatif sur les performances du modèle. J'ai décrit ici les premières étapes du processus pour réfléchir logiquement à la manière de traiter les différentes variables que j'ai. Une fois dans la phase de construction du modèle, je vais presque toujours revenir en arrière et peaufiner les données en utilisant différentes méthodes pour améliorer la précision des modèles. Cependant, je constate qu’en suivant ces étapes au début, cela réduit souvent le temps que je passe à retourner aux étapes de la transformation.