<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Traitement de données classique
Nous allons voir dans cet exemple comment utiliser la bibliothèque numpy pour récupérer des valeurs dans un fichier csv et commencer à les traiter.
Nous allons utiliser le module csv qui permet de lire un fichier csv et d'en extraire les valeurs lignes par lignes.
Nous allons travailler sur le fichier de données d'entraînement du Titanic. Le but est de prédire les chance de survie à bord du bateau. Il faut récupérer le fichier train.csv (voir le premier cours ou téléchargez le depuis https
Step1:  Regardons comment sont stockées les données en mémoire
Step2:  Regardons maintenant la colonne de l'âge, n'affichons que les 15 premières valeurs
Step3:  On peut donc remarquer que les âges sont stockés comme des chaîne de caractères. Transformons les en réels 
Step4:  Numpy ne sait pas convertir la chaîne de caractère vide '' (en 6e position dans notre liste) en réels. Pour traiter ces données, il faudrait écrire un petit algorithme. Nous allons voir comment on peut utiliser pandas pour faire ces traitements beaucoup plus facilement.
Traiter et manipuler les données avec pandas
Step5:  Pour lire le fichier csv nous allons utiliser la fonction read_csv
Step6:  Pour vérifier si cela a bien fonctionné, affichons les premières valeurs. On voit apparaître l'identifiant du passager, s'il a survécu, sa classe, son nom, son sexe, son âge, le nombre de frères/soeurs/époux/épouse sur le bâteau, le nombre de parents ou d'enfants, le numéro de ticket, le prix, le numéro de cabine et le port d'embarquement.
Step7:  Comparons le type de donnees, obtenu précédemment. C'est un numpy array. Le type de df est un objet spécifique à pandas.
Step8:  Nous avions vu qu'avec numpy, toutes les valeurs importées étaient des chaînes de caractères. Vérifions ce qu'il en est avec pandas
Step9:  On peut voir que Pandas a détecté automatiquement le types des données de notre fichier csv
Step10:  L'âge n'est pas renseigné pour tous les passagers, seulement pour 714 passagers sur 891. Idem pour le numéro de cabine et le port d'embarquement. On peut également utiliser describe() pour calculer plusieurs indicateurs statistiques utiles.
Step11:  On peut voir que pandas a calculé automatiquement les indicateurs statistiques en tenant compte uniquement des données renseignées. Par exemple, il a calculé la moyenne d'âge uniquement sur les 714 valeurs connues. pandas a laissé de coté les valeurs non-numériques (nom, sexe, ticket, cabine, port d'embarquement).
Pour aller un peu plus loin avec pandas
Référencement et filtrage
Pour afficher uniquement les 15 premières valeurs de la colonne âge 
Step12:  On peut également utiliser la syntaxe
Step13:  On peut calculer des critères statistiques directement sur les colonnes
Step14:  On peut voir que c'est la même valeur que celle affichée dans describe. Cette syntaxe permet d'utiliser facilement la valeur de la moyenne dans des calculs ou des algorithmes.
Pour filtrer les données, on va passer la liste de colonnes désirées
Step15:  En analyse, on est souvent intéressé  par filtrer les données en fonction de certains critères. Par exemple, l'âge maximum est 80 ans. On peut examiner les informations relatives aux personnes âgées 
Step16:  Comme on a trop d'informations, on peut les filtrer
Step17:  On peut voir que parmis les persones âges, il y a principalement des hommes. Les personnes qui   ont survécues était principalement des femmes. 
Nous allons maintenant voir comment traiter les valeurs manquantes pour l'âge. Nous allons filtrer les données pour afficher uniquement les valeurs manquantes
Step18:  Pour combiner des filtres, on peut utiliser '&amp;'. Affichons le nombre d'hommes dans chaque classe
Step19:  Visualisons maintenant l'histogramme de répartition des âges.
Step20:  Créations et modifications des colonnes
Pour pouvoir exploiter les informations sur le sexe des personnes, nous allons ajouter une nouvelle colonne, appellée genre, qui vaudra 1 pour les hommes et 0 pour les femmes.
Step21:  Pour créer et renommer de nouvelles colonnes, on peut également agréger des informations issues de différentes colonnes. Créons par exemple une colonne pour stocker les nombre de personnes de la même famille à bord du Titanic.
Step22:  Nous allons remplir les valeurs manquantes de l'âge avec la valeur médiane dépendant de la classe et du sexe.
Step23:  On va créer une nouvelle colonne AgeFill qui va utiliser ces âges médians
Step24:  Pour sauvegarder votre travail, vous pouvez utiliser le module pickle qui compresse et sauvegarde vos données 
Step25:  Pour récuperer votre travail, on utilise l'opération inverse, toujours avec pickle
Step26:  Retour à numpy pour l'apprentissage
Pour faire de l'apprentissage, et prédire la survie des passagers du Titanic, on peut utiliser scikit-learn. Ce dernier prend en entrée des données sous forme de numpy array, la conversion se fait simplement 
Step27:  On cherche à prévoir la survie, on extrait donc l'information utile 
Step28:  L'apprentissage du classifieur est fait, c'est-à-dire que nous avons entraîné une SVM sur nos données $X$ pour qu'elle soit capable de prédire la survie $y$. Pour vérifier que notre SVM a bien appris à prédire la survie des passagers, nous pouvons utiliser la méthode predict() et comparer visuellement pour les dix premières valeurs prédite par la SVM et la survie réelle des passagers.
Step29:  La SVM a bien appris à prédire ce que nous lui avons montré. Cela ne permet pas cependant d'évaluer sa capacité à généraliser à des cas qu'elle n'a pas vu. Pour ce faire, une approche classique est de faire de la validation croisée, c'est à dire qu'on entraîne le classifieur sur une partie des données et qu'on le teste sur une autre. Scikit-learn en donne une implémentation très simple d'utilisation.
Step30:  Sur les 7 partitions de nos données, la SVM prédit la survie des passagers dans 77% des cas, avec un écart-type de 0,04.
Pour améliorer les résultats, nous pouvons rajouter l'âge dans les features. Il faut cependant faire attention aux valeurs non-renseignées NaN, nous allons donc utiliser une nouvelle colonne AgeFilled avec l'âge ou la médiane.
Step31:  Nous pouvons maintenant créer un nouveau $X$ incluant l'âge, en plus du sexe et de la classe, et vérifier si cela améliore les performances de la SVM.
<ASSISTANT_TASK:>
Python Code:
import csv
import numpy as np
fichier_csv = csv.reader(open('train.csv', 'r'))
entetes = fichier_csv.__next__()  # on récupère la première ligne qui contient les entetes
donnees = list()              # on crée la liste qui va servir à récupérer les données
for ligne in fichier_csv:     # pour chaque ligne lue dans le fichier csv
    donnees.append(ligne)     # on ajoute les valeurs lues dans le tableau donness
