<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Ateliers
Step1:  Téléchargement des données
On télécharge les données de train et de validation néttoyé et racinisé dans le notebook précédent.
Step2:  On créé un dossier dans lequel nous allons sauvegarder les DataFrame constitués des features que l'on va construire dans ce notebook
Step3:  Dans un premier temps, en guise d'exemple et pour réduire le temps de calcul, on ne considère que la colonne Description de nos DataFrame générés dans le calepin précédent.
Step4:  Vectorisaton
Step5:  One-Hot-Encoding
One-Hot-Encoding
L'encodage  One-Hot-Encoding des données peut être effectué grâce à la classe CountVectorizerde scikit-learn
Step6:  Q A quoi sert l'argument binary de la classe?
Q Sous quel format sont stockées les vecteurs OHE? Pourquoi ce format est-il choisi?
La fonction get_feature_names permet d'avoir accès à la liste des mots présents dans l'ensemble des lignes de l'array converti.
Step7:  Exercice Pour la première ligne de votre dataset train. retrouvez l'ensemble des mots constituant cette ligne à partir de l'objet data_train_OHEet de vocabulary ainsi que le nombre d'occurence de chacun de ces mots dans la ligne.
Step8:  La même transformation est appliqué sur l'échantillon de validation.
Step9:  Q Que se passe-til pour les mots présents dans le dataset de validation mais qui ne sont pas présent dans le dataset d'apprentissage?
Q Pourquoi on ne 're-fit' pas la Classe CountVectorizerl'échantillon de validation. 
TF-IDF¶
TF-IDF. Le TF-IDF permet de faire ressortir l'importance relative de chaque mot $m$ (ou couples de mots consécutifs) dans un texte-produit ou un descriptif $d$, par rapport à la liste entière des produits. La fonction $TF(m,d)$ compte le nombre d'occurences du mot $m$ dans le descriptif $d$. La fonction $IDF(m)$ mesure l'importance du terme dans l'ensemble des documents ou descriptifs en donnant plus de poids aux termes les moins fréquents car considérés comme les plus discriminants (motivation analogue à celle de la métrique du chi2 en anamlyse des correspondance). $IDF(m,l)=\log\frac{D}{f(m)}$ où $D$ est le nombre de documents, la taille de l'échantillon d'apprentissage, et $f(m)$ le nombre de documents ou descriptifs contenant le mot $m$. La nouvelle variable ou features est $V_m(l)=TF(m,l)\times IDF(m,l)$.
Comme pour les transformations des variables quantitatives (centrage, réduction), la même transformation c'est-à-dire les mêmes pondérations, est calculée sur l'achantillon d'apprentissage et appliquée à celui de test.
On utiliser la fonction TfidfVectorizer qui permet de parser également le texte
Dans un premier temps, on fixe le paramètre norm = False afin de rendre les résultats plus explicite et analyser les sorties
Step10:  Q A quoi sert l'argument ngram_range?
Constatez que data_train_TFIDFest stocké sous le même format que data_train_OHE et que la taile du vocabulaire est la même.
Step11:  Exercice Pour la première ligne de votre dataset train. retrouvez l'ensemble des mots constituant cette ligne à partir de l'objet data_train_TFIDFet de vocabulary ainsi que la valeur de l'idf, du tf et du poids tfidf de chacun de ces mots dans la ligne
Step12:  Q Commentez les valeurs de l'idf pour chacun des mots.
Q Comment evolue les poids en changeant les paramètre smooth idf et sublinear_tf de la méthode TfidfVectorizer?
Exercice Changez l'argument ngram_range de la méthode TfidfVectorizer et re-affichez les résultats.
On applique maintenant le vectorizer sur le jeu de données de validation
Step13:  ATENTION Si le tf est recalculé pour chaque ligne, le même idf est utilisé
Step14:  Hashing
Le Hashage. Il permet de réduire l'espace des variables (taille du dictionnaire) en un nombre limité et fixé a priori n_hash de caractéristiques. Il repose sur la définition d'une fonction de hashage, $h$ qui à un indice $j$ défini dans l'espace des entiers naturels, renvoie un indice $i=h(j)$ dans dans l'espace réduit (1 à n_hash) des caractéristiques. Ainsi le poids de l'indice $i$, du nouvel espace, est l'association de tous les poids d'indice $j$ tels que $i=h(j)$ de l'espace originale. Ici, les poids sont associés d'après la méthode décrite par Weinberger et al. (2009).
N.B. $h$ n'est pas généré aléatoirement. Ainsi pour un même fichier d'apprentissage (ou de test) et pour un même entier n_hash, le résultat de la fonction de hashage est identique
Au contraire des classe CountVectorizeret TfidfVectorizer, la classe FeatureHasher prend en entré un dictionnaire d'occurence des mots.
Step15:  Constatez que data_train_hash est stocké sous le même format que data_train_OHE ou data_train_TFIDF.  
Q Que dire cependant de sa dimension?
La cellule suivante permet d'afficher le poids de chacun des indices dans le nouvel espace.
Step16:  Q Que pouvez-vous dire des poids?
La taille de la matrice a donc été très réduit par rapport au vectorizer, TFIDF ou One-Hot-Enconding. Cependant, il n'y a pas de fonction inverse transform ce qui peut rendre le résultat moin compréhensible.
Il est possible de combiner le FeatureHasheravec un autre vectorizer comme le TFIDF. 
C'est cette fois la classe TFIDFTransformer qui est utilisé. Celle ci ne ne considère pas des string en entré mais l'array en sortie de l'étape de Hashage. Les mots sont les nb_hashindices sélectionnés et le tf pour chaque individu sont les poids calculé par la fonction de hasage.
Step17:  Build and Save Vectorize Vector
Afin de comparer l'effet de ces différentes vectorisation sur l'apprentissage, nous allons sauvegarder ces dernières sur les machines.
De nombreux paramètres sont à régler ce qui entraine donc un un très grand nombre de combinaison.
ici nous allons créer 4 jeu de données avec CountVectorizer et TFIDF chacun avec et sans hashage de taille 300.
Il est evidemment possible de tester d'autre combinaison. Libre à vous de les tester ;) 
Fonction de Vectorisation
on créé deux fonctions vectorizer_train and apply_vectorizer afin de générer automatiquement différent dataframe d'apprentissage et de validation vectorisé.
Step18:  Word2Vec
Dans cette partie, des modèles Word2VecSeront créés à l'aide de la librairie gensim.
Step19:  Build Word2Vec model
La fonction gensim.models.Word2Vecqui permet de construire des modèle Word2Vec prend en entrée une liste de tokens. On tranformer donc nos données dans un premier temps
Step20:  Cette fonction contient un grand nombre d' arguments. Le but de ce TP n'est pas d'optimiser les paramètres de ce modèle mais de les comprendre. Nous allons donc fixer quelques arguments par défault 
Step21:  Nous allons créer deux modèles 
Step22:  Q Que dire du temps d'apprentissage de ces deux modèles? D'ou vient cette différence?
Pre-Trained Model
Comme pour les réseaux de convolution, des modèles pré-entrainés de Word2Vec éxistent également. 
Le plus célèbre et le plus utilisé étant GoogleNewsVectors appris sur plus de 100 milliard de mots à partir des articles de GoogleNews. Cependant ce modèle est en anglais, et n'est donc )as utile ici.
On utilisera des modèle appris dans le projet suivant https
Step23:  Propriété du modèle
Nous allons maintenant comparer quelques propriétés de chacun des trois modèles à notre disposition (CBOW, Skip-Gram et le modèle online)
Les modèles que nous avons appris l'ont été sur les mots racinisé. Ainsi, nous allons avoir besoin de la racine des mots pour tester les différentes propriétés du modèle.
Step24:  Most similar world
La fonction most_similar de gensim permet de retrouver les mots les plus proches à un ou une combinaison de mots données en argument.
Q A l'aide de la documentation répondez aux questions suivantes. Quelle est la mesure de similarité utilisée? Dans quel espace est-elle utilisé? Comment fonctionne la fonction lorsque plusieurs mots sont passés en paramètres? 
1 mot
Exercice Pour chacun de ces trois modèles, affichez les sorties de la fonction 'most_similar' pour le mot homme.
Step25:  Q Comparez la qualité de prévision des modèles que nous avons entrainés sur le jeu de données 'Cdiscount' avec celui appris online. Que pouvez-vous en dire? 
Q Comparez les prévisions des deux modèles que nous avons entrainés. Que pouvez-vous en dire?
Exercice Affichez maintenant les sorties de la fonction 'most_similar' pour le mot femme. 
Exercice Affichez les sorties de la fonction 'most_similar' pour des mots propre au jeu de données (ex. xbox, pantalon,..)
Combinaison de mots
Exercice Pour chacun de ces trois modèles, affichez les sorties de la fonction 'most_similar' pour l'opération suivante 
Step26:  Exercice Testez d'autres combinaisons si vous le souhaitez.
Predict output word
La fonction predict_output_word de gensim permet de retrouver les mots prédit par le modèle à partir d'un mot ou d'une combinaison de mots données en argument.
Exercice  Affichez la prédiction des trois modèles pour des mots/combinaisons de mots communs (homme, femme) ou plus propre au jeu de données étudiés. (coque-de-téléphone)...
Step27:  Build Features
Nous allons maintenant créer des matrices de features à partir des modèles de Word2Vec générés précédemment dans un but de prédiction. 
La modèles créés permettent d'obtenir pour chaque mot x, sa représentation dans l'espace d'embeddings de la manière suivante 
Step28:  Cbow
Step29:  Skip-Gram
Step30:  Online model
<ASSISTANT_TASK:>
Python Code:
#Importation des librairies utilisées
import time
import pandas as pd
import numpy as np
import collections
import itertools
import os
import warnings
warnings.filterwarnings('ignore')
from sklearn.cross_validation import train_test_split
Explanation: Ateliers: Technologies de l'intelligence Artificielle
<center>
<a href="http://www.insa-toulouse.fr/" ><img src="http://www.math.univ-toulouse.fr/~besse/Wikistat/Images/logo-insa.jpg" style="float:left; max-width: 120px; display: inline" alt="INSA"/></a> 
<a href="http://wikistat.fr/" ><img src="http://www.math.univ-toulouse.fr/~besse/Wikistat/Images/wikistat.jpg" width=400, style="max-width: 150px; display: inline"  alt="Wikistat"/></a>
<a href="http://www.math.univ-toulouse.fr/" ><img src="http://www.math.univ-toulouse.fr/~besse/Wikistat/Images/logo_imt.jpg" width=400,  style="float:right;  display: inline" alt="IMT"/> </a>
</center>
Traitement Naturel du Langage (NLP) : Catégorisation de Produits Cdiscount
Il s'agit d'une version simplifiée du concours proposé par Cdiscount et paru sur le site datascience.net. Les données d'apprentissage sont accessibles sur demande auprès de Cdiscount mais les solutions de l'échantillon test du concours ne sont pas et ne seront pas rendues publiques. Un échantillon test est donc construit pour l'usage de ce tutoriel.  L'objectif est de prévoir la catégorie d'un produit à partir de son descriptif (text mining). Seule la catégorie principale (1er niveau, 47 classes) est prédite au lieu des trois niveaux demandés dans le concours. L'objectif est plutôt de comparer les performances des méthodes et technologies en fonction de la taille de la base d'apprentissage ainsi que d'illustrer sur un exemple complexe le prétraitement de données textuelles. 
Le jeux de données complet (15M produits) permet un test en vrai grandeur du passage à l'échelle volume des phases de préparation (munging), vectorisation (hashage, TF-IDF) et d'apprentissage en fonction de la technologie utilisée.
La synthèse des résultats obtenus est développée par Besse et al. 2016 (section 5).
Partie 1-2 : Construction des caractéristiques ou features, Vectorisation et Word embedding.
Les données textuelles ne peuvent pas être utilisés directement dans les différents algorithmes d'apprentissage statistiques. Nous allons voir dans ce tutoriel plusieurs techniques permettant de traduire les données textuelles sous formes de vecteur numérique : 
Fonction de vectorisation présente dans la librairie scikit-learn :
One-Hot-Encoder
Tf-Idf
Hashing
Word Embedding  présente dans la librairie gensim :
Word2Vec
Téléchargement des librairies
End of explanation
data_valid_clean_stem = pd.read_csv("data/cdiscount_valid_clean_stem.csv").fillna("")
data_train_clean_stem = pd.read_csv("data/cdiscount_train_clean_stem.csv").fillna("")
Explanation: Téléchargement des données
On télécharge les données de train et de validation néttoyé et racinisé dans le notebook précédent.
End of explanation
DATA_OUTPUT_DIR = "data/features"
if not(os.path.isdir("data/features")):
    os.mkdir("data/features")
