Bloc-notes-aide-mémoire pour un prétraitement rapide des données

Souvent, les personnes qui entrent dans le domaine de la science des données ont des attentes loin d’être réalistes quant à ce qui les attend. Beaucoup de gens pensent qu'ils vont désormais écrire des réseaux de neurones sympas, créer un assistant vocal à partir d'Iron Man ou battre tout le monde sur les marchés financiers.
Mais le travail Données Le scientifique est axé sur les données, et l'un des aspects les plus importants et les plus longs consiste à traiter les données avant de les introduire dans un réseau neuronal ou de les analyser d'une certaine manière.

Dans cet article, notre équipe décrira comment vous pouvez traiter les données rapidement et facilement avec des instructions et du code étape par étape. Nous avons essayé de rendre le code assez flexible et pourrait être utilisé pour différents ensembles de données.

De nombreux professionnels ne trouveront peut-être rien d'extraordinaire dans cet article, mais les débutants pourront apprendre quelque chose de nouveau, et quiconque rêve depuis longtemps de créer un ordinateur portable séparé pour un traitement rapide et structuré des données pourra copier le code et le formater lui-même, ou téléchargez le cahier terminé depuis Github.

Nous avons reçu l'ensemble de données. Que faire ensuite?

Donc, la norme : nous devons comprendre à quoi nous avons affaire, la situation globale. Pour ce faire, nous utilisons des pandas pour définir simplement différents types de données.

import pandas as pd #импортируем pandas
import numpy as np  #импортируем numpy
df = pd.read_csv("AB_NYC_2019.csv") #читаем датасет и записываем в переменную df

df.head(3) #смотрим на первые 3 строчки, чтобы понять, как выглядят значения

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

df.info() #Демонстрируем информацию о колонках

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

Regardons les valeurs des colonnes :

  1. Le nombre de lignes dans chaque colonne correspond-il au nombre total de lignes ?
  2. Quelle est l’essence des données dans chaque colonne ?
  3. Quelle colonne voulons-nous cibler afin de faire des prédictions sur celle-ci ?

Les réponses à ces questions vous permettront d'analyser l'ensemble de données et d'élaborer grossièrement un plan pour vos prochaines actions.

De plus, pour un examen plus approfondi des valeurs de chaque colonne, nous pouvons utiliser la fonction pandasscribe(). Cependant, l'inconvénient de cette fonction est qu'elle ne fournit pas d'informations sur les colonnes contenant des valeurs de chaîne. Nous les traiterons plus tard.

df.describe()

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

Visualisation magique

Regardons où nous n'avons aucune valeur du tout :

import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis')

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

C'était un bref aperçu d'en haut, nous allons maintenant passer à des choses plus intéressantes

Essayons de trouver et, si possible, de supprimer les colonnes qui n'ont qu'une seule valeur dans toutes les lignes (elles n'affecteront en rien le résultat) :

df = df[[c for c
        in list(df)
        if len(df[c].unique()) > 1]] #Перезаписываем датасет, оставляя только те колонки, в которых больше одного уникального значения

Maintenant, nous nous protégeons et protégeons le succès de notre projet des lignes en double (lignes qui contiennent les mêmes informations dans le même ordre que l'une des lignes existantes) :

df.drop_duplicates(inplace=True) #Делаем это, если считаем нужным.
                                 #В некоторых проектах удалять такие данные с самого начала не стоит.

Nous divisons l'ensemble de données en deux : l'un avec des valeurs qualitatives et l'autre avec des valeurs quantitatives.

Ici, nous devons apporter une petite précision : si les lignes avec des données manquantes dans les données qualitatives et quantitatives ne sont pas très corrélées les unes aux autres, alors nous devrons décider ce que nous sacrifions - toutes les lignes avec des données manquantes, seulement une partie d'entre elles, ou certaines colonnes. Si les lignes sont corrélées, nous avons alors parfaitement le droit de diviser l’ensemble de données en deux. Sinon, vous devrez d'abord traiter les lignes qui ne corrèlent pas les données manquantes sur les plans qualitatif et quantitatif, puis diviser l'ensemble de données en deux.

df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])

Nous faisons cela pour faciliter le traitement de ces deux types de données différents - nous comprendrons plus tard à quel point cela nous facilite la vie.

Nous travaillons avec des données quantitatives

La première chose à faire est de déterminer s’il existe des « colonnes d’espionnage » dans les données quantitatives. Nous appelons ces colonnes ainsi parce qu’elles se présentent comme des données quantitatives, mais agissent comme des données qualitatives.

