J-9 Text mining avec SPARK (1/2)

Dans ce billet je voudrais vous présenter un cas d’usage typique de SPARK: Le « Text Mining ». Nous nous trouvons face à un Corps de documents et il faut que nous puisons reconnaitre des mots clés par article et par sujet. Ce billet fait partie d’une série des exercices courtes (1h) destinés à l’apprentissage de SPARK nommés A la conquête de SPARK sur AZURE.

Parcours du Combattant:

  1. WordCount
  2. Recherche bête des termes les plus courantes par article
  3. Recherche un peu moins bête de termes les plus courantes par article avec TF-IDF

Boite à outil du combattant:

  1. Abonnement Azure ou la Version d’essai Gratuite (avec 170€)
  2. 1H de libre devant vous
  3. Avoir déployé un Cluster SPARK avoir téléchargé ce-fichier dans un Blob Storage Azure dans la compte de stockage du Cluster (voir ce billet)

1.WordCount avec flatMap

Un petit exemple pour chauffer les doigts et exemplifier l’usage de flatMap

[pastacode lang= »ruby » message= »Simle word count avec flatMap » highlight= »4,5,6″ provider= »manual »]

val url = "wasb://yourContainer@yourAccount.blob.core.windows.net/wiki.txt" val art = sqlContext.jsonFile(url) val UneLigneParMot = art.flatMap(ligne => ligne.getString(0).split("\\W")) val CountWords = UneLigneParMot.map(word => (word, 1)).reduceByKey((a,b)=>a+b) val SortByCount = CountWords.map(pair => (pair._2, pair._1)).sortByKey(false) SortByCount.take(10) /** res11: Array[(Int, String)] = Array((6306524,""), (366569,de), (175339,la), (170986,d), (142089,l), (140075,et), (131867,le), (106881,en), (104522,des), (98043,s)) */

[/pastacode]

Les clés du code

  • (ligne 4) Contrairement à « map », qui retourne un élément par input, flatMap retourne entre 0 et N en utilisant une fonction anonyme qui retourne un Enumerable. Donc on passe d’une ligne par article à une ligne par article et mot.
  • (ligne 5) Utilisation de reduceByKey pour sommer la quantité d’occurrences par mot parmi tous les articles. On utilise le constructeur des pairs.
  • (ligne 6) Utilisation de sorByKey pour trier par valeur. Notez qu’il a fallu une opération map pour inverser les paires (mot, occurrences) en (occurrences, mot), car la fonction sortByValue n’existe pas.

Un peu déçus non? On a trouvé quels dont les prépositions les plus courantes de la langue Française!! Il ne faut pas désespérer et plutôt continuer la lecture 🙂

2. Recherche bête des termes les plus courantes par article

Vu le titre, ce n’est pas encore le temps du Super Data Science! Encore un peu de patience on va y arriver! Cette étape est plutôt pour apprendre les bases de Scala.

Dans l’exemple ci-dessous je vous présente un morceau du code qui va calculer les termes le plus courantes par article. Dans ce cas j’ai choisi de produire un RDD avec un ligne par article et dans chaque ligne un Pair avec le titre de l’article et une Table Hash (artisanal) où on va calculer les occurrences des mots dans l’article.

Code

Et voici les clés du code:

  • (lignes 1-2) Syntaxe pour importer de namespaces scala
  • (ligne 7) Définition de la classe « WordCount » qui va nous permettre de stocker pour chaque mot, le nombre d’occurrences et le nombre des articles où le mot est présent.
  • (ligne 9) Définition de la fonction « WordCount ». Notez l’utilisation du mot clé « def » utilisé dans scala pour la définition des fonctions. WordCount reçoit comme paramètre une ligne du RDD Json et retourne un (String, Array[LinkedList[WordCount]]). Ceci est un Pair de String pour le titre de l’article et un Array qui contient un objet du type WordCount par mot dans l’article. La position d’un mot dans l’Array est donné par son HashCode modulo la taille de l’Array et pour éviter les collisions, l’Array (Immutable) contient une LinkedList (mutable car peux changer de taille) des mots.
  • (ligne 13) Je souligne cette ligne pour présenter le boucle for dans scala, qui va itérer pour chaque mot dans l’article.
  • (ligne 14) Deux choses à remarquer ici. En premier l’utilisation du mot clé « var » à la place de « val » pour définir une variable. La différence entre les deux est que seulement les variables « var » peuvent être réassignes a une nouvelle valeur. Et deuxième cette ligne calcule la position du mot courante dans l’Array.
  • (ligne 24) Cette ligne va augmenter en 1 le « wordCount » du mot s’il se trouve déjà dans l’Array)
  • (ligne 30) Instruction de renvoi de la fonction. Noter que la sentence « return » n’est pas nécessaire.
  • (ligne 33) Définition de la fonction TopCount, qui retourne un Array de WordCount avec les N mots les plus fréquents de l’article.

[pastacode lang= »java » message= »Résultat des mots les plus fréquents » highlight= » » provider= »manual »]

res131: Array[(String, List[WordCount])] = Array( (Antoine Meillet,List(WordCount(,1328,1), WordCount(de,73,1), WordCount(d,33,1), WordCount(l,31,1), WordCount(la,29,1), WordCount(e,20,1), WordCount(et,20,1), WordCount(des,20,1), WordCount(meillet,17,1), WordCount(le,16,1))) , (Algèbre linéaire,List(WordCount(,1336,1), WordCount(de,119,1), WordCount(d,86,1), WordCount(des,61,1), WordCount(la,46,1), WordCount(un,45,1), WordCount(l,41,1), WordCount(les,41,1), WordCount(s,39,1), WordCount(est,37,1))) , (Algèbre générale,List(WordCount(,302,1), WordCount(alg,19,1), WordCount(bre,15,1), WordCount(de,10,1), WordCount(math,8,1), WordCount(des,8,1), WordCount(et,7,1), WordCount(matiques,7,1), WordCount(l,6,1), WordCount(alg,6,1))) , (Algorithmique,List(WordCount(,1769,1), WordCount(de,164,1), WordC

[/pastacode]

Encore un peu déçu du résultât? Espérons donc que l’étape suivante soit plus réconfortante 🙂

3. Recherche un peu moins bête de termes les plus courantes par article avec TF-IDF

On va améliorer notre code pour utiliser l’algorithme  TF-IDF (Term frequency, inverse document frequency). Je vous invite à lire le lien pour une explication détaillé de l’algorithme, mais l’idée de base est que dans chaque article, le poids de chaque mot va être réduit pour les termes populaires par pondération.

[pastacode lang= »ruby » path_id= »2015/09/tf-idf1.txt » highlight= » » lines= » » provider= »file »/]

et les résultats commencent à ressembles à quelque chose inintéressante:

blog ai3 TFIDF J-9 Text mining avec SPARK (1/2)

 

2 thoughts on “J-9 Text mining avec SPARK (1/2)

  1. Pingback: J-4 Text mining avec SPARK (2/2) | Le blog Ai3Le blog Ai3

  2. Pingback: A la conquête de SPARK sur AZURE | Le blog Ai3Le blog Ai3

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.