#entete = donnees[0]
#donnees[0] = []
donnees = np.array(donnees)   # le tableau donnees est transformé en numpy array
Explanation: Traitement de données classique
Nous allons voir dans cet exemple comment utiliser la bibliothèque numpy pour récupérer des valeurs dans un fichier csv et commencer à les traiter.
Nous allons utiliser le module csv qui permet de lire un fichier csv et d'en extraire les valeurs lignes par lignes.
Nous allons travailler sur le fichier de données d'entraînement du Titanic. Le but est de prédire les chance de survie à bord du bateau. Il faut récupérer le fichier train.csv (voir le premier cours ou téléchargez le depuis https://www.kaggle.com/c/titanic-gettingStarted/data ) et le sauvegarder dans le répertoire dans lequel le notebook s'éxecute. Vous pouvez utiliser la commande pwd pour connaître ce répertoire. Sinon, vous pouvez déplacer le répertoire courant pour rejoindre l'endroit où vous avez sauvegardé votre fichier avec la commande cd.
End of explanation
print (donnees)
Explanation: Regardons comment sont stockées les données en mémoire:
End of explanation
print (donnees[1:15, 5])
Explanation: Regardons maintenant la colonne de l'âge, n'affichons que les 15 premières valeurs:
End of explanation
donnees[1:15, 5].astype(np.int)
Explanation: On peut donc remarquer que les âges sont stockés comme des chaîne de caractères. Transformons les en réels :
End of explanation
import pandas as pd
import numpy as np
Explanation: Numpy ne sait pas convertir la chaîne de caractère vide '' (en 6e position dans notre liste) en réels. Pour traiter ces données, il faudrait écrire un petit algorithme. Nous allons voir comment on peut utiliser pandas pour faire ces traitements beaucoup plus facilement.
Traiter et manipuler les données avec pandas
End of explanation
df = pd.read_csv('train.csv')
Explanation: Pour lire le fichier csv nous allons utiliser la fonction read_csv
End of explanation
df.head(6)
Explanation: Pour vérifier si cela a bien fonctionné, affichons les premières valeurs. On voit apparaître l'identifiant du passager, s'il a survécu, sa classe, son nom, son sexe, son âge, le nombre de frères/soeurs/époux/épouse sur le bâteau, le nombre de parents ou d'enfants, le numéro de ticket, le prix, le numéro de cabine et le port d'embarquement.
End of explanation
type(donnees)
type(df)
Explanation: Comparons le type de donnees, obtenu précédemment. C'est un numpy array. Le type de df est un objet spécifique à pandas.
End of explanation
df.dtypes
Explanation: Nous avions vu qu'avec numpy, toutes les valeurs importées étaient des chaînes de caractères. Vérifions ce qu'il en est avec pandas
End of explanation
df.info()
Explanation: On peut voir que Pandas a détecté automatiquement le types des données de notre fichier csv: soit des entiers, soit des réels, soit des objets (chaînes de caractères). Il y a deux commandes importantes à connaître, c'est df.info() et df.describe()
End of explanation
df.describe()
Explanation: L'âge n'est pas renseigné pour tous les passagers, seulement pour 714 passagers sur 891. Idem pour le numéro de cabine et le port d'embarquement. On peut également utiliser describe() pour calculer plusieurs indicateurs statistiques utiles.
End of explanation
df['Age'][0:15]
Explanation: On peut voir que pandas a calculé automatiquement les indicateurs statistiques en tenant compte uniquement des données renseignées. Par exemple, il a calculé la moyenne d'âge uniquement sur les 714 valeurs connues. pandas a laissé de coté les valeurs non-numériques (nom, sexe, ticket, cabine, port d'embarquement).
Pour aller un peu plus loin avec pandas
Référencement et filtrage
Pour afficher uniquement les 15 premières valeurs de la colonne âge :
End of explanation
df.Age[0:15]
Explanation: On peut également utiliser la syntaxe
End of explanation
df.Age.mean()
Explanation: On peut calculer des critères statistiques directement sur les colonnes
End of explanation
colonnes_interessantes = ['Sex', 'Pclass', 'Age']
df[ colonnes_interessantes ]
Explanation: On peut voir que c'est la même valeur que celle affichée dans describe. Cette syntaxe permet d'utiliser facilement la valeur de la moyenne dans des calculs ou des algorithmes.
Pour filtrer les données, on va passer la liste de colonnes désirées:
End of explanation
df[df['Age'] > 60]
Explanation: En analyse, on est souvent intéressé  par filtrer les données en fonction de certains critères. Par exemple, l'âge maximum est 80 ans. On peut examiner les informations relatives aux personnes âgées :
End of explanation
df[df['Age'] > 60][['Pclass', 'Sex', 'Age', 'Survived']]
Explanation: Comme on a trop d'informations, on peut les filtrer:
End of explanation
df[df.Age.isnull()][['Sex', 'Pclass', 'Age']]
Explanation: On peut voir que parmis les persones âges, il y a principalement des hommes. Les personnes qui   ont survécues était principalement des femmes. 
Nous allons maintenant voir comment traiter les valeurs manquantes pour l'âge. Nous allons filtrer les données pour afficher uniquement les valeurs manquantes
End of explanation
for i in range(1, 4):
    print ("Dans la classe", i, ", il y a", len( df[ (df['Sex'] == 'male') & (df['Pclass'] == i) ]), "hommes")
    print ("Dans la classe", i, ", il y a", len( df[ (df['Sex'] == 'female') & (df['Pclass'] == i) ]), "femmes")