Comment les définissons-nous ? Bien sûr, tout dépend de la nature des données que vous analysez, mais en général, ces colonnes peuvent contenir peu de données uniques (de l'ordre de 3 à 10 valeurs uniques).

print(df_numerical.nunique())

Une fois que nous aurons identifié les colonnes espion, nous les déplacerons des données quantitatives vers les données qualitatives :

spy_columns = df_numerical[['колонка1', 'колока2', 'колонка3']]#выделяем колонки-шпионы и записываем в отдельную dataframe
df_numerical.drop(labels=['колонка1', 'колока2', 'колонка3'], axis=1, inplace = True)#вырезаем эти колонки из количественных данных
df_categorical.insert(1, 'колонка1', spy_columns['колонка1']) #добавляем первую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка2', spy_columns['колонка2']) #добавляем вторую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка3', spy_columns['колонка3']) #добавляем третью колонку-шпион в качественные данные

Enfin, nous avons complètement séparé les données quantitatives des données qualitatives et nous pouvons désormais les utiliser correctement. La première chose est de comprendre où nous avons des valeurs vides (NaN, et dans certains cas 0 sera accepté comme valeur vide).

for i in df_numerical.columns:
    print(i, df[i][df[i]==0].count())

À ce stade, il est important de comprendre dans quelles colonnes des zéros peuvent indiquer des valeurs manquantes : est-ce dû à la manière dont les données ont été collectées ? Ou cela pourrait-il être lié aux valeurs des données ? Il faut répondre à ces questions au cas par cas.

Ainsi, si nous décidons toujours qu'il nous manque peut-être des données là où il y a des zéros, nous devrions remplacer les zéros par NaN pour faciliter le travail ultérieur avec ces données perdues :

df_numerical[["колонка 1", "колонка 2"]] = df_numerical[["колонка 1", "колонка 2"]].replace(0, nan)

Voyons maintenant où il nous manque des données :

sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Можно также воспользоваться df_numerical.info()

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

Ici, les valeurs manquantes dans les colonnes doivent être marquées en jaune. Et maintenant, le plaisir commence : comment gérer ces valeurs ? Dois-je supprimer les lignes avec ces valeurs ou colonnes ? Ou remplir ces valeurs vides avec d'autres ?

Voici un diagramme approximatif qui peut vous aider à décider de ce qui peut, en principe, être fait avec des valeurs vides :

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

0. Supprimez les colonnes inutiles

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. Le nombre de valeurs vides dans cette colonne est-il supérieur à 50 % ?

print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)#Удаляем, если какая-то колонка имеет больше 50 пустых значений

2. Supprimez les lignes avec des valeurs vides

df_numerical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, если потом останется достаточно данных для обучения

3.1. Insérer une valeur aléatoire

import random #импортируем random
df_numerical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True) #вставляем рандомные значения в пустые клетки таблицы

3.2. Insérer une valeur constante

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>") #вставляем определенное значение с помощью SimpleImputer
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.3. Insérez la valeur moyenne ou la plus fréquente

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #вместо mean можно также использовать most_frequent
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.4. Insérer la valeur calculée par un autre modèle

Parfois, les valeurs peuvent être calculées à l'aide de modèles de régression utilisant des modèles de la bibliothèque sklearn ou d'autres bibliothèques similaires. Notre équipe consacrera un article séparé à la manière dont cela peut être réalisé dans un avenir proche.

Donc, pour l'instant, le récit sur les données quantitatives sera interrompu, car il existe de nombreuses autres nuances sur la façon de mieux préparer et prétraiter les données pour différentes tâches, et les éléments de base des données quantitatives ont été pris en compte dans cet article, et Il est désormais temps de revenir aux données qualitatives, que nous avons séparées de plusieurs pas des données quantitatives. Vous pouvez modifier ce carnet à votre guise, en l'adaptant à différentes tâches, pour que le prétraitement des données se fasse très rapidement !

Données qualitatives

Fondamentalement, pour les données qualitatives, la méthode One-hot-encoding est utilisée afin de les formater d'une chaîne (ou d'un objet) en un nombre. Avant de passer à ce point, utilisons le diagramme et le code ci-dessus pour gérer les valeurs vides.

df_categorical.nunique()

sns.heatmap(df_categorical.isnull(),yticklabels=False,cbar=False,cmap='viridis')

Bloc-notes-aide-mémoire pour un prétraitement rapide des données

0. Supprimez les colonnes inutiles

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. Le nombre de valeurs vides dans cette colonne est-il supérieur à 50 % ?

print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True) #Удаляем, если какая-то колонка 
                                                                          #имеет больше 50% пустых значений

2. Supprimez les lignes avec des valeurs vides

df_categorical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, 
                                   #если потом останется достаточно данных для обучения

3.1. Insérer une valeur aléatoire

import random
df_categorical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True)

3.2. Insérer une valeur constante

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>")
df_categorical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_categorical[['колонка1', 'колонка2', 'колонка3']])
df_categorical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True)

Nous avons donc enfin une idée des valeurs nulles dans les données qualitatives. Il est maintenant temps d'effectuer un encodage à chaud sur les valeurs qui se trouvent dans votre base de données. Cette méthode est très souvent utilisée pour garantir que votre algorithme puisse apprendre à partir de données de haute qualité.

def encode_and_bind(original_dataframe, feature_to_encode):
    dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
    res = pd.concat([original_dataframe, dummies], axis=1)
    res = res.drop([feature_to_encode], axis=1)
    return(res)

features_to_encode = ["колонка1","колонка2","колонка3"]
for feature in features_to_encode:
    df_categorical = encode_and_bind(df_categorical, feature))

Nous avons donc enfin fini de traiter des données qualitatives et quantitatives distinctes : il est temps de les combiner à nouveau.

new_df = pd.concat([df_numerical,df_categorical], axis=1)

Après avoir combiné les ensembles de données en un seul, nous pouvons enfin utiliser la transformation de données à l'aide de MinMaxScaler de la bibliothèque sklearn. Cela rendra nos valeurs comprises entre 0 et 1, ce qui aidera lors de la formation du modèle à l'avenir.

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)

Ces données sont désormais prêtes à tout : réseaux de neurones, algorithmes ML standards, etc. !

Dans cet article, nous n'avons pas pris en compte le travail avec des données de séries chronologiques, car pour ces données, vous devez utiliser des techniques de traitement légèrement différentes, en fonction de votre tâche. À l'avenir, notre équipe consacrera un article séparé à ce sujet, et nous espérons qu'il pourra apporter quelque chose d'intéressant, de nouveau et d'utile dans votre vie, tout comme celui-ci.

Source: habr.com

Ajouter un commentaire