Explanation: On créé un dossier dans lequel nous allons sauvegarder les DataFrame constitués des features que l'on va construire dans ce notebook
End of explanation
train_array = data_train_clean_stem["Description"].values
valid_array = data_valid_clean_stem["Description"].values
Explanation: Dans un premier temps, en guise d'exemple et pour réduire le temps de calcul, on ne considère que la colonne Description de nos DataFrame générés dans le calepin précédent.
End of explanation
train_array[0]
Explanation: Vectorisaton
End of explanation
from sklearn.feature_extraction.text import CountVectorizer
extr_cv = CountVectorizer(binary=False)
data_train_OHE = extr_cv.fit_transform(train_array)
Explanation: One-Hot-Encoding
One-Hot-Encoding
L'encodage  One-Hot-Encoding des données peut être effectué grâce à la classe CountVectorizerde scikit-learn
End of explanation
vocabulary = extr_cv.get_feature_names()
N_vocabulary = len(vocabulary)
print("Nombre de mots : %d" %N_vocabulary )
Explanation: Q A quoi sert l'argument binary de la classe?
Q Sous quel format sont stockées les vecteurs OHE? Pourquoi ce format est-il choisi?
La fonction get_feature_names permet d'avoir accès à la liste des mots présents dans l'ensemble des lignes de l'array converti.
End of explanation
# %load solution/2_1.py
Explanation: Exercice Pour la première ligne de votre dataset train. retrouvez l'ensemble des mots constituant cette ligne à partir de l'objet data_train_OHEet de vocabulary ainsi que le nombre d'occurence de chacun de ces mots dans la ligne.
End of explanation
data_valid_OHE = extr_cv.transform(valid_array)
data_valid_OHE
Explanation: La même transformation est appliqué sur l'échantillon de validation.
End of explanation
from sklearn.feature_extraction.text import TfidfVectorizer
vec = TfidfVectorizer(ngram_range=(1,1), norm = False)
data_train_TFIDF = vec.fit_transform(train_array)
Explanation: Q Que se passe-til pour les mots présents dans le dataset de validation mais qui ne sont pas présent dans le dataset d'apprentissage?
Q Pourquoi on ne 're-fit' pas la Classe CountVectorizerl'échantillon de validation. 
TF-IDF¶
TF-IDF. Le TF-IDF permet de faire ressortir l'importance relative de chaque mot $m$ (ou couples de mots consécutifs) dans un texte-produit ou un descriptif $d$, par rapport à la liste entière des produits. La fonction $TF(m,d)$ compte le nombre d'occurences du mot $m$ dans le descriptif $d$. La fonction $IDF(m)$ mesure l'importance du terme dans l'ensemble des documents ou descriptifs en donnant plus de poids aux termes les moins fréquents car considérés comme les plus discriminants (motivation analogue à celle de la métrique du chi2 en anamlyse des correspondance). $IDF(m,l)=\log\frac{D}{f(m)}$ où $D$ est le nombre de documents, la taille de l'échantillon d'apprentissage, et $f(m)$ le nombre de documents ou descriptifs contenant le mot $m$. La nouvelle variable ou features est $V_m(l)=TF(m,l)\times IDF(m,l)$.
Comme pour les transformations des variables quantitatives (centrage, réduction), la même transformation c'est-à-dire les mêmes pondérations, est calculée sur l'achantillon d'apprentissage et appliquée à celui de test.
On utiliser la fonction TfidfVectorizer qui permet de parser également le texte
Dans un premier temps, on fixe le paramètre norm = False afin de rendre les résultats plus explicite et analyser les sorties
End of explanation
vocabulary = vec.get_feature_names()
N_vocabulary = len(vocabulary)
N_vocabulary
Explanation: Q A quoi sert l'argument ngram_range?
Constatez que data_train_TFIDFest stocké sous le même format que data_train_OHE et que la taile du vocabulaire est la même.
End of explanation
# %load solution/2_2.py
Explanation: Exercice Pour la première ligne de votre dataset train. retrouvez l'ensemble des mots constituant cette ligne à partir de l'objet data_train_TFIDFet de vocabulary ainsi que la valeur de l'idf, du tf et du poids tfidf de chacun de ces mots dans la ligne
End of explanation
data_valid_TFIDF = vec.transform(valid_array)
data_valid_TFIDF
Explanation: Q Commentez les valeurs de l'idf pour chacun des mots.
Q Comment evolue les poids en changeant les paramètre smooth idf et sublinear_tf de la méthode TfidfVectorizer?
Exercice Changez l'argument ngram_range de la méthode TfidfVectorizer et re-affichez les résultats.
On applique maintenant le vectorizer sur le jeu de données de validation
End of explanation
# %load solution/2_2bis.py
Explanation: ATENTION Si le tf est recalculé pour chaque ligne, le même idf est utilisé
End of explanation
train_dict_array  = list(map(lambda x : collections.Counter(x.split(" ")), train_array))
train_dict_array[0]
from sklearn.feature_extraction import FeatureHasher
nb_hash = 300
feathash = FeatureHasher(nb_hash)
data_train_hash = feathash.fit_transform(train_dict_array)
Explanation: Hashing
Le Hashage. Il permet de réduire l'espace des variables (taille du dictionnaire) en un nombre limité et fixé a priori n_hash de caractéristiques. Il repose sur la définition d'une fonction de hashage, $h$ qui à un indice $j$ défini dans l'espace des entiers naturels, renvoie un indice $i=h(j)$ dans dans l'espace réduit (1 à n_hash) des caractéristiques. Ainsi le poids de l'indice $i$, du nouvel espace, est l'association de tous les poids d'indice $j$ tels que $i=h(j)$ de l'espace originale. Ici, les poids sont associés d'après la méthode décrite par Weinberger et al. (2009).
N.B. $h$ n'est pas généré aléatoirement. Ainsi pour un même fichier d'apprentissage (ou de test) et pour un même entier n_hash, le résultat de la fonction de hashage est identique
Au contraire des classe CountVectorizeret TfidfVectorizer, la classe FeatureHasher prend en entré un dictionnaire d'occurence des mots.
End of explanation
ir = 0
rw = data_train_hash.getrow(ir)
print("Liste des tokens racinisé de la première ligne : " + train_array[0])
pd.DataFrame([(v, k)  for k,v in zip(rw.data,rw.indices)], columns=["indices","weight"])
Explanation: Constatez que data_train_hash est stocké sous le même format que data_train_OHE ou data_train_TFIDF.  
Q Que dire cependant de sa dimension?
La cellule suivante permet d'afficher le poids de chacun des indices dans le nouvel espace.
End of explanation
from sklearn.feature_extraction.text import TfidfTransformer
vec =  TfidfTransformer(norm = False)
data_train_HTfidf = vec.fit_transform(data_train_hash)
data_train_HTfidf
ir = 0
rw = data_train_HTfidf.getrow(ir)
print(train_array[ir])
pd.DataFrame([(ind, vec.idf_[ind], w/vec.idf_[ind], w)  for w,ind in zip(rw.data, rw.indices)], columns=["indices","idf","tf","weight"])
Explanation: Q Que pouvez-vous dire des poids?
La taille de la matrice a donc été très réduit par rapport au vectorizer, TFIDF ou One-Hot-Enconding. Cependant, il n'y a pas de fonction inverse transform ce qui peut rendre le résultat moin compréhensible.
Il est possible de combiner le FeatureHasheravec un autre vectorizer comme le TFIDF. 
C'est cette fois la classe TFIDFTransformer qui est utilisé. Celle ci ne ne considère pas des string en entré mais l'array en sortie de l'étape de Hashage. Les mots sont les nb_hashindices sélectionnés et le tf pour chaque individu sont les poids calculé par la fonction de hasage.
End of explanation
def vectorizer_train(df, columns=['Description'], nb_hash=None, nb_gram = 1, vectorizer = "tfidf" , binary = False):
    
    data_array = [" ".join(line) for line in df[columns].values]
    
    # Hashage
    if nb_hash is None:
        feathash = None
        if vectorizer == "tfidf":
            vec = TfidfVectorizer(ngram_range=(1,nb_gram))
            data_vec = vec.fit_transform(data_array)
        else:
            vec = CountVectorizer(binary=binary)
            data_vec = vec.fit_transform(data_array)
    else:
        data_dic_array = [collections.Counter(line.split(" ")) for line in data_array]
        feathash = FeatureHasher(nb_hash)
        data_hash = feathash.fit_transform(data_dic_array)
        
        if vectorizer=="tfidf":
            vec =  TfidfTransformer()
            data_vec =  vec.fit_transform(data_hash)
        else:
            vec = None
            data_vec = data_hash
    return vec, feathash, data_vec