Explanation: Pour combiner des filtres, on peut utiliser '&amp;'. Affichons le nombre d'hommes dans chaque classe
End of explanation
df.Age.hist(bins=20, range=(0,80))
Explanation: Visualisons maintenant l'histogramme de répartition des âges.
End of explanation
df['Gender'] = 4 # on ajoute une nouvelle colonne dans laquelle toutes les valeurs sont à 4
df.head()
df['Gender'] = df['Sex'].map( {'female': 0, 'male': 1} ) # la colonne Gender prend 0 pour les femmes et 1 pour les hommes
df.head()
Explanation: Créations et modifications des colonnes
Pour pouvoir exploiter les informations sur le sexe des personnes, nous allons ajouter une nouvelle colonne, appellée genre, qui vaudra 1 pour les hommes et 0 pour les femmes.
End of explanation
df['FamilySize'] = df.SibSp + df.Parch
df.head()
Explanation: Pour créer et renommer de nouvelles colonnes, on peut également agréger des informations issues de différentes colonnes. Créons par exemple une colonne pour stocker les nombre de personnes de la même famille à bord du Titanic.
End of explanation
ages_medians = np.zeros((2, 3))
ages_medians
for i in range(0,2):
    for j in range(0,3):
        ages_medians[i,j] = df[ (df['Gender'] == i) & (df['Pclass'] == j+1) ]['Age'].median()
        
