Préparation des données pour l’apprentissage automatique

La première étape de notre processus de ML consiste à déterminer ce que nous voulons prévoir. Une fois que cela est établi, notre deuxième étape est la "préparation des données". La préparation des données, ainsi que l'ingénierie des caractéristiques, représentent la majeure partie de notre temps de traitement de la ML.
Intelligence artificielle
Équipe AI Spiria
2020-11-11 11:10
5 min. de lecture
<p>La préparation des données consiste à effectuer la récolte de données, la réconciliation <em>(Data Wrangling)</em> et même l’enrichissement si nécessaire.</p> <h2>Récolte des données</h2> <p>Premièrement, rassemblez les données dont vous aurez besoin pour l’apprentissage automatique. Veillez à les rassembler sous une forme consolidée, afin qu’elles soient toutes contenues dans une seule table <em>(Flat Table</em>).</p> <p>Pour cela, vous pouvez utiliser l’outil qui vous convient le plus. Par exemple :</p> <ul> <li>Outils de bases de données relationnelles (SQL)</li> <li>Jupiter notebook</li> <li>Excel</li> <li>Azure ML</li> <li>R Studio</li> </ul> <h2>Réconciliation <em>(Data Wrangling)</em></h2> <p>il s’agit de préparer les données pour les rendre utilisables par des algorithmes d’apprentissage automatique. <em>(Nettoyage des données, décomposition, agrégation, mise en forme et transformation, mise à l’échelle “Data Scaling”.)</em></p> <h3><em>Nettoyage des données</em></h3> <p>Il s’agit de trouver les valeurs “Null”, les valeurs manquantes et les données dupliquées.</p> <p>Exemple de valeurs manquantes :</p> <ul> <li>blanks</li> <li>NULL</li> <li>?</li> <li>N/A, NaN, NA</li> <li>9999999</li> <li>Unknown</li> </ul> <p> </p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>#Row</th> <th>Title</th> <th>Type</th> <th>Format</th> <th>Price</th> <th>Pages</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>Series – Learning – Kids -</td> <td>Big</td> <td>16</td> <td>100</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>One Book – Story - Kids</td> <td>Big</td> <td> </td> <td> </td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>Adults – learning- Series</td> <td> </td> <td>10</td> <td>120</td> <td>8</td> </tr> <tr> <td>5</td> <td>Dictation</td> <td>Series - Teenagers</td> <td>Small</td> <td>13</td> <td>85</td> <td>22</td> </tr> </tbody> </table> </div> <p><code>data_frame</code> dans ce code est notre ensemble de données sur “pandas”.</p> <pre><code>#Count the number of missing values in each row in Pandas dataframedata_frame.isnull().sum()</code></pre> <pre><code>#Row 0Title 0Type 0Price 1Format 1Pages 1NumberSales 0</code></pre> <p>Si certaines lignes ont des données manquantes dans plusieurs colonnes importantes, nous pouvons envisager de les supprimer. En utilisant la requête <code>DELETE</code> en SQL ou <code>pandas.drop()</code> en Python.</p> <p>On peut parfois remplacer la valeur manquante par zéro, la valeur la plus fréquente ou par la moyenne, cela dépend des valeurs et du type de colonne. En utilisant la requête de mise à jour <code>UPDATE</code> en SQL ou en utilisant <code>pandas.fillna()</code> en Python.</p> <p>Dans le code suivant, nous remplaçons les valeurs manquantes de “Pages” par la moyenne :</p> <pre><code>global_mean = data_frame.mean()data_frame['Pages'] = data_frame['Pages'].fillna(global_mean['Pages'])data_frame.isnull().sum()</code></pre> <pre><code>#Row 0Title 0Type 0Price 1Format 1Pages 0NumberSales 0</code></pre> <p>Et la valeur la plus fréquente, pour les valeurs manquantes de “Format” :</p> <pre><code>#Counts of unique valuesdata_frame["Format"].value_counts()</code></pre> <pre><code>Big 2Small 1Name: Format, dtype: int64</code></pre> <p>Comme “Big” est la valeur la plus fréquente dans notre cas, nous allons donc remplacer toutes les valeurs manquantes par “Big”.</p> <pre><code># Replace missing "Format" value with the most common value “Big”data_frame["Format"] = data_frame['Format'].fillna("Big")data_frame["Format"].value_counts()</code></pre> <pre><code>Big 3Small 1</code></pre> <p>Le <code>data_frame</code> résultant serait :</p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>#Row</th> <th>Title</th> <th>Type</th> <th>Format</th> <th>Price</th> <th>Pages</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>Series – Learning – Kids -</td> <td>Big</td> <td>16</td> <td>100</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>One Book – Story - Kids</td> <td>Big</td> <td>13</td> <td>100</td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>Adults – learning- Series</td> <td>Big</td> <td>10</td> <td>120</td> <td>8</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>Series - Teenagers</td> <td>Small</td> <td>13</td> <td>85</td> <td>22</td> </tr> </tbody> </table> </div> <p>Assurez-vous de ne pas avoir de doublons. S’il y en a, supprimez les lignes dupliquées (<code>DELETE</code> en SQL et <code>pandas.drop()</code> en Python).</p> <h3><em>Décomposition des données</em></h3> <p>Les colonnes de texte contiennent parfois plusieurs informations ; séparez-les en autant de colonnes dédiées que nécessaire. Si certaines colonnes représentent des catégories, convertissez-les en colonnes de catégories dédiées.</p> <p>Dans notre exemple, la colonne “Type” contient plus d’une information, nous pouvons clairement la diviser en 3 colonnes comme ci-dessous <em>(Style, Type et Readers)</em>, et faire ensuite le même processus pour les valeurs manquantes s’il y a lieu.</p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>#Row</th> <th>Title</th> <th>Style</th> <th>Kind</th> <th>Readers</th> <th>Format</th> <th>Price</th> <th>Pages</th> <th>SalesMonth</th> <th>SalesYear</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>Series</td> <td>Learning</td> <td>Kids</td> <td>Big</td> <td>16</td> <td>100</td> <td>11</td> <td>2019</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>One Book</td> <td>Story</td> <td>Kids</td> <td>Big</td> <td>13</td> <td>100</td> <td>12</td> <td>2019</td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>Series</td> <td>learning</td> <td>Adults</td> <td>Big</td> <td>10</td> <td>120</td> <td>10</td> <td>2019</td> <td>8</td> </tr> <tr> <td>4</td> <td>Writing book</td> <td>Series</td> <td>learning</td> <td>Adults</td> <td>Big</td> <td>10</td> <td>120</td> <td>11</td> <td>2019</td> <td>13</td> </tr> <tr> <td>5</td> <td>Dictation</td> <td>Series</td> <td>learning</td> <td>Teenagers</td> <td>Small</td> <td>13</td> <td>85</td> <td>9</td> <td>2019</td> <td>17</td> </tr> <tr> <td>6</td> <td>Dictation</td> <td>Series</td> <td>learning</td> <td>Teenagers</td> <td>Small</td> <td>13</td> <td>85</td> <td>10</td> <td>2019</td> <td>22</td> </tr> </tbody> </table> </div> <h3><em>Agrégation des données</em></h3> <p>Il s’agit du regroupement des données, si c’est pertinent.</p> <p>Dans notre exemple, le nombre de ventes est en fait déjà une agrégation de données. Au départ, la base de données présentait des lignes de transactions, que nous avons agrégées pour obtenir le nombre de livres vendus par mois.</p> <h3><em>Mise en forme et transformation des données</em></h3> <p>Cela implique la conversion de données catégorielles en données numériques, puisque les algorithmes ne peuvent utiliser que des valeurs numériques.</p> <p>Les colonnes Style, Kind, Readers et Format sont clairement des colonnes de type catégorie. Nous allons voir deux façons de faire la transformation.</p> <p><strong>1. <em>Premièrement méthode, convertir toutes les valeurs de type catégorie en valeurs numériques</em></strong> en remplaçant toutes les valeurs uniques par des nombres séquentiels.</p> <p>Exemple de la façon de le faire en Python :</p> <pre><code>cleanup_nums = {"Format": {"Big": 1, "Small": 2}, "Style": {"Serie": 1, "One Book": 2}, "Kind": {"Learning": 1, "Story": 2}, "Readers": {"Adults": 1, "Teenagers": 2, "Kids": 3} }data_frame.replace(cleanup_nums, inplace=True)data_frame.head()</code></pre> <p>Ce qui nous donne :</p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>#Row</th> <th>Title</th> <th>Style</th> <th>Kind</th> <th>Readers</th> <th>Format</th> <th>Price</th> <th>Pages</th> <th>SalesMonth</th> <th>SalesYear</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>1</td> <td>1</td> <td>3</td> <td>1</td> <td>16 $</td> <td>100</td> <td>11</td> <td>2019</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>2</td> <td>2</td> <td>3</td> <td>1</td> <td>13 $</td> <td>100</td> <td>12</td> <td>2019</td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>10 $</td> <td>120</td> <td>10</td> <td>2019</td> <td>8</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>10 $</td> <td>120</td> <td>11</td> <td>2019</td> <td>13</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>1</td> <td>1</td> <td>2</td> <td>2</td> <td>13</td> <td>85</td> <td>9</td> <td>2019</td> <td>17</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>1</td> <td>1</td> <td>2</td> <td>2</td> <td>13</td> <td>85</td> <td>10</td> <td>2019</td> <td>22</td> </tr> </tbody> </table> </div> <p><picture><source srcset="https://www.spiria.com/site/assets/files/5792/output_1.400x0.webp" type="image/webp" media="(max-width: 599px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_1.760x0.webp" type="image/webp" media="(max-width: 999px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_1.1039x0.webp" type="image/webp" media="(min-width: 1000px)" /><img title=" " src="/site/assets/files/5792/output_1.png" alt=" " /></picture></p> <p><strong>2. <em>La deuxième méthode est celle des “dummies” :</em></strong> elle consiste à créer une colonne séparée pour chacune des valeurs uniques des colonnes de catégories. Comme la valeur de chaque colonne est binaire (0/1), vous ne pouvez donc avoir qu’une seule valeur 1 dans les colonnes nouvellement générées.</p> <p>Faire cette conversion en Python :</p> <pre><code># Convert category to dummydata_frame = pd.get_dummies(data_frame, columns=["Format"])data_frame = pd.get_dummies(data_frame, columns=["Style"])data_frame = pd.get_dummies(data_frame, columns=["Kind"])data_frame = pd.get_dummies(data_frame, columns=["Readers"])data_frame.head()</code></pre> <p>Vous remarquerez ci-dessous que “Format” a généré deux colonnes, “Format_Big” et “Format_Small”, parce que la colonne a deux valeurs distinctes, “Big” et “Small”. Cependant, “Readers” génère trois colonnes différentes parce qu’elle a trois valeurs distinctes “Adults”, “Teenagers” et “Kids”.</p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>Id</th> <th>Title</th> <th>Style_Series</th> <th>Style_OneBook</th> <th>Kind_Learning</th> <th>Kind_Story</th> <th>Readers_Adults</th> <th>Readers_Teenagers</th> <th>Readers_Kids</th> <th>Format_Big</th> <th>Format_Small</th> <th>Price</th> <th>Pages</th> <th>SalesMonth</th> <th>SalesYear</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>1</td> <td>0</td> <td>16</td> <td>100</td> <td>11</td> <td>2019</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>1</td> <td>0</td> <td>13</td> <td>100</td> <td>12</td> <td>2019</td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>10</td> <td>120</td> <td>10</td> <td>2019</td> <td>8</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>10</td> <td>120</td> <td>11</td> <td>2019</td> <td>8</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>13</td> <td>85</td> <td>9</td> <td>2019</td> <td>22</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>13</td> <td>85</td> <td>10</td> <td>2019</td> <td>22</td> </tr> </tbody> </table> </div> <p><picture><source srcset="https://www.spiria.com/site/assets/files/5792/output_2.400x0.webp" type="image/webp" media="(max-width: 599px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_2.760x0.webp" type="image/webp" media="(max-width: 999px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_2.1039x0.webp" type="image/webp" media="(min-width: 1000px)" /><img title=" " src="/site/assets/files/5792/output_2.png" alt=" " /></picture></p> <p>* Les colonnes “Id” et “Title” ne seront pas utilisées pendant notre processus de ML.</p> <p>L’avantage de la méthode des <em>dummies</em> est que toutes les valeurs ont le même poids. Cependant, comme elle ajoute autant de nouvelles colonnes que le nombre de catégories distinctes de chaque colonne initiale, soyez prudent avec l’utilisation de cette méthode si vous avez déjà de nombreuses colonnes à prendre en compte dans votre processus de ML.</p> <p>D’autre part, si vous procédez en remplaçant les valeurs de catégories par des valeurs numériques séquentielles, cela peut avantager certaines catégories si leur nombre est plus élevé. Pour “Readers”, par exemple, la catégorie 3 aura un impact trois fois plus important que la catégorie 1. Imaginez le cas où vous aurez une colonne avec un très grand nombre de catégories.</p> <h3><em>Mise à l’échelle (Data Scaling)</em></h3> <p>Cela permet d’obtenir des données numériques à une échelle commune, si ce n’est déjà le cas. La mise à l’échelle des données ne s’applique pas au <em>label</em> ou aux <em>colonnes de catégories</em>. Elle est nécessaire lorsqu’il y a une grande variation entre les plages de valeurs des différentes colonnes.</p> <p>Nous devons procéder à une mise à l’échelle, pour donner encore une fois le même poids à toutes les colonnes.</p> <p>Dans notre exemple, nous allons mettre à l’échelle les colonnes “Price” et “Pages” :</p> <ol> <li>Price [10, 16]</li> <li>Pages [85, 120]</li> </ol> <p>Nous devons mettre ces deux colonnes à l’échelle, sinon la colonne “Pages” aura plus de poids sur le résultat que la colonne “Price”.</p> <p>Il existe de nombreuses méthodes de mise à l’échelle. Pour notre exemple, nous utiliserons le <code>MinMaxScaler</code> de 0 à 1.</p> <pre><code>#scale the columnsscaler = MinMaxScaler()rescaledX = scaler.fit_transform(X[:,0:2])#put the scaled columns in dataframecolnames = [ 'Price', 'Pages']df_scaled = pd.DataFrame(rescaledX, columns=colnames)# Replace the original columns with the new scaleddata_frame_scalled = data_framedata_frame_scalled[colnames] = df_scaled[colnames]data_frame_scalled.head()</code></pre> <p>Le résultat est le suivant :</p> <div> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <th>Id</th> <th>Title</th> <th>Style_1</th> <th>Style_2</th> <th>Kind_1</th> <th>Kind_2</th> <th>Readers_1</th> <th>Readers_2</th> <th>Readers_3</th> <th>Format_1</th> <th>Format_2</th> <th>Price</th> <th>Pages</th> <th>NumberSales</th> </tr> <tr> <td>1</td> <td>Kids learning book</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>1</td> <td>0</td> <td>1</td> <td>0.42857143</td> <td>10</td> </tr> <tr> <td>2</td> <td>Guts</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>1</td> <td>0</td> <td>0.5</td> <td>0.42857143</td> <td>3</td> </tr> <tr> <td>3</td> <td>Writing book</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>8</td> </tr> <tr> <td>4</td> <td>Dictation</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>0.5</td> <td>0</td> <td>22</td> </tr> </tbody> </table> </div> <p><picture><source srcset="https://www.spiria.com/site/assets/files/5792/output_3.400x0.webp" type="image/webp" media="(max-width: 599px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_3.760x0.webp" type="image/webp" media="(max-width: 999px)" /><source srcset="https://www.spiria.com/site/assets/files/5792/output_3.1039x0.webp" type="image/webp" media="(min-width: 1000px)" /><img title=" " src="/site/assets/files/5792/output_3.png" alt=" " /></picture></p> <p>Comme indiqué, il existe de nombreuses autres méthodes de mise à l’échelle ; la manière et le moment opportun d’utiliser chacune d’entre elles feront l’objet d’un prochain article.</p>

Want to Work Together?

Every great project starts with a conversation.