def apply_vectorizer(df, vec, feathash, columns =['Description', 'Libelle', 'Marque']):
    
    data_array = [" ".join(line) for line in df[columns].values]
    
    #Hashage
    if feathash is None:
        data_hash = data_array
    else:
        data_dic_array = [collections.Counter(line.split(" ")) for line in data_array]
        data_hash = feathash.transform(data_dic_array)
    
    if vec is None:
        data_vec = data_hash
    else:
        data_vec = vec.transform(data_hash)
    return data_vec
parameters = [[None, "count"],
              [300, "count"],
              [None, "tfidf"],
              [300, "tfidf"]]
from scipy import sparse
for nb_hash, vectorizer in parameters:
    ts = time.time()
    vec, feathash, data_train_vec = vectorizer_train(data_train_clean_stem, nb_hash=nb_hash, vectorizer = vectorizer)
    data_valid_vec = apply_vectorizer(data_valid_clean_stem, vec, feathash)
    te = time.time()
    
    print("nb_hash : " + str(nb_hash) + ", vectorizer : " + str(vectorizer))
    print("Runing time for vectorization : %.1f seconds" %(te-ts))
    print("Train shape : " + str(data_train_vec.shape))
    print("Valid shape : " + str(data_valid_vec.shape))
    
    sparse.save_npz(DATA_OUTPUT_DIR +"/vec_train_nb_hash_" + str(nb_hash) + "_vectorizer_" + str(vectorizer), data_train_vec)
    sparse.save_npz(DATA_OUTPUT_DIR +"/vec_valid_nb_hash_" + str(nb_hash) + "_vectorizer_" + str(vectorizer), data_valid_vec)
    
