Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
site:enseignement:master:bdle:tmes:tme3-prise-main-spark [11/10/2017 11:58] amine [Manipulation de RDDs sous forme de paires clé-valeur] |
site:enseignement:master:bdle:tmes:tme3-prise-main-spark [15/10/2018 09:09] (Version actuelle) amine [Interrogation des données] |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | {{indexmenu_n>2}} | + | {{indexmenu_n>30}} |
- | ====== [TME II-2] MapReduce en Spark ====== | + | ====== [TME II-1] Introduction à Spark (Algèbre RDD) ====== |
- | Pour l'aide sur l'utilisation de Spark voir [[spark|ici]] | + | **Remarque générale :** Le cours ne peut être //self-contained// --> consulter la documentation en ligne de [[https://spark.apache.org/docs/2.1.1/api/scala/index.html#package|Spark]]. |
+ | Pour l'aide sur l'utilisation de Spark voir [[spark|ici]] | ||
===== Exercice 1 ===== | ===== Exercice 1 ===== | ||
- | //Cet exercice est la suite de l'exercice 2 du TME précédent.// | ||
+ | Copier le fichier | ||
+ | <code> /Infos/bd/spark/bdle/2015/data/wordcount.txt.bz2</code> sur votre espace personnel. | ||
Lancer le spark-shell en mode local ([[spark|voir Doc]]) en suivant les instructions fournies | Lancer le spark-shell en mode local ([[spark|voir Doc]]) en suivant les instructions fournies | ||
puis charger le fichier | puis charger le fichier | ||
Ligne 24: | Ligne 26: | ||
- Grouper les paires par ‘mot’ et additionner leur nombre nb. | - Grouper les paires par ‘mot’ et additionner leur nombre nb. | ||
- Reprendre les questions 3 et 4 en calculant ‘mot’ différemment : désormais, ‘mot’ doit correspondre au préfixe du premier sous-élément de chaque élément de list, çad, pour en.d, mot doit être en, pour fr.d, mot doit être fr, etc. Comparer les résultats avec ceux obtenus précédemment. | - Reprendre les questions 3 et 4 en calculant ‘mot’ différemment : désormais, ‘mot’ doit correspondre au préfixe du premier sous-élément de chaque élément de list, çad, pour en.d, mot doit être en, pour fr.d, mot doit être fr, etc. Comparer les résultats avec ceux obtenus précédemment. | ||
- | **Remarque** pour partitionner une chaîne de caractères en utilisant le point (.) comme délimiteur à l'aide de la méthode split(), il faut protéger le point avec \, i.e split("\.") | + | **Remarque** pour partitionner une chaîne de caractères en utilisant le point (.) comme délimiteur à l'aide de la méthode split(), il faut protéger le point avec \, i.e split("\\.") |
Ligne 82: | Ligne 84: | ||
* films (MovieID, Title, Genres) | * films (MovieID, Title, Genres) | ||
- | === Structure de donnée : Dataset=== | + | |
- | Pour le TME sur les Dataset, récupérer le fichier suivant: | + | |
- | <code bash> | + | |
- | cp /Infos/bd/spark/tme-dataset-etudiant.scala <votre repertoire de travail> | + | |
- | emacs tme-dataset-etudiant.scala & | + | |
- | </code> | + | |
Ligne 104: | Ligne 101: | ||
Par exemple, pour le nuplet (1,Toy Story (1995),Animation|Children's|Comedy) de films, il existe trois nuplets dans films_bis : (1,Toy Story (1995),Animation), (1,Toy Story (1995), Children's) et (1,Toy Story (1995), Comedy). | Par exemple, pour le nuplet (1,Toy Story (1995),Animation|Children's|Comedy) de films, il existe trois nuplets dans films_bis : (1,Toy Story (1995),Animation), (1,Toy Story (1995), Children's) et (1,Toy Story (1995), Comedy). | ||
Indice: pour construire films_bis, il est possible d’imbriquer une fonction map à l’intérieur d’une autre (cf. question 2 de l’exercice 3). | Indice: pour construire films_bis, il est possible d’imbriquer une fonction map à l’intérieur d’une autre (cf. question 2 de l’exercice 3). | ||
+ | |||
+ | |||
+ | <showif isloggedin> | ||
+ | **Réponse** | ||
+ | <code scala> | ||
+ | //a. le nombre de notes (ratings) réalisées par chaque utilisateur identifié par son UserID | ||
+ | val q2a = notes.map{case(userId,movieId,rating,ts)=>(userId,1)}.reduceByKey(_+_) | ||
+ | |||
+ | //b. le nombre de notes (ratings) réalisées par chaque localisation donnée par le Zip-code | ||
+ | val q2b = utilis.map{case(userId,gender,age,occup,zipcode)=>(userId,zipcode)} join(notes.map{case(userId,movieId,rating,ts)=>(userId,1)}) map{case (userId,(zipcode, nb))=>(zipcode, 1)} reduceByKey(_+_) | ||
+ | |||
+ | |||
+ | //c. le nombre de notes (ratings) réalisées par chaque genre de film | ||
+ | //jointure en notes et films | ||
+ | val q2c = notes.map(x=>(x(1),1)).join(films.map(x=>(x(0),x(2)))).map{case (movieID, (genre,nb))=>(genre, 1)}.reduceByKey(_+_) | ||
+ | |||
+ | |||
+ | //d. les 10 utilisateurs ayant noté le plus de films. | ||
+ | val q2d = notes.map(x=>(x(0),1)).reduceByKey(_+_).takeOrdered(10) | ||
+ | |||
+ | //e. Les films ayant reçu le moins de notes | ||
+ | //f. Les utilisateurs n’ayant noté aucun film | ||
+ | |||
+ | |||
+ | |||
+ | //genre de films | ||
+ | val films_bis = films.map(x=>(x._1,x._2,x._3.split("\\|"))).flatMap{case(a,b,l)=>l.map(x=>(a,b,x))} | ||
+ | |||
+ | </code> | ||
+ | </showif> | ||
+ | |||
+ | |||
+ | === Exercice Subsidiaire : reprendre les questions précédentes en utilisant l'API Dataset === | ||
+ | Pour utiliser les Dataset, récupérer le fichier suivant: | ||
+ | <code bash> | ||
+ | cp /Infos/bd/spark/tme-dataset-etudiant.scala <votre repertoire de travail> | ||
+ | emacs tme-dataset-etudiant.scala & | ||
+ | </code> | ||