ages_medians
Explanation: Nous allons remplir les valeurs manquantes de l'âge avec la valeur médiane dépendant de la classe et du sexe.
End of explanation
for i in range(0, 2):
    for j in range (0, 3):
        df.loc[ (df.Age.isnull()) & (df.Gender == i) & (df.Pclass == j+1), 'AgeFill'] = ages_medians[i,j]
# pour afficher les 10 premières valeurs qui sont complétées
df [df.Age.isnull()][['Gender', 'Pclass', 'Age', 'AgeFill']].head(10)
Explanation: On va créer une nouvelle colonne AgeFill qui va utiliser ces âges médians
End of explanation
import pickle
f = open('masauvegarde.pck', 'wb')
pickle.dump(df, f)
f.close()
Explanation: Pour sauvegarder votre travail, vous pouvez utiliser le module pickle qui compresse et sauvegarde vos données :
End of explanation
with open('masauvegarde.pck', 'rb') as f:
    dff = pickle.load(f)
Explanation: Pour récuperer votre travail, on utilise l'opération inverse, toujours avec pickle
End of explanation
ex = df[ ['Gender', 'Pclass'] ] # on choisit seulement quelques features.
X = ex.as_matrix() # on convertit en numpy array
print(ex.head(5))
print(X[:5,:])
Explanation: Retour à numpy pour l'apprentissage
Pour faire de l'apprentissage, et prédire la survie des passagers du Titanic, on peut utiliser scikit-learn. Ce dernier prend en entrée des données sous forme de numpy array, la conversion se fait simplement :
End of explanation
y = df['Survived'].as_matrix()
print (y[:5])
from sklearn import svm
clf = svm.SVC()
clf.fit(X,y)
Explanation: On cherche à prévoir la survie, on extrait donc l'information utile :
End of explanation
print(clf.predict(X[:10,:]))
print (y[:10])
Explanation: L'apprentissage du classifieur est fait, c'est-à-dire que nous avons entraîné une SVM sur nos données $X$ pour qu'elle soit capable de prédire la survie $y$. Pour vérifier que notre SVM a bien appris à prédire la survie des passagers, nous pouvons utiliser la méthode predict() et comparer visuellement pour les dix premières valeurs prédite par la SVM et la survie réelle des passagers.
End of explanation
from sklearn import cross_validation
scores = cross_validation.cross_val_score(clf, X, y, cv=7)
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Explanation: La SVM a bien appris à prédire ce que nous lui avons montré. Cela ne permet pas cependant d'évaluer sa capacité à généraliser à des cas qu'elle n'a pas vu. Pour ce faire, une approche classique est de faire de la validation croisée, c'est à dire qu'on entraîne le classifieur sur une partie des données et qu'on le teste sur une autre. Scikit-learn en donne une implémentation très simple d'utilisation.
End of explanation
df['AgeFilled'] = df.Age # on recopie la colonne Age
df.loc[df.AgeFilled.isnull(), 'AgeFilled'] = df[df.Age.isnull()]['AgeFill'] # on met l'age médian pour les valeurs non renseignées
Explanation: Sur les 7 partitions de nos données, la SVM prédit la survie des passagers dans 77% des cas, avec un écart-type de 0,04.
Pour améliorer les résultats, nous pouvons rajouter l'âge dans les features. Il faut cependant faire attention aux valeurs non-renseignées NaN, nous allons donc utiliser une nouvelle colonne AgeFilled avec l'âge ou la médiane.
End of explanation
X = df[['Gender', 'Pclass', 'AgeFilled']].as_matrix()
scores = cross_validation.cross_val_score(svm.SVC(), X, y, cv=7)
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Explanation: Nous pouvons maintenant créer un nouveau $X$ incluant l'âge, en plus du sexe et de la classe, et vérifier si cela améliore les performances de la SVM.
End of explanation
<END_TASK>