Explanation: Build and Save Vectorize Vector
Afin de comparer l'effet de ces différentes vectorisation sur l'apprentissage, nous allons sauvegarder ces dernières sur les machines.
De nombreux paramètres sont à régler ce qui entraine donc un un très grand nombre de combinaison.
ici nous allons créer 4 jeu de données avec CountVectorizer et TFIDF chacun avec et sans hashage de taille 300.
Il est evidemment possible de tester d'autre combinaison. Libre à vous de les tester ;) 
Fonction de Vectorisation
on créé deux fonctions vectorizer_train and apply_vectorizer afin de générer automatiquement différent dataframe d'apprentissage et de validation vectorisé.
End of explanation
import gensim
Explanation: Word2Vec
Dans cette partie, des modèles Word2VecSeront créés à l'aide de la librairie gensim.
End of explanation
train_array_token = [line.split(" ") for line in train_array]
valid_array_token = [line.split(" ") for line in valid_array]
train_array_token[0]
Explanation: Build Word2Vec model
La fonction gensim.models.Word2Vecqui permet de construire des modèle Word2Vec prend en entrée une liste de tokens. On tranformer donc nos données dans un premier temps
End of explanation
Features_dimension = 300
hs = 0
negative = 10
Explanation: Cette fonction contient un grand nombre d' arguments. Le but de ce TP n'est pas d'optimiser les paramètres de ce modèle mais de les comprendre. Nous allons donc fixer quelques arguments par défault : 
Features_dimension = 300 : Dimension de l'espace des features (d'embedding) qui sera crée.
hs = 0
negative = 10
Q A quoi servent les arguments hs et negative? Quels influences ces arguments ont sur le modèle avec les valeurs définies ici?
End of explanation
sg = 1
print("Start learning skip-gram Word2Vec")
ts = time.time()
model_sg = gensim.models.Word2Vec(train_array_token, sg=sg, hs=hs, negative=negative, min_count=1, size=Features_dimension)
te = time.time()
t_learning = te-ts
print("Learning time : %.2f Word2Vec" %t_learning)
sg = 0
print("Start learning CBOW Word2Vec")
ts = time.time()
model_cbow = gensim.models.Word2Vec(train_array_token, sg=sg, hs=hs, negative=negative, min_count=1, size=Features_dimension)
te = time.time()
t_learning = te-ts
print("Learning time : %.2f Word2Vec" %t_learning)
Explanation: Nous allons créer deux modèles :
Un modèle skip-sgram, sg = 1
Un modèle CBOW, sg = 0
End of explanation
model_online_dir = "data/fr/fr.bin"
#model_online_dir = "ACOMPLETER/fr.bin"
model_online = gensim.models.Word2Vec.load(model_online_dir)
Explanation: Q Que dire du temps d'apprentissage de ces deux modèles? D'ou vient cette différence?
Pre-Trained Model
Comme pour les réseaux de convolution, des modèles pré-entrainés de Word2Vec éxistent également. 
Le plus célèbre et le plus utilisé étant GoogleNewsVectors appris sur plus de 100 milliard de mots à partir des articles de GoogleNews. Cependant ce modèle est en anglais, et n'est donc )as utile ici.
On utilisera des modèle appris dans le projet suivant https://github.com/Kyubyong/wordvectors appris sur 1Giga d'articles de wikipedia en mode *Skip-Gram
Vous pouvez télécharger ce modèle en suivant ce lien. Dezipez-le puis téléchargez le modèle en indiquant la direction du fichier "fr/bin"
End of explanation
import nltk 
stemmer=nltk.stem.SnowballStemmer('french')
Explanation: Propriété du modèle
Nous allons maintenant comparer quelques propriétés de chacun des trois modèles à notre disposition (CBOW, Skip-Gram et le modèle online)
Les modèles que nous avons appris l'ont été sur les mots racinisé. Ainsi, nous allons avoir besoin de la racine des mots pour tester les différentes propriétés du modèle.
End of explanation
# %load solution/2_3.py
Explanation: Most similar world
La fonction most_similar de gensim permet de retrouver les mots les plus proches à un ou une combinaison de mots données en argument.
Q A l'aide de la documentation répondez aux questions suivantes. Quelle est la mesure de similarité utilisée? Dans quel espace est-elle utilisé? Comment fonctionne la fonction lorsque plusieurs mots sont passés en paramètres? 
1 mot
Exercice Pour chacun de ces trois modèles, affichez les sorties de la fonction 'most_similar' pour le mot homme.
End of explanation
# %load solution/2_4.py
Explanation: Q Comparez la qualité de prévision des modèles que nous avons entrainés sur le jeu de données 'Cdiscount' avec celui appris online. Que pouvez-vous en dire? 
Q Comparez les prévisions des deux modèles que nous avons entrainés. Que pouvez-vous en dire?
Exercice Affichez maintenant les sorties de la fonction 'most_similar' pour le mot femme. 
Exercice Affichez les sorties de la fonction 'most_similar' pour des mots propre au jeu de données (ex. xbox, pantalon,..)
Combinaison de mots
Exercice Pour chacun de ces trois modèles, affichez les sorties de la fonction 'most_similar' pour l'opération suivante : roi + femme - homme à l'aide des arguments positive et negative de la fonction. Commentez encore une fois la qualité de sortie des différents modèle
End of explanation
# %load solution/2_5.py
Explanation: Exercice Testez d'autres combinaisons si vous le souhaitez.
Predict output word
La fonction predict_output_word de gensim permet de retrouver les mots prédit par le modèle à partir d'un mot ou d'une combinaison de mots données en argument.
Exercice  Affichez la prédiction des trois modèles pour des mots/combinaisons de mots communs (homme, femme) ou plus propre au jeu de données étudiés. (coque-de-téléphone)...
End of explanation
def get_features_mean(lines, model, f_size):
    features = [model[x] for x  in lines if x in model]
    if features == []:   
        fm =np.ones(f_size)
    else :
        fm = np.mean(features,axis=0)
    return fm
def get_matrix_features_means(X, model, f_size):
    X_embedded_ = list(map(lambda x : get_features_mean(x, model, f_size), X))
    X_embedded = np.vstack(X_embedded_)
    return X_embedded
Explanation: Build Features
Nous allons maintenant créer des matrices de features à partir des modèles de Word2Vec générés précédemment dans un but de prédiction. 
La modèles créés permettent d'obtenir pour chaque mot x, sa représentation dans l'espace d'embeddings de la manière suivante : 
x_feature = model_word2vec[x] 
Dans notre problématique, les individus que nous cherchons à classer sont des descriptions représentées par une liste de token à l'issue du nettoyage du calepin précédent.  Il exsite donc plusieurs façon de représenter ces individus à l'aide de modèle Word2Vec. 
Moyenne des vecteurs dans l'espace des features des différents mots/token de la description.
Moyenne pondérées des vecteurs dans l'espace des features des différents mots/token de la description en fonction de l'occurence de chacun de ces mots/tokens dans la description.
Moyenne pondérées par des poids calculés à l'aide du TF-IDF.
etc...
C'est la seconde solution qui sera utilisée ici. 
Les fonctions détaillées ci-dessous permettent de :
get_features_mean : retourne le vecteur moyen dans l'espace d'embedding, des projections des mots/tokens composant lines
get_matrix_features_means : applique la fonction get_features_mean sur tous les éléments de la matrice X.
End of explanation
ts = time.time()
X_embedded_train_cbow = get_matrix_features_means(train_array_token, model_cbow, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_train_cbow.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_train_cbow", X_embedded_train_cbow)
ts = time.time()
X_embedded_valid_cbow = get_matrix_features_means(valid_array_token, model_cbow, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_valid_cbow.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_valid_cbow", X_embedded_valid_cbow)
Explanation: Cbow
End of explanation
ts = time.time()
X_embedded_train_sg = get_matrix_features_means(train_array_token, model_sg, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_train_sg.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_train_sg", X_embedded_train_sg)
ts = time.time()
X_embedded_valid_sg = get_matrix_features_means(valid_array_token, model_sg, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_valid_sg.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_valid_sg", X_embedded_valid_sg)
Explanation: Skip-Gram
End of explanation
data_valid_clean = pd.read_csv("data/cdiscount_valid_clean.csv").fillna("")
data_train_clean = pd.read_csv("data/cdiscount_train_clean.csv").fillna("")
train_array_token_nostem = [line.split(" ") for line in data_train_clean["Description"].values]
valid_array_token_nostem = [line.split(" ") for line in data_valid_clean["Description"].values]
ts = time.time()
X_embedded_train_online = get_matrix_features_means(train_array_token_nostem, model_online, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_train_online.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_train_online", X_embedded_train_online)
ts = time.time()
X_embedded_valid_online = get_matrix_features_means(valid_array_token_nostem, model_online, Features_dimension)
te = time.time()
t_build = te-ts
#np.save(embedded_train_dir, X_embedded_train)
print("Time conversion : %d seconds"%t_build)
print("Shape Matrix : (%d,%d)"%X_embedded_valid_online.shape)
np.save(DATA_OUTPUT_DIR +"/embedded_valid_online", X_embedded_valid_online)
Explanation: Online model
End of explanation
<END_TASK>