Transcription
1. Introduction: Et j'ai passé plus de neuf ans chez Amazon.com et IMDB.com à comprendre leurs ensembles de données massifs. Et je veux vous apprendre sur la technologie la plus puissante
que je connaisse pour lutter contre le Big Data dans le Cloud aujourd'hui. C' est Apache Spark, utilisant le langage de programmation Scala étincelle et exécuter dans cluster
Hadoop pour répandre des tâches massives d'analyse de données et d'apprentissage automatique dans le Cloud. Et savoir comment le faire est une compétence très chaude à avoir en ce moment, nous allons commencer par un cours de crash dans le langage de programmation Scala. Ne vous inquiétez pas, c'est assez facile à ramasser tant que vous avez déjà fait de la programmation ou des scripts. Nous commencerons par quelques exemples simples, mais nous passerons à des exemples plus complexes et intéressants en utilisant de vrais jeux de données massifs. À la fin de ce cours, vous aurez mis en pratique plus de 15 exemples réels. Et vous serez à l'aise avec l'écriture, débogage et l'exécution de vos propres applications Spark à l'aide de Scala. Et certains d'entre eux sont assez amusants. Nous allons regarder un réseau social de super-héros et utiliser ces données pour déterminer qui est le Kevin Bacon de l'univers des super-héros. Nous allons également examiner un million d'évaluations de films provenant de personnes réelles et construire un moteur de recommandation de film réel qui fonctionne sur un cluster Spark dans le Cloud à l'aide du service Elastic MapReduce d'Amazon. Nous allons également faire de grandes tâches d'apprentissage automatique en utilisant la bibliothèque Sparks ML Lib. Et nous allons faire une analyse graphique en utilisant la bibliothèque Spark GraphX. Alors essaye-le avec moi. Je pense que vous serez surpris de voir comment quelques lignes de code peuvent lancer un travail d'analyse de données complexe massif sur un cluster utilisant Spark. Alors commençons. La première chose que nous devons faire est d'installer le logiciel dont nous avons besoin. Alors sortons ça du chemin maintenant.
2. Installer les matériaux du cours: Donc, nous allons tout mettre en place, y compris Java et intelligence et tout le matériel de cours dont nous avons besoin pour tout le cours. Ce que nous allons faire, c'est commencer par aller sur notre propre site Web ici, qui vous dirigera vers le matériel de cours où vous pouvez télécharger tous les fichiers de projet et les données dont vous avez besoin pour ce cours. Nous allons aller de l'avant et installer ça dans votre système. Ensuite, nous allons installer un kit de développement Java si vous n'en avez pas déjà un, nous avons juste besoin de nous assurer que nous avons un JDK entre les versions 8 et 14 installé sur votre système. Les chances sont que si vous êtes un développeur, vous le faites déjà. Après cela, nous allons installer l'IntelliJ idea Community Edition. C' est un environnement de développement libre qui peut, nous pouvons utiliser pour Scala et pour Spark. Et la beauté de celui-ci est qu'il intègre aussi quelque chose appelé sbt. Donc obtenu une poignée tout le sale travail d'
installation réellement Apache Spark pour nous sur Windows, nous avons une étape supplémentaire. On a besoin de simuler les fenêtres pour penser qu'il fonctionne Hadoop et je vais vous montrer comment faire ça. Ce n'est pas trop dur. Et enfin, nous allons mettre en place notre projet de renseignement. Exécutez un petit problème helloworld simple dans Apache Spark. Assurez-vous que tout fonctionne. Plongons dedans et je vous guènerai à travers tout ça. Commençons donc par mettre en place tout ce dont vous avez besoin pour ce cours. tête sur les médias Dotson chien, un tiret soft.com slash Spark scala point HTML. Faites attention à la capitalisation et chaque petite lettre compte. Et vous devriez atteindre cette page ici qui contient tout ce dont vous avez besoin pour aller de l'avant. Mais surtout, installons le matériel du cours, tous les scripts dont vous avez besoin pour passer à travers ce cours pratique. Allez-y et cliquez sur ce lien ici pour le tableau de bord de chien Dotson immédiat, soft.com slash Spark Scala slash Spark Scala course dot zip. Si vous tapez cela à la main pour une raison quelconque, assurez-vous de faire attention à la capitalisation. Une fois que cela télécharge. On va aller de l'avant et on va le décompresser. Et sur Windows, je peux juste aller de l'avant et cliquer avec le bouton droit de la souris et dire extraire tout. Sur un Mac ou Linux, bien sûr, vous allez simplement à une invite de terminal et utilisez la commande unzip. Et nous devrions obtenir est un dossier de cours Scala étincelle
dans un dossier de cours Scala étincelle, C'est correct. C' est ce qu'on veut. Et dans ce deuxième niveau de dossier est tous les matériaux lui-même, tout le projet pour ce cours. Donc, tout d'abord, déplaçons ça un endroit où on ne va pas le perdre. Donc je prends ce dossier de cours de
gala étincelles de haut niveau et je vais le déplacer dans un endroit sûr. Mettons-le sur mon disque C. Bon, donc maintenant dans mon lecteur C j'ai un dossier de cours Spark Scala. Et à l'intérieur il y a un autre dossier de cours de gala étincelles. Et sur Mac ou Linux, bien sûr, vous n'auriez pas de répertoire C. Tu le mettrais dans ton répertoire personnel, juste un endroit où tu ne vas pas le perdre. D' accord, alors nous devons obtenir des données de test ici. Et malheureusement, les termes de licence des données que j'aime utiliser ne me permettent pas de les inclure moi-même. Donc tu vas devoir aller le télécharger toi-même. C' est le jeu de données MovieLens ici. Pour mettre en place un 100 mille évaluations de films que nous allons utiliser pour jouer tout au long de ce cours. Donc, vous pouvez utiliser ce lien dandy pratique pour obtenir des fichiers doc Grouplens.org slash données slash slash slash MovieLens slash ML dash 100, k dot zip. Allez-y et téléchargez ça. Et si, pour une raison quelconque, le site Grouplens.org est en panne, cela arrive de temps en temps. Vous pouvez généralement trouver le fichier M L dash 100 K sur Kaggle si vous en avez besoin. Allons de l'avant et décompresser cela aussi. Cliquez avec le bouton droit sur Tout Encore une fois, utilisez simplement la commande unzip sur Mac ou Linux. Et le dossier MLH1 100 K résultant devrait contenir ce genre de choses. On va prendre ce niveau ici et on va copier ça. Et je vais revenir à mon dossier de matériaux de cours que je viens de créer, qui pour moi a été voir étincelles cours Scala. Et dans le répertoire des autres cours de gala Sparks sous cela il y a un dossier de données. Allez dans le dossier Data et c'est là que je veux mettre mon dossier AML dash 100 K. Très bien, donc c'est comme ça que les choses devraient regarder à ce point, vous
soyez quel que soit le système d'exploitation sur lequel vous êtes, vous voulez un dossier de cours Scala Spark. Dans ce cas, il devrait y avoir un autre dossier de cours Spark Scala. Dans cela devrait être un dossier de données. Et dans cela devrait être un dossier ML tiret 100 K. Et à l'intérieur de cela devrait être toutes ces données de test. Ok, alors assure-toi que tout va bien, sinon tu vas
rencontrer des problèmes bizarres et tu ne sauras pas ce qui se passe. Une fois que vous êtes sûr que c'est bon, revenons à nos instructions ici. L' étape suivante consiste à installer IntelliJ a, qui va être notre IDE pour le développement dans ce cours. Maintenant, j'avais l'habitude de dire aux gens d'installer Eclipse et l'IDE Scala, mais il semble que intelligent gagne la bataille qu'ils sont contre l'éclipse. Donc je vais vous demander d'installer IntelliJ J maintenant à la place. Maintenant, afin d'exécuter du code Scala, vous avez d'abord besoin d'un JDK et tout ce qui se passe entre l'aide des versions et 14 que nous ferons pour ce cours. Mais si vous avez besoin d'un JDK, il y a un lien pratique ici pour le faire. Vous pouvez simplement aller sur Oracle.com barre oblique Java et aller de l'avant et accéder au téléchargement JDK 14 pour votre système d'exploitation. Pour moi, ce sera Windows 64. Vous devrez accepter leurs termes. Et attendez que ça se télécharge. On dirait qu'il y a un petit avertissement de sécurité ici. C'est bon. Je lui fais confiance. Et nous allons que ça descend. On va aller de l'avant et l'installer. Évidemment sur Linux ou Mac que vous utiliserez probablement un autre moyen d'obtenir Java. En fait, vous avez probablement déjà installé Java si vous êtes sur Linux ou Mac. Donc c'est probablement quelqu'un de cette chose spécifique. On va aller de l'avant et passer par l'installateur ici. Et une chose sur Windows est que lorsque vous exécutez du code Linux comme Apache Spark sur Windows, parfois cela devient confus lorsque vous avez des espaces dans votre chemin. Donc, cet espace entre le programme et les fichiers pourrait en fait être un problème. Allons de l'avant et changeons ça juste pour être en sécurité. Et je vais le dire à la place dans un répertoire JDK 14 points C. Eh bien, laissez ça faire son truc. Ça ne devrait pas prendre trop longtemps. Et on a fini. D' accord, on en a fini avec ce site, à nos instructions. Donc maintenant, nous pouvons installer l'IntelliJ idea Community Edition. Ça va être notre véritable carte d'identité. Allons de l'avant et cliquez sur ce lien. Et nous voulons l'édition communautaire, la libre, l'open source. On n'a pas besoin de l'ultime. Alors allez-y et téléchargez-le pour quel que soit votre système d'exploitation. Vous voyez l'offre que pour Windows, Mac et Linux. Et c'est environ un demi-concert. Et nous prendrons quelques secondes pour descendre. Reviens quand ce sera fait. Bon, l'installateur a téléchargé et allons de l'avant et le coup d'envoi. Et un installateur assez standard ici. Allons de l'avant et marchons à travers. Et si vous voulez des raccourcis de bureau ou en tant qu'associations de fichiers, vous pouvez le faire totalement à vous de décider. Je vais juste les laisser tels quels. Et c'est très bien aussi. prend environ une minute à installer, donc je reviendrai quand c'est fait. D'accord, bien bien bien. Allons de l'avant et appuyez sur le bouton Exécuter pour réellement le lancer. Je ne veux pas importer de paramètres existants. Et la préférence personnelle, si vous aimez un thème sombre ou un thème léger, j'aime un thème léger. Alors je vais choisir ça, faire ce que tu veux. Et maintenant, nous allons installer des plugins. Peut-être que le seul plugin dont nous avons vraiment besoin est le plugin Scala. Et malheureusement, je ne vois pas ça offert ici, alors je vais juste passer à autre chose. Je ne vois pas ça offert ici non plus. Donc, si vous voyez le plug-in Scala cependant, allez-y et profitez-en pour l'installer. Mais je ne l'ai pas fait. J' ai donc à voir avec la voie dure, ce qui n'est pas si difficile. Je vais juste cliquer sur le bouton Configurer ici à partir de l'écran d'accueil et sélectionner Plugins. Et à partir de là, je peux trouver le plugin Scala. Allons de l'avant et installons ça. Très bien. D'accord, et on peut redémarrer l'IDE pour le récupérer. Et maintenant une chose de plus que nous devons lui dire quel JDK utiliser. Revenez donc au menu de configuration ici et allez à la structure pour les nouveaux projets. Et si vous avez besoin de sélectionner un JDK ici, sélectionnez celui que nous venons d'installer, ce sera 14 pour nous et appuyez sur OK. Maintenant, il y a une étape de plus que nous devons faire, c'est seulement pour Windows. Donc, si vous êtes sur Mac ou Linux, vous pouvez, vous pouvez ignorer cette étape suivante, nous devons sorte de tromper les fenêtres en pensant que Hadoop est en cours d'exécution dessus. Et pour faire ça, c'est un peu maladroit. Les instructions se trouvent dans votre page de matériel de cours ici sous la section Windows uniquement ici, il suffit de suivre ses instructions. Allez-y et créez un répertoire bin Hadoop C. Alors je vais aller à mon lecteur C. Je vais créer un nouveau dossier appelé Hadoop. Et dans ce dossier Hadoop, je vais créer un autre dossier appelé bin. Maintenant, je vais retourner à mon matériel de cours, qui est sous le cours de gala étincelles. Et vous verrez un fichier When utils dot EXE là. Je vais aller de l'avant et le copier et le coller dans C. Hadoop été. Ensuite, j'ai besoin de configurer quelques variables d'environnement. Donc, la façon la plus simple de le faire est d'aller dans
votre barre de recherche Windows ici et de taper des variables d'environnement. Juste ENV est probablement suffisant. Et sélectionnez éditer les variables d'environnement système qui vous mènera au panneau de configuration système. À partir de là, vous pouvez appuyer sur le bouton des variables d'environnement. Et nous allons en créer un nouveau appelé Hadoop souligner la maison tous les casquettes. Et la valeur sera la barre oblique inverse C deux-points, Hadoop. Nous devons également éditer notre variable d'environnement de chemin. Si vous n'en avez pas, vous pouvez en faire un, mais vous en avez probablement déjà un. Donc, je vais juste éditer celui que j'ai un ajouter un chemin supplémentaire à elle en
double-cliquant ici et en tapant le signe de pourcentage,
Hadoop soulignent le signe de pourcentage de la maison, C'est la barre oblique bin. Appuyez sur OK et OK à nouveau et OK à nouveau. Bon, donc maintenant nous sommes prêts, prêts à essayer d' importer le projet pour le cours lui-même. Retournons à IntelliJ. Maintenant, avant de charger ce projet, c'est toujours une bonne idée de redémarrer vos applications après avoir modifié les variables d'environnement. Donc, si vous êtes sur Windows, allez-y et fermez l'idée IntelliJ et redémarré. Il devrait être dans votre menu de démarrage. Et maintenant, nous allons cliquer sur Ouvrir ou Importer. Et nous voulons naviguer vers le dossier Matériel de cours, le cours
Spark Scala et le dossier de cours Spark Scala à l'intérieur de
cela, c'est notre projet réel pour le cours lui-même. Frappez OK. Et laissez-le faire son truc. Cela va automatiquement essayer de trouver un sens à partir de ce qui est dans ce dossier. Je ne veux pas de pourboires. Et si nous avons de la chance, tout fonctionnera. D' accord. Voir quelque chose de trop alarmant, frappons l'icône de construction juste pour vous assurer qu'il a construit avec succès. C' est cette petite icône de marteau ici. Vous le trouverez également dans le menu Construire si vous préférez. Et on dirait que ça a marché. Alors donnons-lui un coup de feu. Allons de l'avant et ouvrons le dossier de cours Spark Scala ici pour le projet, puis ouvrons le dossier source. Et sous cette ouverture principale, puis Scala et com dot Sun dot logiciel point étincelle. Ce sont tous les scripts du cours ici. Donc tout ce qu'on a à faire, c'est en choisir un et voir si ça marche. J' ai inclus un script helloworld très simple. Donc, double-cliquez sur ça. Et vous pouvez voir ici que cela ne fait pas beaucoup, mais il utilise en fait Apache Spark. Donc, il va effectivement vérifier que vous avez tout configuré correctement et configurer la bonne façon ici. Il va juste mettre en place un SparkContext et charger le fichier de données dans notre jeu de données MovieLens que nous avons installé plus tôt. Donc, cela vous assurera également que vous avez cela au bon endroit aussi. Tout ce qu'il va faire est de faire tourner un travail Apache Spark pour compter le nombre de lignes dans ce fichier. Donc, une façon très compliquée de le faire, mais cela vérifiera que cela fonctionne. Et quand ce sera fait, il imprimera Hello World. Le fichier de données a espérons-le, 100 mille lignes car c'est le jeu de données 100 mille. Alors voyons si ça marche. Faites un clic droit sur HelloWorld et dites « run hello-world ». Et à ce stade, il y a une très bonne chance que vous allez
obtenir une erreur de classe non trouvée si vous le faites, c'est juste un bug et de l'intelligence. Si vous quittez intelligent et que vous le relancez, il devrait l'éclaircir. Et ça devrait déclencher Spark. Vous verrez que quelques avertissements sont sûrs d'ignorer cependant. Et maintenant, c'est en cours d'exécution et ça a fonctionné. Donc là, vous l'avez. Helloworld, le fichier de données a 100 mille lignes. Donc, si vous voyez cela, félicitations, vous configurez Spark et Scala et l'intelligence en Java tous avec succès. Et tout fonctionne. Et maintenant, tout ce que nous avons à faire est de parcourir tous les autres scripts tout au long du cours et de parler de ce qu'ils font et apprennent en cours de route. Si vous n'avez pas vu cette sortie cependant, retournez en arrière, vous avez probablement manqué quelques petits endroits quelque part. Il y a toujours une petite chose et n'hésitez pas à poster dans le Q et un ou des commentaires de ce cours pour obtenir de l'aide si vous en avez besoin. Mais j'espère que cela fonctionnera pour vous et que nous pourrons aller de l'avant et commencer à apprendre.
3. Introduction à Apache Spark: Laissez-moi vous présenter Apache Spark à un niveau élevé et parler de son fonctionnement et de ce que c'est pour vraiment rapide. Donc, la description officielle de Spark est que c'est un moteur rapide et général pour le traitement des données à grande échelle. Et bien, c'est une très bonne description. Fondamentalement, l'idée est que vous pouvez écrire un script très simple potentiellement qui décrit comment vous voulez transformer une énorme quantité de données ou analyser une énorme quantité de données et scintiller
comprendre comment distribuer ce travail sur un ensemble cluster d'ordinateurs pour vous. C' est donc un moteur pour comprendre comment paralléliser le traitement de vos données. Tu peux toujours lui dire ce que tu veux. Tu le sais ? Est-ce que je veux prendre un tas de fichiers journaux et extraire quelques informations et le mettre ailleurs. Très bien. Spark va trouver comment le faire dans l'ensemble de
votre cluster et faire en sorte que cela se produise le plus rapidement
possible en utilisant les ressources de dizaines ou même des centaines de machines individuelles pour le faire. Donc, la clé à cela est son évolutivité. Donc encore une fois, vous écrivez juste un seul programme de pilote, nous l'appelons. C' est tout aussi simple script écrit en Scala ou Python ou Java. Cela indique à Spark ce que vous voulez faire à vos données. C' est alors le problème Sparks de comprendre comment paralléliser cela et le faire évoluer presque toute une flotte d'ordinateurs. Donc, l'aperçu clé ici est que vous n'êtes pas limité à la puissance de calcul d'une machine ici avec Apache Spark, vous pouvez prendre un, un jeu de données massif que vous ne pouviez pas espérer traiter sur un seul PC et réellement distribuer ce traitement sur toute une flotte d' ordinateurs en parallèle en même temps. Ce genre d'approche diviser et conquérir est la façon dont nous pouvons traiter ensembles de données
massifs et gérer ce que nous appelons le Big Data. Du point de vue de l'architecture, votre programme pilote est juste quelque chose que vous écrivez. Comme je l'ai dit, c'est un script différent, potentiellement très simple. Et ça est remis à un gestionnaire de cluster d'un magasin. Vous avez besoin d'une sorte de système qui orchestre l'ensemble de votre cluster d'ordinateurs. Et cela pourrait être un cluster Hadoop, auquel
cas le gestionnaire de cluster de fils de Hadoop serait entrer en jeu là. Et cela va être inquiétant de savoir comment déployer les ressources dont vous avez besoin, comment distribuer ce travail et où placer
les différents emplois à l'endroit le plus optimal. Pense à des choses comme comment puis-je exécuter le code à l'endroit où les données sont les plus accessibles ? Donc, si mes données, par exemple, sont divisées sur un système de fichiers distribué, le gestionnaire de cluster pourrait dire, ok, je vais exécuter les données
qui traitent ce morceau des données sur cette même machine pour le faire fonctionner même plus vite. Cependant, vous n'avez pas besoin d'utiliser Hadoop. Spark dispose également de son propre gestionnaire de cluster intégré. Donc, si vous voulez simplement exécuter Spark dans un environnement autonome, vous pouvez le faire pour installer Spark et toutes les machines de votre cluster et le configurer correctement. Et il va juste fonctionner afin Spark et courir sur son propre. Il n'a pas nécessairement besoin de fonctionner au-dessus de Hadoop, bien qu'il puisse le faire. Parfois, vous voudrez exécuter d'autres applications Hadoop sur le même cluster et définir des pipelines d'opérations plus complexes. Donc, il peut y avoir des avantages à courir sur Hadoop, mais vous n'avez pas à le faire. Donc, une machine individuelle, il y a différents nœuds que nous les appelons. Et ceux-ci seront en cours d'exécution différents exécuteurs. Et chaque processus exécutif qui peut être distribué dans l'ensemble de votre cluster a son propre cache et il a sa propre tâche qui essaie de fonctionner sur vos données. Et vous pouvez voir avec toutes les flèches ici que presque tout se parle l'un à l'autre. Votre programme pilote envoie des commandes
au gestionnaire de cluster et aussi directement aux exécuteurs si nécessaire. Et les exécuteurs se parlent les uns aux autres et se synchronisent entre eux. Et bien sûr, un gestionnaire de cluster parle aussi à tous ces processus exécuteurs, essayant d'orchestrer. Ce qui est exécuté où et ensuite entrer en collision ces résultats ensemble pour obtenir voir votre résultat final quand tout est fait. C' est donc l'architecture sparc à un niveau très élevé. Pourquoi Spark est-il si populaire ? Eh bien, Spark est à peu près remplacé. Hadoop MapReduce car il peut être jusqu'à 100 fois plus rapide s'il est basé sur l'exécution en mémoire. Donc, si vous avez assez de mémoire dans votre cluster, c'est une approximation réaliste. Si vous lisez des données directement à partir du disque, cela sera encore environ 10 fois plus rapide. Pourquoi est-ce beaucoup plus rapide que MapReduce ? Eh bien, c'est à cause de ce qu'on appelle un moteur graphique acyclique dirigé ou un moteur DAG. Fondamentalement, il va regarder le flux de travail que vous avez décrit dans votre script de pilote et il l'optimisera automatiquement pour vous. En revanche, dans MapReduce, vous êtes un peu coincé dans une seule façon de penser au traitement des données. Vous devez mapper explicitement toutes vos données en parallèle ,
puis définir un moyen de réduire ces données en réponse finale. Avec le moteur DAG cependant, peut être un peu plus flexible. Il peut organiser ce flux de travail d'
une manière plus complexe et potentiellement plus optimale. Et parce que Spark est basé sur la mémoire, cela lui donne également un énorme avantage. C' est donc rapide et très facile à utiliser. Il fait aussi chaud, c'est un très largement utilisé. C' est en fait une très ancienne liste de personnes utilisant Spark et il y a beaucoup, beaucoup, beaucoup, beaucoup plus de gens qui l'utilisent maintenant. Mais le but de cette diapositive est juste de vous montrer que c'est une technologie éprouvée. Il est utilisé par de très grandes sociétés. C' est une technologie très mature. Il est sorti depuis un moment. Vous savez, les nouvelles fonctionnalités de Spark ou un peu ralentir, moins dans le monde open source. Et c'est bon parce qu'il fait à peu près tout ce que vous devez faire et il le fait de manière assez fiable à ce stade. Donc, pour le traitement des données distribuées, Spark est une technologie mature et elle est très largement adoptée. Ce n'est pas aussi dur. Vous avez donc le choix d'écrire votre code en Python ou Java ou Scala. Évidemment, dans ce cours, nous allons nous concentrer sur Scala et nous allons parler de pourquoi dans un instant. Mais c'est facile à utiliser si vous connaissez SQL Structured Query Language, c'est le même langage
que vous utilisez pour interfacer avec n'importe quelle base de données relationnelle. Vous vous sentirez comme chez vous car Spark possède des fonctionnalités appelées jeux de données spark et Spark DataFrames qui fonctionnent de façon très similaire aux instructions SQL. Et vous pouvez même lui donner des commandes SQL directement via une fonctionnalité appelée Spark SQL. Donc, si vous connaissez SQL, vous pouvez utiliser Spark. C' est aussi facile que ça. Mais tout n'est pas un problème SQL. Toutes les analyses ou transformations de données ne peuvent pas être définies à l'aide d'une commande SQL. Et si vous voulez accéder à une API de niveau
inférieur, disponible pour l'API d'origine pour Spark, s'appelle Resilient Distributed Dataset ou RDD en bref. Nous allons approfondir beaucoup plus la façon dont cela fonctionne dans un instant ici. Mais avec l'API RDD, vous pouvez obtenir un niveau inférieur et parfois je peux vous donner encore de meilleures performances. Et cela vous donne également plus de flexibilité dans ce que vous pouvez faire. Mais pour la plupart des tâches courantes de transformation ou d'analyse de données, vous pouvez probablement définir cela comme une commande SQL. Et le plus souvent, vous utiliserez des jeux de données, des dataframes ou l'API SQL Spark. Du point de vue de l'architecture logicielle, c'est ainsi que Spark est aménagé, et cela remonte à l'architecture originale de Sparks. dernières années, les lignes sont floues sur quelques-unes d'entre elles. Mais à son cœur est, eh bien, Spark Core et c'est là que RDD vit dans le genre, n'est-ce pas ? Donc c'est un peu comme le moteur sous-jacent de Spark lui-même. Et vous pouvez aller directement à Spark Core. Eh bien, nous verrons ça en action. Mais il existe ces autres API de niveau supérieur construites sur Spark Core pour vous faciliter la vie pour des tâches spécifiques. Quand son Spark Streaming, c'est-à-dire,
c'est évidemment une technologie très puissante pour l'ingestion de données en temps réel ou quasi réel. Vous pouvez imaginer, par exemple, avoir une flotte de serveurs fonctionnant sur votre site Web qui
alimentent des données dans Spark via le streaming Spark à partir de leurs fichiers journaux en continu. Et en temps réel, Spark peut surveiller ces données, regarder une fenêtre de ces données au fil du temps, vous
fournir des analyses sur cette période et prendre des mesures en fonction de celles-ci. Exemple simple, disons que vous voulez avoir
une sorte d' alarme sur 500 erreurs sur votre site Web. Vous pouvez configurer un système de diffusion en continu Spark afin que les journaux soient diffusés dans Apache Spark. Et en temps réel, il compte combien de 500 erreurs il y a dans le passé, notre dernière minute, tout ce que vous voulez surveiller et prendre des mesures si cela dépasse un certain seuil. De toute évidence, des opérations beaucoup plus complexes sont également disponibles. Peut-être qu'une application plus courante
transformerait ces données de journal et les mettrait ailleurs. Donc, je pourrais avoir un processus de streaming Spark qui ingère des données de mes journaux, les transforme en un format que Elastic Search veut
peut-être voir ou quelque chose comme ça. Nous avons également Spark SQL et qui existent pour vous permettre d'intégrer avec les commandes
Spark SQL afin que vous puissiez traiter Spark comme une base de données géante distribuée dans la nature. Donc, si vous pouvez définir vos données en termes de structure de table, ce que vous pouvez généralement, et vous pouvez définir le problème que vous voulez résoudre en termes d'une commande SQL que vous pouvez probablement le faire. Vous pouvez simplement utiliser Spark SQL pour définir ce que vous voulez qu'il fasse. Et scintiller trouver comment paralléliser ça sur toute une flotte d'ordinateurs. Donc c'est vraiment excitant, non ? Il vous donne toute la flexibilité d'une base de données relationnelle. Mais vous n'êtes plus limité à une seule machine. Vous pouvez réellement mettre à l'échelle horizontale cette base de données. Maintenant, il fallait choisir entre des bases de données NoSQL si vous le souhaitez, informatique
distribuée et une grande base de données relationnelle monolithique si vous ne le faites pas. Et il y a encore quelques limites ici. Souvenez-vous de faire de grosses jointures ne sera toujours pas très efficace dans un environnement de serveur partitionné horizontalement. Mais vous pouvez le faire si vous voulez écrire. Donc c'est un peu le meilleur des deux mondes. Maintenant, comme je l'ai mentionné, les lignes sont floues dans certains cas ici. Donc, ces API plus modernes que nous allons examiner plus tard dans Spark
à l'aide de dataframes et de jeux de données. Ils sont également très similaires à SQL dans leur structure et la façon dont ils sont utilisés. Donc, vous savez, faites-vous cela, considérez-vous que les dataframes et les jeux de données font partie de Spark SQL ou Spark Core. Encore une fois, les lignes sont quelque peu floues là, mais les interfaces basées sur SQL deviennent un peu le moyen prédominant d'utiliser Spark. Nous avons également ML Lib, Sparks Machine Learning Library. Et si vous voulez faire de
l'apprentissage automatique distribué sur Apache Spark, vous pouvez le faire aussi. C' est un ensemble assez limité d'algorithmes, bien qu'il y ait la plupart de ceux dont vous auriez besoin dans la pratique. Nous allons donc examiner cela dans une section ultérieure du cours également. Et c'est vraiment excitant, non ? Parce que si vous avez l'apprentissage automatique que vous souhaitez traiter sur un jeu de données massif, n'êtes-vous plus limité à ce que vous pouvez faire sur une seule machine ? Il existe des algorithmes qui, à ce jour, sont difficiles à mettre à l'échelle, mais Spark l'a trouvé pour de
nombreux algorithmes d'apprentissage automatique les plus populaires que vous pourriez vouloir utiliser. Et enfin, ce graphique X, ne veut pas trop parler de ça. C' est un peu tombé au bord du chemin. Graphx n'est pas à propos, vous savez, des
graphiques et des graphiques impriment, vous savez, petites lignes et des trucs comme ça. C' est plus de graphiques dans le sens de l'informatique. Nous parlons donc de réseaux d'information. Par exemple, un réseau social où vous avez utilisateurs connectés à d'autres utilisateurs est un graphique en ce sens. Et les graphiques peuvent faire des choses comme, vous savez, analyser ces graphiques d'informations, vous
dire des attributs à ce sujet, et vous permettre de les parcourir de manière répartie. Ce graphique X est, encore une fois tombé au bord du chemin. Il n'a pas vraiment été bien entretenu ces derniers temps et il existe des API alternatives plus
récentes de nos jours qui sont plus populaires. Nous en parlerons plus à la fin du cours. Dans ce cours, nous utilisons le langage de programmation Scala. Pourquoi, pourquoi utilisons-nous Scala ? C' est un langage obscur, n'est-ce pas ? Eh bien, il y a quelques raisons. L' un est que Spark lui-même est écrit en Scala. Donc, en écrivant vos scripts dans Scala, vous êtes un peu comme vous vous rapprocher de la façon dont Spark lui-même est écrit dans optimisé. Donc, vous le savez,
cela peut potentiellement conduire à de meilleures performances. L' autre chose est que Scala est ce que nous appelons un langage de programmation fonctionnel. Et en tant que tel, c'est vraiment un bon ajustement pour le traitement distribué. Scala applique vraiment que vous écrivez votre code de manière à ce que vos fonctions puissent être réparties sur un cluster entier. Alors que d'autres langages comme Java et Python n'essaient pas vraiment de vous forcer à cela. Donc, en écrivant vos scripts de pilote Spark dans Scala, vous êtes plus susceptible d'écrire du code qui peut être parallélisé en toute sécurité et facilement. Il vous donne également des performances rapides. Donc, à l'échelle, il compile vers le code d'octet Java. Donc, à la fin de la journée, il fonctionne sur la JVM, l'interpréteur Java, et c'est assez rapide sur la plupart des systèmes. Évidemment, Java vous donnera également des performances rapides car cela compilera également des codes d'octets Java. Mais contrastez cela à l'écriture de vos scripts d'étincelle en Python, ce que vous pouvez faire. Mais tu dois passer par une autre couche là-bas, non ? Comme ça, le code python doit être
transformé en quelque sorte en bytecode Java à la fin de la journée. Donc, écrire dans Scala juste parce que vous vous rapprochez un peu de ce niveau inférieur ultime où votre code sera réellement en cours d'exécution. Maintenant, pour être juste, python est assez rapide dans Spark ces jours-ci. Donc la différence n'est pas aussi grande qu'elle l'était auparavant, mais il y a encore une petite différence. L' autre avantage de Scala si vous voulez le mettre contre Java, est qu'il est plus facile à utiliser. Donc il va y avoir beaucoup moins de code. Vous devez écrire beaucoup moins de choses standard que vous auriez à écrire si vous codez en Java. Java a beaucoup de frais généraux associés en termes de comment vous pouvez réellement compiler ce code et distribué et des choses comme ça. C' est beaucoup plus facile à Scala s'avère. Et comme je l'ai dit, en comparaison, Python plus lent, ce n'est pas aussi lent qu'avant. Tu vas toujours avoir un peu d'avantage avec Scala, mais cette comparaison de vitesse s'est terminée au fil du temps. Mais où sont les inconvénients de Scala ? Eh bien, l'une est que vous ne connaissez peut-être pas encore Scala. Tu sais, ce n'est pas un langage très courant. Donc vous allez devoir aller apprendre les bases de la maison Gallo fonctionne, mais ce n'est pas aussi difficile que vous le pensez. Par exemple, jetons un coup d'oeil à ce petit extrait de code. Nous faisons la même chose ici en Python et en Scala. Nous allons juste aimer écrire du code pour caler les nombres dans un jeu de données. Des trucs assez simples. Donc, dans la version Python et la version Scala, si vous regardez, ils ne sont pas si différents, n'est-ce pas ? Donc syntaxiquement, il y a des petites choses comme,
vous savez, vous devez déclarer dans Scala que c'est une constante
immuable que vous utilisez en disant val. La syntaxe pour définir une liste de choses est légèrement différente. La syntaxe des fonctions Lambda est un peu différente, mais c'est la même idée, non ? Donc Scala est une sorte de syntaxe bizarre. Parfois, les choses peuvent être un peu en arrière et nous allons en parler. Ne vous inquiétez pas pour ça. Mais à la fin de la journée, il ne semble pas si différent du code Python dans le contexte d'un script de pilote d'étincelle. Et avec cela, nous allons réellement plonger dans un cours de crash à Scala si vous en avez besoin. Dans cette section suivante, nous allons réellement entrer dans les bases de Scala. Qu' est-ce qui est différent, qu'est-ce qui est bizarre ? Je m'attends à ce que vous ayez une certaine expérience dans l'écriture de code quelque part, langage de script ou de programmation. Je ne suis pas là pour t'apprendre à programmer à partir de zéro. Ce serait une autre voie. Mais si vous avez un Python sous votre ceinture, ou C ou Java ou quelque chose, je pense que vous pouvez ramasser, augmenter assez rapidement. Donc, dans cette prochaine section, si vous en avez besoin, nous avons un peu d'introduction à Scala qui démystifie la syntaxe pour vous. Et au fur et à mesure que nous suivons le cours, vous verrez beaucoup et beaucoup d'exemples d'utilisation de Scala. Et je pense que cela va simplement tomber en regardant assez et en voyant assez d'exemples. Alors plongons dans notre cours de crash Scala si vous en avez besoin. Si vous n'êtes pas libre de sauter la section suivante et nous allons juste plonger dans le fonctionnement de Spark.
4. Les bases de Scala [Activité] Scala: Bonjour, je suis Frank canne et bienvenue dans mon bureau. Nous allons commencer par faire un petit cours de crash sur le langage de programmation Scala lui-même. Maintenant, évidemment, si vous êtes déjà familier avec Scala, vous pouvez ignorer cette section et c'est très bien. Mais si vous êtes nouveau sur Scala, mais que vous avez déjà eu une certaine expérience de programmation, vous trouverez une section très utile pour comprendre le code que nous allons examiner tout au long de ce cours. C' est juste assez pour être dangereux, non ? Donc, ne vous attendez pas à une introduction complète du cours Scala ici dans cette section, mais il suffit de vous faire passer ce cours au moins et à travers les exemples que nous allons passer dans cette section et les exemples plus tard dans le cours. Je pense que vous terminerez ce cours avec une assez bonne compréhension de la façon dont Scala fonctionne et même comment écrire votre propre code Scala. Cependant, si vous êtes nouveau dans la programmation, ce ne sera pas suffisant pour vous. Je vous encourage à aller trouver un cours d'introduction sur Scala qui va d'abord plus en profondeur et ensuite revenir à celui-ci. Mais pour le reste d'entre vous, nous allons labourer et apprendre Scala. D' accord, apprenons Scala juste pour fixer des attentes. Vous ne serez pas un expert de Scala à la fin de regarder des vidéos avec moi. Donc, ce que j'essaie vraiment de faire ici est juste de vous familiariser avec la syntaxe
du langage de programmation Scala et d'introduire certaines
des constructions de base comme comment puis-je appeler une fonction dans Scala ? Quels sont les travaux de contrôle de flux où certaines structures de données de base que je pourrais utiliser avec Scala, vous
montrer assez de code Scala pour que cela ne vous semble pas effrayant et intimidant pendant que nous traversons le reste du cours. Donc, avec cela, parlons d'abord de l'échelle à un niveau élevé. Tout d'abord, pourquoi apprendre Scala ? Eh bien, vous n'en avez probablement jamais entendu parler avant. Peut-être que tu l'as fait, mais tu ne le sais probablement pas. Il est principalement utilisé pour la programmation Spark. Mais il est particulièrement adapté pour spar car il est vraiment structuré
d'une manière qui se prête à faire le traitement distribué des données sur un cluster. Et vous verrez pourquoi un peu plus tard. C' est aussi ce que Spark lui-même est construit. Ainsi, en apprenant Scala, vous aurez accès à toutes les fonctionnalités les plus récentes et les plus grandes à mesure qu'elles sortent. Et cela peut généralement prendre beaucoup de temps pour que ces fonctionnalités s' écoulent vers le bas pour dire le support Python dans Spark. Et ce sera aussi le moyen le plus efficace d'exécuter le code Spark lui-même. Ainsi, en utilisant Scala, vous aurez les tâches Spark les plus rapides et les plus fiables que vous pouvez créer. Et je pense que vous seriez assez surpris de voir combien plus rapide et combien plus fiable. Le même travail d'étincelle écrit en Scala est comparé à dire, le même travail d'étincelle écrit en Python. Donc, même s'il pourrait être tentant de s' en tenir à la langue que vous connaissez déjà. Apprendre Scala vaut la peine de l'effort et ce n'est vraiment pas si difficile. La vérité est le même code Spark pour Scala et Python semblent très similaires les uns aux autres à la fin de la journée. Maintenant, le crâne lui-même fonctionne au-dessus de la machine virtuelle Java. Donc, il compile simplement en code d'octet Java et est exécuté par la JVM. Donc, une bonne chose à ce sujet est que vous avez également accès à tout Java. S' il y a une bibliothèque Java que vous voulez extraire dans votre code Scala, vous pouvez le faire. Donc, vous n'êtes pas limité à ce qui est dans le langage Scala lui-même. Vous pouvez réellement atteindre la couche Java et tirer vers le haut. C' est un travail que vous voulez utiliser aussi. Et nous le ferons plus tard dans ce cours, par exemple, pour traiter les expressions régulières dans un peu plus intuitif que vous ne le feriez autrement. Un autre point clé à propos de Scala est qu'il est axé sur ce qu'on appelle la programmation fonctionnelle. Où les fonctions sont en quelque sorte le cœur de ce que nous avons à faire. Les fonctions sont passées à d'autres fonctions et
enchaînées de manière à ce que vous ne soyez peut-être pas habitué. Mais c'est vraiment ainsi que Spark fonctionne à un niveau fondamental. Nous prenons essentiellement une abstraction sur un morceau de données et nous lui assignons une fonction pour effectuer un traitement sur ces données. Et la programmation fonctionnelle dans Scala rend cela très intuitif à faire d'un point de vue linguistique. Bon, donc allons juste sauter dans le fond
de la piscine et couler ou nager avec Scala, on va juste écrire du code et voir ce qui se passe et se salir les mains. Maintenant, je ne vous ai pas fourni une copie de ce code que je vais traverser parce qu'il y a en fait une valeur
et la taper vous-même pour faire une sorte de couler dedans. Commençons donc par créer ce qu'on appelle une feuille de calcul Nouvelle Scala. Cela va nous donner un environnement interactif où nous pouvons juste faire une sorte d' expérience avec le code Scala et évalué de manière interactive. Alors allez dans votre menu de fichiers et de l'intelligence et dites Nouvelle feuille de calcul Scala. Et nous appellerons celui-ci apprenant Scala un. Et dans cette première conférence, nous allons juste parler de la syntaxe et de la structure
du langage Scala parce que c'est un peu bizarre par rapport aux autres langues là-bas. Donc, tout d'abord, si vous voulez un commentaire, vous pouvez simplement faire une double barre oblique comme vous le feriez dans beaucoup d'autres langues. Et d'abord, nous allons parler de valeurs. Les valeurs sont donc des constantes immuables. Donc, c'est un exemple de ligne de commentaire là-bas. Maintenant, dans d'autres langues, nous avons le concept de variables. Vous savez, c'est une chose très universelle et une programmation d' attribuer une certaine valeur à une variable nommée, non ? Et comme utiliser cela tout au long de votre code. Maintenant, dans Scala, il y a deux types différents quand on l'appelle des valeurs qui sont immuables et des variables qui sont immuables. Et dans Scala, vous voulez rester avec les valeurs autant que possible. Voici donc un exemple de la façon d'en définir un. Nous pourrions dire val pour la valeur, Bonjour, deux-points, chaîne égale citation Ola. Et si vous voulez vraiment exécuter ça, on peut juste appuyer sur un petit bouton de lecture ici. Ou vous pouvez voir qu'il y a aussi un raccourci clavier de Control Alt W que je vais utiliser à partir de maintenant. Et il crée un environnement pour l'exécuter en ce moment et nous l'avons là. Ainsi, vous pouvez voir qu'il a réellement exécuté cette commande et affecté la valeur o loi à une chaîne appelée Hello. Donc passons un peu de temps à parler de la syntaxe ici parce que c'est un peu à l'envers de nombreuses autres langues, non ? Donc, nous commençons par dire que c'est une valeur. Cela signifie que nous définissons une constante immuable. Une fois que nous définissons réellement ce qu'est bonjour, nous ne pourrons plus le changer. Donc, nous allons appeler cette valeur Bonjour. Et puis après le deux-points, nous devons déclarer quel type c'est. Donc, nous disons que bonjour est un type de chaîne. Donc c'est à l'envers de la plupart des autres langues, non ? Habituellement, vous verrez comme une chaîne bonjour, mais dans Scala c'est bonjour, chaîne de deux-points. Et puis nous l'assignons à une valeur. Rien de trop bizarre. Ce sont juste la chaîne hola entre guillemets. Ok, donc ça a du sens, non ? Est un peu en arrière, mais vous vous y habituez assez rapidement. Parlons maintenant des variables. Les variables sont donc immuables. Cela signifie que vous pouvez réellement les changer après les avoir définis. Donc, pour définir une variable, c'est la même chose. Vous utilisez juste un var au lieu d'un Val. Donc, nous pouvons dire var bonjour là, qui est aussi une chaîne, et nous allons mettre cela à Bonjour. Nous allons assigner cela à la valeur de la chaîne constante, la constante bonjour immuable. Donc, je vais dire Control Alt, W. Et vous pouvez voir là que bonjour il a été affecté la valeur de chaîne o loi parce que cela a été stocké dans notre valeur immuable. Bonjour a du sens jusqu'à présent. Mais bonjour, il y a une variable, nous pouvons la changer maintenant ce n'est pas collé à être Hello. Donc, nous pourrions dire quelque chose comme bonjour il est égal bonjour plus l'espace là et le contrôle Alt W. Et vous pouvez voir que nous avons effectivement modifié Bonjour il aussi contient maintenant la chaîne Bonjour. Il y a Ola là plutôt. Ainsi, comme vous pouvez le voir, les variables peuvent être modifiées les valeurs, cependant, ne peut pas. Nous pourrions également utiliser la commande print line pour imprimer cette valeur explicitement. Imprimer la ligne bonjour là, qui fait exactement ce que vous penseriez. Vous imprimeriez la valeur de cette variable sur une ligne Control Alt W là-bas. D' accord, donc tu as vu des trucs de base ici. Tout d'abord, le concept de valeurs dans les variables et les valeurs est encore immuable. Une fois que vous les avez définis, vous ne pouvez pas les modifier. Alors que les variables sont mutables, vous ne pouvez pas les modifier après les avoir définies. Et notez également la syntaxe ici de déclarer des valeurs et des variables. C' est valor var, le nom de l'identificateur, deux-points, le type, puis est égal à ce que vous voulez qu'il le définisse. Encore une fois, c'est en arrière de beaucoup d'autres langues. Et juste pour vous montrer ce qui se passe et pour vous prouver que les valeurs ne peuvent pas être changées. Changeons ce var2 eval et voyons ce qui se passe si nous essayons d'exécuter cela à nouveau, Control Alt W. Vous pouvez voir que nous avons quelques erreurs ici maintenant, réaffectation eval, nous ne pouvons pas dire bonjour il est égal
bonjour plus là parce que vous ne pouvez pas changer un val. Une valeur est immuable. Revenons à var et exécuté à nouveau contrôle Alt W. Ok, Jusqu'à présent si bon, non ? Maintenant pourquoi avons-nous cette distinction entre les valeurs et les variables dans Scala ? Eh bien, c'est parce que c'est ce que nous appelons un langage de programmation
fonctionnel à l'échelle est un peu centré autour de l'idée de passer des fonctions autour et potentiellement les exécuter en parallèle. C' est pourquoi c'est un si bon match pour Apache Spark. Et la raison pour laquelle nous voulons rester avec des constantes immuables chaque fois que nous pouvons est d'éviter un tas de problèmes de sécurité des fils et de les mettre hors de la passe. Imaginez donc que vous avez une fonction qui a une variable que vous obtenez, qu'elle peut changer et que vous passez cette variable dans beaucoup, beaucoup de threads. Que se passe-t-il si un thread essaie de changer cette variable en même temps qu' un autre thread essaie de la changer en autre chose, les résultats deviennent indéfinis, non ? Nous évitons donc beaucoup de ces conditions de course en essayant d'utiliser des constantes immuables chaque fois que possible. Si nos fonctions ne font qu'agir et traiter des données immuables, nous n'avons pas à nous soucier de tous ces threads, de la sécurité et des conditions de course. Ça ne vous limite pas autant que vous le pensez. Vous pouvez toujours faire beaucoup de choses simplement en utilisant des valeurs constantes immuables. Donc, par exemple, si je voulais faire l'opération ci-dessus et construire la chaîne o la là à partir de la valeur Bonjour. Je peux toujours le faire en utilisant des valeurs. Je pourrais dire quelque chose comme val immuable bonjour il est égal bonjour plus là. Droit ? Et je pourrais imprimer ce résultat. Contrôle Alt W. Et cela fonctionne parce que je définit bonjour immuable là sur la même ligne ici je prends une valeur précédemment immuable, en
ajoutant une autre valeur immuable et en affectant cela à une valeur immuable. Donc, c'est correct avec les variables. On l'a fait d'une manière différente. Comme nous avons commencé par définir bonjour là pour bonjour, puis à une autre opération, nous avons ajouté la chaîne là. Donc, tant que nous faisons tout en une seule ligne, en une seule opération atomique, nous respectons toujours les règles d'utilisation des valeurs dans la mesure du possible. Bon, donc nous avons vu le type de données de chaîne ici en action, non ? Il y a donc beaucoup d'autres types de données disponibles dans Scala. Parlons des types de données. Donc, par exemple, nous pourrions dire val numéro un. Wops, si je tape bien, numéro un deux-points int. Donc, un int est exactement ce que pensez-vous qu'il est un entier, un nombre entier, un nombre entier. On pourrait aussi dire val. La vérité est un booléen. Et nous allons mettre ça sur vrai. Notez que dans Scala, constantes
true et false sont toutes minuscules. Il y a des langues où vous capitaliseriez sur true et false, mais pas dans Scala. Donc, c'est juste une valeur booléenne, true ou false. Nous pouvons aussi avoir des personnages. Donc nous pouvons dire val, lettre a. comme un type de voiture, un seul caractère, une seule valeur ascii. Nous avons aussi des nombres à double précision, bien sûr. Donc on peut dire que Pi est un double. Et réglez ça à 3.14159265 ou quoi que ce soit. Et nous pouvons également représenter une valeur à virgule flottante unique de précision avec une seule précision Pi. Et nous allons déclarer cela comme un flotteur, qui est une variable à virgule flottante de précision unique. Et nous allons régler cela sur 3.14159265 F, ce qui signifie une précision unique en virgule flottante. Contrôlons Alt W pour voir que nous avons jusqu'à présent ça marche. Vous pouvez donc voir que toutes ces variables ont été définies comme prévu. Continuons. Il y a aussi un type de données long, disons val big number. Nous définirons ça comme un long. Et nous allons définir ça sur un gros entier. 1, 2, 3, 4, 5, 6, 7, 8, 9, sur ce que vous voulez. Et on pourrait dire aussi un seul numéro de caractère. Nous pouvons sauver tout petit nombre. Déclarez que sous forme d'octet est égal à 127. Donc, un octet est fondamentalement un nombre qui est entassé en un seul octet. Il ne peut donc représenter que des nombres allant de 127 négatif à 127 positif. Ou s'il n'était pas signé 0 à 255, Contrôlez Alt W pour les exécuter. Ok, ça a l'air bien. Parlons maintenant de la façon d'imprimer et d'afficher vos données et de formater votre sortie. C' est toujours une chose importante, non ? Donc, disons que nous voulons concaténer un tas de chaînes ensemble ou un tas de valeurs ensemble et les imprimer. Évidemment, vous voulez pouvoir voir les résultats de vos programmes Spark. Donc c'est comme ça que tu ferais ça. On pourrait dire ligne d'impression. Voilà un bordel. Et le secret ici est que vous pouvez simplement utiliser l'opérateur plus pour concaténer des choses ensemble et imprimé comme une grande chaîne. Et ce n'est pas seulement des ficelles non plus. Il peut s'agir de n'importe quel type de données. Il le convertira implicitement en une chaîne. Donc je peux dire qu'il y a un désordre plus le numéro 1 plus la vérité, plus la lettre a, plus pi, plus grand nombre. Et ça devrait marcher. Contrôle Alt W. Il est là. Crabe tout ensemble parce que je n'ai pas inséré espaces entre tout, mais ça marche. Notez également d'ailleurs, il n'y a pas de point-virgule ou quoi que ce soit à la fin des lignes ici. Il suppose simplement que chaque nouvelle ligne est une nouvelle commande fondamentalement. Donc, il n'y a pas besoin de mettre explicitement fin à vos lignes de code dans Scala. Que voulez-vous faire comme imprimer le style F, si vous venez d'un arrière-plan comme C ou C plus, vous pourriez être familier avec la commande print f, qui vous permet de mettre en sorte de conseils de mise en forme pour afficher réellement des données numériques ou insérer des chaînes et d'autres données dans une chaîne existante. Voici à quoi cela ressemble dans Scala. Nous pouvons dire imprimer la ligne F, ce qui signifie que nous voulons imprimer le format. Citation pi est à propos du signe dollar pi, simple précision, pour cent 0,3 F. Ok, alors décomposer ça un peu. Donc, d'abord, notez que nous avons ce signe de dollar là qui indique que nous avons un nom de variable ou un nom de valeur plutôt, dans ce cas, après ce signe de dollar. Donc Pi est simple précision va insérer la valeur de Pi simple précision. Et pour cent 0,3 f signifie que c'est une valeur à virgule flottante que nous allons afficher là. C'est ce que veut dire le F. Et pour cent 0,3 signifie qu'après la virgule, nous ne voulons afficher que trois chiffres de précision. Alors allons de l'avant et frapper le contrôle Alt W. Et vous pouvez voir qu'il a fait exactement ce que nous avons dit. Pi est d'environ 3.142. Donc, il a juste affiché ces trois chiffres après le point décimal là-bas parce que c'est tout ce que nous voulions. Cela peut être pratique si vous affichez une double précision ou même un numéro de précision unique qui a un grand nombre de chiffres ensemble a plus de précision que vous n'avez besoin. Vous pouvez également faire des choses comme nous allons voir comment cela fonctionne avec des entiers. Donc, par exemple, nous pourrions dire ligne d'impression F, Encore une fois indiquant juste le format d'impression f 0, remplissage sur la gauche. Signe dollar numéro 1, pour cent 05 D. D'accord. Donc, cette fois, nous disons que nous allons insérer la valeur de la valeur numéro 1 et le pourcentage 05 D. Le D signifie juste que c'est un nombre, un entier, et pour cent 05 signifie que je veux avoir au moins cinq chiffres à gauche de la virgule décimale. Alors voyons ce que ça fait. Contrôle. Alt W. Et nous obtenons 000 000 001, promettant les cinq chiffres de précision sur la gauche que nous voulions. Cela peut être utile lorsque vous essayez d'aligner la sortie et les colonnes, n'est-ce pas ? Donc c'est aussi un truc pratique parfois. Aussi si vous voulez simplement substituer des variables dans une chaîne sans spécifier réellement la mise en forme. C' est aussi facile à faire. Par exemple, imprimez la ligne S pour le devis de remplacement. Je peux utiliser le préfixe S pour utiliser variables comme le signe dollar numéro un, la
vérité
et la lettre a. la
vérité Donc, vous pouvez voir que c'est un moyen très facile d'insérer noms de
valeur dans votre chaîne là sans avoir à utiliser l'opérateur de concaténation inutilement. Donc juste une autre façon de le faire. Ok, qu'est-ce qu'on peut faire d'autre ? Nous pouvons inclure des expressions dans nos commandes d'impression. Laisse-moi te montrer comment ça marche. Ligne d'impression S. Le préfixe S n'est pas limité aux variables. Je peux inclure n'importe quelle expression comme Ross, un signe de dollar, un crochet bouclé ouvert, un plus deux. Et il a automatiquement complété cette ligne pour moi. Donc la clé ici sont ces crochets bouclés. Une fois que vous avez un crochet bouclé défini après un signe de dollar, il va en fait évaluer l'expression à l'intérieur de ces crochets bouclés et imprimer le résultat de cela dans le cadre de la chaîne Control Alt W. Et si nous faisons défiler, nous devrions voir qu'il a imprimé le numéro trois. Donc c'est une astuce soignée à écrire. Donc, ces crochets bouclés après le signe dollar pourraient réellement évaluer une expression dans une commande de ligne d'impression si vous utilisez le préfixe S. Il y a aussi des expressions régulières. Donc, si vous êtes familier avec ceux-ci, c'est un outil puissant pour empiler réellement vos données de chaîne. Voyons comment ça marche. Commençons donc par une chaîne qui est Val, la réponse ultime. Nous allons définir cela comme une chaîne. Encore une fois, nous ne revenions pas à la façon de définir une valeur. Et nous mettrons ça à la vie, à l'univers. Et tout est 42. Et si vous reconnaissez cette référence, alors U2, notre fan de The Hitchhiker's Guide to the Galaxy. Bienvenue. D' accord, donc nous avons cette chaîne et nous voulons faire est écrire une expression régulière qui va extraire la réponse à la question ultime de la vie, de l'univers, et tout. Nous allons donc mettre en place une expression régulière pour extraire ce nombre à partir de la fin de cette chaîne. Donc, nous pouvons dire que le modèle val est égal à trois guillemets 123. Et puis nous allons l'écrire dans une expression régulière pour extraire l'information que nous voulons de cette chaîne. Dot étoile, parenthèse, crochet carré, barre oblique inverse d, n crochet carré. Plus proche parén dot star, et puis ces trois guillemets, point r. Ok, donc le point R signifie que c'est une expression régulière que nous définissons ici. Et passer en revue le fonctionnement des expressions régulières est probablement hors de portée pour ce cours. Mais il existe un outil très utile pour des choses comme extraire informations à partir des fichiers journaux et des choses comme ça. Une rapide ventilation de ce qui se passe ici. L' étoile de point signifie correspondre à n'importe quoi dans cette chaîne suivie d'un espace. Et puis entre les parenthèses est la chose que nous
essayons d'extraire de ce modèle. Et les crochets et la barre oblique inverse d signifie que je veux extraire un nombre. Très bien, et n'importe quel nombre, c'est ce
que signifie le signe plus, suivi de tous les autres caractères. Ok, donc en cherchant un tas de personnages suivis d'un espace et puis un numéro suivi de tout ce qui va sortir ce 42 de cette chaîne. Nous n'avons pas besoin de ce contrôle Alt W juste pour nous assurer que ça marche. Bon, cool. Alors jetons un coup d'oeil par ici. Donc nous avons cette chaîne que nous avons définie pour la vie de l'univers et tout est 42. Et maintenant, nous avons défini un objet d'expression régulière correspondant qui consiste en cette expression régulière. Ok, donc c'est ce qui s'est passé avec cette ligne ici. Maintenant, pour appliquer cette expression régulière à la chaîne, c'est très simple. Nous pouvons simplement dire val pattern, parenthèses Réponses, chaîne égale la réponse ultime. D' accord, donc la syntaxe est un peu bizarre. Cela signifie que nous allons prendre l'expression régulière que nous avons définie dans pattern. Nous allons assigner la sortie de cela à la chaîne de réponse. Donc, la syntaxe ici, c'est essentiellement dire, je veux prendre ce qui est entre ces parenthèses et transférer ce résultat à ce qui est entre ces parenthèses. Ok, c'est une façon d'y penser. Et nous allons assigner la réponse ultime à ce modèle. Donc, la syntaxe là encore, un peu en arrière de la façon dont vous pourriez penser à des choses dans d'autres langues. Et puis nous pouvons juste imprimer ce qu'est cette réponse. Tout d'abord, nous allons le convertir en un entier. Nous pouvons dire val, réponse égale chaîne de réponses à int. Donc, c'est juste vous montrer comment convertir réellement un type en un autre. Cela aiderait si j'ai tapé correctement la chaîne de réponse. Et puis je peux imprimer ça. Imprimer la ligne, répondre. D' accord, donc nous avons défini une chaîne, nous avons défini une expression régulière pour extraire des informations de cette chaîne, nous définissons une instruction. Appliquez effectivement cette expression régulière à la chaîne et stockez le résultat quelque part. Nous appelons cette chaîne de réponse. Nous avons converti cela d'une chaîne en un entier, puis nous allons imprimer ce blesse sur Control Alt W. Et ça a fonctionné. Donc, vous pouvez voir que nous avons extrait la chaîne 42. Nous avons converti cela en un entier 42 et l'avons imprimé quand nous avons terminé. D' accord, aller de l'avant. Parlons des Booléens. Donc chose vraiment facile qu'ils fonctionnent exactement comme vous vous attendez. Parlons donc des Booléens. Ainsi, par exemple, on pourrait dire que val est plus grand et que c'est égal à un supérieur à deux. Qu' est-ce que tu penses que ça va sortir ? Un est plus grand que deux ? Non, la réponse est fausse. Donc, cela fonctionne à peu près comme vous vous attendiez. On dirait que Val est moins égal, un, moins que deux. C' est vrai. On pourrait dire que val impossible égal est plus grand et moins. Et vous pouvez voir qu'on peut utiliser une seule esperluette là-bas. C' est très bien. Mais on pourrait aussi dire une double esperluette. Voyons ce que ça fait. Contrôlez l'Alt W. Donc ce ne sont pas la même chose ici. Donc, comme en C ou C plus, plus une esperluette double est en fait une fin logique où c'est une esperluette unique est un bit. Et donc la seule raison pour laquelle cela fonctionne du tout est parce que ce sont des
ailes plus grandes et plus petites peuvent évaluer jusqu'à zéro et ceux et il finit toujours par travailler. Et nous le convertissons implicitement en vrai ou faux. Mais si vous essayez de faire une opération logique, c'est
ce que nous essayons vraiment de faire ici. Vous devriez utiliser la double esperluette. C' est l'opérateur logique ou booléen. Donc, ils vous donnent le même résultat dans ce cas, mais il est vraiment préférable d'utiliser la double esperluette il fonctionne de la même façon avec ou si vous voulez dire est plus ou moins, cela fonctionne. Ce serait vrai, sans doute, oui. Donc, vous avez l'idée. Les booléens travaillent à peu près comme vous l'attendez d'autres langues. Jouons un peu plus avec ça. Et on pourrait dire Val, la carte, qui est une corde, et mettre ça égal à Pickard. Et on peut dire Val Best Capitaine. Une autre valeur juste avec un nom différent. Aussi une chaîne égale Pickard. Et on peut dire que Val est le meilleur. Déclarez-le en tant que booléen. Et nous mettrons ça à Picard. C' est égal au meilleur capitaine. Alors allons de l'avant et exécutons cela et Control Alt W fait ce que vous pourriez penser. Donc, il est égal, égal ici est en fait aller à l'intérieur de ces chaînes et en comparant les valeurs des chaînes. Donc, cela signifie que nous voulons réellement comparer les valeurs de ces deux choses et voir si elles sont identiques. Donc, il ne s'agit pas réellement
de comparer les objets eux-mêmes ou l'adresse des objets eux-mêmes. Il va en fait dans cette chaîne et en comparant les chaînes les unes aux autres. Donc, si vous voulez comparer deux chaînes, utilisez
simplement l'opérateur égal égal. Ça peut être quelque chose de bizarre dans certaines langues. Il est donc important de le signaler ici. Et si vous voulez débattre dans le Q et un temps, Picard est le meilleur capitaine. Je me réjouis de cette discussion. D' accord. Si vous vouliez vous salir les mains, jouez avec ces trucs, faites plus de trucs, continuez, les gars. Ainsi, par exemple, vous pouvez écrire du code qui prend la valeur de pi et le double, puis l'imprime dans une chaîne avec trois décimales de précision à droite. Ok, donc en fait, je vais coller ça ici comme un petit défi pour toi. Et c'est vraiment facile. Je ne vais même pas vous donner la réponse. Vous pouvez parler dans le Q et un si vous voulez parler de la solution réelle. Mais voilà mon défi pour vous. Va appliquer ce que tu viens d'apprendre et fais ça. Oui, écrivez juste un petit extrait de code qui prend la valeur de Pi. Nous avons défini, multiplié par deux, et imprimé dans une chaîne avec trois décimales de précision à droite. Tout ce que vous devez faire pour accomplir cela devrait être au-dessus de vous ici. Si peu de façon simple d'obtenir une exposition pratique. Alors se salir les mains, jouer un peu plus. Et puis nous passerons au prochain chapitre de l'apprentissage de Scala.
5. [Exercice] Contrôle de flux dans Scala: Donc, si vous voulez enregistrer ce que vous avez fait jusqu'à présent, vous pouvez simplement dire Control-S, vous pouvez simplement dire Control-S,
fermer c'est de le garder pour référence future si vous le voulez. Et nous allons faire un autre bloc-notes Scala ou feuille de calcul Scala plutôt. Et nous appellerons celui-ci le nom créatif de l'apprentissage de Scala. Et cette fois, on va parler de contrôle du débit. Voyons donc comment les instructions d'autre fonctionnent. Ils fonctionnent exactement de la même manière que dans d'autres langues. Ce n'est rien de trop bizarre ici. Par exemple, nous pourrions dire si on est supérieur à trois, ligne d'impression, impossible. Autre ligne d'impression. Le monde a du sens. Donc exactement comme toutes les autres langues là-bas, si une expression est vraie, vous faites cette expression, sinon faites une autre expression. Et si vous voulez tout faire sur une seule ligne, c'est à ça que ça ressemble. Donc Control Alt W, le monde a du sens comme il se doit. Maintenant, si vous voulez diviser cela en plusieurs lignes, la syntaxe vous est à nouveau assez familière. Ceux d'entre vous qui ont programmé avant, nous pourrions juste dire si l'un est supérieur à trois crochets bouclés. Et cela nous permet de mettre plusieurs expressions dans ce cas positif. On pourrait dire que la ligne d'impression est impossible. Et si nous le voulions, nous pourrions imprimer autre chose. Vraiment autrement, fais autre chose. On peut dire ligne d'impression, le monde a du sens. Et quand même, je ne sais pas, j'invente ça. Contrôle Alt W. Le monde a du sens, encore froid. Donc rien de trop surprenant là-bas. C' est très similaire à d'autres langues là-bas. Eh bien, donc vous savez comment nous pouvons avoir comme des instructions de changement dans certaines langues où vous avez un peu comme correspondance entre différents cas. Eh bien, à quoi ça ressemble à Scala ? Regardons un exemple de cela. Donc, nous pourrions dire que le nombre de val est égal à 3 SAT le nombre 32, une valeur nommée nombre. Et on peut dire que le nombre correspond au support bouclé, cas un. Petite flèche bizarre il est égal signe supérieur à la ligne d'impression 1, cas 2. Vous pouvez voir où je vais avec ça. Imprimer la ligne 2, le cas 3, la ligne trois. Et puis on peut dire cas, soulignement, ligne d'impression, autre chose. Devinez probablement ce que cela fait Control Alt W. Nous obtenons la valeur libre imprimé. Donc, ce qui se passe ici, c'est que nous avons cette déclaration de cas ici où nous pouvons avoir une liste de différents cas que nous allons vérifier par rapport au numéro de valeur. C' est égal à 1. Nous allons exécuter cette expression. Si elle est égale à 2 plus q, cette expression est égale à 3, nous exécutons cette expression, qu'elle s'avère être. Et ce trait de soulignement est un peu comme un fourre-tout. C' est comme l'instruction par défaut où quoi que ce soit d'autre, tout autre cas que nous ne correspondions pas, nous allons frapper ça à la place. Donc, par exemple, on pourrait mettre ça à 30 et ça devrait frapper cette dernière déclaration fourre-tout, n'est-ce pas ? Contrôle Alt W. Bien sûr, nous obtenons quelque chose d'autre et changer cela pour, pour arriver à. C' est ainsi qu'une déclaration de correspondance fonctionne. Vous ne voyez pas ça trop souvent dans Scala, mais c'est là si vous en avez besoin. Ensuite, parlons de for-loops. Chose très courante à faire dans la plupart des langages de programmation, non ? Alors, comment ça marche ? C' est un peu bizarre en termes de syntaxe. Alors. Une façon de le faire est de x moins de tiret un à quatre. Et puis nous pouvons dire que val carré est égal x fois x et imprimer la ligne au carré. Donc, ce que cela fait, c'est qu'il itère à travers les valeurs un à quatre. Et à chaque fois à travers elle, si signe que la valeur actuelle de cette itération actuelle à la valeur x. puis nous calculons une nouvelle valeur appelée carré qui multiplie x par lui-même et imprime le résultat. Donc ce que nous devrions voir, nos quatre résultats ici, chacun avec le carré des numéros un à quatre, Contrôle Alt W. Et là, ils sont, 14916 parce que c'est un carré, deux carrés, trois carrés, et quatre carrés. Donc, à peu près fonctionne comme vous vous attendiez, non ? Nous avons aussi des boucles while, tout comme vous le feriez dans d'autres langues. Donc, nous pourrions aussi faire quelque chose comme var x est égal à 10. Et notez que j'utilise une variable mutable ici. Ce n'est généralement pas une bonne pratique dans Scala. Et je dirai alors que x supérieur ou égal à 0, crochet
bouclé, ligne d'impression x, puis x moins égal à un. Donc nous allons commencer à définir x à 10. Alors que x est supérieur ou égal à 0, nous allons imprimer la valeur de x, puis en soustraire une. Donc, vous pouvez voir que nous avons dû faire x une variable là afin de continuer à modifier la valeur de x. donc pas une structure. Vous allez voir trop souvent à Scala, mais vous ne pouvez pas le faire si vous en avez besoin. Faisons en sorte que ça marche. Contrôle Alt W. Et bien sûr, il compte à rebours à partir de 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. Cool. Intéressant comment la feuille de calcul a formaté cela d'ailleurs, il va de son chemin pour essayer de garder les choses compactes. C' est plutôt cool. Une autre structure pour le contrôle de flux est la boucle do while. Encore une fois, similaire à d'autres langues. Donc, nous pourrions également définir x égal à 0. Nous utilisons toujours la même variable que nous avons définie précédemment. Et nous pouvons dire Do print line x, point-virgule x plus égal à un, tandis que x inférieur ou égal à 10. Donc, cette fois, nous allons commencer à 0 et imprimer chaque valeur en comptant d'un, tandis que x est inférieur ou égal à 10. Nous faisons donc cette comparaison à la fin du bloc plutôt qu'au début. C' est comme ça que ça marche. Contrôle Alt W et pourtant cela fonctionne 0123, tout le chemin à 10. Ok, c'est à propos de ça pour le contrôle de flux, parlons plus d'expressions. Alors, les expressions. Donc, une chose qui est un peu bizarre à propos de Scala est que quand vous avez une expression, il renvoie implicitement la valeur de cette expression automatiquement dans ce bloc. Par exemple, disons que le support bouclé Val X est égal à 10 point-virgule, x plus 20 point-virgule. Qu' est-ce qui va se passer ici ? Qu' est-ce que ça fait réellement ? Contrôle Alt W. Donc ce qu'il a fait a été en fait retourné la valeur 30, même si nous n'avons pas vraiment dit, je veux imprimer ceci, je n'ai pas dit explicitement, je veux le retourner, juste l'acte d'avoir cette expression est la dernière chose dans ce bloc, signifie que c'est ce que ce bloc sort en conséquence. Donc, c'est un peu une chose importante pour envelopper votre tête en termes de programmation fonctionnelle et d'expression, n'importe quel bloc de code comme celui-ci peut lui-même être passé comme une fonction a sa propre petite entité. Et la chose que cette fonction renvoie est quelle que soit la dernière chose et cette expression. Maintenant, vous pouvez explicitement renvoyer des choses comme un canon d'autres langues. Mais implicitement la dernière chose qui se passe dans un bloc de code va être la valeur de retour de cette expression. Donc, ce petit morceau de code ici est une fonction en soi implicitement. Et il renvoie dans ce cas, la valeur 30. Ok, c'est un peu important. Je pourrais juste l'imprimer. Et je peux dire ligne d'impression. Et imprimez cette expression, val x est dix, point-virgule x plus 20, juste comme ça. Et cela va effectivement imprimer avec espoir la valeur 30. Ok, voyez comment ça marche. Point important là, parce que c'est probablement l'un des points les plus confus de Scala. Si vous apprenez la programmation dans une langue différente, ce qui est le cas pour la plupart des gens. Ce dernier petit peu dans le bloc est la valeur de retour de cette expression. Et vous pouvez traiter cette expression comme sa propre entité. Ok, ça va être important quand on parlera des fonctions. Très bien, ça suffit pour ce petit bloc ici. Encore une fois, je vais vous donner un défi ici pour pratiquer ce que vous avez appris. Laissez-moi copier et un petit exercice que j'ai écrit sur le côté ici. Vous avez peut-être entendu parler de la séquence de Fibonacci. Et c'est ce que c'est. Fondamentalement, c'est une séquence où chaque nombre est la somme des deux nombres qui l'ont précédé. Donc, vos résultats devraient être 011235 et ainsi de suite. Voyez ce qui se passe ici. Donc, nous avons, donc nous commençons par une valeur 01, puis nous itérons en ajoutant les valeurs des deux nombres avant cela. Donc 0 plus 1 est 1, 1 plus 1 est 2, 1 plus 2 est 3. 2 plus 3 est 5. 3 plus 5 est 8, et ainsi de suite et ainsi de suite. Donc, votre défi est d'écrire un petit extrait de code dans Scala qui fait cela. Donc, vous allez devoir appliquer ce que vous avez appris sur le contrôle de flux ici et les valeurs et les variables pour tirer
cela, c'est un peu plus un exercice difficile. Encore une fois, je ne vais pas vous donner la réponse. Vous pouvez le regarder assez facilement si vous êtes coincé. Mais c'est une question d'entrevue assez courante pour montrer aux gens que vous savez coder et que vous pouvez envelopper votre tête autour des algorithmes. Je vous encourage donc à prendre le temps de passer à travers cet exercice parce
que mon entretien d'embauche est utile un jour. Et c'est également une bonne pratique pour le contrôle de flux dans le langage Scala. Alors va t'amuser avec ça. Et quand nous reviendrons, nous en apprendrons plus.
6. [Exercice] des fonctions dans Scala: La prochaine conférence est plus courte, mais c'est très important. Nous allons parler des fonctions dans Scala. Et étant donné que c'est un langage de programmation fonctionnel, évidemment c'est d'une grande importance. Fermons le squelette d'apprentissage et créons une autre feuille de calcul, Nouvelle feuille de calcul Scala, et nous appellerons celle-ci, devinez quoi ? Apprendre Scala trois. Et cette fois, nous allons parler de fonctions. Donc, le format d'une fonction dans Scala va être la mort. Nom de la fonction, paramètre, nom, type
deux-points pour autant de paramètres que vous en avez. Et puis le type de retour deux-points est égal, puis une expression qui définit ce que fait cette fonction. C' est une syntaxe vraiment, vraiment bizarre si vous êtes habitué à d'autres langages de programmation non fonctionnels. Alors regardons quelques exemples. Nous pouvons dire, par exemple, def carré. X deux-points int, deux-points int est égal à crochet bouclé x fois x Donc, c'est ainsi que vous définiriez une fonction qui prend une valeur et les carrés, elle renvoie le carré de cette valeur. Allons briser ça. Donc encore une fois, nous commençons par def pour définir une fonction, le nom de la fonction, dans ce cas, la carré. Paramètre. Dans ce cas, nous n'avons qu'un seul paramètre appelé x, et qui est de type entier. Donc x deux-points int signifie que le premier paramètre est un entier nommé x. et puis la valeur de retour de cette fonction va être un entier lui-même. Donc, que deux-points int est la valeur de retour, encore une fois, totalement en arrière de beaucoup d'autres langues. Ensuite, nous devons dire égal à attribuer cette fonction à une expression. Donc, nous disons que cette définition de fonction est égale à cette expression dans les crochets bouclés, x fois x. N'oubliez pas que c'est égal, c'est une erreur très courante. Encore une fois, nous ne renvoyons pas explicitement une valeur. Juste cette dernière chose qui est évaluée dans la fonction est la valeur de retour implicite de cette fonction. Donc c'est tout ce qu'il y a. Un autre exemple, disons def cubit x int, deux-points int égal x fois x fois x fois x. Donc, nous pourrions faire tout cela dans une ligne à ceci est simplement pour un one-liner rapide. Voyons ça en action. Donc, nous pouvons dire imprimer la ligne, carrer, en passant le paramètre deux. Et nous pouvons dire impression ligne coudée, en
passant le paramètre 3. Contrôlons Alt W et exécutons tout ça. Et vous pouvez voir que nous avons attribué la fonction racine carrée et le cube. Et nous avons en fait passé la valeur 2 pour le carré et obtenu la valeur pour retour. Nous passons la valeur 3 à Cuba et nous avons obtenu 27 en retour. Donc, tout comme ça devrait fonctionner. Encore une fois, c'est se concentrer un instant sur cette syntaxe. Il faut s'habituer au nom de la fonction def, le type de
paramètre deux-points, le type de valeur de retour deux-points est égal, puis l'expression qui définit la fonction elle-même. Voilà où ça devient bizarre. Si tu ne trouvais pas ça assez bizarre. Les fonctions peuvent en fait prendre d'autres fonctions comme paramètres. C'est comme la création. Si vous n'obtenez pas cette référence de culture pop, je m'excuse, mais disons par exemple, la mort transformée int int. Et nous le prendrons en X, qui est un paramètre entier. Et aussi un f, qui va définir une fonction qui prend un entier et retourne un entier comme valeur de retour. Et cette fonction de transformation elle-même retournera un entier et nous allons définir cela égal à l'expression suivante, f de x. ok, cela prend un peu de réflexion, n'est-ce
pas, alors que se passe-t-il ici ? Nous définissons une nouvelle fonction appelée transform int. Il prend à la fois une valeur, une valeur entière nommée X. Et il prend également une fonction qui prend un entier et retourne un autre entier. Donc, cela peut être n'importe quelle fonction qui prend un entier et le transforme en un autre entier. Nous savons que cela à son tour retournera un entier et il est défini sur l'expression f de x. Donc, nous allons prendre la fonction que nous avons passée appelée f et passer dans cette fonction, le paramètre x que nous avons passé dans la transformer. Si vous avez besoin de vous asseoir et de réfléchir un peu à la façon dont cela fonctionne, n'ayez pas peur d'appuyer sur pause car c'est un concept très important pour la programmation fonctionnelle. Voyons ce qu'il fait réellement quand on a essayé de l'utiliser. Nous dirons que le résultat de Val est égal à transform int, et nous allons passer en deux et le cube de fonction il. Alors que crois-tu qu'il va se passer ici ? Nous passons la valeur deux dans x, la fonction coudée en F. Donc nous allons finir par appeler coudée sur la valeur deux ici dans la transformation. Donc, nous transformons ensuite int. On va appeler la fonction cubique qu'on a passée avec la valeur X. Donc on devrait revenir à cube, non ? Contrôle Alt W. Bien sûr que nous avons la valeur huit. D' accord, encore une fois, des nouilles sur ça. Et si vous voulez réellement imprimer ce résultat, au lieu de simplement compter sur ce à quoi cela a été évalué, nous pourrions dire imprimer la ligne, résultat, le contrôle Alt W et revenir évaluer explicitement là. Ok, Donc encore plus important est le concept de fonctions Lambda, ou parfois ils sont appelés fonctions anonymes sont des littéraux de fonction, vous savez, c'est une terminologie beaucoup différente pour cela. Mais fondamentalement, vous pouvez déclarer une fonction en ligne sans même lui donner un nom. Et vous verrez que cela se passe beaucoup dans le code Spark. Par exemple, je pourrais dire transformer int trois x signe égal supérieur à x fois x fois x fois. Donc, ce que j'ai fait est de contourner la nécessité de définir réellement une fonction cubique là. Et j'ai juste un peu aimé trouver cette fonction en ligne avec si appeler une fonction lambda ou une fonction anonyme ou un littéral de fonction. Encore une fois, une terminologie différente pour la même chose. Donc, cela fait la même chose que 3 coudées. Mais au lieu de définir réellement une fonction cubique, nous définissons juste les tripes de cette fonction cubique ici en ligne dans le cadre de cette ligne. Donc, nous disons transform int la valeur 3, qui va être passé en x. et maintenant en passant dans le paramètre f transformez-le. Nous passons dans cette expression, Ross dit que nous allons prendre un paramètre d'entrée x et retourner x fois x fois x. Donc, c'est juste une sorte de raccourci de passer dans des expressions vraiment courtes en tant que fonctions. Et nous allons juste nous assurer qu'il fait ce que nous pensons qu'il fait. Donc, si nous frappons le contrôle Alt W, cela nous donne la valeur 27 parce qu'il passe en trois, passant trois en x, puis en cubinant ça. D'accord. Regardons un autre exemple. Même idée, transformer int 10 x x divisé par deux. Donc, c'est définir une chose nouvelle que nous n'avons pas vu auparavant. Et nous allons utiliser cette transformation et la fonction passer en dix dans x et en f. Nous passons dans ce genre de fonction lambda en ligne qui prend x et le divise par deux. Donc vous vous attendez à ce que ça revienne 1, 5, non ? Assez sûr. Un autre exemple, nous pourrions dire transformer int en x. et cela ira à, et nous pouvons mettre, nous devions plus compliqués ici. On pourrait dire que val y est égal x fois 2
point-virgule y fois. Et fermez ça. On pense qu'il va arriver avec celui-ci. Donc, ce que nous faisons ici est de passer une expression multi-ligne ici, au lieu d'une seule ligne, vous pouvez le faire, c'est cool. Donc, ici, nous sommes en train de configurer une valeur nommée y et de la définir sur x fois 2. Donc encore une fois, deux sont passés dans cette fonction en tant que x. donc nous allons commencer par dire 2 fois 2, ce qui est 4. Et puis on va dire y fois y, donc 4 fois 4. On devrait en avoir 16, non ? Contrôle Alt W. Bien sûr que nous obtenons 16. Ainsi, vous pouvez voir que ces fonctions lambda peuvent contenir des expressions
multilignes si vous les mettez juste entre parenthèses bouclés, c'est très bien. Donc c'est juste une sorte de nouveau, un raccourci de définir une petite fonction sans réellement définir la fonction elle-même. est donc pratique parfois, mais cela peut être un peu déroutant. D' accord. C'est beaucoup pour vous envelopper la tête. Comme je l'ai dit, il n'y a pas beaucoup de matériel ici, mais c'est difficile de s'enfoncer pour vous aider à le faire entrer. Encore une fois, j'ai un défi pour vous. Voici votre exercice pour cette leçon. Donc, les chaînes, il s'avère avoir la méthode dot intégrée ToUpperCase. Ainsi, par exemple, vous pouvez dire foo dot en majuscules et cela vous donnera FU dans toutes les majuscules. Donc, le mode de tweet rage, si vous voulez, votre,
votre exercice, votre défi est d'écrire une fonction qui convertit une chaîne majuscules, puis utiliser cette fonction pour quelques chaînes de test. Et puis je veux que vous fassiez la même chose en utilisant un littéral de fonction. C' est ces petites fonctions en ligne ici, au lieu d'utiliser une fonction nommée séparée. Donc, pratiquez-vous à faire en majuscules en utilisant une fonction traditionnelle, puis en utilisant un
littéral de fonction en utilisant ces petites fonctions lambda en ligne ici à la place. Pas trop dur, mais c'est une bonne pratique. Alors allez-y et prenez soin de ça. Et je te verrai dans la leçon suivante.
7. [Exercice] Des structures de données dans Scala: D' accord, continuons, Faisons encore une autre feuille de calcul Scala. Et on appellera ça, tu ne devineras jamais apprendre Scala 4. Et cette fois, nous allons parler de structures de données. Concept très important dans n'importe quelle langue. Et ça va être un peu long, alors supporte avec moi. Il existe donc de nombreux types de structures de données dans Scala. On a des tuples. C' est très courant quand on a affaire au code Spark. Nous avons des listes immuables. Et vous pouvez les considérer comme des champs de base de données ou des colonnes de données. Et ceux-ci peuvent être utiles pour passer des lignes entières de données ensemble, à droite, alors voyons à quoi cela ressemble. On peut dire des trucs de Val Capitaine. Et si vous n'êtes pas familier avec Star Trek II, je m'excuse pour les références de la culture pop ici. Picard, entreprise D, NCC 17, 0, 1, D, n'a pas vraiment d'importance. Il y a une liste de chaînes qui sont rassemblées dans ce que nous appelons un tuple ici. Maintenant, malgré le nom de tuple, ne doit pas nécessairement avoir trois choses en elle. C' est juste dans ce cas. Nous avons donc ce trio d'objets différents ici, ces trois chaînes qui sont regroupées entre ces parenthèses. Et nous pouvons traiter ça comme une seule entité que nous appelons trucs de
capitaine. Imprimantons ça. Contrôlez Alt W. Et vous pouvez voir que cela imprime comme cet objet lui-même, les trois chaînes, Picard Enterprise D, et NCC 17, 100 one-d. Dans ces parenthèses, c'est en fait un seul objet que nous avons appelé cap et trucs, et cet objet contient ces trois chaînes. Maintenant, nous pouvons déchirer cela et nous référer à ces composants individuels individuellement. Et nous le faisons en nous référant à eux sur la base de leur index unique qui est important. Reportez-vous aux champs individuels avec un index basé sur un seul. Cela peut être déroutant parce que dans beaucoup de langages de programmation, vous commencez à compter à partir de 0, n'est-ce pas ? Ce n'est pas le cas dans cet exemple particulier. Par exemple, une ligne d'impression, trucs de
capitaine, des points de soulignement. L' un est la syntaxe ici. Disons Control Alt W, qui imprime une carte, le premier élément de ce tuple. De même, on peut dire imprimer des trucs de capitaine de ligne soulignent deux, et imprimer des trucs de capitaine de ligne soulignent trois. Et nous obtenons chacun de ces éléments dépouillés de leur tuple d'origine. C' est ainsi que vous faites référence à des éléments individuels d' un tuple en utilisant ce format de soulignement commençant par un. Ok, qu'est-ce qu'on peut faire d'autre ? Nous pouvons créer des paires de valeurs clés, tout comme nous le faisons dans de nombreuses autres langues en utilisant l'opérateur flèche. Donc, par exemple, nous pourrions dire val cards ship est égal à la chaîne Picard tiret plus grand que petit symbole de flèche là, tiret d'entreprise d. Et je pourrais ensuite me référer à la partie valeur de cela avec une syntaxe similaire. Je pourrais dire la ligne d'impression, le vaisseau de
Picard, le point de soulignement deux, ça me donnera cette valeur. Donc, contrôlez Alt W. Donc vous pouvez voir que nous avons créé ce mappage de Pixar à Enterprise D. Et si nous voulons extraire cette valeur particulière, nous pouvons juste utiliser le soulignement 2 pour l'obtenir. Et vous pouvez réellement mélanger différents types dans un tuple. Au fait, on peut dire val, un tas de choses égal entre parenthèses Kirk, qui est une chaîne, 1964, qui est un nombre. L' année où Star Trek est sorti, bien sûr. Et un booléen, exécutons un booléen, vrai. Est-ce une chose valable à faire ? C'est légal ? Oui, c'est le cas. Ainsi, vous pouvez avoir un tuple qui contient différents types de données ainsi. Dans ce cas, une chaîne et int et un booléen. C' est parfaitement correct à Scala. Parlons ensuite des listes. Donc, les listes sont un peu comme un tuple, mais ce sont un objet de collection réel qui a plus de fonctionnalités. Et les listes ne peuvent pas contenir des éléments de types différents. Donc, comme un tuple, mais plus de fonctionnalités doivent être du même type. Très bien, petite note pour vous-même là-bas, par exemple. C' est en fait une liste unique liée sous le capot si vous êtes dans les structures de données. Donc on peut dire val, la liste des navires est égale à une liste, le capital L, l'
entreprise, le défi, le Voyager, le Deep Space neuf. J' ai oublié l'index 01, le meilleur de toutes façons. Alors, qu'est-ce que ça fait ? Contrôle Alt W. Et pourtant, nous avons un objet de liste qui a une liste de chaînes. Encore une fois, la liste doit contenir le même type d'objet. Dans ce cas, il s'agit d'une liste d'objets de chaîne. Et que pouvons-nous en faire ? Donc, comme avec un tuple, nous pouvons extraire des éléments individuels de cette liste, mais la syntaxe va être complètement différente. Donc, disons par exemple, imprimer la ligne, vaisseau, la liste, les parenthèses, un, juste comme ça. Qu'est-ce que tu crois que ça va faire ? Rendons l'entreprise ou me ramèneront à trouver, découvrons le contrôle Alt W me donne le définir. Donc, contrairement à la syntaxe de tuple, nous sommes en fait zéro ici. Bon, donc le vaisseau était 0 nous rendrait l'entreprise. Laisse-moi te le prouver. Mais la liste des navires 1 va nous donner le définir. Parce que nous commençons à compter à partir de 0 dans ce cas, qui est un peu plus ce que vous attendez. Nous avons également des opérateurs de tête et de queue disponibles. Donc on pourrait dire ligne d'impression, vaisseau, liste, tête de point. Et on peut dire que la ligne d'impression, le navire, la liste des points de queue, la tête fait probablement ce que vous attendez. Cela va vous donner le premier élément de la liste,
mais la queue ne l'est probablement pas. Qu' est-ce que vous attendez ? Il vous donne en fait tous les éléments restants. Au-delà de la première, Voyons voir, Contrôle Alt W. Et nous allons faire défiler vers le bas. Donc la tête nous a donné la première chose dans l'entreprise de liste qui est attendue, mais queue nous donne tout le reste. Donc, cela nous donne la liste de Voyager défini et DSpace neuf, sorte de sous-liste excluant le premier élément. Petite alchimie SQL bizarre, parfois bizarre. Supposons que vous vouliez parcourir chaque élément d'une liste. C' est une chose assez courante à faire, non ? La syntaxe pour cela est assez simple. On peut dire entre parenthèses, expédier moins de, alors jetez l'opérateur de flèche gauche leur liste de navires. Et puis une expression qui opèrera sur le navire. Imprimantons-le. D' accord. Donc, cela va parcourir chaque élément de la liste d'expédition, extraire chacune de ces chaînes et l'affecter à l'expédition, puis l'imprimer. Regardons. Oui, ça a marché. Donc, cela a imprimé chaque nom de vaisseau individuel. Et vous savez, si nous n'étions pas dans le cadre de la feuille de calcul, ce serait en fait sur
des lignes séparées, bien sûr, mais il essaie d'être intelligent en conservant de l'espace pour nous, ce qui est bien. Ok, soyons bizarres. Appliquons un littéral de fonction à une liste. Ok, c'est une programmation fonctionnelle. On peut faire des choses comme ça. Ainsi, nous pouvons utiliser la carte, la fonction de carte pour appliquer n'importe quelle fonction que nous voulons à chaque élément d'une collection. Voyons comment ça marche. Nous pouvons dire, par exemple, val backwards navires est égal à la carte des points de la liste des navires. Donc, cela signifie que nous allons mapper chaque élément de cette liste à une fonction que nous allons fournir. Et voici cette fonction. Nous allons juste le faire comme une fonction littérale dira que nous commençons par le vaisseau qui est une chaîne. Et cela va être transformé en parenthèses
bouclées expédition point inverse car il y a un opérateur inverse intégré sur l'opérateur de chaîne. Ok, alors élargissons ça un peu. Ça vaut la peine de voir tout ça dans un seul écran. Ok, alors enroulez votre tête autour de ça. Maintenant, c'est en quelque sorte lier beaucoup de ce dont nous avons déjà parlé. Donc on va prendre une liste. Nous allons utiliser la fonction de carte, qui est très importante dans le monde de l'informatique distribuée, pour mapper une fonction à chaque élément de cette liste. Et cette fonction va être un littéral de fonction où nous disons juste que certaines chaînes de vaisseaux vont être mappées à l'envers et retourner cela. Donc, après avoir exécuté ceci, nous devrions avoir une nouvelle liste appelée navires en arrière qui contient tous les navires en marche arrière. Alors allons de l'avant et imprimez-les. Avec quatre vaisseaux. arrière, nous venons juste de parcourir tout ce qui se trouve dans cette liste comme nous l'avons vu auparavant. Imprimer la ligne de livraison. Ok, alors voyons ce que ça fait. Là, vous l'avez. Donc les navires arriérés ont été affectés à cette liste où nous appliquons la fonction inverse à chaque élément de cette liste de navires. Et il a juste fait chaque mot à l'envers. Et puis nous avons parcouru un itéré à travers chacun de ces éléments de cette liste de navires arriérés et les avons imprimés. Donc ça a fonctionné. Cool. Eh bien, ça va faire. Alors. On a vu la carte. Vous avez peut-être entendu parler de MapReduce. Alors réduisons. Même concept. Donc, comme nous avions une carte, nous pouvons utiliser reduce pour combiner ensemble tous les éléments d'une collection en utilisant une fonction que nous allons fournir. D' accord ? Par exemple, disons que la liste des numéros de val est égale à la liste contenant 1, 2, 3, 4, 5. D' accord ? Assez simple. Maintenant, nous allons dire que val sum est égal à la liste des points de réduction. Donc, map appliquerait une fonction à chaque élément de la liste. Mais réduire va passer par tous les éléments de la liste et exécuter la même fonction dessus, vous
permettre d'accumuler tous les résultats de cela. Cela aura plus de sens avec un exemple. On pourrait donc dire, par exemple. Parenthèses, puis imprimez le c x deux-points int y deux-points int. Mappe
ça à X plus Y. Alors réfléchissons à ce qui se passe ici. Donc réduire conserve fondamentalement un total en cours d'exécution d'une sorte. Donc, il va prendre la sortie précédente de la fonction reduce de l'itération précédente, passer cela dans x. il a ensuite pris l'itération actuelle, le nombre qui regarde en ce moment appelle ce Y et applique une opération à ça. Et la sortie de cette opération sera introduite dans l'étape suivante lorsque nous passerons à l'élément suivant. Laisse-moi parcourir ce qui se passe ici. On va commencer par un. Et nous allons dire 1 plus 2, qui est 3, va ensuite passer cela dans la prochaine itération. Et nous aurons 3 plus 3. Le résultat en sera six. Ensuite, nous avons six plus quatre. Le résultat sera 10, puis 10 plus 5 devrait être 15. D' accord, c'est comme ça que Reduce fonctionne. Quand nous aurons fini, nous allons imprimer cette valeur, en imprimer une ligne. Exécutons ça. Bien sûr, j'en ai 15. Alors réduisez. C' est juste un moyen d'effondrer en quelque sorte tous les résultats en une seule réponse finale. Et souvent c'est utilisé pour calculer comme un grand total ou quelque chose comme ça. Vous pourriez penser à des moyens plus simples de le faire. Mais la bonne chose à propos de la carte et de la réduction des fonctions est qu'elles sont très parallélisables. Il est donc très facile d'appliquer des fonctions de carte en parallèle, puis de combiner les résultats de ces fonctions de carte dans une sorte d'étape de réduction pour obtenir la réponse finale que vous voulez. Nous verrons cela plus en action avec des exemples plus tard dans le cours. Que pouvons-nous faire d'autre une opération de filtrage aussi. Si vous voulez supprimer des choses que vous ne voulez pas. Donc, le filtre supprime les choses. Par exemple, nous pourrions faire une nouvelle liste appelée Je déteste cinq et passera, assigner cela au filtre de points de liste de numéros, en lui
passant une autre fonction en ligne ici. Fonction littérale, si vous voulez. X-Nulght égale cinq. D' accord ? Donc, ce que cela va faire est d'appliquer cette fonction de filtre. Est-ce que x néant est égal à cinq et ne retourne cela dans notre liste résultante que si c'est vrai. Alors voyons ce que ça fait. Cela nous donne une liste 1234 parce qu'elle excluait la valeur cinq. C' est ainsi qu'un filtre fonctionne. Il peut filtrer les informations invalides, les valeurs aberrantes, tout ce que vous voulez faire. C' est un bon moyen de nettoyer les données. Encore une fois, d'une manière qui est parallélisable. On fait la même chose. On pourrait dire dans une syntaxe légèrement différente. Val je déteste 3s égale liste de nombre filtre point. Et c'est une sorte de soulignement abrégé, pas égal à trois. Donc, au lieu d'écrire réellement ce x en donnant à cette valeur x un nom, nous n'avons pas vraiment besoin d'un nom. Nous voulons juste prendre la valeur qu'il y a et vérifier ça contre trois. Donc, c'est une sorte d'expression abrégée de faire cela en utilisant le caractère de soulignement. Alors voyons ce que ça fait. 12, 45. Donc syntaxe équivalente, vous avez remarqué en utilisant trois au lieu de cinq et un peu plus facile à taper. Donc, si vous voyez cette syntaxe, c'est ce qui se passe là-bas. Le trait de soulignement est essentiellement un détenteur de place pour chaque élément de la liste. D' accord ? D' accord. Maintenant, il est intéressant de noter que Spark a ses propres fonctions MapReduce et filtrer qui distribuent ces opérations. Ils fonctionnent exactement de la même façon. Donc Scala a son propre MapReduce intégré et filtre. Spark a également son propre MapReduce et son propre filtre. La différence est que Spark va être sûr de paralléliser cela sur toutes les machines de votre cluster si elle le peut. Ok, hey, vous comprenez réellement MapReduce maintenant d'ailleurs, c'est le concept fondamental derrière MapReduce. C' est assez simple, si peu Bonus Army pour toi. Quelques autres opérations de liste que vous pouvez faire. Comment concaténer des listes ? Syntaxe pour ça ? Disons Val, créons une autre liste. Donc on a quelque chose à jouer. Plus de nombres équivaut à la liste 678. Et on peut dire val, beaucoup de nombres équivaut à la liste des nombres plus, plus plus plus de nombres. Donc, pour concaténer deux listes ensemble, utilisez cet opérateur double plus. Voyons ce que ça fait. Contrôle Alt W. Donc là, vous l'avez. Nous avons une nouvelle liste appelée beaucoup de numéros. Je peux concaténer la liste des nombres qui contiennent 1, 2, 3, 4, 5 et les plus de nombres énumérés 678 en une seule liste, 1, 2, 3, 4, 5, 6, 7, 8. Notez que nous n'avons pas récupéré un tuple de deux listes. Il s'agit d'une liste unique qui contient toutes les valeurs de ces deux listes. Quelques choses plus aléatoires que nous pouvons faire avec des listes. Donc nous sommes inversés. Ce qui est dans une liste avec inversé égal à nombre de
points de liste inverse, Cinq 4321. Et ils étaient en fait une question d'entrevue que je donnais aux gens d'Amazon inverser les mots dans une chaîne ou inverser les éléments d'une liste auparavant, c'était une chose difficile à faire et la plupart des langages de programmation, mais si vous entrez dans leur utilisation Scala, vous pouvez le faire dans une ligne de code. Tellement peu de moyen de tricher. Ils sont en train de trier. Vous pouvez dire que val trié est égal à point inversé assorti. Oups, j'espère que j'ai orthographié inversé, non ? Alors allons de l'avant et trions ça. Et c'est de retour dans l'ordre trié. 1, 2, 3, 4, 5. Facile à pétiller. Que veux-tu d'autre voyelle ? Beaucoup de doublons. Égale liste de numéros plus, plus nombre. Alors concaténons les deux listes ensemble et voyons ce qui se passe. Nous concaténons une liste à elle-même et vous voyez que nous pouvons le faire. 1234512345. Ainsi, les éléments d'une liste n'ont pas besoin d'être uniques. Vous ne pouvez pas avoir de doublons là-dedans. C' est ce que je vous montre avec ce petit exemple. Mais si vous ne voulez rien d'autre que des valeurs distinctes, vous pouvez le faire aussi. Nous pourrions dire que val valeurs distinctes est égal à beaucoup de doublons, points distincts. Et cela ne retournera que ces valeurs distinctes dans cette liste. Et vous pouvez voir qu'on est de retour à 12345. n'y a pas de doublons dans ce distinct. Je veux juste obtenir le maximum, la valeur maximale dans une liste C'est facile. La valeur maximale des voyelles est égale à la liste des points x. et c'est cinq. Si vous vouliez obtenir le total, nous pourrions dire que val total est égal à point de liste de nombre. Un peu plus simple moyen de le faire que d'utiliser une fonction réduite. Ça marche aussi. On a la valeur 15. Il y en a beaucoup plus simplement. Et nous pourrions dire, si vous voulez vérifier si un élément existe dans une liste, c'est aussi facile à faire. Val a trois égaux, je déteste trois. Dot contient trois, donc nous vérifions la liste Je déteste les trois que nous avons faite plus tôt pour voir si elle contient la valeur 3, elle ne devrait pas. Assez sûr que c'est revenu comme faux. D' accord, on y arrive les gars. La dernière chose dont je veux parler, c'est des cartes. Ainsi, vous pouvez les savoir en tant que dictionnaires et d'autres langues sont des recherches de valeur clé sur des clés distinctes. Structure de données très utile dans beaucoup de situations différentes. Alors parlons de comment ça marche. Mettons en place une carte appelée carte du navire. Petit commentaire ici. Donc, nous savons que nous parlons d'applications qu'elles sont importantes. Donc, eval shit map va être égal à une majuscule de carte M qui contient les paires de valeurs clés suivantes. Ainsi, par exemple, Kirk, flèche, entreprise, virgule Picard, flèche entreprise D, Cisco, Deep Space Nine, Janeway, Voyager. Je pourrais continuer, Archer et ainsi de suite. Mais je vous épargnerai la dactylographie. D' accord, donc ce que nous avons fait ici, c'est de mettre en place un objet de carte. Assurez-vous que je ferme ça correctement. Et vous pouvez voir que nous avons récupéré un objet cartographique qui mappe des chaînes à des chaînes. Encore une fois, les types de données doivent être les mêmes. On mappe les chaînes nommées par le capitaine à leur vaisseau. Et vous pouvez avoir des chaînes de mappage à ints ou quelque chose comme ça, mais vous devez avoir un type cohérent dans chaque paire de valeur de clé, au moins. C'est logique. Donc maintenant, si nous voulions utiliser cette carte, nous pourrions dire quelque chose comme la ligne d'impression, la carte expédiée, Janeway entre parenthèses, et Control Alt W, qui nous ramène Voyager. Vous pouvez donc voir que nous avons une petite table de recherche rapide que nous avons définie en utilisant une carte qui nous
donnera la valeur Voyager étant donné le nom de clé Janeway. Chose très utile dans beaucoup de situations. Et les clés manquantes ? Donc, en fait, j'ai intentionnellement omis un des capitaines de navires là-bas. Disons la ligne d'impression. Navire, point de carte contient archer. Archer n'est pas dans ma liste sur ma carte là-bas. Ça revient comme faux. Comment puis-je gérer ça ? Que se passe-t-il si j'essaie d'aimer chercher archer, où il n'existe pas sur la carte. Eh bien, essayons-le. Val archers navire égale util dot essayer. Donc on va faire un essai ici, carte du navire, Archer, obtenir ou autrement Inconnu. Très bien, donc nous faisons une gestion des exceptions ici. Et puis on imprimera la ligne ou le bateau touristique. Oups, ligne d'impression, archers, vaisseau, contrôle, Alt W. Donc, fondamentalement, nous faisons comme un petit traitement d'exception ici. Donc, nous essayons d'obtenir notre bloc d'autre ici. Donc en enveloppant la carte Archer dans cette try-block, ça veut dire que ça ne va pas aimer devenir balistique parce que notre vrai n'existe pas. Nous récupérons une sorte de valeur indéfinie dans ce cas. Donc, l'exception d'essai là, elle est déclenchée. Et c'est cette clause getter else à la place et retourne une chaîne inconnue dans ce cas. C' est donc une façon de gérer les valeurs
manquantes dans une carte ou de gérer la possibilité de valeurs manquantes dans une carte. Ok, ça suffit définitivement. Et nous en avons fini avec les bases de Scala. Donc, tu sais, juste assez pour être dangereux ici. Maintenant, nous allons obtenir beaucoup plus de pratique au fur et à mesure que nous le cours en regardant beaucoup d'exemples différents. Et c'est vraiment comme ça que tu vas l'apprendre. Mais j'espère que cela démystifie une partie de la syntaxe pour vous, au moins. Un dernier exercice pour vous. Permettez-moi de copier ceci dans un dernier défi. Donc, c'est pour toi. Votre défi, si vous choisissez de l'accepter, créez une liste des numéros un à 20. Et je veux que vous imprimiez les chiffres qui sont divisibles uniformément par trois. Et il y a quelques indices ici dans le texte qui pourraient vous guider. Encore une fois, c'est une question d'entrevue très courante que j'avais l'habitude donner
aux gens pendant les écrans de téléphone et Amazon, vous seriez étonné combien de gens ne pouvaient pas faire cela avec succès dans importe quelle langue qu'ils voulaient essayer et le faire dans Scala. Il y a un opérateur modulo, comme dans d'autres langues dont je parle ici, qui vous donne le reste après la division. Donc, tout ce qui est divisible par trois devrait avoir un modulo 3 qui revient comme 0. Donc c'est votre premier indice. Donc juste itérer à travers tous les éléments dans les tests de liste. test modulo est que vous allez et vous pouvez ensuite le faire à nouveau en utilisant une fonction de filtre sur la liste à la place. Donc, quelques façons d'y arriver. Allez-y et pratiquez-y. Et après ça, je pense que tu sauras assez de squelette dangereux. Et nous allons passer à autre chose et entrer dans les tripes d'Apache Spark lui-même.
8. Les Dataset distribuées résilientes: Alors plongons dans Spark lui-même et nous commencerons par un aperçu de Spark et aussi de son API d'origine, le RDD. Nous parlerons de ce que cela signifie bientôt. C' était la première API qui étincelle est sortie dans Spark un. Et même s'il a été largement remplacé dans les versions
suivantes par des API plus récentes, il est toujours là. Vous allez toujours devoir l'utiliser de temps en temps. Et il y a quelques problèmes, comme nous le verrons, où les RDD sont toujours la solution la plus efficace. Vous devez également rencontrer des bibliothèques tierces que vous voudrez peut-être
utiliser RDD et vous devrez peut-être regarder un code hérité qui utilise deux, donc cela vaut toujours la peine d'apprendre. Après cette section cependant, nous allons nous concentrer sur des API plus modernes comme les dataframes et les jeux de données. Mais pour l'instant, commençons par les bases et apprenons le noyau Spark lui-même, le RDD. Alors commençons par parler de racines étincelles et c'est l'interface RDD. Rdd signifie Resilient Distributed Dataset, à
ne pas confondre avec les jeux de données dans Spark, c'est une chose différente. Les jeux de données sont plutôt confus sur des RDD. C' est une API de niveau supérieur. Mais à son cœur, Spark est tout au sujet des RDD. Et qu'est-ce que c'est ? Eh bien, fondamentalement un RDD est un tas de rangées de données d'une sorte ou d'une autre. Et parce qu'elle est divisée en lignes, ces lignes peuvent être distribuées différents ordinateurs et être traitées en parallèle sur ces différents ordinateurs. C' est pourquoi il est distribué. Donc, c'est un jeu de données parce que c'est un tas de lignes d'informations est distribué parce que nous pouvons potentiellement diviser ces lignes entre plusieurs ordinateurs. Et c'est résilient parce que, eh bien, Spark s'assure que le traitement que vous faites sur le RDD se fait d'une manière ou d'une autre, non ? Donc, il est étincelle problème de comprendre ce qui se passe si un nœud descend au milieu de votre opération pour faire tourner un nouveau pour prendre sa place. Donc, la première chose que vous devez faire avant de créer un RDD et Spark est de créer un contexte Spark. Et votre programme pilote fera cela comme l'une des premières choses qu'il fait. Donc, l'objet de contexte Spark est ce responsable de rendre ces RDD résilients et distribués. Vous n'avez pas besoin d'écrire le code pour vous assurer que vous pouvez gérer aucune défaillance ou défaillance matérielle. Vous n'avez pas besoin d'écrire le code pour savoir comment
distribuer ces données sur l'ensemble de votre cluster. Le RDD lui-même dans le contexte Spark est de trouver comment le faire pour vous. Tout ce dont vous avez besoin est de savoir comment transformer vos données. Ainsi, votre contexte Spark va créer les RDD que vous demandez. Et si vous utilisez réellement le shell Spark de manière interactive, il va créer un objet pour vous automatiquement, ce sera votre contexte Spark. Vous devez le créer explicitement, il est déjà là. Cela aura plus de sens lorsque nous examinerons un code. Alors, comment puis-je créer un RDD ? C' est généralement assez simple. Une façon est de lui donner une liste explicite de choses. Donc, le premier exemple il y avait dit val nums égale liste 1, 2, 3, 4. Cela va créer un RDD appelé nums qui contient juste sur chaque ligne 1, 2, 3 et 4. Évidemment, ce n'est pas terriblement utile dans le monde réel parce que si vous êtes capable d'écrire et de coder en dur ce qui est dans votre RDD. Ce n'est probablement pas de Big Data et ce ne sont probablement pas de vraies données non plus. vous savez, pour tester les choses,
tester des cas parfois c'est utile. Plus souvent, vous allez charger des données à partir d'un fichier texte quelque part. Et pour ce faire, vous pouvez simplement dire SC, en supposant que c'est votre fichier Txt d'objet de contexte Spark et le passer le,
le chemin vers votre fichier texte géant et d'autres choses. Et cela va créer un RDD où chaque ligne de ce texte fichiers sa propre ligne dans le RDD. Et il n'a pas besoin de provenir du système de fichiers local. Maintenant, un peu vaincre le but du Big Data, n'est-ce pas ? Donc, il peut également le lire à partir de systèmes de fichiers distribués, y compris HDFS, qui est le Hadoop Distributed File System, ou même Amazon
S3, S3 et n serait le préfixe pour cela. Donc, il y a toujours des extensions pour charger des données dans un Spark RDD à partir de diverses sources de données distribuées parce que des étincelles sur le Big Data, n'est-ce pas ? Donc, sa capacité à charger des données à partir de magasins de données
distribués est un peu fondamental pour ce que vous faites. Cela ne doit pas nécessairement être un fichier texte. Vous pouvez même créer un, un RDD à partir d'un contexte de ruche. Par exemple, si vous utilisez Hive, et que vous pouvez alors faire demi-tour et simplement exécuter commandes
SQL sur ce haut de contexte si vous le souhaitez également. C' est donc une façon de faire du SQL dans l'environnement Hadoop. Vous pouvez également créer des RDD directement à partir de JDBC. Donc, si vous avez une base de données quelque part, vous pouvez assez facilement la transformer en un RDD et Spark. Vous pouvez parler à aucune base de données SQL comme Cassandra ou Hbase. Vous pouvez également l'intégrer à Elastic Search si vous le souhaitez. Et il ne doit pas être un fichier texte soit vous pouvez utiliser des données structurées comme des JSON ou CSV ou des fichiers de séquence ou des fichiers d'objet. Et il prend également en charge divers formats compressés également. Encore une fois, avec le Big Data, les données sont parfois compressées. Et aussi longtemps que c'est un format sans perte qui peut être parallélisé, alors vous pouvez créer un RDD à partir de lui aussi. Une fois que vous avez un RDD, qu'en faites-vous ? Eh bien, vous voulez probablement le transformer d'
une manière ou d'une autre et il y a diverses opérations pour le faire. Map, par exemple, fonctionne exactement comme MapReduce vraiment. Il vous permet d'appliquer une fonction à chaque ligne de votre RDD en parallèle. Et nous en verrons un exemple sous peu. Flatmap est similaire. La seule différence entre map et FlatMap est que la carte a une relation un-à-un. Donc, la carte prendra une ligne de votre RDD et la transformera en une ligne d'un autre RDD. Flatmap, celui qui peut diviser les choses. FlatMap pourrait donc prendre une ligne d'un RDD et créer plusieurs lignes dans un autre RDD. Par exemple, si vous aviez comme une liste de choses dans chaque ligne, FlatMap pourrait le diviser en lignes individuelles pour chaque chose. Et nous le verrons dans un exemple sous peu. Vous pouvez également faire des filtres. Donc, si vous voulez supprimer des données, nettoyer les données, vous pouvez le faire aussi. Vous pouvez définir une fonction de filtre sur laquelle chaque ligne sera testée. Et si cette fonction retourne false, elle la jettera dans le RDD résultant. C' est donc un bon moyen de nettoyer vos données et de se débarrasser des données manquantes, des choses comme ça. Vous pouvez également exécuter distinct dessus. Si vous souhaitez éliminer les valeurs en double dans vos RDD, vous pouvez l'échantillonner. Et si vous voulez juste prendre un petit échantillon d'un RDD fins d'expérimentation ou autre. Et vous pouvez également faire des opérations booléennes fantaisies entre RDD, comme l'union de deux RDD, l'intersection de deux RDD, vous pouvez soustraire un RDD d'un autre ou faire un produit cartésien entre deux RDD également. Ce sont des cas d'utilisation plus avancés. Voyons ça en action. Donc disons que je veux juste tout caler dans mon RDD. Disons que vous avez un RDD que j'appelle RDD vrai nom créatif, non ? Et nous avons fait cela en faisant ce tour parallélisé à nouveau, nous avons juste un RDD de quatre lignes où chaque ligne contient respectivement 1234. Sur la ligne suivante, nous créons un nouveau RDD appelé carrés en appelant simplement la carte de points RDD x à x fois x. Donc ce que cela fait est de passer la fonction, prendre X et de le transformer en x fois x et de l'appliquer à chaque ligne du RDD, RDD, le RDD résultant sera appelé carrés. Donc, quand on aura fini d'exécuter cette opération de carte, les carrés contiendront les lignes suivantes, 1, 4, 9 et 16, non ? Alors nous suivons, suivez-moi là-bas. Et la beauté de celui-ci est que, qui peut être distribué. Donc, si déjà D était vraiment énorme, il pourrait réellement diviser ce traitement et gérer ce carré sur différents morceaux de ce RDD sur différents nœuds
différents dans votre cluster, puis aspirer tous ces renvoie à votre script de pilote pour obtenir les réponses finales que vous voulez. Donc c'est une syntaxe un peu bizarre là-bas. Tu n'as peut-être pas vu ça avant. Ce x à x fois x truc de ce qui se passe là-bas ? Eh bien, c'est de cela que nous parlons quand nous parlons de programmation fonctionnelle. Donc, beaucoup de méthodes RDD vont
accepter une fonction en tant que paramètre et pas seulement une valeur. Et c'est ce qui se passe ici. Donc syntaxiquement x, puis la flèche funky à x fois x est la même chose exacte que de définir une fonction pour carré quelque chose. On l'appelle « carré ». Et cette diapositive qui prend un entier appelé x et retourne x fois x. en fait, le mot-clé return serait optionnel et Scala, vous pouvez simplement dire x fois x et cela fonctionnerait juste. Et puis en disant carte de points RDD passant dans la fonction racine carrée, il appliquerait cette fonction racine carrée à tout dans ce RDD. Mais syntaxiquement, c'est la même chose exacte que de dire carte de points RDD x, flèche
funky x fois x. donc vous avez tendance à voir ce raccourci. Si vous avez une transformation très simple que vous faites, que vous pouvez entrer dans une ligne là-bas. Mais c'est tout ce que c'est. Comme si on passait cette fonction. Donc, dans cet exemple, nous définissons une fonction sur la façon de carrés des nombres. Et nous transmettons cette fonction dans le RDD à travers l'opérateur de carte là-bas. Et c'est ce que vous comprenez la programmation fonctionnelle. Maintenant, c'est le concept clé. On ne fait que passer des fonctions. Et le plus grand aperçu ici est que, vous savez, le langage de l'échelle lui-même vous
oblige en quelque sorte à écrire ces fonctions qui peuvent être distribuées. Donc, les caractéristiques de l'échelle et le rendre plus facile de le faire un peu, mais c'est, c'est tout. C' est tout ce que nous entendons par programmation fonctionnelle. Vous savez, nous pensons en quelque sorte en parallèle et en appliquant des fonctions, deux gros ensembles de données en transmettant ces fonctions à des choses comme RDD à ce sujet, c'est tout. Ce n'est pas si dur. Très bien, une fois que vous avez réellement transformé tout dans votre RDD comme vous le voulez. Qu' est-ce que tu en fais ? Comment récupérez-vous vos résultats ? Eh bien, c'est ce qu'est une action RDD. Donc, une action est fondamentalement quelque chose qui provoque effondrement de
votre RDD et vous redonne un résultat à votre script de pilote. Une chose que vous pourriez faire est d'appeler la collecte sur le RDD qui vous donnera
tout dans ce RDD retour comme une structure de données géante dans Scala. Vous savez, si c'est un gros jeu de données qui n'aura pas beaucoup de sens plus souvent vous allez essayer d'en tirer plus d'une opération réduite. Par exemple, nous pourrions dire compter si nous voulons juste compter combien de choses est dans le RDD, nous pouvons dire compter par valeur. Si vous voulez obtenir un compte du nombre de lignes existant pour chaque valeur unique donnée dans une paire clé-valeur. Vous pouvez prendre juste, vous savez, sorte d'échantillon d'un certain nombre de lignes du haut RDD pour prendre les premières lignes ou réduire pour obtenir une sorte de grand total de toutes les lignes de votre RDD. Et il y a d'autres actions aussi. Mais l'idée de base est qu' une action RDD vous donne une réponse à votre script de pilotes. Donc, il y a une force Spark pour sortir et dire, Ok, je vais vous les processus exécuteurs finis ce que vous faites et donnez-moi une réponse. Et nous allons rendre cette réponse à mon script de pilote. C' est ce qu'une action fait. Et la façon dont ça marche est un peu intéressante. Donc tu dois te souvenir de ça à Spark. Rien ne se passe vraiment dans votre programme pilote tant que vous n'appelez pas une action. C' est une sorte de stratégie d'évaluation paresseuse ici. Et il y a une très bonne raison à ça. Donc, jusqu'à ce que Spark sache ce que vous
essayez d'accomplir grâce à l'action que vous essayez d'obtenir à la fin, il ne sait pas comment optimiser toutes les opérations que vous avez effectuées. Rappelez-vous donc que la clé ou l'une des clés de la performance de Spark est qu'il peut construire ce graphique acyclique dirigé qui est très optimisé pour le résultat final que vous voulez atteindre. Donc, cela peut être un peu déroutant lorsque vous déboguez vos scripts de pilote Spark parce que, vous savez, vous pouvez appeler une opération de carte ou une sorte de transformation sur votre RDD. Et il semblera que rien ne s'est passé dans votre code. Ce n'est que lorsque vous appelez réellement une action que tout va réellement être exécuté et envoyé aux différents nœuds de votre cluster et vous obtiendrez réellement un résultat. Donc ça peut rendre le débogage un peu délicat, non ? Parfois, vous devez coller un peu d'action temporaire là pour revenir et résultat intermédiaire dans. Assurez-vous que c'est ce que vous attendez lorsque vous déboguez les scripts du pilote Spark. Donc quelque chose à être conscient, surtout pendant que vous déboguez ces choses. Et avec ça, plongons dans d'autres détails.
9. Exemple Histogram avec des évaluations avec des évaluations: Donc, il est généralement préférable de comprendre les choses à travers un exemple, n'est-ce pas ? Alors faisons ça. Voyons en savoir plus sur les RDD en regardant un exemple très simple de les utiliser. Nous allons donc plonger dans un exemple simple dans notre matériel de cours qui
compte juste le nombre d'une note donnée dans notre jeu de données MovieLens. Donc, comme vous vous en souvenez, le jeu de données MovieLens est un jeu de données de 100 000 évaluations de films, où les gens ont évalué un tas de films de une à cinq étoiles. Et disons que nous voulons juste savoir combien il y a une étoile,
combien de cotes deux étoiles, combien de cotes trois étoiles, et cetera ? C' est quelque chose qu'on peut faire avec Apache Spark. Donc, avant de plonger dans le code ici et ce qu'il fait, nous allons juste le lancer et nous familiariser avec ce qu' il fait et nous mettre à l'aise avec le code lui-même. Alors allons faire ça. Donc, si vous ouvrez l'intelligence et allez dans le fichier du compteur de notes ici, c'est celui avec lequel nous allons jouer ici et plonger exemple
très simple d'un script de pilote Apache Spark ici. Et nous allons parler de chaque ligne et de ce qu'elle fait plus en détail. Mais à un niveau élevé, ce que nous faisons est de charger le jeu de données MovieLens sur chaque cœur de CPU de notre machine ici. Et nous allons compter combien de fois chaque valeur d'évaluation unique se produit dans cet ensemble de données. Nous allons donc charger chaque ligne qui représente chaque évaluation dans ce jeu de données. Et nous allons le diviser en son propre RDD. Nous allons compter combien de fois chaque évaluation apparaît réellement, trier les résultats et les imprimer. Et nous allons juste le faire et
nous convaincre que cela fonctionne et fait quelque chose d'intéressant, non ? Donc, nous allons faire un clic droit sur le compteur de notes et dire Exécuter. Et si on clique sur, on y va. Et ça devrait aller dans Spin Up Spark. Et voilà nos réponses. Donc, ce que cela nous dit, c'est que nous avons eu 61101 évaluations d'étoiles, 11 372 évaluations d'étoiles, 27 145, trois étoiles, et ainsi de suite et ainsi de suite. Et ces données elles-mêmes sont un peu perspicaces, non ? Comme il nous dit que la note la plus courante pour un film est quatre étoiles. Et il y a une bonne quantité de trois étoiles et cinq étoiles ne sont pas là aussi. Mais les gens ont tendance à être qui semblait avoir une échelle raisonnable pour la façon dont ils lisent ces films. Et ils semblent réserver une étoile pour le pire des pires. Donc, sur 100 000 évaluations, seulement 6000 et quelques changements, nous sommes en fait notés une étoile. Donc, cela nous donne une certaine confiance que ces données sont significatives juste dans ce script très simple ici, même. Donc, revenons en arrière et parlons plus de ce que fait ce code. Alors passons à travers ce que ce code fait à chaque étape ici. Nous commençons donc par importer ce dont nous avons besoin. Et nous disons juste que nous déclarons cela dans le paquet que nous avons nommé logiciel de chiens Dotson, point étincelle. Vous savez, c'est une sorte de convention dans le monde Java sur la façon dont vous donnez à vos paquets un nom unique. Dans ce cas, j'utilise un nom de domaine que je possède. Et puis nous importons les paquets dont nous avons besoin. Nous importons simplement tout de Spark et tout de log pour J parce que nous allons utiliser un journal pour J pour ajuster notre niveau d'erreur dans notre journalisation. C' est tout ce qui est. Ensuite, nous avons mis en place un contexte Spark, comme nous avons parlé plus tôt. Nous définissons donc SC dans un nouveau contexte Spark. L' étoile des parenthèses locales signifie que nous allons être en cours d'exécution juste sur notre machine locale. Donc on n'a pas de groupe dans notre salon ici, n'est-ce pas ? Alors. À des fins d'expérimentation et d'apprentissage, nous allons simplement fonctionner sur notre propre machine. Mais cette étoile signifie que je vais la laisser paralléliser elle-même, au moins tout
au long des multiples cœurs de CPU qui pourraient exister sur ma machine. Donc, même si c'est sur un système, il pourrait en fait faire tourner plus d'un processus et
profiter des différents cœurs de CPU que j'ai. Et compteur de notes est juste ce que nous nommons cette application. Ensuite, nous chargeons les données et nous créons juste une ligne RDD en appelant SC dot fichier txt avec un chemin relatif à l'endroit où ces données sont. Dans notre code, ce chemin est plus explicite quant à l'endroit où il réside
réellement dans notre matériel de cours, mais vous avez l'idée. Donc, il a un chemin vers le fichier de données u dot, qui est le fichier de données qui contient toutes les informations de lecture et le format de cela. Un exemple de cela est dans le coin supérieur gauche ici. Donc chaque rangée ressemble à ceci. Il commence par un ID utilisateur, puis un ID vidéo, puis une évaluation, puis un horodatage. Donc, tout est encodé dans une sorte d'ID numérique ici. Je veux dire, je ne sais pas ce qu'est l'utilisateur 196 ou quel est l'ID de film 242. Il y a un fichier séparé pour les chercher. Mais l'ID de l'utilisateur 106 évalué film 2423 étoiles. Et ils l'ont fait à cette époque, qui se traduit par un
certain rencard et que nous pourrions humainement avidité mais des ordinateurs comme Epoch secondes. C' est donc juste le format de ces données. Donc la première chose que nous allons faire est de charger les 100 000 lignes de ce fichier dans le RDD d'une ligne, où chaque ligne représente une ligne de ce fichier de données. D' accord ? Et encore une fois, nous commençons par RDD ici. Nous allons dans la section suivante parler de la façon de
faire tout cela en utilisant des jeux de données à la place, qui est l'API la plus moderne. Mais encore une fois, ils sont tous les deux un outil utile. Parfois, les RDD vont être plus rapides que les jeux de données. Parfois, les RDD vous permettent de faire plus. Donc, nous commençons par les bases, l'API de niveau inférieur ici des RDD. Et vous constaterez que l'utilisation de jeux de données n'est pas très différente. Mais commençons par les RDD ici. Donc, en ce moment, nous avons une ligne RDD. Ensuite, nous devions faire quelque chose à ces données. Donc la première chose que nous voulons faire est d'extraire les informations qui nous intéressent réellement de ce RDD. Donc, nous allons appeler la carte sur les lignes RDD, passant en fonction de la façon dont nous voulons transformer chaque ligne de ce RDD. Et dans ce cas, la fonction prend chaque ligne et l'appelle x. puis sur cette ligne, cette chaîne, nous allons la convertir explicitement en une chaîne et appeler split dessus, en se
divisant sur le caractère de tabulation parce que c'est données délimitées par des tabulations et l'extraction ajuster le champ numéro 2. Maintenant, rappelez-vous en informatique, nous commençons souvent à compter à partir de 0. Donc deux est en fait la troisième colonne de données. Donc, ce que cela fait est d'extraire la troisième colonne, qui est la note elle-même, et rien d'autre. Donc, c'est extraire cette note de chaque ligne et l'insérer dans un nouveau RDD appelé rating. Suivez-moi. Donc nous commençons par une ligne RDD, c'est ceux dans le coin supérieur gauche là-bas. Nous appelons une fonction de carte sur elle pour appliquer cette fonction à chaque ligne
des lignes RDD pour extraire cette troisième colonne de données, la notation elle-même. Et cela va dans un nouveau RDD appelé évaluations, qui dans cet exemple contiendrait juste 33 un à un sur chaque ligne des notes RDD respectivement. Donc, c'est pour cela que la cartographie est utilisée
là, c'est juste pour extraire les données qui nous tiennent à cœur. Et vous savez, dans certains cas, vous pouvez reformater les choses ou les
mettre dans un format différent que certains processus en aval veulent. Mais en général, c'est ce qu'est la cartographie. Maintenant, nous devons faire quelque chose avec toutes ces informations. Donc, dans ce cas, nous allons effectuer une action et notre action dans ce cas est comptée par valeur. C' est ce qui va provoquer l'effondrement de nos données et nous donner une réponse. Donc ce mappage que nous avons fait dans la diapositive précédente aurait pu être distribué entre de nombreux nœuds d'exécuteurs, non ? Mais en disant que nous voulons compter les valeurs, Cela va nous rendre une réponse explicite et
remettre un résultat à notre script en tant qu'objet Scala. Donc, dans ce cas, nous disons que les notes sont comptées par une valeur. Cela fera ce qu'il dit. Vous donnez un compte du nombre de fois que chaque valeur unique apparaît. Donc, dans cet exemple, nous avons 23 évaluations. Donc, nous récupérons la valeur trois virgule deux, ce qui
signifie que pour la note 3, il y en a deux. Pour le classement 1, il y en a deux. Et pour la note 2, il n'y en a qu'un. C' est donc ce que le compte par valeur renvoie. Et dans ce cas, ça ne nous rend pas un nouveau RDD. Il transmet cela à nos scripts pilotes qui vont dans une, une nouvelle valeur appelée résultats au niveau Scala. Donc, en appelant cette action, nous avons récupéré ces résultats
du cluster et les avons remis dans notre lecteur ou script local. Et à ce stade, nous ne sommes plus dans Spark terre étaient de retour en ligne Scala. Nous sommes de retour dans notre script de pilote. C' est là que vit l'État à ce stade. Et à ce moment-là, nous voulons juste le trier et l'afficher. Donc, nous avons un peu de code Scala simple ici pour prendre cet ensemble de résultats, les
convertir en une séquence et les trier par le second champ. Et puis nous les imprimons simplement en appliquant la fonction de ligne d'impression à chaque ligne de ce résultat final, à chaque ligne de cette séquence que nous avons définie, n'est-ce pas ? Donc encore une fois, c'est juste la syntaxe Scala ici. Nous prenons les résultats, les convertissons en une structure de données de séquence, trions par cette deuxième colonne. Et puis pour chaque ligne de cette séquence dans Scala, nous appliquons la fonction de ligne d'impression pour imprimer le contenu de cette séquence. Et c'est ainsi que nous voyons notre résultat final ici. Où nous avions vu que nous avons à 1 étoiles évaluations, 12 étoiles, et deux évaluations trois étoiles. Donc c'est aussi facile que ça. Encore une fois. Allons le lancer et nous convaincre à nouveau que cela fonctionne maintenant que nous avons plus d'une appréciation de ce que fait le code. Donc maintenant que nous avons parlé de ce code plus en profondeur, si nous regardons cela à nouveau, cela devrait avoir un peu plus de sens. Donc certaines choses dont on n'a pas parlé. Donc, tout d'abord, nous avons enveloppé tout ce code et l'intégration est un objet de compteur. Donc c'est juste une sorte de, vous savez, comment les choses doivent être structurées pour un script de pilote et dans Scala. Donc, dans cet objet compteur de rayon, nous définissons une fonction principale. C' est essentiellement la structure à laquelle chaque script de pilote doit se
conformer pour Apache Spark. Et la première chose que nous avons fait, dont nous n'avons pas vraiment parlé avec
la définition du niveau d'erreur sur nos journaux à l'erreur. Et malheureusement, comme vous l'avez vu ici, quelques avertissements ont glissé avant que ce code soit réellement exécuté par Spark. Mais une fois que le script du pilote commence réellement à être exécuté, cela va empêcher tout message de journal
qui est moins qu'une erreur de s'afficher. Et c'est juste pour réduire notre portée et nous laisser voir les résultats. Donc on veut voir plus qu'un tas d'avertissements dont on ne peut rien faire. Après cela, nous entrons dans le code dont nous avons parlé dans les diapositives. Nous créons donc notre nouveau contexte Spark. Nous l'appelons comme C. Il est configuré pour utiliser chaque noyau sur notre machine locale et nous appelons le nom de l'application ou le compteur de notes. Nous chargeons vers le haut à partir du fichier de données ML dash 100 K répertoire ru dot, qui contient chaque ligne de chaque évaluation individuelle dans cet ensemble de données. C' est la viande de tout ça ici. C' est là que nous appelons la fonction de carte sur les lignes RDD et appliquons cette fonction qui divise et chaque ligne dans ses champs individuels en fonction du délimiteur de tabulation et extrait le troisième champ. Encore une fois, nous commençons à compter à partir de 0. Il se trouve qu'il s'agit de la valeur de notation réelle elle-même. Cela est jeté dans un nouveau RDD appelé évaluations, qui contient chaque évaluation individuelle. Nous appelons ensuite le nombre d'actions par une valeur à pour que Spark aille et nous donne une réponse et trouver la meilleure façon de l'obtenir. Une fois que cela s'exécute, nous avons ici
une structure de résultats qui vit juste dans notre script de pilote maintenant. Donc, nous n'avons plus nos données sur le cluster. Nous avons réduit cela en quelques résultats dans le script. Et maintenant, nous pouvons prendre cette structure de données de pétoncles résultante convertie en une séquence triée par son deuxième champ réel, qui est la valeur de notation réelle. Ensuite, appliquez la ligne d'impression à chaque résultat trié pour imprimer la réponse finale. Et nous allons le faire une fois de plus juste pour le plaisir. Donc encore une fois, nous pouvons simplement cliquer sur scanner 3D et cliquer avec le bouton droit et exécuter. Mais comme nous l'avons déjà fait une fois, il va être dans un raccourci ici aussi, nous pouvons juste appuyer sur le bouton de lecture et le faire à nouveau. Et là, c'est encore. Tellement cool. Très bien, donc nous avons parlé du code et de son fonctionnement, et vous avez une idée approximative de la façon d'utiliser les RDD et de pratiquer. Encore une fois, nous allons parler de jeux de données plus tard, très bientôt, ne vous inquiétez pas, nous allons y arriver. Mais d'abord, parlons plus de ce qui s'est passé sous le capot quand nous avons fait tout cela au sein de notre grappe.
10. Spark: Qu' est-ce qui s'est passé sous le capot quand tout ça a couru ? Parlons de ça un peu plus en profondeur. Donc, lorsque notre script de pilote est arrivé à cette action, la commande de comptage par valeur et plan d'
exécution ont été créés à partir des RDD que nous avons définis. Donc, c'est un peu comprendre ce que je dois faire pour obtenir cette réponse finale. Dans ce cas, ça ressemble à ça, non ? Donc nous commençons avec ce fichier texte, les données brutes de notre RDD. Et nous allons appeler une opération de cartographie qui peut être appliquée en parallèle sur plusieurs processus ou plusieurs ordinateurs, même pour extraire les évaluations que nous voulons là-bas. Et puis, enfin, nous allons faire un comptage par valeur pour les additionner tous. Donc le plan d'exécution, ça va dire, hé, je peux faire tout ce premier truc de cartographie totalement en parallèle. Mais cette action va vous demander ces notes qui parlent les uns aux autres d'une
manière ou d' une sorte de communiquer et Coli, leurs résultats. Donc, ce qui se passe, c'est que le travail est divisé en
étapes en fonction du moment où les données doivent être réorganisées. Ainsi, le mappage parallèle peut être une étape qui ne nécessite aucune sorte de réorganisation des données elles-mêmes. Mais le compte par valeur mélangent un peu les choses, n'est-ce pas ? Cela doit donc être sa propre étape distincte dans le processus. Et puis chaque étape, il est divisé en tâches qui peuvent être réparties sur le cluster. Donc peut-être dans la première étape, vous savez, ces flèches violettes
traitent des parties des données et ça ira à un exécuteur. Executeur, peut-être que les verts iront vers un autre exécuteur et que le bleu ira vers un troisième exécuteur, n'est-ce pas ? Donc, il pense à la façon de distribuer ces données efficacement et que compte par opération de valeur, eh bien, ce n'est pas facilement parallélisable. Donc ça devient une sorte de stratégie différente là-bas. Et enfin, les tâches sont planifiées sur l'ensemble de
votre cluster et exécutées et vous obtenez votre réponse. Donc, sous le capot, C'est ce qui s'est passé pour obtenir
notre réponse finale sur le nombre de chaque type de notation existant dans notre jeu de données. Ce n'est pas si dur, mais sous le capot, c'est un peu ce qui se passe.
11. Clé et valorisez les RDD, et les amis moyennes par âge: Donc, nous avons vu quelques très simples RED ces en utilisation avec notre contre-exemple précédemment. Mais il existe aussi un type spécial de RDD appelé la valeur clé RDD. Et avec ces RDD, il y a quelques opérations supplémentaires que vous pouvez effectuer qui peuvent être utiles. Et nous allons regarder cela avec un exemple avec nos amis par script d'âge ici. Ce que nous allons essayer de faire à la fin de la journée ici, ou à la fin de cette leçon, c'est de trouver comment calculer le nombre moyen d'amis par âge. Donc nous commençons par un jeu de données qui a un tas de personnes individuelles, leurs noms, leur âge, et combien d'amis ils ont imaginé que nous avons obtenu ça d'un réseau social quelque part, non ? Donc, dans ce cas, nous allons structurer nos données en paires de valeurs clés. Rdds peut tenir ces choses. Dans notre cas. Dans ce cas, la clé sera l'âge et la valeur sera le nombre d'amis. Parce que nous voulons chercher les choses à l'âge, écrire, consolider les choses et les réduire à cet âge. Donc, au lieu de juste une liste d'âges ou une liste de nombre d'amis et un RDD. Nous pouvons stocker cela d'une manière plus structurée où chaque rover RDD se compose d'un tuple d'
un âge donné, d'un certain nombre d'amis pour un individu, de l'âge
et du nombre d'amis pour un autre individu , etc. Nous avons donc maintenant ces paires de valeurs clés sur chaque ligne de notre RDD. Comment créez-vous ces syntaxiquement ? Ce n'est vraiment rien de spécial à Scala. Tout ce que vous devez faire est de mapper des paires de vos données dans le RDD en utilisant des tuples. Donc, par exemple, si je voulais juste prendre un RDD qui avait une chose dedans et créer une paire de valeur clé de cette chose comme la clé et le numéro 1 est la valeur. Je pourrais simplement appeler une opération de carte qui dit prendre la ligne, tout son texte est x et le transformer en la virgule x tuple. Et cela devient une paire de valeur de clé où la clé est x et la valeur est un. C' est tout ce qu'il y a. Vous avez maintenant une valeur de clé, RDD, et vous n'êtes pas limité à avoir une chose et la clé est une chose et la valeur soit vous pourriez avoir des tuples ou d'autres sortes d'objets en tant que valeurs. Donc au lieu d'un, je pourrais avoir un autre tuple intégré dans cela. Donc je peux avoir x deux-points, imprimer la mer, vous savez, quelque chose de virgule quelque chose d'autre. Fermez les parenthèses si je le voulais aussi. Ainsi, vous ne pouvez pas avoir des types de données plus complexes intégrés dans votre valeur à parfois cela est utile. Donc, une fois que vous auriez ces paires de valeurs clés dans vos RDD, Spark peut faire des choses spéciales avec elles. Il y a de nouvelles fonctions qui deviennent disponibles pour vous. L' un est réduit par clé, et c'est utile pour combiner toutes les valeurs pour la même clé ensemble d'une manière ou d'une autre. Donc, fondamentalement, vous avez fourni une fonction qui définit comment puis-je combiner toutes les valeurs ensemble pour une clé donnée ? Dans ce cas, nous passons dans cette petite fonction qui dit x, y, flèche funky x plus
y.Donc , cela signifie que pour combiner une sorte de valeurs dans ces valeurs, je vais utiliser l'opérateur d'addition pour les combiner ensemble. Et c'est un peu déroutant ce qui se passe sous le capot ici. Donc, il pourrait être de garder un total courant car il passe par chaque valeur pour une clé unique sous le capot là-bas. Donc x pourrait représenter notre total actuel. Et pourquoi suis-je représenter la nouvelle valeur qu'il voit à partir d'une nouvelle ligne et l'ajouter à cela. Donc, ce qui est important ici, c'est l'opérateur à droite ici. Dans ce cas, nous disons explicitement, nous voulons ajouter tout dans toutes les valeurs ce RDD et nous donner une réponse pour chaque clé unique. Quelle est la somme ? Toutes les valeurs associées à cette clé ont du sens. Si ce n'est pas le cas, nous aurons un exemple qui aura plus de sens lorsque vous le verrez en action. On peut aussi dire groupe par clé. Donc, cela vous donnera juste un groupe de toutes les valeurs pour une clé donnée. Pas nécessairement réduire les choses, mais cela vous permet juste de mieux organiser vos données et peut-être de
les transmettre à une autre opération. Plus tard. On peut aussi trier par clé. Donc, si vous avez des paires de valeurs clés, vous pouvez effectuer ce tri dans votre cluster. Rappelez-vous que dans notre exemple précédent pour le compteur d'évaluations, nous avons effectivement obtenu nos résultats
au niveau Scala dans notre script de pilote et les avons triés là. Ce n'est vraiment pas la façon la plus évolutive de faire les choses, n'est-ce pas ? Il serait préférable que nous puissions trier sur le cluster. Et si on avait une paire clé-valeur à la place, on aurait pu le faire. En outre, nous avons des clés et des valeurs, donc nous pouvons extraire toutes les clés ou extraire toutes les valeurs d'une paire clé-valeur. Si vous avez besoin de revenir dans l'autre direction et de créer un RDD de seulement les clés ou un RDD de seulement les valeurs qui vous permet de les séparer d'une paire clé-valeur. En outre, il est possible de faire des jointures de style SQL si vous avez deux RDD de valeur clé et nous aurons un exemple de cela plus tard. Je veux dire, cela pénètre dans la zone où vous pourriez vous
demander pourquoi vous utilisez des RDD si vous faites une opération SQL. Donc je vais juste noter que vous pouvez le faire. Mais dans la pratique, évidemment, vous allez probablement utiliser des jeux de données sont DataFrames sont l'API SQL Spark pour faire ce genre d'opérations dans l'étincelle moderne. En outre, si vous devez effectuer une sorte d'opération de mappage sur une valeur clé RDD et que vous allez seulement transformer la partie valeur. Une petite astuce consiste à utiliser des valeurs MapValues ou FlatMap. De cette façon, vous pouvez simplement appliquer votre transformation à la partie valeur qui va être plus efficace que d'
essayer de comprendre comment garder la clé sur le côté et affecter uniquement la partie valeur. C' est donc un, à la fois plus efficace dans un moyen plus facile d'appliquer une opération de mappage aux valeurs d'une valeur clé RDD. Alors souvenez-vous de ça. Alors plongons dans notre exemple un peu plus. Donc encore une fois, ce que nous essayons de faire est de déterminer le nombre moyen d'amis pour un âge
donné, compte tenu d'un petit jeu de données faux ici. Donc encore une fois, imaginez que nous avons un réseau social d'une sorte ou d'une autre, où nous avons un groupe de personnes qui sont dans notre réseau social. Et pour chaque personne, nous connaissons leur âge en années, et nous savons combien d'amis ils ont dans notre réseau social. Ainsi, par exemple, chaque ligne peut ressembler à ceci. Une sorte d'identifiant d'utilisateur suivi de leur nom, suivi de leur âge, suivi de leur nombre d'amis. Donc, Will a 33 ans et a 385amis. John Luke a 33 ans et a deux amis. Il avait 55 ans et a 221amis et ainsi de suite. Donc, la première chose que nous devons faire est de mapper ces données
d'entrée et de les diviser en une sorte de structure. Et ici, nous définissons une fonction de ligne d'analyse qui prend chaque ligne individuelle de ce RDD et la divise en fonction de la virgule. Délimiteur, extrait le champ H et appelle à l'âge, extrait le champ de l'ami num et l'appelle amis num. Et puis nous retournons un tuple, une paire clé-valeur-clé d'amis num d'âge. Donc, l'âge dans ce cas est la clé et la valeur est amis engourdis. Et nous voyons ici dans la ligne suivante que nous créons les lignes RDD en chargeant les faux amis dot-dot CSV données brutes. Nous appelons ensuite map avec cette fonction de ligne d'analyse pour transformer ces données brutes en un nouveau RDD appelé RDD qui contient des paires clé-valeur. Donc, la sortie ici de RDD ressemblera à ceci en bas. Une paire clé-valeur. Par exemple, 33 est la clé, l'année, l'âge, et 385 est le nombre de France. Donc encore une fois, le nombre d'âge de la France. La clé est l'âge, le nombre de valeurs de la France et d'autres 33 ans avaient deux amis. Un homme de 55 ans avait 221amis, ainsi de suite et ainsi de suite. Et vous pouvez voir que nous pouvons avoir des valeurs en double ici pour les clés, n'est-ce pas ? Donc, les clés ne doivent pas être uniques dans ce contexte, pas tant que nous réduisons les choses. Ensuite, nous voulons commencer à réduire ces données. Donc, pour calculer la moyenne, nous devons avoir deux choses, non ? Nous avons besoin de la somme globale du nombre d'amis qui existaient pour un âge donné et du nombre de personnes qui le représentent. Donc pour calculer la moyenne, on va manger le nombre total d'amis qui ont l'âge et le nombre de personnes qui existaient pour cet âge. Et en divisant ces deux-là, on obtiendra la moyenne que nous voulions à la fin de la journée. L' étape suivante consiste donc à calculer ces totaux. Et c'est ce qui se passe ici. Maintenant, vous verrez souvent dans les scripts de pilote Spark, les gens rassemblent les choses en une seule longue ligne. Donc, vous pouvez aussi bien vous y habituer. Maintenant, parlons de quoi, disons ce qui se passe ici, non ? Donc, divisons cela en ses deux composants. Nous commençons par les valeurs de carte de points RDD X à X virgule un. Donc, ce que cela va faire est de prendre chaque valeur et le
transformer en son propre tuple de cette valeur, puis un. Maintenant, la méthode de cette folie est mais qu'
en associant un à chaque valeur unique là, je peux additionner toutes ces entrées individuelles et obtenir le grand total de combien existaient pour cet âge. D' accord. Donc celui-ci dit juste que je vais compter chaque ligne individuelle comme une, et je vais résumer cela plus tard pour obtenir un grand total, un petit truc là. Donc, après ce point, lorsque nous exécutons
cette opération MapValues, c'est à quoi ressemblera notre RDD. Ainsi, par exemple, 33, 35, qui nous disait qu'un enfant de 33 ans avait un avenir 95. La France va se transformer en la même chose. La clé est toujours 33, mais la nouvelle valeur est un tuple de 385 virgule. Et nous le faisons pour chaque rangée de ce RDD. Et ensuite, nous disons dot ReduceByKey. Donc, nous n'avons pas explicitement assigné le résultat de cela à un nouveau RDD nommé. Nous allions juste passer ce nouveau RDD directement dans une autre opération ici, dans ce cas l'action ReduceByKey. Donc, cette opération ici va additionner les deux éléments de ce tuple dans la valeur, non ? Donc, ce qui se passe ici, c'est que nous allons prendre 22 entrées ici de notre RDD que nous réduisons, appelez-les x et y. Nous allons additionner le premier élément des deux tuples et le second élément des deux tuples, et ajoutez-les tous pour chaque clé unique. D' accord ? Voyez où on va avec ça. Donc, à ce stade, ce que nous avons ici, c'est pour tous les 33 ans là-bas, nous avons réduit ces données au total global de tous les amis que les 33 ans avaient et le nombre total de 33 ans existaient. Alors réfléchis à ça pendant une minute. C' est un peu délicat. Notre stratégie ici était de retourner ici, ok, nous avons tout cartographié à ces tuples de 433 ans pour chaque individu, nous avions un tuple du nombre d'amis que cette personne avait dans le numéro d'un. Et cette astuce ici est qu'en faisant cela et en les ajoutant tous ensemble. Si nous additionnons tous les premiers éléments de ce tuple du nombre d'amis chacun, chaque 33 ans avait, nous obtenons le total général du nombre d'amis de 33 ans. Et puis, en les additionnant, tous ceux-là, on obtient un décompte du nombre de 33 ans qu'il y avait. Et cela nous donne les deux choses dont nous avons besoin pour calculer la moyenne que nous voulions. Et c'est ce que nous faisons à l'étape suivante. Nous disons les valeurs cartographiques et tout ce que nous faisons est de passer par
chaque valeur, chaque tuple avec lequel nous avons fini, et de les diviser les uns par les autres pour obtenir le nombre moyen final que nous voulons dans le résultat final. D' accord ? À ce stade, nous pouvons simplement recueillir et afficher les résultats. Donc, nous allons dire collecter pour récupérer ces valeurs moyennes réduites. Et nous allons les trier et
appeler la ligne d'impression et chacun d'eux pour afficher le résultat final. Donc, avec ça, allons de l'avant et allons le faire dans notre prochaine conférence.
12. [Activité] à partir de l'amis moyenne par échantillon: Très bien, plongons dans le code et voyons comment tout fonctionne en action ici et nous allons le lancer et voir si ça marche. C' est donc tout ce dont nous avons parlé dans les diapositives précédentes. Bon, alors passons à travers le code ici une ligne à la fois. Donc, nous commençons par déclarer quel paquet nous vivons dans ce genre de chose standard pour n'importe quel script Scala. Ensuite, nous importons les paquets dont nous dépendons. Dans notre cas, nous sommes un peu paresseux et nous importons simplement tout depuis Apache Spark et aussi depuis le journal pour J. Nous définissons ensuite les objets dans lesquels notre script vit. On va l'appeler amis par âge, ce qui devrait correspondre au nom du fichier. Je vais sauter la fonction de ligne de parcelle pour l'instant et descendre à la fonction principale parce que c'est là que l'exécution commencera pour dire que nous faisons à nouveau est de définir le niveau de journal à l'erreur afin que nous n'obtenions pas un tas de journaux spam sur avertissements dont nous ne pouvons rien faire. Il y en aura quelques-uns qui ont glissé avant que cela ne soit exécuté, mais nous allons attraper la plupart d'entre eux, au moins. Ensuite, nous créons notre contexte Spark, nouveau configuré pour fonctionner sur notre machine locale en utilisant chaque cœur de CPU. Et nous donnerons notre nom d'application amis par âge. La prochaine chose que nous faisons est de charger nos données brutes et il y a un faux tableau de bord d'amis, pas de fichier CSV hétérodox. C' est une version des données qui n'a pas de ligne d'en-tête qui peut, qui peut vous gâcher. Alors soyez conscient de cela. Et nous allons charger cela dans RDD
d'une ligne où chaque ligne représente une ligne de ces données. Alors, à quoi ressemblent ces données ? Jetons un coup d'oeil juste pour nous le rappeler. Donc ça ressemble à ça. Rappelez-vous que la première colonne est l'identifiant de l'utilisateur, la seconde est le nom et l'âge et le nombre d'amis et tout ce que nous nous
soucions de notre problème, c'est ces deux dernières colonnes, non ? Je ne me fiche pas vraiment si l'ID d'utilisateur est, je me fiche de savoir si leur nom l'était. J' essaie juste de trouver le nombre moyen d'amis pour chaque a
donné afin que je puisse jeter les deux premières colonnes. Et c'est ce que nous faisons dans la fonction de ligne d'analyse ici. Donc, nous allons prendre la fonction de ligne d'analyse, mapper cela à chacune de ces lignes d'entrée et obtenir un nouveau RDD appelé RDD. Voyons ce que fait la ligne de parcelle. Donc, ce que cela fait est de diviser chaque ligne par une virgule parce que c'est un fichier de valeurs séparé par des virgules. Et nous extrayons les champs 2 et 3. Ce sont les deux dernières colonnes de nos données. Il les appellera l'âge et les amis du NAM et retournera un tuple d'âge et d'amis du NAM. Et encore une fois, ce tuple deviendra notre paire de valeur clé dans notre RDD, RDD. Donc maintenant l'âge va être notre clé et les amis du NAM seront notre valeur pour chaque personne que nous avons dans notre jeu de données. Donc c'est là qu'on en est. Et maintenant, nous avons cette ligne très compliquée dont nous avons passé beaucoup de temps à parler.
13. Filtrer les RDD, et l'exemple de température minimale: Alors parlons ensuite du filtrage. Vos RDD. filtrage est une opération très simple qui vous permet juste de nettoyer les données de vos RDD et vous trouverez le même concept que les autres API dans les offres Spark. Nous allons illustrer cela avec quelques exemples utilisant des données météorologiques. Il s'agit de données réelles provenant de deux stations météorologiques différentes en Europe. Et ce que nous allons faire, c'est utiliser le filtrage pour nettoyer ces données avant
de les extraire pour que la température minimale et maximale soit enregistrée dans une année donnée à ces stations météorologiques. Utiliser un filtre est assez simple. Tout ce que vous faites est de fournir une fonction qui renvoie un booléen. Et si ce booléen retourne true, alors nous gardons cette ligne, sinon, nous la retirons du RDD. Donc, par exemple, si nous voulions filtrer les entrées qui n'ont pas T min comme deuxième élément dans le tuple de données, nous pourrions dire le filtre de points de lignes analysées, en supposant que les lignes d'analyse sont ce RDD qui contient ces tuples. Et en passant à la fonction où chaque ligne de données est appelée x. et nous vérifions si le deuxième élément de x est égal à l'équipe dans. Si c'est le cas, alors on le garde. Si ce n'est pas le cas, alors nous l'enlevons dans le Min résultant tente RDD. Donc, les termes Min contiennent les résultats filtrés des lignes analysées. Voici un exemple de ces données brutes qui se trouvent dans nos données sources pour cet exemple. Donc, ce que nous allons essayer de faire ici, c'est de trouver la température minimale dans un an pour une station météorologique donnée. Et ce premier identificateur, cette première colonne d'informations dans nos données d'entrée est l'identificateur de station. Donc, cela représente juste l'endroit où cette lecture de la température a été prise. suite, il s'agit de l'année réelle et de la date à laquelle cette mesure a été prise. Vous pouvez donc voir qu'il s'agit d'un jeu de données assez ancien qui remonte à l'an 1800. Et vous pouvez voir que nous avons de nombreux types de données différents enregistrés dans cet ensemble de données. Tmax indique la température maximale enregistrée ce jour-là à cette station météorologique. T min est la température minimale enregistrée et la précision est la quantité de précipitations enregistrée. Et le format de ces données de température est un peu bizarre. C' est degrés Celsius multiplié par 10. Donc, 75 négatif est en fait négatif 7,5 degrés Celsius devra faire face à cela car nous analysons les données et les importons. Voici à quoi ressemble ce code qui analyse ces données. Donc, pour chaque ligne que nous recevons que nous lisons pour ce fichier texte CSV de 8800 points, nous allons utiliser cette fonction de ligne d'analyse pour en faire un sens. Vous pouvez voir qu'au début le divise en fonction du délimiteur de virgules. Il extrait l'ID de la station, qui est le premier champ, et le type d'entrée, qui est un second champ. Et enfin le numéro de température lui-même. Et vous pouvez voir ici que nous commençons par multiplier cela par 0,1 pour obtenir deux degrés centigrades. Et puis nous convertissons cela en degrés Fahrenheit parce que je vis aux États-Unis,
qui, je pense, est l'un des derniers pays à utiliser encore l'échelle Fahrenheit. Mais de toute façon, si vous voulez garder cette partie off et la garder en centigrade, très bien par moi, je ne dirai à personne ce que nous retournons est un tuple qui contient l'ID de la station, le type d'entrée, qui dans ce cas sera équipe en T max ou précipitation et la température associée à cette rubrique. Ensuite, nous devons filtrer les informations que nous ne voulons pas. Nous ne sommes donc intéressés que par les entrées T min parce que la question à laquelle je réponds est de savoir quelle était la température minimale tout au long de l'année pour chaque station météorologique. Donc je me fiche des températures maximales qui ont été enregistrées. Je me fiche des précipitations. Je vais jeter toutes ces informations. Donc, en disant simplement les lignes d'analyse filtre point, en vérifiant si ce deuxième champ est égal à T min. Je peux jeter toutes les données là où ce n'est pas vrai, n'est-ce pas ? Donc, si x point soulignement deux est égal à l'équipe et je préserverai cette ligne et le RDD Min temps résultant. Sinon, je vais le filtrer. Donc, cela va se débarrasser de toutes les autres choses en plus de l'équipe dans les entrées. C' est donc un filtre en action. Après cela, nous pouvons créer les paires de
valeurs clés de température ID station parce que nous voulons faire quelques astuces avec les RDD de valeur clé, tirant sur notre leçon précédente. Nous allons donc cartographier cette température minimale à un nouveau tuple qui se compose juste de l'ID de la station et de la température. Nous n'avons plus besoin de cette équipe dans le champ de type d'
entrée parce que nous savons que tout est dans une équipe, donc c'est juste de l'espace perdu, non ? Nous allons donc convertir cela en juste un identifiant de station et la température de la température minimale pour chaque rangée qualifiée. Et nous appellerons ce nouveau temps de station RDD résultant. Et puis définissez le minimum. Tout ce qu'on peut faire, c'est dire ReduceByKey. Donc encore une fois, nous utilisons une sorte de truc clé-valeur ici et faisons une opération de réduction dessus. Donc, fondamentalement, nous voulons prendre chaque total courant que nous avons pour la température minimale actuelle, comparer cela à une nouvelle rangée. Donc ça va être X et Y. et nous allons exécuter les hommes d'opération minimum pour ne préserver que la valeur minimale vue. Donc, fondamentalement, il va continuer à passer rangée par rangée toutes les températures minimales pour une clé donnée, où chaque clé représente une station météorologique. Et ça va continuer, en essayant de garder une trace de la température minimale vue. Donc, il va regarder la première rangée. Regardez la deuxième rangée est un secondaire ou moins que la première rangée. Ok, génial, c'est le nouveau minimum. Est-ce que le troisième repaire est grand, moins que la deuxième rangée ? Non. D'accord. Le second reste le minimum immobile, donc il continue juste à passer en gardant une trace de la température minimale qui est rencontrée. Et ce que nous finirons avec un RDD beaucoup plus petit appelé une minute de tentatives par station qui contient juste toutes les clés uniques. Dans ce cas, seulement deux identifiants de stations météorologiques différents et la scène de température minimale pour chaque station. À ce stade, tout ce que nous avons à faire, c'est de recueillir les résultats. Donc, nous allons appeler l'action de collecte pour aller et forcer sont des RDD à aller et réellement faire quelque chose sur notre cluster. Et puis nous allons parcourir chaque résultat après
les avoir triés et extraire l'ID de la station et la température, nous allons formater la température en utilisant un format d'impression comme nous avons parlé dans l'introduction des leçons Scala. Et imprimez-le à nouveau en utilisant le format de substitution dont nous avons parlé également. Donc un peu mettre certains de ces trucs de
formatage de chaîne que nous avons appris plus tôt dans le cours en action ici. Donc, nous allons juste imprimer l'ID de la station, les mots température minimale deux-points, puis la température formatée avec deux points décimaux de précision après la virgule décimale. Alors allons-y et voyons si ça marche.
14. [Activité] exécutez l'exemple de température minimale et modifiez-le pour le maximum: Donc, si vous ouvrez le script de température Min en intelligence ici, vous devriez voir ce script ici. Marchons à travers la ligne par ligne. Et étant donné que vous êtes peut-être nouveau à l'échelle, je vais passer un peu plus de temps à examiner la syntaxe ici. C' est un exemple assez simple, donc ne devrait pas prendre trop de temps. Nous allons donc ouvrir ce bloc d'importation ici juste pour nous assurer que nous voyons tout ce que nous utilisons. Comme d'habitude, nous commençons par déclarer le paquet dans lequel nous sommes. Calme Dotson chiens logiciel point Spark, et nous importons tous les trucs dont nous dépendons. Ce que nous importons tout d'Apache Spark, de log pour J. Et aussi nous avons besoin de Scala dot Math.min pour utiliser cette fonction Min pour garder une trace des températures minimales que nous rencontrons. Donc nous le déclarons à la température. Object pour correspondre au nom de notre fichier ici. Et encore une fois, je vais passer la fonction de ligne d'analyse pour l'instant et aller directement à la fonction principale parce que c'est là que l'exécution commence. La première chose que nous faisons est de définir le niveau de journal sur erreur pour essayer de se débarrasser de tous ces messages d'avertissement qui vont encombrer nos résultats. Nous créons ensuite un contexte Spark. Et ici, nous disons que le maître sera star locale, disant que nous allons l'exécuter ou la machine locale en utilisant tous les cœurs CPU disponibles et le nom de l'application est Températures min. Maintenant, parlons un peu de la syntaxe ici. Donc maître égal et le nom de l'application est égal ou juste de petites notations qui intelligent inséré pour nous à des fins d'affichage. En général, vous n'avez pas à
dire que Master est égal à votre nom d'application est égal à vous pouvez simplement passer les paramètres et il
alignera les paramètres attendus pour cette fonction. Donc, nous savons qu'un constructeur SparkContext commence par le maître, puis le nom de l'application pour les deux premiers paramètres. Mais si vous voulez être plus explicite en les nommant, vous pouvez le faire de cette façon également. C' est la syntaxe est également valide et qui peut conduire à un code plus lisible. Donc, si je regardais cela en dehors d'Intel J, je ne sais peut-être pas vraiment ce que signifie la température min ou l'étoile
locale en mettant explicitement ces noms de paramètres, cela rend le code un peu plus lisible et plus facile à comprendre . Nous avons vu la même chose ici sur l'enregistreur, obtenir le nom de lager égal organisation. Nous n'avons pas eu à dire que le nom est égal à 0, nous pouvons simplement dire 4D, mais cela rend plus clair que le nom de ce paramètre que nous définissons est nom, et cela nous indique ce que c'est. Après avoir obtenu l'enregistreur pour le nom de l'organisation, nous définissons l'erreur point de niveau deux pour dire que nous ne voulons que des messages d'erreur et aucun avertissement ou message d'information. En continuant, la première chose que nous faisons est de charger nos données d'entrée. Donc nous disons Val Lines. Donc, nous faisons une valeur immuable ici appelée lignes qui est définie sur le fichier texte de la barre oblique 1800 points csv. Donc, cela prendra chaque ligne de ce format CSV et juste mettre le texte brut de chaque ligne dans le RDD de la ligne. Jetons un coup d'œil à ce à quoi ressemblent ces données. Il s'agit donc d'une visualisation de ce fichier CSV dans Microsoft Excel. Vous pouvez voir que la première colonne est l'ID de la station, et il n'y en a que quelques-uns ici,
suivi de la date, qui est au format de date année, mois. Donc 8800, le 1er janvier. Et ce fichier entier contient toutes les données pour l'année 1800. Donc nous n'avons pas à faire quelque chose de spécial à dire. Nous ne voulons que des données de l'année 1800. C' est tout ce qu'on a. Cette troisième colonne est le type de mesure enregistré dans cette ligne de données. Donc la température maximale, la température minimale ou les précipitations. Et la suivante est la valeur associée à cette mesure. Et encore une fois, c'est un format bizarre. Donc je pense que le mot technique est comme deci centi grade ou quelque chose comme ça. Je ne sais pas. Fondamentalement, il est réglé à degrés centigrades fois 10. Donc encore une fois, négatif 75 signifie juste négatif 7,5 degrés Celsius. Les colonnes restantes ne sont pas utilisées à nos fins, donc nous pouvons faire semblant qu'elles n'existent pas. C' est ce que nous lisons dans nos lignes RDD. Nous utilisons ensuite notre fonction de lignes d'analyse et l'appliquons pour mapper chaque ligne des lignes RDD pour produire un nouveau RDD appelé lignes analysées. Jetons donc un coup d'oeil à ce que fait la ligne d'analyse. Encore une fois, nous allons ralentir un peu ici sur le format. Rappelez-vous, la façon dont nous déclarons les fonctions dans Scala est que nous commençons par def, le nom de la fonction, et tous les paramètres. Et rappelez-vous que nous déclarons des paramètres un peu en arrière à partir d'autres langues. Donc, nous commençons par le nom deux-points, puis le type. Beaucoup d'autres langues ou tapez le nom dans Scala, son nom puis tapez. Donc, le paramètre est appelé ligne et il devrait être d'une chaîne. Et puis nous avons un deux-points, et c'est ce qu'il va être sorti par la fonction. Encore une fois, c'est à l'envers de toutes les autres langues. Beaucoup de fois que vous mettez le type de retour avant le nom de la fonction dans Scala, c'est après. Alors allez voir. Donc, ce que nous retournons est un tuple qui contient une chaîne, chaîne et
un nombre à virgule flottante. Et nous définissons cette fonction égale au bloc de code suivant. abord, nous commençons par la valeur d'un champ qui va diviser cette ligne en utilisant le délimiteur de virgules. Et encore une fois, le nom regex de ce paramètre est inséré ici pour notre commodité. Nous extrayons ensuite le premier champ. On commence à compter à partir de 0 ici. Donc, Fields 0 extrait le premier membre de cela et l'appelle ID de station. Extrayez le troisième champ et appelez ce type d'entrée et le quatrième champ, et nous appelons cette température après l'avoir converti en Fahrenheit. Alors que se passe-t-il ici ? Nous prenons ce quatrième champ, qui est une chaîne pour commencer parce que nous le divisons d'une chaîne de données. Nous devons donc convertir explicitement cela en
un nombre à virgule flottante avant de pouvoir faire des opérations numériques dessus. Donc, nous disons de flotter, pour en faire un nombre à virgule flottante, nous allons multiplier cela par 0,1 parce que vous vous souvenez, tout a été multiplié par dix et les données source. Donc, à ce stade, nous avons des degrés réels centigrades. Nous faisons ensuite la conversion en degrés Fahrenheit en multipliant par neuf cinquièmes et en ajoutant 32. Si tu voulais rester en centigrade, c'est cool. Sortez cette partie et vous serez en centigrade. Ce que nous retournons est la dernière chose qui est dans cette fonction, donc nous n'avons pas à le renvoyer explicitement. Et juste la dernière chose qui est dedans est implicitement retournée par cette fonction. Et cela va être un nouveau tuple qui se compose de l'ID de la station, qui est encore une chaîne, le type d'entrée, qui est encore une chaîne. Et cela peut être l'équipe et T, max ou priciple. Et la température que nous avons calculée comme une valeur à virgule flottante. C' est donc ce que le, chaque ligne individuelle de nos lignes analysées résultantes RDD va contenir à ce stade. Ensuite, nous voulons tout filtrer sauf l'équipe dans les entrées parce que tout ce que nous
essayons de calculer est la température minimale pour toute l'année pour chaque station, non ? Pour qu'on puisse jeter toutes ces entrées TMax. On peut jeter toutes ces entrées de précipitations. Et nous le faisons avec cette ligne ici. Donc, nous disons filtre, qui est tout le point de cet exercice, en
passant cette petite fonction en ligne ici. Nous allons donc appeler chaque ligne entrante des lignes de parcelle déjà dx. Nous allons ensuite prendre le deuxième champ de x. et rappelons que ce sera le type d'entrée. Donc, en regardant ici, le deuxième champ est le type d'entrée. Et nous allons vérifier si ce type d'entrée est égal à t Min. Si cela renvoie true, alors cette ligne est transmise dans le RDD Min temps sinon avoir des filtres cette entrée et ne va pas dans MiniTab. Ainsi, les mintues RDD résultantes ne contiennent que les lignes qui correspondent à t min et ce second champ. Ensuite, nous allons jeter cette équipe dans
ce champ de type d'entrée parce que nous n'en avons plus besoin. Nous savons que toutes les rangées et la température minimale à ce stade. Donc, nous pouvons cartographier cela à nouveau pour juste extraire le premier champ, qui va être l'ID de la station et le troisième champ. Et juste pour être en sécurité, nous dirons explicitement que c'est un nombre à virgule flottante. Donc notre nouvelle station, temps RDD, va juste contenir des identifiants de station, qui est une chaîne et une température, qui est un nombre à virgule flottante dans Fahrenheit. Maintenant, nous pouvons dire ReduceByKey, en gardant
juste une trace de la valeur minimale que nous
rencontrons lorsque nous traversons chaque tentative de station de ligne. Alors que nous traversons les tentations de Station, nous allons continuer à comparer le minimum actuel à chaque ligne entrante et retourner le minimum entre ces deux qui
aura pour effet de garder une trace
du plus bas enregistré température pour chaque clé parce que nous réduisons par clé. Alors rappelez-vous que chaque clé est un ID de station. Donc, ce que les hommes tentes par Station finissent avec est un RDD beaucoup plus petit qui contient juste une rangée pour chaque clé unique qui contient ce nom de clé et la température minimale associée à cet ID de station météorologique. Nous collectons ensuite les résultats dans notre script et mettons cela dans l'objet résultat. Nous le trions ensuite avec les résultats points triés et itérons à travers elle avec cette boucle for. Donc, pour le résultat, les résultats triés, qui passe par chaque ligne de résultats triés chaque entrée, et extrait chacun en conséquence. Pour chacun, nous extrayons le premier champ de ce tuple appelé station. Le deuxième champ est la température. Nous formons cette température. Le F signifie que nous allons utiliser un format d'impression f. Et le pourcentage 0,2 F signifie que nous voulons deux points décimaux de précision à droite de la virgule décimale. Et on tient un F à la fin pour indiquer que c'est Fahrenheit. Ensuite, nous avons juste à l'imprimer avec la ligne d'impression. Et nous allons remplacer
en utilisant la station de signe dollar pour la valeur de la station, la température minimale, puis formater une température, le signe du dollar indiquant à nouveau que nous substituons dans cette valeur immuable appelée Temp formaté. Alors faisons-le et voyons ce qui se passe. Cliquez avec le bouton droit de la souris sur Températures Min et Il s'en va. Et nous l'avons là. Donc, nous pouvons voir que pour
les deux stations météorologiques qui avaient des températures minimales associées à eux, la première s'appelait Easy Ease quelque chose ou autre. Et la température minimale enregistrée il y avait 7,7 degrés Fahrenheit. Et pour ITE, quoi que ce soit, la température minimale était de 5,36 degrés Fahrenheit. Donc, il semble avoir fonctionné très cool. Maintenant, si tu veux te salir les mains, je t'encourage toujours à te mettre en pratique ici. Voici un défi très rapide pour vous. Et si vous vouliez garder une trace de la température maximale pour chaque station météorologique au lieu de la température minimale. Eh bien, le, les changements associés à cela devraient être assez simples. Si vous voulez un petit défi, appuyez sur pause dès maintenant et allez essayer cela vous-même. Voyez si vous pouvez modifier ce script pour imprimer les températures maximales au lieu des températures minimales. Et il s'arrête si vous voulez faire ça. Sinon, je vais te montrer comment j'ai fait. Donc c'est assez simple, mais tu dois changer, non ? Donc, tout d'abord, vous voulez changer le nom de l'objet et le fichier à des températures maximales pour
la cohérence, l'analyse des données sera la même, non ? Ça ne va pas changer. Le format des données n'a pas changé sur nous. Mais ce que nous extrayons va être différent, non ? Les températures min veulent changer. L' événement de la température maximale est probablement ce que nous allons faire cela cependant, filtrer tout avec TMax au lieu de t min. Donc ça nous donnera tout sauf les entrées T max. Et puis ici quand nous faisons notre opération de réduction ou de réduction de ByKey, nous voulons juste les changer en un maximum. Et cela devrait à peu près changer la façon dont nous affichons les résultats pour dire que c'est une température maximale. Je suppose qu'on doit aussi importer des math.max squelettiques, non ? Donc, des choses assez simples, mais il est bon de mettre la main sur et en quelque sorte d'obtenir une certaine confiance en apporter changements au code Scala et au code Spark et de voir que vous pouvez le faire,
C' est plus sur votre confiance en quoi que ce soit. Si vous voulez voir comment je l'ai fait, double-cliquez sur le script de température maximale ici. Et ça fait tout ce que je viens de dire. Donc, nous importons scala dot math.max. J' ai changé le nom de celui-ci, changer le nom de fichier. Nous l'appelons maintenant températures maximales. Nous filtrons pour TMax et réduisons en
fonction de la fonction max et imprimons la température maximale. C' est à peu près tout. Allons de l'avant et allons voir ce qu'il fait. Et là, tu l'as, ça. Il s'avère qu'ils ont tous les deux le même. C' est plutôt curieux, n'est-ce pas ? Donc, pour les deux stations plutôt, la température maximale était de 90 points 104 degrés Fahrenheit. Et je suppose que cela correspond à un bon nombre rond et note
incitative qui se trouve être la même pour ces deux stations. Donc pas trop loin l'un de l'autre. Donc, ce n'est pas une surprise énorme. Et là, vous avez le filtre en action. Et aussi un autre exemple d'écriture d'un simple script Apache Spark en utilisant des RDD. Vous constaterez que ce n'est pas très différent. Nous allons parler de différentes API, mais encore une fois, elles sont réelles bientôt.
15. [Activité] Comptabiliser les événements Word à l'aide Flatmap(): Nous avons donc vu plusieurs exemples d'utilisation de l'opération de carte dans Spark jusqu'à présent, Parlons de FlatMap, qui est un peu différent. Et nous avons un exemple simple pour l'illustrer, où nous comptons le nombre de chaque mot dans un livre pour montrer comment cela fonctionne. Examinons donc ce que la carte fait. Donc, par exemple, si nous avions un fichier texte d'entrée qui contenait la lecture rapide sur une ligne et Fox a sauté sur une autre ligne et sur le paresseux sur une autre ligne et les chiens bruns sur la dernière ligne. Nous pourrions lire cela dans un RDD appelé lignes où chaque ligne de texte correspond à une ligne de ce RDD. Et puis dans ce cas, nous appelons carte sur les lignes RDD, en lui passant une fonction pour convertir chaque ligne en majuscules. Donc, ce que nous obtenons est une nouvelle rage caps RDD qui met juste en majuscule chaque ligne ou chaque ligne unique plutôt que cette RDD d'entrée. Donc, la chose à noter ici est qu'il existe une relation un-à-un entre le RDD d'entrée et le RDD de sortie. Et lorsque vous appelez map, map prend chaque ligne d'entrée et la convertit d'une manière ou d'une autre en une seule ligne de sortie. Donc, nous avons commencé avec quatre lignes et le RDD de la ligne, et nous nous retrouvons avec quatre lignes et les plafonds de rage en sortie RDD, carte a toujours cette relation un-à-un. Une rangée entre, une rangée sort. Flatmap, cependant, supprime cette restriction. Donc, avec FlatMap, vous pouvez renvoyer n'importe quel nombre de lignes pour une ligne d'entrée, il pourrait être 0, cela pourrait être 20, cela pourrait être 200, tout ce que vous voulez. Donc, dans cet exemple différent ici, nous commençons avec la même entrée. Rdd sont appelés lignes, mais maintenant nous appelons FlatMap. Et nous passons en tant que fonction là pour prendre dans chaque ligne, appeler x, puis le diviser en fonction du caractère d'espace. Cela a donc pour effet de diviser chaque ligne en mots individuels. Et parce que nous appelons FlatMap, chaque mot individuel finit sur sa propre nouvelle ligne dans les mots résultants RDD. Donc, en utilisant FlatMap ici, nous avons commencé avec quatre lignes, mais nous avons fini avec beaucoup plus de lignes que dans les mots RDD en sortie, où nous avons une ligne pour chaque mot par opposition à une ligne pour chaque ligne. Et encore une fois, FlatMap peut afficher n'importe quel nombre de lignes que vous voulez, y compris 0. Pour voir cela en action, faisons un petit exemple de code simple où nous comptons combien de fois chaque mot se produit dans un livre entier. Et je n'essaie pas de vous vendre ce livre, même si je l'ai écrit,
ça n'a rien à voir avec Apache Spark, mais c'est un livre où je possède les droits pour que je
puisse l'utiliser comme exemple sans payer de redevances. Alors allons de l'avant et plongons dans et voyons combien de fois chaque mot apparaît dans mon livre. Nous avons donc un script très simple ici pour illustrer l'utilisation de FlatMap. Ça s'appelle les comptes de mots. Alors allez-y et ouvrez Word Count et intelligent si vous
voulez suivre le script vraiment simple. Et cela est souvent utilisé comme sorte de l'exemple HelloWorld pour les programmes Spark. Nous commençons comme toujours déclarer notre paquet, importer ce dont nous avons besoin pour les dépendances, et déclarer l'objet dans lequel nous vivons. Notre fonction principale commence en disant que le niveau de journal est toujours et en déclarant un nouveau SparkContext fonctionnant sur notre PC local. Maintenant, nous entrons dans la viande de celui-ci. Nous l'appelons donc fichier texte SparkContext avec un chemin vers l'ensemble du contenu du texte de ce livre entier
qui vit dans le fichier txt de point de livre. Et nous appelons cela RDD résultant notre entrée, où chaque ligne de cette entrée RDD correspond à une ligne de texte du livre. Et maintenant, comme nous l'avons vu dans les diapositives, nous appelons FlatMap sur ce fractionnement chaque ligne par le caractère de l'espace, ce qui nous donne plus ou moins les mots individuels dans ce livre. Donc maintenant FlatMap a généré un nouveau mot RDD, où chaque ligne des mots RDD est un mot dans le livre et il peut y avoir des mots répétés dedans. C' est chaque mot individuel, même s'il se produit plus d'une fois, va être une ligne dans ce RDD et cette séquence. Et maintenant, nous allons utiliser l'action comptage par valeur pour compter combien de fois chaque mot unique apparaît dans les mots RDD. Donc c'est une façon de faire ce qui serait autrement une opération assez compliquée, non ? Et la beauté de Spark est qu'il peut réellement paralléliser cela sur un cluster entier si vous le souhaitez, ou dans notre cas, chaque cœur de notre CPU. Tout ce que nous faisons alors est d'itérer à travers chaque résultat dans cet objet de nombre de mots que nous avons obtenu de Spark. Et nous appelons la ligne d'impression sur chacun de ces résultats pour imprimer chaque résultat sur sa propre ligne. Alors allons de l'avant et allons voir ce qui se passe. Nous allons faire un clic droit sur le nombre de mots, disons exécuter WordCount, il va. Et même si c'est un livre entier, il devrait en faire un court travail. Là, nous l'avons. Intéressant. Donc, si vous faites défiler cela, vous pouvez voir combien de fois chaque mot apparaît dans mon livre. Le mot cash apparaît 18 fois, seulement 77 fois. Travailleur indépendant, seulement 10 fois. Un peu surprenant là-bas parce que c'est un livre sur le travail indépendant. Mais il y a une sorte de mots uniques ici aussi, comme l'idée n'apparaît qu'une fois. livraison directe n'apparaît qu'une seule fois. Des trucs tellement cool. Donc à notre ça a fonctionné. C' est un exemple de flatmap en action. Mais à mesure que vous examinez ces résultats, vous pouvez constater qu'il y a des problèmes sur lesquels nous pourrions nous pencher. Alors explorons cela dans les conférences suivantes ici, par
exemple, en fonction de la capitalisation, je pourrais les traiter comme des mots différents. Le mot « produits » était-il vraiment inclus une seule fois ? Tout ce que cela veut dire, c'est que les produits ne sont apparus qu'une fois avec un P majuscule, peut-être au début d'une phrase ou quelque chose comme ça, n'est-ce pas ? Il y a donc des moyens d'améliorer ces résultats pour être plus intéressants. Et c'est aussi comme des choses bizarres comme est le tableau de bord ouvert terminé un mot ou deux. Qu' en est-il de la ponctuation ? Devrais-je enlever ces points d'interrogation, ces virgules et ces points, non ? Donc les propriétaires virgule apparaissent deux fois, mais ce ne est pas vraiment parler du mot propriétaires. Il y a donc une place à améliorer et comment nous analysons ces données. Alors explorons ça.
16. [Activité] Améliorer le scénario Word Count avec des expressions régulières: Ok, donc pour passer en revue dans notre leçon précédente, nous avons fait un exemple simple d'utilisation de FlatMap pour compter combien de fois chaque mot de mon livre apparaît. Et nous analysons très naïvement ces données en les
divisant en fonction des caractères espacés pour essayer d'obtenir des mots individuels, qui à première vue, vous penseriez que cela fonctionnerait. Mais comme vous pouvez le voir dans les résultats ici, ce n'est pas le cas. On finit par avoir de la ponctuation là-dedans. Ainsi, par exemple, citation, y compte comme un mot unique individuel. La capitalisation est également importante ici. Donc Y majuscule serait compté comme un mot différent de y minuscule. Nous avons des choses comme des virgules, ponctuation et des majuscules affectant nos résultats. Alors réparons ça. Donc, nous allons fermer de WordCount point Scala et au lieu de cela ouvrir Word Count mieux. Et ici, nous allons utiliser une expression régulière à la place pour obtenir de meilleurs résultats. Clv, rien de vraiment différent ici est qu'au lieu d'avoir cette fonction qui se divise en fonction d'un caractère d'espace, lorsque nous divisons les données d'entrée, nous allons
plutôt utiliser une expression régulière. Donc, dans ce cas, nous allons dire x point split et définir l'expression régulière à ce format d'expression régulière, barre oblique inverse, barre oblique inverse majuscule W plus. Et dans la terre d'expression régulière, cela signifie juste que je veux briser les choses en se basant sur des mots entiers. Le W majuscule signifie mot. Donc, les expressions régulières savent ce qu'est un mot. Il va filtrer toute la ponctuation et tous ces caractères spéciaux et nous laisser avec des mots qui contiennent les caractères réels. Donc ça doit se débarrasser de tous les problèmes que la ponctuation gâche nos résultats. Cependant, nous avons encore le problème de la capitalisation, n'est-ce pas ? Donc R majuscule Et rappelez-vous va être un mot différent de r. minuscules et rappelez-vous, même après avoir enlevé toute ponctuation qui aurait pu exister là. Donc, pour prendre soin de ce problème, nous allons en outre une carte de nos résultats en minuscules. Donc, nous voyons ici nous commençons à cartographier nos données d'entrée en mots individuels. Mais dans ce cas, nous nous divisons sur des mots d'expression régulière plutôt que sur des caractères d'espace, ce qui est plus robuste. Ensuite, nous faisons une carte régulière pour prendre chaque mot individuel et le mapper sur une base individuelle à sa version en minuscules. Donc, en normalisant tout en caractères minuscules, nous pouvons être sûrs que nous comptons tous les mots de la même manière indépendamment de la majuscule. Et puis nous partons et comptons par valeur sur les mots minuscules résultants RDD et imprimons ces résultats. Voyons si ça nous donne quelque chose d'un peu mieux. Faites un clic droit sur le nombre de mots mieux et exécutez cela. Et d'accord, ça a l'air un peu mieux, non ? Donc c'est cool. Maintenant, on n'a pas de ponctuation bizarre qui se passe ici. Tout est en minuscules, donc nous obtenons résultats qui ont un peu plus de sens, espérons-le. Ainsi, par exemple, le mot publicité apparaît 41 fois dans le livre qui semble crédible. Religieux seulement une cache 19 fois. Cherchons un mot vraiment populaire ici, cependant, qui apparaît 1292 fois. Donc pas trop surprenant là-bas, c'est un mot très courant. Cool. Donc ça semble avoir fonctionné comme si je pense que nous recevons des mots valides ici. Tout semble normalisé. On ne va pas se faire foirer. Je ponctuation, donc mission accomplie, mais ce n'est pas terriblement utile encore dans la façon de l'utiliser, n'est-ce pas ? Je dois aller à la pêche pour les mots communs ici. Je ne devrais pas avoir à faire ça. Ne serait-il pas mieux si je pouvais trier ces résultats en fonction de la fréquence à laquelle chaque mot apparaît. Donc il y aura plus utile. Je peux très facilement trouver les mots les plus courants et les mots les moins communs dans le livre. Et cela pourrait même me donner un aperçu de ce qu'est le livre. Ou peut-être des mots que j'utilise trop ou quelque chose comme ça, c'est bien. J' ai en fait une application pratique pour les écrivains. Alors passons à autre chose et rendons ce script encore meilleur dans notre prochaine conférence et
trions réellement ces résultats afin que nous puissions en tirer plus de sens.
17. [Activité] trier les résultats de comptabilité Word: Ok, donc dans notre leçon précédente, nous avons affiné notre exemple de comptage de mots pour être un peu plus intelligent sur l'identification des mots. Nous avons donc une très bonne sortie ici
des comptes de chaque mot unique dans notre livre entier. Mais ce n'est pas terriblement utile parce qu'il n'est pas trié par la fréquence à laquelle chaque mot se produit. Je dois donc aller à la pêche pour savoir quels sont les mots les plus communs et les moins communs dans mon livre. Donc ce n'est pas très utile, n'est-ce pas ? Alors réparons ça. Nous voulons trier les résultats en fonction de la fréquence à laquelle chaque mot se produit. Nous pouvons rapidement voir les mots les plus utilisés dans mon livre. Maintenant, dans les conférences précédentes de ce cours,
nous l'aurions fait en triant simplement les résultats finaux que nous avons obtenus de Spark qui ont été retournés à notre script de pilote et en les triant simplement dans Scala. Mais ce n'est pas vraiment la façon de faire les choses en Big Data, n'est-ce pas ? Ce serait mieux si nous pouvions les trier sur le cluster si nous avions tellement de mots que nous ne pouvions pas tout traiter sur une seule machine. Vous auriez besoin de le faire, non ? Je veux dire, c'est un exemple alambiqué. Il est peu probable que vous ayez autant de mots dans un livre, mais vous avez l'idée. Il sera préférable de faire ce tri distribué sur le cluster si nous le pouvons. Alors faisons-le de cette façon et voyons comment cela pourrait fonctionner. Donc, ouvrons le nombre de mots mieux triés exemple ici. Juste un petit raffinement sur le mot précédent compter meilleur script ici, c'est à peu près la même chose sauf pour le nom
du script jusqu'à ce point ici. Nous avons donc chargé notre livre dans un RDD d'entrée. Nous l'avons divisé en mots en utilisant FlatMap. Donc maintenant, nous avons un mot RDD contenant chaque mot du livre, et ensuite nous mappons cela en minuscules pour normaliser ces données. Donc maintenant, auparavant, nous aurions utilisé le nombre par valeurs, n'est-ce pas ? Si nous revenons à notre exemple précédent ici, nous utilisons le nombre par valeur pour obtenir
rapidement le nombre de fois que chaque mot se produit dans ce RDD. Mais nous voulons le trier en même temps. On doit donc le faire à la dure. Donc, disons ce qui se passe dans ce genre de ligne compliquée ici. Donc, d'abord, nous allons mapper ce résultat à x r1. Prenez chaque ligne, chaque mot individuel, et mappez cela à un tuple du mot et au numéro 1. Maintenant on a déjà vu ce truc, non ? Donc, ce que nous voulons dire, c'est que chaque tuple individuel aura ce mot et qu'il s'est produit une fois dans cette rangée. Et c'est un petit truc que nous pouvons utiliser parce que cela nous
permettra de résumer tout, juste, et d'obtenir le nombre de fois que chaque mot unique se produit lorsque nous faisons une opération de réduction. Et c'est ce qu'on fait ici. Nous disons de réduire par clé, en additionnant tous ces totaux. Alors repassons à travers ça. Nous transformons chaque mot en un tuple du mot et le numéro un. Et parce que c'est un tuple avec deux choses qui pourraient être considérées comme une valeur clé, RDD, où la clé est le mot et la valeur est le numéro un. Donc maintenant, nous pouvons dire ReduceByKey parce que nous avons fondamentalement une valeur clé RDD résumant toutes les valeurs, ok ? Donc, pour chaque mot unique, nous allons compter toutes les valeurs, qui est juste le numéro 1. Donc, quand nous additionnons tous les nombres pour chaque occurrence de mot, nous finissons avec un compte de combien de fois ce mot s'est produit. Ok, la prochaine chose qu'on veut faire est de le trier. Donc, à ce stade, l'opération ReduceByKey nous a laissé avec un mot compte RDD qui contient des paires clé-valeur, encore une fois, où la clé est le mot et la valeur est le nombre de fois que ce mot se produit. Maintenant spark offre un tri par fonction clé ici que nous pouvons utiliser, mais il va trier par la clé et la valeur que nous voulons trier par la, la
fréquence à laquelle chaque mot se produit. Donc, nous devons d'abord retourner ça. C' est tout ce qu'on fait dans cette opération de carte. Nous prenons le nombre de mots RDD et le retournerons afin que la valeur de clé RDD soit retournée en clé de valeur si vous voulez. Et donc nous prenons l'entrée RDD, qui contient le nombre de mots, et retournerons cela pour compter le mot en le transformant en x point t2 et x-dot un. Le deuxième champ dans le premier champ. Une fois que nous avons cela, nous pouvons utiliser tri par clé pour trier les résultats par le nombre de fois que chaque mot se produit. Donc avec moi ici, passons à travers vite une fois de plus. Tout cela est pareil d'avant. Mais dans ce cas, nous allons prendre nos mots en minuscules RDD, dont il a chaque mot unique sur sa propre rangée. Nous allons mapper cela à une paire clé-valeur où la clé est le mot et la valeur est le numéro un. Nous faisons une opération ReduceByKey pour additionner combien de fois chaque clé unique, chaque mot unique se produit. Et puis nous devons retourner cette paire clé-valeur résultante sur sa tête afin que nous
puissions réellement utiliser tri par clé pour trier par le nombre de fois que chaque mot apparaît. Nous passons ensuite en revue et imprimons les résultats, un peu comme nous l'avions fait auparavant. Et nous devrions obtenir quelque chose de plus utile. Alors allons-y et essayons-le. clic droit sur le nombre de mots, mieux triés et dites courir. Et nous l'avons là. Et il est trié dans l'ordre croissant. Donc, les mots les plus populaires seront à la fin. Et c'est intéressant. Donc mes mots les plus courants étaient aussi et vous pas dans un puits, je suis heureux que j'ai utilisé les mots vous dans votre plus que moi et moi. C' est une meilleure façon d'écrire. Elle veut se connecter avec votre lecteur et ne pas parler beaucoup de vous-même. Donc je vais appeler ça une victoire. Mais oui, un dans le peu profond apparaît assez souvent. Et de tous les mots courants que vous attendez à voir
là-bas, il y a à dire, une entreprise apparaît beaucoup. Donc, quand vous creusez dans la lumière, les mots les plus intéressants vous pouvez dire ce qu'est le livre juste par ce que sont les mots les plus courants, non ? Donc le premier mot qui a quelque sens, il y a des affaires, et c'est un regard sur les affaires. de défilement vers le haut. Vous savez, nous parlons beaucoup de gestion du temps en raison du produit. D' accord. Oui, on a beaucoup parlé de la façon de sélectionner le produit à vendre. Donc oui, vous pouvez en fait obtenir quelques informations sur ce qu'est
le livre juste en regardant ces données maintenant. Et si on fait défiler jusqu'aux mots les moins courants, on ne devrait pas avoir des trucs assez obscurs ici. La mousse que j'ai utilisée était le téléphone. Je me demande d'où ça vient. Swot cité. Donc, ouais, des trucs intéressants. Donc, vous pouvez vraiment dire ce qu'est le livre juste en regardant ces données. Nous avons donc un peu aimé voir l'évolution du script. Et sur le chemin de rendre ce script plus utile, nous avons appris non seulement comment utiliser FlatMap, mais aussi comment utiliser des expressions régulières et comment faire une utilisation
créative de ReduceByKey et trier par clé pour obtenir les résultats que vous vouloir. Maintenant encore une fois, nous verrons que c'est un peu plus simple lors de l'utilisation de jeux de données en SQL. Mais on y arrive. Nous voulons juste aimer, commencer par les bases ici et les principes fondamentaux de Spark, qui sont construits sur des RDD. Et dans les cas où vous devez utiliser des RDD, il est bon de connaître ces astuces.
18. [Exercice Trouvez le montant total dépensé par client: Ok, je pense que vous en avez assez appris sur les RDD et vu assez de code Scala à ce stade pour essayer de faire quelque chose par vous-même. C' est donc un petit défi, un peu d'activité pratique. Je vais vous demander de créer un programme Spark très simple à Scala qui comptera juste le montant total d' argent commandé par chaque ID client individuel et une petite base de données de commerce électronique fausse. Je vais donc vous fournir un fichier CSV qui contient des choses dans ce format. Et cela représentera un ID client
ainsi qu'un ID d'article et le montant dépensé pour cet article. Donc chaque ligne de ces fausses données représente quelques transactions, certains achats à une personne fictive faite. Vous allez écrire du code et afficher le total général de combien a été dépensé par chaque ID client unique. Donc, dans cet exemple particulier, vous pouvez voir que l'ID utilisateur 44 a acheté quelque chose pour 37, 19, et quelque chose d'autre pour 4064. Le total général pour notre utilisateur 44 est donc 77, 83. Et nous voulons le faire pour chaque client individuel de notre base de données. Donc, je vais l'épeler un peu pour
vous si vous êtes un peu anxieux à ce sujet, non,
ne regardez pas si vous voulez essayer cela par vous-même, mais quelques conseils généraux sur la stratégie pour le faire. Je veux commencer par diviser chaque ligne délimitée par des virgules en ses champs uniques. Et comme je l'ai dit, ce sera l'ID d'utilisateur, l'ID d' article et le montant dépensé. Vous allez ensuite mapper chaque ligne à une paire clé-valeur d'ID client et d'un montant en dollars. Et utilisez l'opération ReduceByKey pour additionner le montant total dépensé par ID client. Lorsque vous avez terminé, collectez les résultats et imprimez-les. Assez simple. Et vous devriez être en mesure de comprendre cela en étudiant les exemples précédents dans ce cours. Ils sont assez semblables. Quelques extraits de code utiles si vous êtes nouveau à Scala, qui pourraient être utiles si vous voulez diviser un champ délimité par des virgules en ses champs individuels,
cette ligne le ferait pour vous, les champs Val sont égaux à la ligne de virgule fractionnement par point. Et vous aurez également besoin à un moment donné de vous assurer que vous traitez le champ 0 est un entier et que vous sentez comme un nombre à virgule flottante. Donc, ce petit extrait de code est important à retenir aussi. Vous devez explicitement les jeter dans
leur représentation numérique réelle et pas seulement des chaînes comme elles sortent du rock de fichiers. Bonne chance. Et avant de vous lâcher, je vais vous montrer très brièvement où trouver les données pour cela et comment créer un nouvel objet dans nos projets afin que vous puissiez réellement jouer avec elle et commencer. Laisse-moi te montrer ça vite et je te lâcherai. Donc, permettez-moi d'abord d'attirer votre attention sur l'endroit où vivent les données de cet exercice. Donc, dans votre dossier de matériel de cours, allez dans le cours Spark Scala, puis dans le dossier de données. Et c'est le fichier de commandes client que nous allons examiner ici. Ouvrons ça, voyons à quoi ça ressemble. Rappelez-vous maintenant que ce sont des valeurs séparées par des virgules. Donc, même si Excel l'affiche sous forme de feuille de calcul, ce sont vraiment des colonnes individuelles séparées par des virgules que nous lisons ici. Et ces données sont complètement générées au hasard. Vous pouvez voir qu'il y en a un peu, 10 000 lignes de données ici, mais tout est faux. La première colonne représente l'ID utilisateur, suivi d'un ID d'article et du montant dépensé pour cet article. Ainsi, chaque ligne représente un seul achat. Et oui, vous pourriez noter
que cette deuxième colonne n'est pas vraiment nécessaire pour ce qu'on fait, n'est-ce pas ? Nous avons juste besoin du montant dépensé par le client. L' ID d'élément n'entre pas vraiment en jeu, donc beaucoup de temps, donc nettoyer vos données va être une grande partie du travail et c'est le cas et ce petit exercice aussi simple. Maintenant, pour vous aider à commencer à ce sujet, laissez-moi vous montrer comment faire pour créer un nouvel objet dans un tele j. Donc, je clique sur Calm dot sundown logiciel dot Spark et dire New Scala classe et lui donner un nom unique. Collez votre nom là juste pour être sûr pour vous assurer qu'il est unique. Donc quelque chose comme le montant total dépensé pour moi, quel que soit votre nom soit pour vous. Et double-cliquez sur l'objet parce que nous voulons un objet et non une classe. Bon, donc maintenant vous avez la plaque d'
un nouvel objet ici , il a le nom de paquet correct parce que nous l'avons mis au bon endroit. Et votre objet est tout configuré. Et maintenant, tout ce que vous avez à faire est d'écrire du code et de le tester. Donc, lorsque vous êtes prêt à essayer cela, vous pouvez simplement cliquer avec le bouton droit sur cette classe et vous pouvez la construire. Et puis après cela, vous pouvez réellement essayer de l'exécuter et voir ce qui se passe. Et oui, c'est tout. Alors va le faire. Pas un exemple très difficile, pas un exercice difficile par tous les moyens, mais je veux que vous vous saliez les mains et obtenez un peu de confort en écrivant du code Scala. Nous en aurons d'autres plus difficiles plus tard dans le cours, bien
sûr, donc nous commençons facilement. Alors va essayer ça. Et quand vous serez prêt, revenez à la prochaine conférence et je vous montrerai ma solution, qui est ici dans le matériel du cours. Vous l'avez peut-être déjà repéré, alors résistez à la tentation de le regarder. Essayez d'abord ça vous-même.
19. [Exercice !, vérifiez vos résultats et triez-les par montant total dépensé: Alors, as-tu fait tes devoirs ? Je l'espère. Eh bien, si vous voulez comparer vos résultats aux miens et comparer votre code au mien, j'ai également inclus ma solution dans votre matériel de cours. Donc j'espère que vous ne les avez pas encore choisies. Il suffit d'ouvrir le total dépensé par classe de clients ici. Et voici comment je l'ai fait. Alors passons à travers ce code ici. Commencez par la déclaration de paquet que vous devriez déjà avoir et en important ce dont nous avons besoin. On a besoin de tout de Spark et d'un journal pour J. Hope que tu n'as pas fait trébucher dessus, y compris ceux. Et nous avons appelé notre objet ici total dépensé par le client. C' est mon fichier de solution ici. Et nous allons descendre à la fonction principale et commencer là. Donc, nous commençons par définir notre niveau de journal sur erreur comme nous l'avons fait auparavant. Et nous avons mis en place un nouveau SparkContext. Et la seule chose unique à ce sujet est que nous avons dit un nom d'application qui est différent des autres exemples. Dans ce cas, le total dépensé par le client. Maintenant, nous entrons dans la viande de tout ça. Nous chargeons notre fichier texte, qui est le client dash commandes point CSV fichier que je vous ai dirigé plus tôt. Et nous allons juste charger cela dans une entrée nommée RDD. Maintenant, nous devons analyser ces données. C' est pourquoi nous avons écrit cet extrait des paires de prix client fonctionnent ici. Bien sûr, vous auriez pu le nommer tout ce que vous voulez. Il prendra toute une ligne de valeurs séparées par des virgules et nous allons juste appeler cette ligne de chaîne et retourner un tuple d'un entier et un flotteur. Ce sera donc nos paires de valeurs clés que nous avons plus tard, où la clé sera l'ID client,
qui est le premier champ, qui est le premier champ, et une valeur à virgule flottante. Nous représentons le montant dépensé sur un article pour ce client dans cette transaction. Nous commençons par diviser les champs de
cette ligne en fonction du caractère virgule en utilisant le fractionnement des points de ligne. Et nous assignons cela dans la valeur des champs. Et puis nous retournons juste le tuple qui contient le premier champ converti en entier, et le troisième champ converti en un nombre à virgule flottante. Et rappelez-vous encore, nous commençons à compter à partir de 0 dans ce format particulier. Donc, à ce stade, nous avons mappé notre entrée dans un nouveau RDD en entrée mappé qui contient des tuples d'ID client et le montant dépensé. Et c'est en fait une paire de valeur clé parce que c'est un tuple de deux choses, non ? Donc, notre clé est maintenant l'identifiant du client et notre valeur est maintenant le montant dépensé dans cette transaction. Maintenant, nous avons juste à réduire cela en utilisant l'opération ReduceByKey. Et nous utilisons cette syntaxe ici pour garder un total courant
du total total total dépensé par chaque ID client. Donc, nous réduisons par clé par chaque client et additionnons ces valeurs au fur et à mesure qu'elles entrent en jeu. Cela prend donc une paire de deux valeurs associées à la clé. Et nous allons dire que nous voulons les additionner parce que nous voulons le grand total. Et ce que nous obtenons est le total par RDD client, qui contiendra les clés, chaque clé unique, chaque ID client unique et le total dépensé par chaque ID client. Nous pouvons ensuite recueillir les résultats. Donc, ce sera notre action qui récupère
les résultats et le retourne à notre script,
à notre script de pilote fonctionnant localement ici. Et puis nous pouvons simplement appeler ForEach avec la fonction de ligne d'impression pour imprimer chaque ligne de ces résultats. Alors exécutons-le et voyons si ça marche. Je vais faire un clic droit sur le total dépensé par le client et dire exécuter total dépensé par le client. Il s'en va. Et nous l'avons là. Très cool. Très bien, il semble que ça ait fonctionné. Ainsi, par exemple, l'ID d'utilisateur 91 a dépensé $4,642.26, et ainsi de suite et ainsi de suite. L' utilisateur 53 a dépensé $4,495. Ils sont tous à peu près dans le même voisinage parce que c'était données générées aléatoirement avec une distribution aléatoire uniforme. Mais ça va entrer dans mon cours de science des données, je suppose. Bref, ça a marché. Donc, j'espère que vous avez une sortie similaire à entendre. L' ordre peut être différent, c'est bon. Mais vous savez, vous devriez être en mesure de voir que pour un ID utilisateur particulier, vous pouvez rechercher cet ID utilisateur et obtenir le même numéro, espérons-le. Donc, si vous voulez rechercher l'utilisateur 89 et assurez-vous que vous avez 4851947, 95. Ça pourrait être une bonne idée. D' accord, donc je vais vous défier plus loin maintenant, vous pouvez rendre cela encore meilleur genre de genre comme nous le faisons dans notre exemple de comptage de mots. Ce sera beaucoup plus utile si ça a été trié, non ? Donc, si j'étais plus intéressé à voir qui sont mes gros dépenseurs, je pourrais vraiment vouloir voir cette banque de données triée par montant dépensé. De cette façon, je pouvais facilement voir qui dépensait le moins d'argent sur mon site et qui dépensait le plus d'argent sur mon petit site de commerce électronique faux ici. C' est donc votre défi. Allez-y et allez de l'avant et voyez si vous pouvez trier les résultats par montant dépensé pour une équipe bonus supplémentaire ajouté, Je veux voir si vous pouvez formater qui ont effectivement deux points décimaux de précision là après le signe du dollar là. Alors faites en sorte que ça ressemble plus à de la vraie monnaie. Mais ils le sont, votre seul véritable défi en ce moment est de trier ces résultats en fonction du montant dépensé. Et encore une fois, se référant au nombre de mots mieux triés exemple que nous avions plus tôt. Même tour exact là-bas. Donc je n'essaie pas de te faire réfléchir trop fort ici. Je veux juste que vous vous entraîniez ici et que vous appliquiez ce que vous avez appris dans cette section. Comme je l'ai dit, nous deviendrons plus difficiles bientôt. Alors vas-y et essaye ça. Maintenant, voyez si vous pouvez trier ces résultats par montant dépensé et lui donner un coup de feu. Et nous reviendrons dans la prochaine conférence et vous pourrez comparer vos résultats dans votre code avec le mien.
20. Vérifiez vos résultats et vos résultats avec la minière: Ok, donc j'espère que vous avez eu la chance d'essayer de trier ces résultats par montant dépensé pour qu'on puisse y avoir une sortie plus utile. Comparons encore votre solution à la mienne. Donc, si vous voulez regarder le mien, vous pouvez cliquer sur le total dépensé par les clients triés. Double-cliquez dessus et voyez comment je l'ai fait. peu près la même chose que le code original que nous avons traversé dans la conférence précédente. Donc je ne vais pas répéter toutes les choses qui n'ont pas changé. Tout ce qu'on a changé, c'est ici. Donc, à ce stade, nous avons le montant total par client. Nous avons donc réduit nos données pour avoir des paires de valeurs clés où nous avons identifiants de client
individuels associés
au montant dépensé par ce client dans l'ensemble de la base de données. Donc, tout comme nous l'avons fait dans le mot count exemple trié, nous allons retourner cela sur sa tête et essayer de profiter
du tri par opération clé que l'étincelle offre. De cette façon, nous pouvons réellement distribuer le tri de ceci sur le cluster si nous le voulons. Pour ce faire, nous devons faire de nos valeurs, des clés et des clés les valeurs parce que nous voulons trier par les valeurs, le montant dépensé. Donc, nous sommes en train de créer ce RDD retourné. C' est juste le mappage total par client pour prendre la paire clé-valeur d'entrée x et prendre le deuxième élément et le faire en premier. Et nous prenons le premier élément et le faisons deuxième. Donc, il suffit de retourner la clé et la valeur pour faire la nouvelle clé, le montant dépensé et la nouvelle valeur, l'ID utilisateur. Nous trions ensuite par clé pour trier cela par le montant dépensé cette première valeur là. Ensuite, nous pouvons recueillir les résultats et imprimer chaque ligne. Alors voyons si ça marche. clic droit sur le total dépensé par les clients triés et exécutez-le. Et nous devrions voir qui sont les grands dépenseurs. On dirait que ça a marché. Nous avons donc dans la première colonne maintenant le montant dépensé. Donc, nous pouvons voir que le plus de gens a dépensé avec $6.375.45 et c'était par numéro d'utilisateur 68. Donc on peut voir que l'utilisateur 68 était notre plus gros dépenseur. Et si nous devions faire défiler vers le haut, nous pouvons voir notre dépenseur le moins cher, si vous voulez. 3 309$ sont allés à l'utilisateur 45. Et encore une fois, si vous voulez vous pousser plus loin, vous pouvez essayer de formater cette sortie un peu plus joliment. Je ne vais pas passer par cela avec vous, mais si vous avez l'impression que vous voulez encore plus d'un défi, voir si vous pouvez imprimer chaque ligne juste pour dire plus verbeusement, ID
utilisateur, ce qui a dépensé autant d'argent et formater l'argent en réel format monétaire, signe
dollar, un point entier deux décimales, n'est-ce pas ? Et ce ne sera pas vraiment un problème d'étincelle. C' est plus un problème de Scala. Mais si tu veux aller plus loin, c'est une façon de le faire. Mais oui, ça suffit pour l'instant. Nous avons donc appris à propos des RDD. Rdds sont l'API originale pour Apache Spark, remontant à Spark 1, et ils ont toujours leur place pour de nombreux types de problèmes. Ils peuvent offrir les meilleures performances et la plus grande flexibilité et ce que vous pouvez faire. Mais il est temps de passer à autre chose. Alors allons parler des dataframes et des jeux de données ensuite, parce que c'est vraiment la façon la plus moderne de faire du code Spark. Et nous allons revoir ces exemples, les
refaisant à l'aide de jeux de données dans la section suivante.
21. Introduction à SparkSQL: Donc, dans notre section suivante, nous présentons Spark SQL. Et avec cela vient les API les plus modernes de Spark DataFrames et jeux de données dans le monde de Scala, nous allons nous concentrer davantage sur les jeux de données parce que c'est encore plus efficace. Donc, ce sera l'interface la plus moderne pour Spark. Et on va se concentrer sur ça pour aller de l'avant dans le cours. Il s'agit d'une couche au-dessus de Spark Core. Mais si vous pouvez penser à vos problèmes en termes de commande SQL, dont la plupart des problèmes d'analyse de données peuvent être Spark SQL et les dataframes et jeux de données offrent une
solution très efficace et facile à utiliser pour obtenir les réponses que vous voulez à travers un cluster entier. Alors plongons et voyons comment ça marche. Donc, nous avons beaucoup parlé de l'interface RDD dans Spark jusqu'à présent qui était l'interface d'origine et Spark dans tout est construit au-dessus de celui-ci. Parfois, il est encore utile de revenir à cela et vraiment descendre à un niveau bas pour la meilleure optimisation pour les problèmes plus simples. Mais à partir de Spark à, ils ont vraiment commencé à mettre l'accent sur l'interface Spark SQL et Apache Spark à la place. Et Spark SQL apporte à la table des choses comme des dataframes et des jeux de données. Parlons de ceux-là. Donc DataFrames est venu en premier. Ils ont étendu les RDD à un objet dataframe. Et un DataFrame ressemble beaucoup à une base de données relationnelle. Il contient des objets de ligne qui contiennent une sorte d'informations structurées. Il a un schéma. Et de cette façon, nous pouvons stocker les choses plus efficacement. Et parce que nous avons un schéma et ces lignes, nous pouvons simplement le traiter comme une base de données SQL et exécuter des requêtes SQL réelles sur nos DataFrames. Et comme cela ressemble beaucoup à une base de données réelle, vous pouvez avoir beaucoup d'interopérabilité avec les bases de données et les formats de fichiers liés à la base de données. Ainsi, vous pouvez lire et écrire au format JSON ou VIH ou parquet. Et vous pouvez même communiquer directement via une interface JDBC ou ODBC ou à l'aide de Tableau. Donc, nous pouvons réellement ressembler à une base de données relationnelle, même si c'est Apache Spark qui fonctionne sur un cluster. Plutôt cool, non ? Et parce qu'il peut penser à des choses en termes de requêtes SQL, cela amène également à la table tout le monde des technologies d'optimisation des requêtes, n'est-ce pas ? Donc, au-delà des optimisations de graphes acycliques dirigées habituelles qui se produisent avec Spark, nous pouvons également regarder vos requêtes SQL réelles que vous essayez d'émettre sur un DataFrame et faire les mêmes choses que celles que base de données
relationnelle ferait pour optimiser cette requête. Donc, si vous faites des choses en quelque sorte de manière SQL avec un DataFrame, vous pouvez parfois obtenir encore plus d'optimisation qu'avec un RDD. Ensuite, nous sommes sortis avec les jeux de données et les jeux de données et les DataFrames sont un peu la même chose. Techniquement, un DataFrame n'est qu'un jeu de données d'objets de ligne. Donc une rangée n'est qu'une rangée de trucs, non ? Donc, le point important ici est que vous pouvez également avoir un jeu de données qui enveloppe l'aide et le type explicite et structure
explicite ou inexplicite où nous connaissons le schéma réel à l'avance au moment de la compilation. Par exemple, je pourrais créer un jeu de données d'une classe de cas de personne qui définit exactement quels sont les champs qui définissent une personne et quels sont ces types. Ou je pourrais créer un jeu de données qui dit explicitement que je veux une chaîne et un double sur chaque ligne. Et en faisant cela, il saura ce que sont ces colonnes dès le début. Donc, contrairement à un DataFrame où tout ce que je sais est que j'ai un jeu de données de lignes dans cette ligne. ligne pourrait contenir n'importe quoi jusqu'à ce que je le définisse, un nez de jeu de données à l'avant, quels types en sont à l'intérieur ? Et pour cette raison, le jeu de données connaît son schéma au moment de la compilation. Cela signifie que les erreurs liées au type seront détectées lorsque vous construisez votre script, plutôt
que lorsque vous exécutez réellement le script. Et c'est énorme, non ? Parce que l'exécution d'
un script est souvent une opération très coûteuse lorsque vous le faites sur un gros cluster. Donc, un grand avantage des jeux de données est que vous allez
détecter ces erreurs liées au type au moment de la compilation. Et cela rend votre développement un peu plus facile. Cela conduit également à une meilleure optimisation. Cela signifie que nous pouvons réellement faire une certaine optimisation pendant que nous compilons plutôt que lors de l'exécution. Et c'est aussi un gros avantage. Maintenant, le catch avec les jeux de données est que parce qu'il fait tout cela au moment de la compilation, vous ne pouvez vraiment les utiliser que dans les langages qui sont compilés. Cela signifie Java ou Scala dans le monde de Spark. C' est donc une autre raison d'utiliser Scala au lieu de Python. Si vous ne pouvez pas, même si Python semble être beaucoup plus populaire. Avec Python, nous sommes limités à DataFrames car il ne
peut pas faire cette optimisation du temps de compilation. Donc avec Scala, cependant, nous pouvons être les enfants cool. Nous pouvons utiliser des jeux de données et nous pouvons savoir quels sont nos types à l'avance. Python, cependant, va être limité à DataFrames. Maintenant, vous n'avez pas à tout faire avec des jeux de données si vous ne le voulez pas, vous pouvez réellement convertir un RDD un jeu de données avec deux ds et vous pouvez également faire l'inverse. Il est donc possible d'avoir le meilleur des deux mondes et de faire traitement en utilisant
des RDD et de faire un traitement ultérieur avec des jeux de données et de faire tout ce qui a du sens. Comme nous le verrons, les RDD sont encore plus utiles pour certaines opérations. Mais pour les requêtes comme SQL,
évidemment, vous allez vouloir utiliser des jeux de données. jeux de données sont vraiment la nouvelle chaleur. l'ensemble, la tendance dans le développement de Spark est d'utiliser moins les RDD et les jeux de données plus. Et en fait, j'ai des étudiants qui se fâchent que je couvre même les RDD du tout maintenant, mais ils ont vraiment leur place. jeux de données, qui sont souvent plus efficaces, peuvent être sérialisés très efficacement. Et à cause de ces plans d'exécution qui déterminaient au moment de la compilation, si vous faites une requête SQL, cela peut souvent être beaucoup plus efficace, comme je l'ai dit, alors simplement utiliser un jeu de données RDD permet également une meilleure interopérabilité, non seulement avec des formats de fichiers et des bases de données externes, mais aussi dans les différents composants de Spark lui-même. Ainsi, la bibliothèque Sparks Machine Learning et Spark Streaming Engine utilisent des jeux de données comme API principale au lieu de RDD maintenant, donc si vous voulez déplacer vos données entre ces différents composants de Spark, vous allez utiliser des jeux de données comme ce genre de façon de le faire dans Scala. Et aussi parfois, l'utilisation d'un jeu de données peut vraiment simplifier votre développement. Si vous faites simplement des opérations SQL et que vous pouvez penser à ce que vous
essayez de faire avec votre analyse sur Spark en termes de commande SQL, vous allez trouver qu'il est vraiment, vraiment, vraiment, vraiment facile de le faire avec un jeu de données. Alors qu'il aurait pu être beaucoup plus difficile de le faire avec une DMR. Maintenant, lorsque vous utilisez Spark SQL, y compris les jeux de données dans Scala, il y a une différence de structure ici quant à la façon dont vous abordez vos scripts. Et nous le verrons avec quelques exemples sous peu. L' essentiel est que vous allez créer un objet SparkSession au lieu d'un contexte Spark lorsque vous démarrez votre script. Si vous allez utiliser Spark SQL ou des jeux de données, vous devez déclencher une session. Pensez à cela comme une session de base de données. Et vous devez arrêter explicitement cette session lorsque vous avez terminé. Maintenant, une fois que vous avez cette session, vous pouvez réellement obtenir un SparkContext à partir de celui-ci et l'utiliser pour émettre des requêtes SQL sur vos jeux de données. Ou vous pouvez simplement utiliser l'API Dataset, un peu comme ceci. Donc, une fois que vous avez un objet de jeu de données chargé, vous pouvez faire des choses comme afficher ou sélectionner ou filtrer ou GroupBy. Et vous remarquerez que cela ressemble beaucoup à des commandes SQL, n'est-ce pas ? Donc, le format devrait sembler très familier. Si vous connaissez SQL, par exemple, sélectionnez un nom de champ qui fait exactement ce que vous pensez qu'il ferait. Il sélectionne en fait la ligne du nom de champ de votre jeu de données et la renvoie dans un nouveau jeu de données. Filtrage. C' est une syntaxe intéressante, non ? Donc, nous pouvons réellement dire filtre avec un nom de champ sur mon jeu de données supérieur à 200. Nous pouvons mettre cette expression comme paramètre dans notre commande filter et en récupérer huit. C' est un jeu de données où nous filtrons simplement les choses qui sont supérieures à 200. Regrouper par, cela fonctionne comme il ne fonctionne pas aussi bien SQL. Donc nous pourrions tout regrouper sur un nom de champ. Et ça va être la même chose qu'une opération de réduction, non ? Et puis nous pouvons dire .me pour calculer automatiquement la moyenne de chacun de ces résultats. Donc, dans une ligne, je pense que nous avons fait tout l'exercice, un de nos exemples précédents utilisant des RDD, non ? C' est donc un bon exemple de la façon dont les choses peuvent être plus simples. Et si vous avez besoin de faire quelque chose de plus bas niveau, vous pouvez toujours. Vous pouvez le convertir en un RDD et passer votre propre fonction de carte personnalisée si vous le souhaitez. Donc, comme je l'ai dit, vous pouvez mélanger et faire correspondre ici et obtenir le meilleur des deux mondes avec des jeux de données et des RDD. Les jeux de données ouvrent également d'autres possibilités. Comme je l'ai dit, vous ne pouvez pas nous parler, JDBC ou ODBC. Donc, il est possible d'ouvrir un shell
pour déclencher SQL et de le traiter comme si c'était une base de données, ce qui est un peu génial, non ? Je veux dire, cela vous donne une sorte de base de données évolutive horizontalement, si vous voulez, sur l'ensemble de votre cluster Spark. C' est cool ? Et certains des détails ici sont listés ici sur la diapositive si vous voulez plus de détails, mais je ne veux pas trop embrouiller votre cerveau avec cela parce que nous ne ferons pas cela dans les exercices, mais sachez simplement que c'est possible. Vous pouvez également avoir des fonctions définies par l'utilisateur si vous le souhaitez. Parfois, cela sera plus facile à faire en dehors des jeux de données, mais vous là, ici si vous en avez besoin. Ainsi, par exemple, nous pourrions créer une fonction simple définie par l'utilisateur en
important simplement org dot apache Spark point SQL, point UDF. Nous pourrions construire une UDF appelée square qui
contient juste l'expression take x et le faire x fois x. et puis nous pourrions, par exemple, dire la colonne width et ajouter une nouvelle colonne appelée square, qui appelle simplement que fonctions définies par l'utilisateur. Vous pouvez donc le faire aussi, tout comme vous pouvez avoir des UDF dans les bases de données. Vous pouvez également avoir des fichiers UDF dans des jeux de données. Donc, cela aura beaucoup plus de sens avec quelques exemples. Alors nous allons simplement plonger dans et passer le reste de cette section à regarder des exemples pratiques. Donc, nous allons revenir à nos fausses données de réseaux sociaux que nous avons utilisées plus tôt dans le cours avec les RDD. Et je vais vous montrer quelques façons d'utiliser les jeux de données pour explorer ces données. Donc, d'abord, nous allons réellement l'interroger avec une commande SQL réelle, puis nous allons revenir en arrière et utiliser les fonctions de l'API du jeu de données pour l'interroger sans utiliser de commandes SQL réelles. Mais le code ressemblera toujours beaucoup à SQL. Et après cela, revenons à nos exemples RDD et refaisons-les avec jeux de données et nous verrons lesquels sont les plus simples maintenant et ceux qui sont les plus complexes. Et il y aura un bon moyen de comprendre les forces et faiblesses des DRD et des jeux de données. Et vous pouvez en apprendre davantage sur la façon de choisir l'API à utiliser pour un problème donné. Alors plongons dans la conférence suivante et revenons à notre faux réseau social et jouons avec elle.
22. [Activité] utilisez SparkSQL: Donc, jouons avec Spark SQL et
DataFrames en fait avec ce petit exemple simple ici, ouvrez l'exemple de jeu de données SQL Spark dans vos matériaux ici. Et passons à travers ce qui se passe dans celui-ci. Nous revenons donc à notre base de données ou à notre jeu de données faux amis qui a été utilisé pour nos amis par exemple d'âge dans la première section. Et nous allons interroger ces données en utilisant des interfaces SQL SAL au lieu d'utiliser Spark SQL. Donc, nous déclarons qu'un paquet est toujours n. Maintenant, notez que nous incluons
juste org dot apache, Spark dot SQL. Nous nous limitons aux API SQL Spark. Pour cet exemple, nous avons également un journal pour J. Nous créons notre objet et nous commençons à créer une classe de cas. C' est quoi tout ça ? C'est donc une fonctionnalité Scala dont nous n'avons pas parlé auparavant. Donc, une classe de cas est juste une façon très compacte de définir une classe et une définition d'objet, si vous voulez. Donc, en disant personne de classe de cas, nous disons que nous voulons définir un objet de personne. Et il contiendra les champs suivants avec les types suivants. Donc, si vous êtes familier avec comme C plus plus, par
exemple, c'est un peu comme déclarer une structure. Mais la syntaxe d'ici est un peu plus compacte. On dit qu'une personne se compose de quatre domaines différents. Il contient un champ ID et ce nom est significatif, qui ne se conserve correctement. Et cet ID est un entier. Il contient un champ de nom de type string et H champ de type entier, et le champ d'un ami de type entier ainsi. D' accord ? Et cela sera effectivement utilisé pour construire les tables de base
de données virtuelle qui interrogeront en utilisant Spark SQL. Donc, lorsque nous avons terminé, cela correspondra aux noms de colonnes et les types de colonnes dans notre table auront une colonne d'ID qui contient des entiers, aura une colonne de nom qui contient des chaînes et ainsi de suite. Donc, avec cette ligne, nous avons défini le schéma pour nos données. Ok, c'est très important. Avec des ensembles de données. Nous devons avoir ce schéma défini au moment de la compilation. Nous ne pouvons pas simplement le déduire des données elles-mêmes. Donc avec ça en main, nous allons entrer dans notre fonction principale. Nous définissons notre niveau de journal. Et maintenant, au lieu de créer un SparkContext, nous créons une session Spark. Encore une fois, vous pouvez penser que cela ressemble à une session de base de données. Donc, pour créer cette session d'étincelle, nous disons constructeur de points SparkSession. Pour créer notre, pour réellement construire notre session. Nous lui donnons un nom d'application était Spark SQL. Nous disons que notre maître est une étoile locale, même syntaxe exacte qu'avant, en
disant que nous allons fonctionner sur votre machine locale et que je vais cœurs
CPU et obtenir ou créer. Cela signifie que nous pouvons réellement créer une nouvelle session Spark ou réutiliser une session existante. Souviens-toi que je t'ai dit que tu devais arrêter ces choses quand tu auras fini. Si nous passons un peu de l'avant,
nous voyons que nous disons un point d'étincelle à la fin pour clôturer cette session. Possibilité pour ces sessions de continuer à fonctionner au-delà de la durée de vie de ce script de pilote. Donc, si vous ne l'arrêtez pas explicitement, ou qu'elle s'arrête de façon inattendue, cette session pourrait toujours être en cours d'exécution sur votre cluster et obtenir notre caisse réutiliserait simplement cette session existante au lieu d'en créer une nouvelle dans ce cas. Des trucs tellement intéressants. Maintenant, nous allons charger nos données. Alors rappelez-vous que nos données existent dans de faux amis point CSV. Et nous allons juste charger cela en utilisant Spark dot read. Ainsi, Spark dot lu sur l'objet SparkSession lira ce fichier CSV. Nous allons lui dire qu'il a une ligne d'en-tête. Et nous allons vous demander d'abord d'inférer le schéma à partir de ce qui se trouve dans cette ligne d'en-tête. Donc, les informations de ligne d'en-tête correspondent mêmes noms que nous avons donnés dans notre classe de cas ici, l'en-tête est id, nom, âge et amis. Et c'est important que ça corresponde dans ce cas. Donc, à ce stade, après avoir dit point d'étincelle read.csv, nous avons un DataFrame. À ce stade, le schéma a été déduit au moment de l'exécution, n'est-ce pas ? C' est la principale différence entre un dataframe et un jeu de données. Mais nous voulons toujours utiliser des jeux de données. Nous voulons tous les avantages de cette vérification du type de temps de compilation. Donc, je vais prendre ce DataFrame qui
se compose juste de ces objets de ligne avec des schémas inférés et le
convertir en un jeu de données avec un schéma explicite en disant point en personne. Donc, ce point en tant que personne prend ce DataFrame que nous lisons à partir du CSV et le convertit un jeu de données avec un schéma que nous connaissons au moment de la
compilation en utilisant la classe de cas de personne avec moi jusqu'à présent. Ok, ça aura plus de sens quand on l'exécutera. La première chose qu'on va faire est d'imprimer ce schéma pour
s'assurer que c'est ce qu'on attendait. Donc, à ce stade, nous avons un jeu de données de personnes de schéma. Et maintenant, nous pouvons créer une vue de base de données sur elle en disant créer ou remplacer la vue temporaire. Encore une fois, cela créera un nouveau ou remplacera un existant avec le même nom. Et on va appeler ça peu de gens. Cela aura pour effet de créer fondamentalement une table de base de données appelée personnes à toutes fins utiles. Et nous pouvons interroger cette table maintenant en disant simplement Spark dot SQL. Nous appelons le SparkSession dot SQL avec une commande SQL réelle ici. Nous allons dire choisir l'étoile parmi les gens. C' est la vue que nous avons créée à partir de notre jeu de données. Lorsque l'âge est supérieur ou égal à 13 ans et que l'âge est inférieur ou égal à 19 ans. Donc, nous créons une instruction SQL réelle ici et retournons les résultats dans une nouvelle structure appelée adolescents, un nouveau jeu de données. Nous allons ensuite collecter le contenu de ces résultats et les parcourir, les
imprimer tous et arrêter la session lorsque nous aurons terminé. Alors allons de l'avant et allons voir ce qui se passe. Cool, ça a marché. Donc nous pouvons voir ce schéma inféré ici, en fait le schéma explicite que nous lui avons donné pour l'ensemble de données, non ? Donc, nous pouvons confirmer que nous avons un champ id, nom, âge et amis des types que nous attendons entier, entier de
chaîne et un entier. C' est donc le schéma de notre
jeu de données de personnes de schéma que nous avons mis en place et lu à partir de ce fichier CSV. Et puis nous avons les résultats de notre requête ici. Et nous voyons que nous avons tous les adolescents dans notre jeu de données ici. Ce sont des jeunes de 19 ans et de 18 ans, et je suppose qu'ils n'ont généré que des données à partir de 18 ans. C' est donc le résultat de notre requête là-bas. On dirait que ça a marché. Plutôt génial. Donc, nous avons réellement exécuté une commande SQL réelle sur un jeu de données sur Apache Spark sur un cluster entier potentiellement. Alors, à quel point c'est cool que vous ayez toute la puissance
du langage SQL à votre disposition avec Apache Spark en utilisant des jeux de données. Et je veux faire encore un point avant de passer à autre chose. Donc, je n'ai pas eu à utiliser un jeu de données ici. J' aurais pu utiliser un DataFrame. Laissez-moi vous montrer comment ça fonctionnerait. Donc, si je commente simplement cette ligne, à ce stade, mes gens de schéma vont être un DataFrame. Il va avoir ce schéma déduit au moment de l'exécution. Je ne le dis pas explicitement avec cette classe de cas quel est le schéma. Donc, en commentant cela, je perds toutes les vérifications d'erreurs au moment de la
compilation et les optimisations au moment de la compilation que j'obtiendrai avec les jeux de données. Mais cela fonctionnera toujours. Cela fonctionnera juste au moment de l'exécution. Allons-y, faisons-le ça et assurons-en que je ne te dis pas de mensonge. Et vous pouvez voir ici que nous avons eu la même réponse. Donc, les résultats de la même requête ici de 18, 19 ans que nous voulions, et les schémas sont toujours les mêmes. Donc, tout fonctionne toujours comme un DataFrame. C' est juste qu'en utilisant un jeu de données et en lui donnant ce schéma explicite,
nous obtenons de meilleures performances et une meilleure vérification des erreurs au moment de la compilation. Plongons dans un autre exemple suivant.
23. [Activité] Utiliser des DataSets: Donc, dans notre conférence précédente, nous avons parlé de l'utilisation de commandes SQL directement sur nos faux amis et les données de notre faux réseau social. Regardons une autre façon de le faire sans réellement utiliser les commandes SQL, mais plutôt utiliser les fonctions similaires SQL disponibles sur les jeux de données. Alors jetez un oeil à cette autre façon de faire les choses. Ouvrez le jeu de données DataFrames, script de pilote. Et regardons ça. Donc, la configuration et le chargement réels de nos données vont être identiques à partir de la dernière fois, nous allons configurer une classe de cas de personne à nouveau qui définit le schéma des données que nous avons l'intention de charger. Et encore une fois, nous avons un ID qui est un entier, un nom qui est une chaîne, et l'âge qui, c'est un entier. Nombre d'amis qui est également un entier. Dans notre fonction principale. Tout comme avant de définir notre niveau de journal, nous créons ici un objet SparkSession avec un nom
et un maître donnés et nous l'obtenons ou créons. Et encore une fois, nous lisons cela à partir du fichier CSV en utilisant Spark dot read. Et nous forçons effectivement cela à être un jeu de données en disant point en tant
que personne à la fin pour convertir ce schéma implicitement défini à l'exécution un schéma codé en dur en le forçant à la classe de cas de personne ici. Donc, j'ai un peu brillé sur cela initialement, le point d'étincelle d'importation implique la ligne de soulignement de points est importante chaque fois que vous avez intelligent inférer implicitement le schéma, vous devez vous assurer que vous importez ce paquet juste avant vous le faites. La syntaxe ici est un peu bizarre. Normalement, vos déclarations d'importation se trouvent en haut de votre fichier. Mais dans ce cas, nous le voulons juste avant de l'utiliser parce que nous voulons seulement appliquer à cette portée spécifique ici. Donc, à chaque fois que vous avez une commande que nous sommes les schémas qui sont déduits. Et ici, c'est assez explicite que nous faisons cela tout en disant « spark dot read » pour utiliser l'en-tête dans le fichier CSV. Et nous déduisons le schéma initialement à partir de cet en-tête CSV, nous avons besoin de déclencher des implicites pour être en mesure de le retirer. Maintenant, quand nous avons fini, nous sommes, nous convertissons cela en un jeu de données avec un schéma explicite. Mais cette étape intermédiaire nécessite des implicites Spark dot. Il existe d'autres façons de charger des jeux de données que nous verrons plus tard qui
ne nécessitent pas l'étape intermédiaire d'un schéma inféré, mais nous y arriverons. Bref, nous imprimons ce schéma comme avant. Et maintenant, nous avons une autre façon de jouer avec nos données ici que nous examinons. Donc c'est le nouveau truc maintenant. Commençons donc par sélectionner seulement la colonne de nom. Une chose que nous avons fait dans nos exemples RDD, donc c'était assez commun, était de jeter des colonnes d'informations dont nous n'avions pas besoin. Et c'est une façon de le faire en utilisant des jeux de données. Nous pouvons dire que les gens dot select, name dot show, et cela ne sélectionnerait que la colonne nom et rien de plus. Dans ce cas, nous n'affecterons pas cela à un nouveau jeu de données. Nous allons juste appeler dot show pour forcer Spark à sortir et obtenir ce résultat et à nous l'afficher à partir de notre script de pilote. Donc, tout comme vous pouvez dire select name, nous disons ici, sélectionnez le nom entre guillemets ici au lieu d'une commande SQL, syntaxe similaire, même idée, juste une façon différente de le faire qui ne
nécessite pas une vue de base de données réelle pour le faire. Nous pouvons également faire quelque chose de similaire à nos amis par exemple d'âge, où nous allons juste filtrer toute personne âgée de plus de 21 ans. Donc on pourrait dire que les gens sont filtrés par points, les gens âgés de moins de 21 points montrent. Donc, c'est la même chose que de dire select name où l'âge est inférieur à 21 et SQL, mais nous le faisons plus explicitement à travers les fonctions sur le jeu de données lui-même. Donc c'est un peu bizarre, non ? Vous savez, si vous êtes habitué, d'autres langues sont des langues non fonctionnelles. L' idée d'avoir une expression comme celle-ci, les gens ont moins de 21 ans et de passer cela comme paramètre à une fonction peut sembler étrange. Mais à Scala, vous pouvez le faire. Ça marche en fait. Donc c'est plutôt cool. Donc, nous disons simplement les gens et nous passons dans
le nom de la colonne que nous voulons filtrer sur moins de 21. Et cette expression en passant par la fonction de filtre d'un jeu de données, fonctionne
simplement. Il fait ce qu'il faut. C' est presque magique. Encore une fois, nous allons montrer les résultats, les afficher, plutôt
que de stocker cela dans un nouveau jeu de données dans notre exemple ici. Aussi en SQL, nous avons le groupe par fonction. Et c'est fondamentalement la même chose que l'opération GroupByKey que nous avions dans RDD. Donc, il va regrouper toutes les valeurs distinctes des âges et les glober toutes ensemble. Et puis nous allons en outre appeler compter sur cela pour juste obtenir un grand total de combien de personnes existent dans chaque âge, année et montrer les résultats sur une ligne ici nous avons fait quelque chose que nous devions faire un peu plus alambiqué en utilisant RDD, droit ? Si vous vous souvenez, nous aurions dû transformer les choses avec une opération de carte pour insérer un numéro un pour chaque personne, puis faire une opération ReduceByKey pour les ajouter tous pour le faire avant. Mais dans ce cas, nous pouvons utiliser plus d'un type
de syntaxe SQL ici et tout faire sur une seule ligne de code. Vous pouvez donc voir la puissance des jeux de données ici. De plus, puisque nous utilisons des jeux de données, cela peut également être plus efficace. Alors, ouais, réfléchis un peu plus à ça. On va regrouper par âge. Donc, cela combine fondamentalement toutes les entrées dans les gens par des numéros d'âge uniques. Nous comptons chacun dans chaque âge et montrons les résultats. Et voici un autre exemple intéressant ici. Dans ce cas, nous allons sélectionner toutes les personnes. Et on va juste sélectionner la colonne de nom. Et puis nous allons aussi sélectionner les personnes âgées de plus de 10 ans. Donc, cela va montrer un affichage de deux colonnes. L' une est la colonne de nom du jeu de données personnes d'origine. Et la deuxième colonne, il affichera que nous sélectionnons ici va être la colonne d'âge avec 10 attitude il. Donc encore une fois, nous pouvons avoir ces expressions dans les fonctions quand dans Scala, et cela fonctionne réellement. Nous pouvons dire que les gens ont plus de 10 ans et passer cela comme paramètre à la fonction select. C' est un peu bizarre si vous êtes habitué à d'autres langues à nouveau, mais c'est comme ça que vous le faites dans Scala et étincelle, cela fonctionne en fait. Et n'oubliez pas d'arrêter votre séance quand vous avez terminé. Sinon, il continuera à fonctionner et à
traîner et à utiliser des ressources que vous ne voulez pas utiliser. Et cela pourrait vous embêter quand vous faites des courses ultérieures aussi. N' oubliez jamais d'arrêter votre séance quand vous avez terminé. Alors allons de l'avant et voyons cela en action et nous convaincre que cela fonctionne réellement. Nous allons faire un clic droit sur DataFrames, Datasets et dire run off, il va. D' accord, et passons à travers ce qui s'est passé ici. Allons au sommet, je vais faire défiler vers le haut. La première chose que nous avons fait était d'imprimer le schéma, et c'est là. Donc, nous pouvons nous convaincre qu'il a effectivement obtenu la structure correcte du jeu de données là-bas. Ça m'a l'air droit. Donc, nous déduisons un nom d'ID, âge et la colonne amis de types entier, chaîne, entier et entier respectivement. Notre première étape ici avec la sélection de la colonne de nom. Et il y avait cette commande ici, les gens dot select col égal nom dot show. Et il a fait exactement ce que vous attendez. Et il ressemble beaucoup à ce que vous attendiez à voir à partir d'une sortie de base de données relationnelle réelle, n'est-ce pas ? Vous savez, ils essaient vraiment de combler l'écart entre Spark et l'utilisation d'une base de données relationnelle et en font la même façon de l'utiliser avec Apache Spark et ses versions plus récentes. La différence, bien sûr, est qu'au lieu d'un serveur de base de données monolithique unique, vous avez un cluster entier qui le fait potentiellement. Vous pouvez donc voir que nous avons sélectionné avec succès la colonne de nom et l'avons montré. Nous avons donc ce petit aperçu des premières entrées. Nous ne montrons que les 20 premières lignes par défaut, sinon, cela continuerait pour toujours. Et notre prochaine expérience ici a été de filtrer toute personne âgée de plus de 21 en
passant dans cet argument de filtre des personnes âgées de moins de 21 ans. Et bien sûr, les données que nous avons obtenues ne montrent que les personnes âgées de 19, 20 ou 18 ans, parce que ce sont toutes les personnes âgées de moins de 21 ans dans notre ensemble de données. Donc, ce travail à très cool. Et nous avons aussi essayé ce groupe par ordre d'âge ici encore, un peu plus de fantaisie ici. Donc, encore une fois pour résumer, nous avons regroupé tout le monde par numéros d'âge uniques et nous les avons tous
comptés et nous les avons montrés et il semble que ça a fonctionné. Nous avons donc 831 ans, 565 ans, 753 ans, et cetera, dans notre ensemble de données. Encore une fois, une ligne de code, très simple, très facile à utiliser. Ils sont très optimisés. Et c'est beaucoup plus simple que la façon dont nous devions le faire en utilisant des RDD. Enfin, nous avons fait cela, faire tout le monde 10 ans plus vieux truc ici où nous avons sélectionné la colonne de nom et aussi inventé une nouvelle colonne qui s'appelle les gens d'âge plus 10. Voyons si ça a marché. Et oui, ça semblait donc on aurait eu 33 ans à l'origine, mais dans la colonne d'âge plus 10 que nous avons créée ici, il a maintenant 43 ans. Et ça marche en fait. Vous pouvez passer des expressions mathématiques comme ça et elles seront réellement évaluées et affichées pour vous de cette manière. Quand nous avons terminé, nous arrêtons la session, et c'était tout. Donc là, vous l'avez. Jeux de données utilisant des fonctions au lieu des commandes SQL réelles. Vous pouvez le faire de toute façon, mais, vous savez, dépend de vos préférences. Donc là, vous l'avez. Deux façons différentes d'utiliser les jeux de données.
24. [Exercice ? l'exemple « Amis par âge » à l'aide de DataSets: Très bien, vous m'avez écouté parler de jeux de données assez longtemps. Je pense qu'il est temps de se salir les mains et d'essayer de les utiliser vous-mêmes. Permettez-moi donc de vous donner votre premier défi en utilisant des jeux de données. Rappelez-vous les amis par exemple d'âge que nous avons fait avec RDD ? Eh bien, je voulais y retourner et le faire à nouveau, mais cette fois en utilisant des jeux de données au lieu de RDD. Donc, juste pour examiner ce que cet exemple est tout au sujet, nous avons fourni un fichier de
valeur séparé par des virgules faux amis qui contient des données dans ce format. C' est essentiellement un identifiant d'utilisateur, leur nom, leur âge et le nombre d'amis qu'ils ont. Et votre tâche est de me donner le nombre moyen d'amis par âge. Donc, je veux savoir en moyenne, combien d'amis comme un 33 ans ont, beaucoup d'amis est un 55 ans ont et ainsi de suite et ainsi de suite pour chaque âge représenté dans mes faux amis dot fichier CSV. Et ça s'appelle de faux amis parce que c'est de fausses données. Tout a été généré au hasard. Donc ils ne sont pas comme, je ne fais pas un jugement de valeur sur tes amis ici. Quoi qu'il en soit, quelques conseils sur la façon de passer à travers cela. Il y a donc un faux fichier csv dot amis dans votre matériel de cours qui contient une ligne d'en-tête. Et comme vous l'avez vu dans nos exemples précédents, utiliser des jeux de données qui va être important pour autoriser le pétoncle et étincelle pour le schéma correct pour ces données. Et quelques commandes ici qui pourraient être utiles. Rappelez-vous, nous pouvons utiliser la commande select pour extraire colonnes
données d'un jeu de données et en obtenir un nouveau qui a juste les données dont nous avons besoin. Vous vous souvenez peut-être que lorsque nous avons fait cela avec des RDD, nous avions une fonction cartographique qui a fait cela pour nous. Donc, cela va être beaucoup plus simple en utilisant une instruction select. Et vous aurez besoin d'une autre fonction de jeu de données. Donc GroupBy nous avons regardé avant qui va fondamentalement agréger les choses par âges
uniques, un peu comme une opération de réduction. Show montrera les résultats finaux et les récupérera. Et quand nous n'avons pas parlé était AVG pour la moyenne. Donc, après avoir regroupé les choses par âge, vous voudrez alors obtenir la moyenne par âge. Et donc je vois toujours les noms de colonnes que je mets ici à des fins d'illustration, c'est à vous de mettre les bonnes
et de les mettre dans le bon ordre et ce qui n'est pas. Mais ce sont les pièces dont vous devriez avoir besoin pour le faire. Et vous pouvez vous référer au fichier Scala
de point DataFrames du jeu de données pour vous inspirer. Et tu n'as pas à le faire de cette façon non plus. Vous pouvez simplement utiliser une commande SQL directe si vous le souhaitez aussi. Donc c'est à vous de décider dans quelle direction vous voulez aller. Alors va essayer ça. Et quand nous reviendrons à la prochaine conférence, je vais vous montrer ma solution et aussi quelques façons de l'étendre pour faire des choses plus intéressantes avec ces données aussi. Alors va lui donner un coup de feu et voir si tu peux faire fonctionner
ça, puis reviens et je te montrerai ma solution. Ne jetez pas un coup d'oeil à la solution. Il est là et bien sûr des matériaux, alors assurez-vous de créer un nouveau fichier qui a un nom unique et résister à la tentation de pic gars et revenir et nous allons passer en revue la réponse.
25. Solution d'exercice : Amis par Age, avec des Datasets.: Ok, Alors j'espère que vous avez pu passer à travers cet exercice et implémenter les amis par l'activité H en utilisant des jeux de données sans trop de problèmes. Si vous voulez comparer votre approche à la mienne. Voici ma solution ici. Si vous ouvrez les amis par script jeu de données âge ici dans les matériaux du cours. Et encore une fois, il y a plusieurs façons de le faire. Donc, si votre code ne correspond pas exactement au mien, c'est bon. Tout ce qui compte vraiment, c'est que vous avez obtenu les mêmes résultats. Donc, vérifiez quelques-uns des résultats moyens que vous avez pour différents âges et s'ils correspondent à la mienne, Vous êtes bon. Alors passons à travers ce que j'ai fait ici. Donc, beaucoup de cela semblera familier. Nous avons créé une classe de cas appelée Fake Friends dans ce cas au lieu de personne juste pour mélanger les choses un peu. Cela définit le schéma explicite de nos données provenant du fichier CSV point d'amis faux, qui se compose d'un ID et d'un nom, âge et amis. On l'a vu avant, juste un nom différent. La première chose que nous faisons est de définir notre niveau de journal, créer une SparkSession, comme nous l'avons fait auparavant. Et comme nous l'avons fait avant, nous chargeons les données slash faux amis dot fichier
CSV en utilisant le schéma inféré de l'en-tête. Et puis nous forçons ce DataFrame dans un jeu de données en disant point S et en passant, dans ce cas classe faux amis pour définir explicitement ce qu'est son schéma. Maintenant, nous pouvons au moment de la compilation vérifier tous les types et ce qui n'est pas et faire quelques optimisations au moment de la compilation aussi. D' accord, donc la première chose que nous faisons est d'aller sélectionner juste les colonnes dont nous avons besoin. Donc, comme vous vous en souvenez peut-être, les seules choses qui nous intéressent vraiment dans cet exemple sont l'âge et le nombre d'amis, les ID d'utilisateur et les noms ne sont pas pertinents pour ce problème. Nous allons donc simplement sélectionner parmi ce jeu de données, les colonnes âge et amis, et le transmettre dans un nouveau jeu de données appelé Friends by age. Et maintenant, tout ce que nous avons à faire est de dire amis par âge point groupby sur âge. Donc, cela va tout regrouper par des valeurs d'âge uniques. Et puis une fois que nous avons cela, nous allons en outre dire point AVG pour obtenir la moyenne colonnes d'
amis regroupées par âge, puis point montrer pour afficher les résultats. Et c'est tout. Nous en aurions fini à ce stade. Il y a d'autres trucs que je veux vous montrer ici, donc il y a d'autres choses à parler. Mais pour le défi comme indiqué, c'est tout ce dont vous avez besoin. Donc c'est plutôt cool, non ? Dans deux lignes de code, nous avons essentiellement fait ce que nous avons fait dans l'exemple entier en utilisant RDD avant. Revenons en arrière et regardons cela juste à des fins de comparaison. Voici donc les amis par script Scala point d'âge où nous avons fait cela en utilisant des RDD. Et vous verrez que c'est beaucoup plus compliqué ici. Donc, ici, nous avons dû écrire cette fonction de ligne d'analyse pour aller analyser tout et diviser
les choses par des virgules et extraire les champs que nous voulons et retourner un nouveau tuple. C' est ce que les champs que nous voulons. Alors qu'avec les jeux de données, nous pouvons simplement utiliser le chargeur CSV intégré à notre session Spark. Et utilisez l'instruction select pour sélectionner les champs que nous voulons. Tellement plus simple en utilisant des jeux de données. Donc, en utilisant des RDD, nous avons dû faire toutes sortes de choses
alambiquées pour calculer cette moyenne, n'est-ce pas ? Nous avons dû aller cartographier les choses en x virgule un ici. Donc, nous pouvons juste compter tout en utilisant ReduceByKey. Et c'est une façon assez tordue de faire ce que nous venons utiliser ici dans l'exemple du jeu de données, grouper par une moyenne. Et après cela ReduceByKey, nous avons dû calculer la moyenne à la main aussi en utilisant MapValues. Donc ce code, je pense que c'est beaucoup plus logique. C' est beaucoup plus facile à lire. C'est beaucoup plus simple. Contrairement à ce que nous devions faire ici en utilisant les RDD pour faire la même chose. C' est donc un bon exemple d'où les jeux peuvent être beaucoup plus faciles à utiliser et même plus rapides. Mais sous le capot, ce sont des RDD à un niveau inférieur. Et donc parfois, il est bon d'aller à ce niveau inférieur si vous avez
vraiment besoin de modifier les choses à ce niveau, passons à l'étape suivante cependant. Et si je voulais trier ces données ? Il s'avère que c'est aussi facile. Si je voulais trier ces choses par âge, je pourrais juste coller une commande de tri de points là-bas avant le spectacle. Et cela prendra les résultats de mes moyennes
par âge et juste les trier par la colonne d'âge avant de l'afficher. Et de plus, je pourrais formater ça plus bien. Nos moyennes ont parfois beaucoup de décimales pour eux et il n'est pas logique d'avoir autant de précision. Je pourrais dire AGG et ensuite arrondir la moyenne. Cela nécessite un peu d'avoir la tête autour. Donc, nous avons la moyenne du nombre d'amis ici que nous avons fait auparavant. Et puis nous disons que nous allons arrondir ça à deux décimales de précision. C' est ainsi que la commande ronde fonctionne là. Et nous devons utiliser cette fonction AGG parce que nous
agrégons toutes les données pour cet âge donné que nous avons regroupées par, non ? Donc agonies, nous allons calculer cette moyenne à travers l'agrégat de toutes les valeurs pour cet âge que nous avons sélectionnées là-bas. Une fois que l'arrondi est terminé, nous trions à nouveau les résultats par âge et les montrons. Et aussi, nous pouvons personnaliser nos noms de colonnes aussi bien. Et c'est ce que fait cet exemple ici. Donc ici, nous ajoutons un alias après cet agrégat d'arrondir tout. Et nous allons renommer ça en amis soulignent moyenne. Et encore une fois, nous le trions et le montrons. Alors passons à travers ça à nouveau. Après avoir vu la sortie, cela pourrait avoir un peu plus de sens. Cliquez avec le bouton droit de la souris sur les amis par jeu de données d'âge et exécutez-le. Et nous y voilà. Bon, alors passons à travers chaque ensemble de résultats ici depuis le haut, faites défiler jusqu'au début ici. Très bien, donc notre premier exemple était le simple où nous
venons un groupe par âge, puis la moyenne d'amis et de le montrer. Et ça marche. Ainsi, le groupe par âge a tout regroupé par âge unique, puis la moyenne de l'ordinateur d'un ami, la moyenne de la colonne des amis pour chaque âge. C' est juste que facile et en effet cela fonctionne. Cependant, vous remarquerez que les bords ne sont pas triés, il est
donc un peu difficile de rechercher les choses et d'en obtenir une réponse spécifique. Aussi, l'affichage ici est un peu bizarre, non ? Nous avons toutes ces quantités folles de précision sur les moyennes qui ne sont probablement pas nécessaires. Donc, sur notre exemple suivant, nous résolvons le problème de tri. Tout ce que nous avons fait ici était d'ajouter un tri de points avec un paramètre d'âge là
à la, au mélange là à la fin. Et ça a fonctionné. Nous voyons donc que les âges sont maintenant triés. Nous commençons par 18, 19, 20, 21, etc. Et cela semble avoir fonctionné aussi. Et de plus, nous pouvons le faire encore plus bien. Donc, si nous passons à ce troisième exemple ici, dans celui-ci, nous arrondissons les résultats à deux décimales de précision en appliquant une fonction arrondie à la moyenne et en utilisant Ag pour l'appliquer à tous les résultats d'âge pour ce groupe. Donc, ici, nous avons l'âge et l'expression ronde moyenne amis virgule deux, qui arrondit cette moyenne à deux décimales de précision. Et vous pouvez voir que cela fonctionne réellement comme prévu. Très cool. Et enfin, nous avons donné à cela un nom de colonne personnalisé en
utilisant la commande alias dans cet agrégat également. Donc, en disant l'alias de point, nous avons renommé cette colonne de ronde moyenne amis virgule deux à quelque chose de plus utile, les amis soulignent moyenne. Et si vous deviez dire cela dans un jeu de données résultant, il serait plus facile de se référer à cette nouvelle colonne que nous avons calculée par son nom sans avoir à taper ces énormes résultats alambiqués. Donc, lorsque vous enchaînez des jeux de données ensemble de cette façon, c'est souvent très utile pour avoir un moyen plus facile de faire référence aux résultats calculés dans cette colonne. Et là, vous l'avez dans les jeux de données avec nos amis par exemple d'âge, fait de quelques façons différentes et étendu de quelques façons différentes pour le faire, j'espère que vous avez appris quelques choses là-bas. Passons à d'autres exemples et nous familiarisons encore plus avec les jeux de données.
26. [Activité] Exemple de comptabilité Word en utilisant des Datasets: Continuons donc à en apprendre davantage sur les jeux de données à travers des exemples. Et encore une fois, nous allons revenir à nos exemples RDD et adapter notre exercice de
comptage de mots pour utiliser des jeux de données au lieu de RDD. Et nous irons directement à la version plus compliquée qui
utilise réellement des expressions régulières et trie les résultats. Maintenant, dans cet exemple, nous allons utiliser les fonctions SQL pour obtenir les résultats que nous voulons. Donc, au lieu d'utiliser FlatMap, nous allons utiliser une fonction appelée exploser qui va exploser des colonnes en lignes. Donc, si chaque colonne représente un mot exploitable, mettez chaque mot dans sa propre ligne. Nous allons utiliser la fonction split pour diviser les choses par mot. Nous allons utiliser la fonction inférieure afin de convertir tout en minuscules. Et quelques notes ici sur la syntaxe à connaître. Ainsi, lorsque vous transmettez un nom de colonne en tant que paramètre dans ces fonctions SQL, la syntaxe est signe dollar, puis le nom de colonne entre guillemets. Ainsi, par exemple, fractionner la valeur des guillemets de signe dollar, puis l'expression régulière diviserait tout le texte se trouvant dans la colonne de valeur en fonction des délimiteurs de mots là. De même, le filtre fonctionnerait de la même manière si nous voulions filtrer pour éliminer les mots qui ont une chaîne vide, nous le ferions de cette façon. Filtrer le signe dollar, puis le mot entre guillemets. Et notez les opérateurs d'égalité bizarres ici quand vous utilisez des déclarations de filtres ici, ce ne sera pas un signe de banque égal, il va être égal, bang sinus égal. C' est un petit truc bizarre. De même opérateur d'inégalité ici serait égal, égal, égal. Donc juste quelque chose à retenir, vous obtiendrez une erreur dans le compilateur si vous ne l'obtenez pas correctement. Donc ça vous rappellera s'il y a un problème, mais quelque chose bizarre, bizarre là-bas. Donc encore une fois, c'est un exemple de juste tester où il contre une chaîne vide, juste deux guillemets avec rien entre eux. Maintenant, il vaut la peine de souligner que le jeu de données fonctionne vraiment mieux avec les données structurées. Et quand on traite juste de lignes de textes, ce ne sont pas vraiment des données structurées. Donc, vous êtes en quelque sorte d'adapter une cheville carrée dans un trou rond ici en utilisant des jeux de données. Dans une certaine mesure. Parfois, les RDD sont plus simples et cela peut être l'un de ceux-ci, mais vous n'avez pas seulement à utiliser des ensembles de données ou des RDD. Vous pouvez les utiliser tous les deux ensemble et nous en parlerons plus dans une seconde. Une autre chose à noter cependant, est que quelque chose d'autre Il est bizarre d'utiliser des jeux de données dans ce sens est que parce que nous n'avons pas de données structurées entrant, nous n'avons pas non plus de schéma entrant. Donc, le schéma qui finit par être déduit est un peu arbitraire. Nous finissons juste avec un DataFrame plein d'objets de ligne avec une colonne nommée valeur par défaut pour chaque ligne de texte car il n'y a pas de schéma. Chaque, chaque ligne est juste une ligne de texte. Donc, il y a un nom par défaut pour cette colonne appelée valeur que vous avez juste un peu à connaître. Et c'est ainsi que nous ferons référence à ces données dans le script. Mais encore une fois, vous pouvez utiliser les deux et nous verrons une façon de le faire aussi. Rappelez-vous donc que vous pouvez convertir des RDD deux jeux de données. Il est donc parfois logique de divulguer votre charge, vos données à l'aide des interfaces RDD, puis convertir en jeu de données pour faciliter le traitement ultérieur. Donc nous allons essayer ça aussi. Plongons et voyons à quoi ça ressemble. Alors ouvrons le nombre de mots, meilleur script de jeu de données assorti ici et parcourons ce qui se passe ici. Donc on va faire ça de différentes façons ici. Commençons comme si nous importons toujours tout ce dont nous avons besoin, déclarons notre paquet, déclarons un objet. Cette fois, nous allons avoir une classe de cas très simple pour charger notre jeu de données initial. On l'appellera le livre. Et la seule donnée qu'il a est une chaîne que nous allons devoir appeler la valeur. Rappelez-vous, nous reviendrons plus tard sur la raison pour laquelle cela doit être nommé valeur. Allons à notre fonction principale, définissez le niveau de journal, créez une session Spark comme avant. Et encore une fois, nous allons initialement importer ceci en
tant que DataFrame en utilisant readme.txt avec du texte de point de livre de données. Et pour comprendre implicitement ce schéma, nous devons importer des implicites de point d'étincelle pour le faire au niveau DataFrame. Nous appelons ensuite point comme livre pour forcer cela dans un jeu de données qui a un schéma défini que nous pouvons connaître au moment de la compilation. Ce qui est bizarre ici, c'est que lorsque nous avons déduit ce schéma implicitement avec le DataFrame, il n'y avait pas de schéma fourni. Donc tout ce que nous savons, c'est que nous avons des lignes de texte qui arrivent par le texte Spark points-points. Et par défaut, chaque ligne de texte va être appelée valeur. C' est le nom de cette colonne que nous avons. Et on doit juste le savoir. Donc, pour que ce jeu de données corresponde au schéma DataFrame inféré, nous devons nommer cette valeur de ligne. Bon, donc on n'a pas choisi ce nom arbitrairement. Si c'était autre chose que la valeur, cette ligne ne fonctionnerait pas. Encore une fois, nous abordons comment utiliser des jeux de données peut être un peu maladroit dans certaines situations où vous ne traitez pas de sources de données structurées réelles provenant d'une base de données ou d'un format de base de données. Mais une fois que nous aurons fait ça, nous allons passer à autre chose. Donc maintenant, nous allons diviser cela en utilisant une expression régulière comme nous l'avons fait avant avec l'opérateur split, nous utilisons des RDD. Et puis au lieu d'utiliser FlatMap pour le souffler en lignes individuelles pour chaque mot, nous allons utiliser la fonction explode. Alors regardez ça plus attentivement. Nous allons dire entrée, qui est notre jeu de données en entrée qui contient une ligne de texte sur chaque ligne. Et nous dirons sélectionner, exploser, diviser la valeur avec un modèle d'expression régulière pour diviser les choses en mots individuels. Ok, alors commençons par le milieu ici. Donc, nous commençons par dire diviser la colonne de valeur. Et encore une fois, c'est juste le nom que nous avons attribué automatiquement à cette colonne de texte que nous avons basée sur le délimiteur de mots. Donc, à ce stade, nous allons avoir un tableau de mots. Nous allons appeler exploser dessus pour ensuite diviser cela
en une série de lignes individuelles pour chaque mot. Et puis de plus, nous allons donner à cela un alias appelé mot parce que sinon ce serait cette grande description alambiquée de cette colonne que nous avons générée. Donc, à ce stade, nous devrions avoir un nouveau jeu de données qui a une colonne de mots où chaque mot est sur sa propre ligne. De plus, il s'avère que nous finissons avec un tas de chaînes vides quand nous le faisons de cette façon, et nous voulons les filtrer afin que nous n'obtenions pas cette grande entrée dans nos résultats finaux sur les chaînes vides étant vraiment communes. Donc, pour ce faire, nous allons juste dire « filtre à points ». Et nous allons filtrer où la colonne de mot n'est pas égale à une chaîne vide, juste deux guillemets avec rien entre eux. Donc encore une fois, notez la syntaxe ici, signe
dollar, puis le nom de la colonne entre guillemets. Et à ce stade, nous avions déjà donné un alias à cette nouvelle colonne de mot appelée mot, sorte que nous pouvons nous y référer par le mot de nom dans l'opération de filtre qui vient après elle. Bon, donc maintenant nous avons un nouveau jeu de données de mots qui a des mots individuels dans chaque ligne. On a filtré tous les mots vides. Ensuite, nous allons convertir ça en minuscules. Et encore une fois, nous allons dire words.py select passant dans notre fonction inférieure. Et nous allons appliquer cette fonction inférieure à la colonne de mots. Et nous allons à nouveau donner un nouvel alias et garder le mot de nom. Nous allons simplement convertir ça en minuscules en place. Ensuite, nous compterons les occurrences de chaque mot en utilisant le groupe par opérateur, puis compterons. Donc groupby va rassembler tous les mots uniques ensemble et compter ensuite, cela
comptera-t-il toutes les occurrences de chacun ? Donc, maintenant, nous avons un nouveau jeu de données de comptes de mots qui contient un compte de chaque mot individuel. On a presque fini. Maintenant, nous avons juste besoin de trier les résultats par la colonne de comptage et de les afficher. Et notez la syntaxe ici. Donc, ce qui se passe ici exactement quand nous disons montrer le nombre de mots, nombre de points
triés, le point t2 int, nous nous assurons juste que la commande show affiche l'ensemble complet des résultats ici. Par défaut, il affichera simplement les 20 premières lignes. Nous voulons montrer tous les résultats. Donc, la façon dont ce spectacle fonctionne est que vous lui passez le nombre de lignes que vous voulez montrer. Et on veut tout ça. Nous allons donc appeler nombre de mots triés nombre de points pour obtenir le nombre de lignes dans les nombres de mots triés. Et puis nous devons convertir explicitement cela en un entier pour nous
assurer que show obtient le type de données qu'il attend. Donc, chaque fois que vous voulez afficher l'intégralité du contenu d'un jeu de données, c'est ainsi que vous le feriez. Vous diriez simplement le jeu de données nome.com dot t2 int, et passez cela en paramètre à la commande show pour vous assurer que nous obtenons chaque ligne affichée. Allons-y et exécutons ceci avant de passer à autre chose et de voir comment cela fonctionne. Donc, cliquez avec le bouton droit, exécutez WordCount, un ensemble de données Il s'en va. Et voilà nos résultats. Alors faisons défiler vers le haut. Et vous pouvez voir que ça a fonctionné. On dirait que j'ai une faute de frappe là-dedans. Utilise trois. Ce sont tous les mots qui ne sont apparus qu'une seule fois dans mon livre entier. Et en faisant défiler vers le bas, nous verrons de plus en plus de mots communs au fur et à mesure que nous allons. Donc, il y a la fin de tout ça. Oui. Donc, le mot vous est en fait le mot le plus courant suivi par le mot, résultats
assez peu surprenants et les mêmes résultats que nous avons obtenus avec RDD aussi. Maintenant, laissez-moi vous montrer une autre façon de le faire parce que, comme je l'ai dit, le processus de chargement de ces données dans un jeu de données était un peu maladroit. Peut-être qu'un RDD est mieux adapté pour piller ces données brutes. Donc, comme je l'ai dit dans les diapositives, nous pouvons mélanger et assortir. Vous pouvez obtenir le meilleur des deux mondes. Donc, dans cette approche alternative ici, nous chargeons les données à l'aide de l'interface RDD. Donc, je vais sortir ces SparkContext de la SparkSession et appeler l'ancienne fonction TextFile sur cela. Donc, cela va juste charger toutes les données de texte de point de livre dans un RDD où chaque ligne est une ligne de texte. Donc maintenant, nous pouvons simplement appeler FlatMap sur le livre RDD et le diviser en utilisant une expression régulière comme nous l'avons fait auparavant. Et c'est sans doute un peu plus simple que la façon dont nous l'avons fait en utilisant un jeu de données. Nous avons dû faire cette chose bizarre alambiquée avec split et exploser un alias et un filtre pour que cela fonctionne en utilisant un jeu de données. Voici donc un exemple où un RDD est en fait plus simple. Mais lorsque vous voulez faire une analyse, les jeux de données sont généralement le meilleur choix, n'est-ce pas ? Parce que vous avez toute la puissance de SQL derrière vous et la meilleure optimisation que, qui offre. Donc, à ce stade, nous pouvons convertir le RDD2 un jeu de données. Et c'est ce qui se passe ici avec deux DS. Et à partir de ce moment,
le code est fondamentalement le même. La seule différence est que nous faisons référence à nom de valeur au lieu de mot, car à ce stade, nous traitons toujours avec le nom de colonne par défaut de valeur ici que nous avons obtenu lorsque nous avons converti le RDD en ds. Et ça marche aussi. Donc nous avons déjà couru ça. Si nous faisons défiler vers le bas, nous pouvons voir cette deuxième exécution où nous avons obtenu les mêmes résultats exacts simplement en utilisant une manière différente, commençant à utiliser un RDD pour charger les données et un jeu de données pour réellement l'analyser. Cela peut donc parfois être une astuce utile, surtout si vous n'avez pas affaire à une source de données structurée. Et vous pouvez voir que nous avons la même réponse là-bas à la fin. C' est donc deux façons de le faire en utilisant des jeux et aussi en utilisant une approche RDD hybride et jeu de données. Donc, avoir ces outils dans votre poche arrière peut parfois être utile.
27. [Activité] revisiter l'exemple de température minimale, avec des Datasets: Donc, en utilisant des jeux de données, c'est en fait assez simple comme vous l'avez vu, mais nous allons rapidement passer en revue quelques exemples supplémentaires ici juste pour revenir en arrière et réimplémenter ces exemples RDD avec des jeux de données par exemple. Revenons donc aux exercices de température minimale et maximale que nous
avons effectués et regardons ceux qui utilisent des jeux de données au lieu de RDD. Pas tout à fait nouveau dans cet exemple. Un cependant, est que nous allons fournir un schéma explicite à SparkSession dot read. Donc, au lieu de l'inférer à partir d'un fichier CSV, nous allons lui dire explicitement quel est le schéma tel qu'il lit dans le DataFrame. Nous allons toujours devoir le convertir en jeu de données avec une classe de cas. Mais c'est une autre façon d'importer des données à partir d'un fichier texte que nous examinerons. Et nous examinerons également l'utilisation de la fonction de colonne de largeur sur un jeu de données pour créer une nouvelle colonne en utilisant notre propre fonction personnalisée. Alors nous allons plonger et voir comment tout cela fonctionne. Jetons donc un coup d'oeil à la version originale RDD de ceci. C' est le script Températures Min ici. Et juste pour rafraîchir votre mémoire, nous avons chargé un fichier CSV de 8800 points contenant des informations météorologiques de l'année 8800. Nous analysons ensuite cela pour extraire les champs que nous voulions
et les convertissons en Fahrenheit au fur et à mesure que nous allions. Et puis nous avons coupé tout ce qui n'était pas une entrée T min pour le type réel d'entrée météo là-bas avec la commande filter. Nous cartographions cela à l'ID de la station et aux tuples de température et nous l'avons réduit par clé pour garder une trace de la température minimale trouvée pour chaque station météorologique unique. Voyons donc comment nous le faisons avec un jeu de données au lieu d'un RDD. Cliquez sur Jeu de données Températures min. Et voici notre nouvelle implémentation ici. Fait intéressant, c'est plus de code, pas moins. Encore une fois, pour des choses simples comme celle-ci qui ne traitent pas vraiment des sortes de problèmes de base de données. Parfois, un RDD peut être plus facile. Mais jetons un coup d'oeil. Nous allons donc commencer par notre déclaration de paquet et nous importons des types SQL spécifiques que nous allons utiliser dans notre script, la fonction SparkSession et SQL. Donc, au lieu de tout importer, c'est généralement une meilleure pratique de simplement importer ce dont vous avez besoin, qui est ce que nous faisons ici. Nous commençons par déclarer une classe de cas de température. Ce sera le format que nous lisons à partir de notre fichier de données réel. Il a le format d'un ID de station basé sur une chaîne, une date, nous pouvons interpréter comme un entier, un type de mesure, qui est une chaîne, et une température, qui va être une valeur à virgule flottante. Nous définissons notre niveau de journal, créons notre session Spark comme nous l'avons fait auparavant. Et maintenant, nous allons faire quelque chose d'un peu nouveau ici. Nous allons déclarer un schéma spécifique pour ces données d'entrée. Donc, au lieu de l'inférer à partir d'un en-tête, parce que nous n'avons pas d'en-tête sur ce fichier CSV. Nous allons lui dire explicitement ce que ces colonnes signifient qu'elles lisent. Maintenant, avant que nous trichions en disant importer l'en-tête et déduire le schéma de l'en-tête, mais nous n'avons pas cela cette fois. Voici donc une autre façon de le faire. Nous sommes donc en train de configurer une valeur de schéma de température qui sera un structType. Et nous allons appeler la fonction add sur ce structType pour ajouter différents champs à cette structure. Donc, nous disons juste ajouter l'ID de la station, qui est un type de chaîne, et il peut être mobile. Date comme un type de mesure de type entier est un type de chaîne, température est un type flottant C. Et tout cela correspond aux noms que nous avons ici dans notre classe de cas également. Et les mêmes types, les mêmes noms. Maintenant que nous avons cela, nous pouvons importer des implicites de
point d'étincelle et lire nos données à partir du fichier CSV. Cette fois, au lieu de dire 3D à partir de l'en-tête, nous allons dire schéma de points avec schéma de température. Donc, cela va nous permettre de construire notre DataFrame correctement à partir de ces données CSV. Et puis comme avant, nous convertissons cela explicitement en un jeu de données avec une structure de compilation codée en dur qui vit dans la classe de cas de température. Encore une fois, vous voyez la différence ici. Nous déduisons encore le schéma à l'exécution, car nous définissons ce schéma comme une structure à l'exécution. Alors qu'en disant point comme température au moment de la compilation, nous savons ce qu'est cet objet de température et Spark peut faire plus d'optimisations, nous
donner des erreurs de compilation au lieu d'erreurs d'exécution. Cela peut sembler être une mesure supplémentaire qui n'est peut-être pas nécessaire, mais nous en retirons un avantage. Donc maintenant, nous allons revenir en arrière et faire les mêmes choses que nous avons auparavant avec RDD mais en utilisant un jeu de données. Donc la première chose que nous allons faire est de filtrer tout ce qui n'est pas une équipe en entrée. Donc, au lieu d'utiliser un filtre sur un RDD, nous utilisons simplement un filtre sur le jeu de données. Et nous utilisons cette syntaxe ici, signe
dollar à nouveau précédant le nom de la colonne. Donc, nous voulons tester la colonne de type de mesure et voir si elle est égale à T min. Et encore une fois, dans ces instructions de filtre, la syntaxe est un peu inhabituelle pour l'égalité. C' est trois signes égaux. Donc, cela va créer un nouveau jeu de données tentes MR1 contient uniquement des lignes d'équipe. Ensuite, nous voulons simplement sélectionner les colonnes dont nous avons besoin. Il y a un tas de choses dont nous n'avons pas besoin comme les dates précises parce que nous cherchons juste le minimum pour toute l'année. On s'en fiche quand c'est arrivé. Donc, nous allons juste faire une sélection avec une liste des colonnes que nous voulons. ID de la station, température virgule. C' est tout ce qu'il faut préserver. Maintenant, nous entrons dans la viande des choses. Nous allons les regrouper et trouver le minimum. conséquent, le groupe par ID de station regroupera toutes les entrées ensemble pour des ID de station uniques. Et il ne devrait en rester que deux dans cet ensemble de données. Et puis une fois que nous aurons ces groupes, nous appellerons Min pour trouver l'entrée minimale dans chaque groupe, regardant la colonne de température et en trouvant la valeur minimale de température pour chaque groupe d'ID de station. ai eu. Maintenant, nous avons un jeu de données Min term Spatial Station qui est juste l'ID de la station et la température minimale. On a presque fini. La dernière chose à faire est de convertir ces températures de deux degrés Fahrenheit. Et nous pouvons aussi bien trier les résultats pendant que nous y sommes. Donc c'est ce qui se passe ici. Nous allons créer un nouveau jeu de données appelé Tentatives Min par la station F parce que nous convertissons ceci en Fahrenheit. Et ce sera prendre nos temps Min par données de
station et appliquer cette fonction de colonne de largeur sur elle. Donc, cela va créer une nouvelle température de nom de colonne. C' est en fait différent de celui avec lequel nous avons commencé ici. Donc, avec la colonne peut soit remplacer une colonne existante ou en créer une nouvelle. Dans ce cas, nous sommes en train d'en créer une nouvelle parce qu'avec de nombreuses tentatives par station, tout ce que nous obtenons de cette commande BY groupe est l'ID de la station et une nouvelle colonne qui s'appelle Min à température avec température entre parenthèses. Donc, notre colonne de température que nous avions à l'origine, elle est en fait partie à l'état et nous allons la recréer maintenant nous allons
faire une nouvelle colonne de température ici avec la commande de la colonne de largeur. Donc avec la colonne, nous allons appeler notre nouvelle température de colonne. Et il sera construit en utilisant cette fonction. Donc, nous avons vu avec colonne avant quand nous avons parlé des fonctions
définies par l'utilisateur, même concept ici. Nous n'utilisons pas une fonction réelle que nous avons définie. Nous passons une expression ici explicitement. Alors commençons par le milieu. Nous commençons par la colonne de température min, et c'est ce que cette colonne a été
nommée automatiquement lorsque nous l'avons créée avec la commande group BY. conséquent, grouper par regroupement sur la température Min créera une colonne Température Min. Et si vous deviez faire un show sur ce jeu de données pendant que vous déboguez des choses, vous auriez vu ce nom de colonne. Alternativement, nous aurions pu appeler alias dessus pour lui donner un nom plus explicite auquel nous pourrions faire référence plus tard, mais nous ne l'avons pas fait. Donc, nous allons juste utiliser ce nom par défaut ici. Donc on va prendre ça, le multiplier par 0,1. Cela va convertir le format de données brutes en degrés Celsius réels. Et puis nous allons convertir ça en Fahrenheit en multipliant par neuf cinquièmes et en ajoutant 32. En outre, cela va vivre à l'intérieur de la fonction ronde ici. Paramètre de deux, ce qui signifie que nous voulons arrondir cela à deux décimales de précision. Ok, donc ça va créer une nouvelle colonne de température, avec notre température convertie en Fahrenheit arrondie à deux décimales. De plus, nous sélectionnerons les données dont nous avons besoin, donc nous n'avons plus besoin de cette colonne de température min. Nous voulons juste la colonne finale convertie Fahrenheit à la place. Nous allons donc sélectionner l'ID de la station et les colonnes de température parce que c'est tout ce que nous voulons afficher à la fin. Et enfin, nous allons le trier par température afin que nous
obtenions ces résultats triés par température, la température minimale qui a été observée à chacun. Enfin, nous recueillerons ces résultats comme vous l'auriez fait avec un RDD. Et à ce stade, toutes nos données sont de retour dans notre script de pilotes et nous vivons à nouveau dans le monde de Scala. Donc, nous passons juste par le code Scala ici, itérons tous les résultats de notre jeu de résultats. Extraire le premier, deuxième éléments du tuple, appelez-le station en temp. Et nous allons en outre explicitement lancer la température comme une valeur à virgule flottante. Nous pouvons ensuite formater cela en utilisant l'opérateur d'impression F ici. Et enfin imprimer en ligne les résultats réels en utilisant l'opérateur de substitution, comme nous avons parlé de retour dans notre cours de crash Scala. Alors exécutons-le et nous convainquons que ça marche. Cliquez avec le bouton droit de la souris, exécutez le jeu de données Températures min et désactivez Et ça a marché. Super. Nous avons donc nos deux stations météorologiques là-bas avec leurs températures minimales à Fahrenheit arrondies à deux décimales de précision. Wu ça a marché. Très bien, donc oui, si vous voulez un petit défi supplémentaire,
vous pouvez aller de l'avant et essayer de modifier cela pour faire des températures maximales et fixer températures minimales juste pour mettre la main sur un peu plus devrait être trivial. Donc, je ne suis même pas parti pour vous fournir une solution pour ça. Mais si vous voulez jouer avec cela un peu plus, je l'encourage certainement.
28. [Exercice ! faites une pratique « Total dépensé par Customer" » avec des Datasets: Nous allons donc terminer cette section en introduisant des jeux avec un autre exercice et d'autres défis pratiques. Ce que nous allons faire est de revenir à l'exercice de la section précédente, où nous avons calculé le total dépensé par le client dans notre faux jeu de données e-commerce. Et nous allons revoir cela en utilisant des jeux de données au lieu de RDD, probablement vu celui qui rentre à la maison. Donc, pour résumer, ce que nous allons faire est d'additionner le montant dépensé par le client dans notre jeu de données ici, les données brutes entrant, c'est au format CSV. Et il contient trois colonnes, un ID utilisateur et un ID d'article et un prix payé pour cet article. Ce que je veux faire est d'additionner tout le montant total payé par ID utilisateur. Donc, dans cet exemple simple encore une fois, l'ID utilisateur 44 a dépensé un total de 77,83$. Userid 35 passé 7897, et ainsi de suite et ainsi de suite. Donc, notre stratégie va être quelque peu semblable à celle que nous avons faite avec les DRD. C' est juste que la technique sera un peu différente. Donc, nous allons charger le fichier CSV point de commande client de données comme un dataframe avec huit schéma explicite sera le moyen le plus simple de le faire. Et vous pouvez choisir de le convertir explicitement en jeu de données si vous le souhaitez. Évidemment, cela conduira parfois à de meilleures performances, mais vous n'avez pas à le faire. Après cela, nous allons regrouper ce jeu de données par ID client. Vous le résumez par le montant dépensé par ID client. Et si vous voulez des points bonus, pas que quelqu'un garde vraiment le score. Vous pouvez arrondir cela à deux décimales pendant que vous y êtes, triés par le montant total dépensé. Ainsi, nous pouvons voir nos meilleurs dépenseurs et nos clients les moins chers
ainsi, puis montrer les résultats. Et quelques extraits utiles si vous voulez plus d'astuces ici, examinant les exemples précédents dans cette section, nous serons certainement utiles. Et il y a une fonction SQL appelée somme que vous pouvez utiliser pour ajouter des choses après les avoir regroupés. Et en particulier la syntaxe pour un arrondi qui, après la somme, ressemblera à AG, arrondi, quel que soit le nom de la colonne en tant que tel, vous additionnez une virgule ronde à deux décimales. C' est si petit, petit tricheur là-bas. Et oui, cette solution est dans les matériaux de cours. S' il vous plaît résister à la tentation de jeter un coup d'œil et regarder vers l'avenir Essayez cela vous-même et voyez si vous pouvez l'arranger. C' est une bonne pratique. Et je reviendrai et je passerai à travers ma solution dans la prochaine conférence.
29. Solution d'exercice : Total dépensé par client avec des Datasets: J' espère que vous avez réussi à faire cet exercice et à recréer montant total dépensé par l'activité client à l'aide de jeux de données. Jetons un coup d'oeil à ma solution et vous pouvez comparer mon approche à la vôtre. Ouvrez ici le total dépensé par les clients script de jeu de données triés. Et encore une fois, vous connaissez votre, votre code n'a pas à être exactement comme le mien. Ce qui compte, c'est le résultat final vraiment là, il y a plusieurs façons de le faire. Donc, nous commençons à importer les choses dont nous avons besoin et nous créons un objet appelé total dépensé par les clients ensemble de
données triées et commençons par une classe de cas définissant le schéma dans lequel notre jeu de données sera forcé. Donc, nous disons explicitement au moment de la compilation que notre jeu de données commandes client va contenir un ID client entier et un ID d'élément entier et un montant à double précision dépensé. Ensuite, allez dans ma fonction principale ici et nous mettons en place notre session Spark comme nous le faisons toujours. Et nous allons créer un schéma à utiliser avec la lecture dans le fichier CSV en tant que DataFrame initialement. Nous allons donc créer un schéma de commande client, qui est, vous savez, ressemble beaucoup à un code précédent que nous avons examiné. Donc, j'espère que vous avez été en mesure de soulever cela, va créer un nouveau structType et ajouter dans un ID client de type entier ID d'élément de montant entier dépensé de type double. Et puis nous avons effectivement lu cela devant
le fichier CSV ici en utilisant le schéma que nous avons fourni. Et nous allons forcer cela dans un jeu de données utilisant la classe de cas de commandes client comme nous l'avons fait auparavant. Maintenant, nous entrons dans la viande de l'exercice. Ici, nous créons un nouveau total par jeu de données client qui fait à peu près tout. Nous commençons par regrouper par le champ ID client. Et rappelez-vous que nous définissons ce nom ici dans notre classe de cas, ce nom doit correspondre à celui d'ici. Par conséquent, en regroupant par ID client, nous regroupons tous les différents achats pour chaque client ensemble. Et puis cette ligne suivante est ce qui résume tout cela. Alors commençons par le milieu et travaillons notre sortie. Nous commençons par additionner le montant de soulignement dépensé colonne. Donc, pour chaque ID client unique, nous allons résumer tous les montants Spence associés à cet ID client. Et c'est encore enveloppé par une fonction
ronde pour arrondir cela à deux décimales de précision. Nous allons utiliser dot egg pour agréger ce résultat en une seule colonne dans le résultat final. Et nous allons donner ce nouveau nom de colonne en disant alias point, soulignement
total dépensé pour le rendre plus facile à consulter. Parce qu'on doit lui donner un nom pour pouvoir le trier, non ? Donc, je me rends compte que cette fonction agg peut être un peu déroutante. Fondamentalement, ce qu'il fait est de dire que nous allons agréger ces fonctions ensemble en une seule colonne, ok ? Et nous allons également donner à cette colonne un nom en utilisant également un alias de point. Donc, à ce stade, la structure de notre jeu de données sera
une colonne d' ID client et une colonne de soulignement totale dépensée. Maintenant, nous pouvons le trier en disant juste point tri avec le nom de colonne de soulignement total dépensé que nous avons spécifié dans la ligne précédente et montrer à nouveau les résultats, raisons petit truc pour obtenir le total général de
combien de lignes sont dans le total par jeu de données client, en le convertissant en entier et en le transmettant en paramètre à la fonction show pour assurer que nous montrons explicitement l'ensemble de données et pas seulement les 20 premières lignes. Alors allons de l'avant et commençons ça. Et nous avons là. On dirait que ça a marché. Il semble que les résultats soient triés par montant dépensé. Donc notre plus gros dépenseur était UserID 68, dépensant 6 375,45$. Très cool. D'accord. J' espère que ça vous a plu et que vous auriez pu aller encore plus loin. Je veux dire, j'aurais pu aller plus loin en forçant cela à être un exemple de point 24, j'utilise un format d'impression f pour parcourir chaque ligne individuelle qui a été retournée et formater la sortie plus à mon goût. Mais oui, si tu as fait ça, des points bonus pour toi. Mais j'espère que tu as traversé ça. Donc, nous avons une introduction CAO aux jeux de données et leur fonctionnement à un niveau assez élevé, il y a plus à explorer, je devrais ajouter. Il y a bien plus à Apache Spark que je ne peux couvrir dans ce cours. Donc, si jamais vous voulez vous référer à la documentation pour l'ensemble complet de référence sur ce que vous pouvez faire. Vous pouvez aller à spark dot apache.org slash docs slash latest pour obtenir la dernière documentation. Si vous souhaitez explorer tout ce que vous pouvez faire avec le jeu de données, par exemple, vous pouvez simplement accéder à l'organisation. Apache Spark. jeu de données Sql va être le chemin d'accès pour ce nom de classe. Et il vous dira tout à ce sujet dans tous les détails complexes. Si vous faites défiler vers le bas, vous verrez quelques exemples qui sont encore plus utiles. Et vous pouvez voir une liste de toutes les méthodes disponibles sur le jeu de données. La plupart d'entre eux sembleront familiers. On a couvert beaucoup d'entre eux. Par exemple, collectez et comptez pour chaque application d'une fonction à chaque ligne. Head est un moyen d'obtenir les n premières lignes du jeu de données montrent que nous l'avons beaucoup utilisé, non ? Take peut également être utilisé pour prendre un certain nombre de lignes du jeu de données. Il y a d'autres choses à explorer ici aussi. Vous pouvez en fait expliquer, pour expliquer la façon réelle dont il va être exécuté,
ce qui est un peu intéressant à des fins de débogage. Il y a des façons de le maintenir sur un disque. Il y a un moyen de le convertir en RDD. On a regardé ça un peu. On peut imprimer le schéma. On l'a déjà fait avant. Nous pouvons réellement le convertir en DataFrame aussi bien si nous le voulons, ainsi qu'une bonne fonction pour le stocker sur le disque. Et on parlera de streaming plus tard, on y reviendra plus tard. Et il y a d'autres choses ici comme diverses opérations comme distinctes pour obtenir juste des valeurs distinctes dans le jeu de données. Nous avons regardé le filtre avant, nous avons parlé de FlatMap. Vous pouvez l'appliquer à un jeu de données ainsi qu' un RDD GroupByKey dont nous avons parlé des intersections de jointure. Vous pouvez faire des opérations booléennes là pour mapper. Vous pouvez le faire sur un jeu de données comme vous le pouvez sur un RDD, bien que cela soit un peu plus lourd avec un jeu de données. Et oui, allez-y et pêchez si jamais vous voulez obtenir un exemple plus complet de ce que vous pouvez faire et de ce qui est disponible. Et si vous avez des questions sur la syntaxe et les paramètres pris en charge sur ces fonctions de jeu de données. C' est l'endroit où se tourner vers vous pour le savoir. Comme vous pouvez le voir, il y a une longue liste de ce que vous pouvez faire le jeu de données. Nous avons abordé certaines des choses les plus courantes que vous pouvez faire. Mais comme vous pouvez le voir, il y a un bon menu ici. Nous continuerons donc d'utiliser des jeux de données tout au long de ce cours. Notez également que dans votre matériel de cours pour chaque exercice, il y a à la fois une version RDD et une version de jeu de données. Donc, si jamais tu veux comparer les deux, ils sont tous là. On ne va pas passer par toutes les versions de chaque script. Comme je l'ai dit, on va se concentrer sur les jeux de données à partir d'ici. Mais si jamais vous êtes curieux, vous pouvez regarder les deux versions. Et il y en a que nous n'avons pas abordé aussi. Par exemple, notre exemple de compteur de notation initiale RDD. C' est aussi une version de jeu de données de cela dedans si vous voulez jouer avec lui aussi. Donc, tout est là pour votre référence et votre joie. Et passons à quelques exemples plus compliqués dans notre prochaine section.
30. [Activité Trouvez le film le plus populaire: Donc, jusqu'à ce stade du cours, nous vous avons présenté Spark et nous avons utilisé quelques exemples assez simples. Mais je veux que tu saches que Spark a beaucoup de pouvoir au-delà. Donc, si vous avez même un problème plus compliqué, parfois si vous pensez de manière créative,
déclenchez des problèmes non résolus que vous n'auriez pas pensé qu'il pourrait résoudre. Et nous allons plonger dans quelques exemples comme ça dans la section suivante en utilisant exemples assez amusants utilisant des données de film et des données de super-héros. Alors nous allons plonger et voir ce que vous pouvez faire avec Spark que vous
n'auriez peut-être pas pensé que vous pourriez faire si vous
pensez juste un peu de créativité à vos problèmes. Ok, Donc je sais que le nom de cette section est des exemples plus avancés d'Apache Spark, mais nous devons commencer par quelque chose de simple et travailler notre chemin vers le haut. Donc, pour jeter les bases de ce prochain exemple, nous allons faire quelque chose de facile. Nous allons trouver le film le plus populaire dans le jeu de données MovieLens. Et pour résumer, fait, Nous avons parlé de MovieLens déjà. Nous avons fait brièvement retour avec le, le contre-exemple de cotes. Nous allons donc ingérer le jeu de données MovieLens 100 K ici. Et pour résumer le format, il contient ces quatre colonnes. Ils correspondent à un ID utilisateur, ID
vidéo, une évaluation et un horodatage. Et pour trouver le film le plus populaire, il
suffit de trouver les identifiants de films qui ont le plus de notes, non ? Donc, si nous supposons que quelqu'un qui a évalué le film l'a regardé, et que nous définissons populaire comme le film le plus regardé plutôt qu'en trouvant simplement l'identifiant de film qui apparaît le plus souvent. Dans ce jeu de données, nous trouverons le film le plus populaire de cette façon. Alors passons au code et voyons comment nous pouvons le faire en utilisant des jeux de données. Assez simple, mais encore une fois, nous allons nous appuyer sur cela pour faire quelque chose d'un peu plus compliqué lors de la prochaine conférence. Nous allons donc explorer le script populaire du jeu de données des films dans vos matériaux de cours. Et on va traverser ça. Ce n'est pas trop chic ici, mais encore une fois, nous allons nous appuyer sur cela pour faire quelque chose d'un peu plus profond et plus complexe dans les conférences suivantes. Donc, nous commençons important lui-même. Nous avons besoin, comme d'habitude, nous allons appeler cela notre objet, jeu de données de films populaires. Nous sommes inutiles classe de cas appelée film. L' aperçu ici est que tout ce que nous faisons est de compter le nombre fois que chaque ID de film apparaît dans notre jeu de données. Et pour ce faire, tout ce dont nous avons besoin, c'est la colonne d'identification du film, non ? On se fiche des notes. On s'en fiche quand ils ont été évalués. On se fiche de qui l'a évalué. Tout ce qui nous intéresse, c'est que cet identifiant de film apparaît sur chaque ligne individuelle. C' est donc les seules données que nous devons extraire, ce qui rend les choses un peu plus simples. Plonger dans notre fonction principale ici, nous définissons notre niveau de log, plus grande SparkSession, rien de spécial là-bas. Nous créons notre schéma de films pour charger le DataFrame initial à partir du fichier CSV. Bien que ce soit en fait un fichier de données de valeur séparé par des tabulations ici. Mais c'est bon. Nous pouvons toujours utiliser le chargeur CSV avant comme nous le verrons. Et nous allons lui dire que la structure de ces données est l'ID utilisateur, l'ID vidéo, l'évaluation et l'horodatage avec trois entiers et un long pour représenter ces données. Importera les implicites déclenchés pour charger ce CSV en utilisant ce schéma implicite. Et nous allons charger, notez l'option jeu de barre oblique inverse t. C'est dire
que le chargeur CSV qui sont un séparateur n'est en fait pas une virgule,
mais un caractère de tabulation, qui est ce que ces données sont réellement formatées comme nous passons dans le chemin d'accès au fichier de données, c'est-à-dire le fichier de données qui contient les informations d'évaluation réelles. Ensuite, nous le forcerons dans un jeu de données vidéo. Et en faisant cela, nous le jetons cette seule première colonne qui se compose uniquement de l'ID du film et rien d'autre. Tellement petit truc intéressant là-bas. Votre jeu de données n'a pas besoin d'inclure toutes les colonnes, donc le DataFrame à partir duquel vous le créez. Et maintenant, la viande se produit dans cette seule ligne. Et c'est très SQL comme et comment il aborde le problème. Nous commençons donc par regrouper par ID de film. Nous avons donc regroupé toutes les évaluations pour chaque ID de film. Nous les comptons ensuite tous. Et puis commander par est fondamentalement comment vous faites un tri en SQL afin qu'il fasse la même chose. Nous disons essentiellement l'ordre BY la colonne count, qui va être créé par cette fonction là. Et dans l'ordre décroissant de sorte que nous obtenons nos films
les plus populaires en haut de la liste et notre moins populaire en bas de la liste. Après cela, nous allons montrer les dix premiers résultats et cela devrait nous donner nos 10 films les plus populaires. Alors commençons ça et voyons ce que nous obtenons. Ok, on a nos résultats et on dirait que ça a marché. Donc apparemment, le film le plus populaire est l'ID 550, avec 583 notes distinctes associées à ce film. Mais ce n'est pas très utile, n'est-ce pas ? Comment savoir ce qu'est le film ID 50 ? Donc, une étape suivante évidente pour étendre ce script serait d'importer réellement le nom du film associé à chaque ID de film afin que nous puissions réellement avoir un aperçu de ce que sont ces films. Je veux dire, nous pourrions le faire de la manière difficile que ces données vivent dans le fichier d'élément de notre jeu de données. Donc, si nous ouvrons cela pour explorer ce qu'il y a dedans, vous pouvez voir que cela contient toutes sortes d'informations supplémentaires sur chaque ID de film. Ainsi, par exemple, l'ID de film 1 est le film Toy Story et il vous indique que l'année a été publiée, liée aux données de la BDIM. Et ceux-ci et zéros correspondent en fait aux genres dans lesquels se trouve le film. Et si vous passez à l'ID 50, nous verrons que notre gagnant est en fait Star Wars, l'original de 1977. Pas trop surprenant. Mais oui, on ne sait pas. On ne veut pas avoir à les regarder à la main, non. Revenons donc et parlons de la façon de le rejoindre avec nos données de noms de films. Et comment le faire de manière optimale afin que nous puissions réellement distribuer ces données à chaque nœud de notre cluster.
31. [Activité Utilisez des variables diffusées pour afficher des noms de film pour afficher des noms de film: Nous devons donc rendre ces résultats lisibles par l'homme. Ces cartes d'identité ne nous sont pas vraiment utiles en tant qu' êtres
humains parce que nous ne savons pas ce que dit le film représente. Donc il n'y a pas d'intuition à gagner. Alors prenons soin de ce problème maintenant. Nous voulons donc afficher les noms des films et pas seulement les identifiants. Et pour ce faire, nous devons fusionner les informations de ce fichier d'élément
u point à partir du jeu de données MovieLens. Maintenant, il y a plusieurs façons de le faire. Le plus simple serait de simplement configurer un autre jeu de données qui mappe les ID aux noms après l'analyse dans ce fichier d'élément point u. Ensuite, nous pouvons simplement rejoindre ce jeu de données avec notre jeu de données d'évaluation par les ID de film et rejoindre ces noms de film de cette façon. Ce serait la façon la plus simple de le faire. Et du point de vue SQL, c'est ainsi
que vous aborderiez ce problème également. Mais ce n'est pas la seule façon de le faire. Tu ne peux pas faire ça. En fait, je vous encourage à essayer cela si vous voulez un peu d'exercice pratique avec lequel vous vous entraînez. Mais on va le faire d'une manière différente. Parce que faire une jointure comme distribuer un jeu de données dans le cluster, c'est une opération assez lourde. Et ce n'est pas totalement nécessaire pour ces données, n'est-ce pas ? Parce qu'il n'y a pas autant de films dans le monde. La table des ID de film aux noms de film n'est pas si grande. Nous pouvons adapter tout cela en mémoire assez facilement sur un seul ordinateur, donc nous n'avons pas vraiment besoin de le distribuer dans un jeu de données. Donc, nous pourrions simplement garder une table chargée dans le programme de pilote et l'utiliser pour mapper les ID aussi. Les noms de films comme nous les imprimons. Ça ira bien. Mais il y a une autre façon de faire deux. Ainsi, nous pourrions également laisser Spark automatiquement pour cela à chaque exécuteur si nécessaire. Imaginez, si vous voulez, que nous devions avoir ces noms de films dans le script pilote lui-même et pas seulement pour la phase finale de sortie. Nous pouvons en fait, il y a un moyen d'utiliser ce que nous appelons variables de
diffusion pour transférer un objet qui peut inclure une carte, qui pourrait être mappage d'ID de film pour déplacer les noms, par exemple, et le fording automatique à chaque exécuteur dans notre grappe doit être utilisée au besoin. Et vous savez, si la table est massive, cela pourrait être une chose importante d'utiliser ces variables de diffusion parce que cela
garantira que nous ne transférons qu'elle veut à chaque exécuteur et la garderons là. Contrastez cela à un jeu de données où il peut être jeté partout. C' est un peu plus une opération complexe. Donc, en utilisant une variable de diffusion, nous pouvons nous assurer que cette table, cette carte d'informations, qui mappe les ID aux noms est seulement envoyé à travers veut à chaque exécuteur, et qu'elle reste là jusqu'à ce que nous nous en débarrassons explicitement. Donc, avec les variables de diffusion, nous pouvons diffuser n'importe quel objet à tous
les exécuteurs de sorte qu'ils soient toujours là quand nécessaire. Nous devons juste appeler broadcast sur l'objet de contexte Spark dans notre script de pilote pour expédier ces données à partir ce que vous vouliez expédier à chaque nœud exécuteur. Nous devons juste nous assurer que cela correspondra à leur mémoire de évidemment. Et puis après que cela a été diffusé, nous pouvons utiliser la valeur point sur cette variable de diffusion pour la récupérer et récupérer cet objet et y faire référence dans le script qui est distribué dans tout le cluster. Et nous pouvons utiliser ces objets diffusés comme vous le souhaitez. Vous pouvez les utiliser dans les fonctions cartographiques dans les RDD ou dans notre cas, nous voulons les appliquer à des jeux de données, ce qui signifie que nous allons configurer une fonction définie par l'utilisateur afin que
nous puissions l'utiliser de manière plus SQL ESC. Donc, avec cela, nous allons plonger vers le code et voir comment fonctionnent les variables de diffusion. Alors, ouvrons les films populaires
plus joli script de jeu de données ici et voyons à quoi cela ressemble. Donc, encore une fois, la façon la plus simple de gérer ce problème serait de charger un jeu
de données d' ID de film sur des noms de film et de le joindre dans une sorte d'opération SQL. Mais nous allons le faire d'une manière un peu différente parce nous savons que c'est un jeu de données relativement petit et nous pouvons nous en sortir avec juste l'expédition à chaque exécuteur individuel au
démarrage de notre script et il suffit de s'y référer localement dans chaque nœud de l'exécuteur. Donc c'est juste une autre façon de le faire. Parfois, les variables de diffusion peuvent être utiles de cette façon, vous ne les voyez pas vraiment utilisées que souvent dans la pratique pour être honnête, mais c'est un outil dans votre coffre à outils que je pense que vous devriez connaître. Et cela nous donne également l'occasion d'illustrer l'utilisation de fonctions définies par l'utilisateur dans un jeu de données, ce qui est aussi quelque chose de bon à savoir. Donc, même si c'est un exemple un peu artificiel, il illustre quelques points importants. Alors plongons dans le code ici. Nous importons tout ce dont nous avons besoin. Et nous allons mettre en place une classe
de cas complète à partir du type de données de films ici qui inclut l'ID utilisateur, l' évaluation de l'ID de
film et l'horodatage qui va importer à partir du fichier de données de point u. Nous allons ensuite créer une fonction de noms de film de chargement. Et le but de cette fonction est simplement de créer une carte Scala qui mappe les ID de film aux noms de film. Donc, c'est juste du code Scala. Ce n'est pas du code Spark. Tout ce qu'il fait est de charger ce dossier d'élément u point en utilisant le codage de caractères correct, en passant, ce qui est un peu obscure. Et nous retournons une carte d'entiers aux chaînes qui mappent les ID de film aux noms de film. Nous chargeons simplement le fichier directement à partir du disque, parcourons chaque ligne de ce fichier, le
divisons en fonction du caractère de tuyau qui le délimite. Et nous faisons un petit contrôle de santé mentale pour nous assurer que c'est une ligne valide. Et si c'est le cas, nous ajoutons à nos noms de films une carte et une entrée qui mappe ce premier champ, qui est l'ID du film au second champ, qui est le nom du film. Fermez le fichier lorsque nous avons terminé et retournez le mappage des noms de film résultant. Donc, encore une fois, ce n'est pas du code Spark, c'est juste du code Scala, en lisant ces données du disque local où que nous soyons, nous exécutons notre script de pilote à partir de. Alors entrons dans le script lui-même. Comme d'habitude, nous commençons par notre niveau de journal et mettons en place un objet SparkSession. Et maintenant, nous allons appeler cette
fonction de chargement des noms de film pour charger cette carte d'ID de film aux noms de film. Et nous allons appeler broadcast depuis notre interface contextuelle Spark. Et nous allons appeler cette variable de diffusion résultante nommée abrégée pour le dictionnaire de noms, ça a du sens, non ? Donc, à ce stade, cette carte a été chargée et elle a été envoyée à tous les exécuteurs qui vont exécuter notre application Spark ici. Il sera donc disponible pour chaque exécuteur local pour effectuer des recherches rapides d'ID de film vers les noms de film. Bon, maintenant nous entrons dans le code Spark lui-même. Nous allons charger les données de nos films avec le schéma suivant. Nous allons donc charger le fichier de données spécifiant le séparateur d'onglets. Encore une fois, c'est le même code exact de l'exemple précédent et en utilisant le schéma que nous fournissons. Et puis nous le forcerons à la classe de cas des films pour obtenir le contenu complet des données de ce film défini ainsi. D' accord, en continuant, nous obtiendrons le nombre de critiques par,
par ID de film, comme nous l'avons fait auparavant avec les simples déclarations de groupe BY. Nous allons donc regrouper par la colonne d'ID de film et compter chaque ID de film individuel le nombre de fois qu'il se produit. Donc, à ce stade, nous avons ce que nous avions avant. Nous avons un jeu de données de comptes de
films qui contient l'ID et le nombre de films pour chaque ID de film individuel. Bon, donc maintenant nous avons besoin d'un moyen de
transformer ces identifiants de films en noms de films dans notre jeu de données. Encore une fois, c'est un exemple artificiel. Vous auriez pu le faire tout aussi facilement au stade de la sortie, n'est-ce pas ? Et nous aurions pu juste parcourir le jeu de données résultant que nous avons récupéré et
rechercher ces noms de films sur le script de pilote localement lorsque nous imprimons réellement les résultats. Mais nous essayons juste d'illustrer l'utilisation des UDF ici et des variables de diffusion. Donc, nous allons réellement faire cela distribué dans le cluster lui-même. Donc, pour chaque exécuteur qui gère un sous-ensemble des films, un sous-ensemble d'ID de film pour ce problème, ils examineront individuellement les titres des films pour les ID de film. Ils sont responsables d'un peu plus évolutif, non ? Pour ce faire, nous devons d'abord configurer une fonction définie par l'utilisateur afin que nous puissions réellement mettre en place une commande de
jeu de données pour créer une nouvelle colonne en utilisant cette fonction pour générer les données de cette colonne. Maintenant, la syntaxe pour cela est un peu bizarre, donc nous n'avons pas vraiment vu cela avant. Nous déclarons ce qu'on appelle une fonction anonyme ici. Et dans Scala, la syntaxe pour cela ressemble à ceci. Donc, nous définissons fondamentalement une fonction en ligne ici. On va l'appeler nom de recherche. C' est le nom de notre fonction. Nous disons qu'il prendra un entier et retournera une chaîne. Et nous allons mettre ça égal à cette fonction anonyme suivante. Donc, il prend un entier nommé ID film et passe dans ce bloc de code, qui retourne juste la recherche du dictionnaire de nom donné cet ID de film, notez la valeur point, donc nommé à nouveau comme une variable de diffusion. Ce n'est pas la vraie carte. Pour récupérer l'objet de la carte, nous devons appeler la valeur de
point voulu récupérer le nom de l'objet de Dick. Donc encore une fois, dict nommé est la variable broadcast. Pour obtenir son contenu, nous devons appeler de la valeur dessus. Donc, à ce stade, nous avons une carte Scala réelle à utiliser. Ensuite, nous pouvons simplement lui passer un ID de film pour
rechercher quel est le nom du film associé à cet ID de film. Ensuite, nous devons envelopper cette fonction avec une UDF. Donc, vous pouvez noter en haut ici que nous avons importé explicitement. Ici, il est, ou point Apache point Spark point SQL point functions.php UDF. Et cela nous permet de réellement envelopper cette fonction comme une fonction définie par l'utilisateur que nous pouvons ensuite utiliser dans un paramètre SQL. Donc maintenant que nous avons le nom de recherche UDF, nous pouvons l'utiliser. Et c'est là que la magie se produit. Donc on va dire des films avec des noms. Ce sera notre nouveau jeu de données qui a une colonne supplémentaire appelée titre du film. Et pour ajouter cette colonne, nous dirons simplement que le film compte la colonne de largeur des points. Pour ajouter cette nouvelle colonne à ce jeu de données, nous appellerons ce nouveau titre de film de colonne. Et le contenu de cette colonne sera généré en utilisant le nom de recherche UDF, cette fonction définie par l'utilisateur que nous venons de définir. Et les paramètres pour cela proviendront de la colonne id du film. Donc, la syntaxe ici est d'utiliser la fonction d'appel qui provient des fonctions SQL dot pour réellement transmettre le contenu d'un nom de colonne donné, dans ce cas l'ID de film. Et parce que nous enveloppons cela avec une FDU, il acceptera cette colonne et
la transformera en entier que la fonction sous-jacente réelle attend pour vous. C' est là que tout se passe. Ainsi, d'une manière répartie sur l'ensemble du cluster, il va utiliser notre fonction définie par l'utilisateur en utilisant notre carte diffusée pour rechercher ID de
film vers les noms de film et générer un nouveau jeu de données appelé films avec des noms. À ce stade, nous pouvons ensuite le trier à nouveau sur l'ensemble du cluster en fonction du champ de comptage. Et à ce moment-là, nous pouvons juste récupérer les résultats et les montrer. Dans ce cas, nous allons juste montrer le tout parce que nous pourrions vouloir creuser dans tous les détails. Et donc nous allons simplement passer en paramètre, la liste entière, le nombre D2 et pour obtenir chaque ligne de ce jeu de données. Et en outre, nous dirons tronquer est égal à faux pour
l'empêcher de tronquer réellement la longueur de chaque ligne individuelle. Sinon, il découperait certains de ces noms de films pour s'adapter à une largeur de ligne donnée. Alors commençons ça et voyons ce qui se passe. Et nous l'avons là. Donc nous n'avons pas fait un genre descendant dans ce cas,
nous avons juste des terminaisons. Donc, le plus commun, les films les plus populaires seront à la fin dans ce cas. Et on a eu le même résultat. Star Wars est, sont enseignés film, suivi par contact, suivi par Fargo, suivi par Retour des Jedi. Vous pouvez dire qu'il s'agit définitivement d'un jeu de données daté. Il y a des plus récents que vous pouvez obtenir de MovieLens si vous voulez expérimenter avec eux. Donc gardez juste à l'esprit que ce sont de vieilles données, alors ne soyez pas surpris que près de blockbusters préférés et apparaissant ici. Mais oui, ça marche. Encore une fois, un exemple un peu artificiel, mais le but était de vous apprendre sur les variables de diffusion et les fonctions définies par l'utilisateur. Encore une fois, vous pouvez souvent accomplir ce que nous devons faire avec une variable de diffusion en utilisant un jeu de données à la place. Mais parfois, une variable de diffusion sera plus efficace. Donc c'est un autre outil dans votre coffre à outils et maintenant vous l'avez. Allons passer à autre chose.
32. [Activité : Trouvez le Superhéros le plus populaire dans un graphique social.: Bon, donc dans nos prochaines conférences, nous allons regarder un jeu de données assez amusant. Il est en fait basé sur l'univers de la bande dessinée Marvel est un Marvell ou Marvell et tout le monde savait comment prononcer ça. Mais de toute façon, on parle de super-héros comme Spiderman et Thor et de tout le monde là-bas. Et il s'avère que vous pouvez réellement penser au monde des super-héros comme un peu un réseau social. L' ensemble de données avec lequel on va travailler est un peu intéressant. Il modélise les superhéros comme un réseau de super-héros en regardant avec
quels autres super-héros chaque héros est apparu dans une seule bande dessinée. Donc, si Spiderman apparaissait dans la même bande dessinée que Thor, alors on dirait qu'il y a un lien entre Spider-Man et minutieux, par exemple. Et il s'avère qu'il y a beaucoup de ces cooccurrences de héros dans la même bande dessinée. Et cela conduit à cette structure de réseau vraiment intéressante entre tous ces héros de l'univers Marvel. Donc, nous avons en fait un jeu de données public assez cool là-bas. Et il contient les deux fichiers qui nous intéressent. L' un est appelé Marvell texte de point de graphique pointillé. Et ce que nous avons fait, c'est que nous avons attribué une pièce d'identité à chaque personnage qui apparaît dans ces bandes dessinées. Donc, le premier numéro qui apparaît dans chaque ligne est le personnage dont nous parlons, suivi d'une liste de tous les identifiants de personnage avec lesquels
ce personnage est apparu dans d'autres bandes dessinées. Donc, je ne sais pas quel est l'ID de personnage pour 395, mais faisons juste semblant que c'est Spider-Man. Donc, cela signifierait que Spider-Man est apparu avec les personnages 22, 37, 17, 6, 7, 4, 7, 2, et ainsi de suite et ainsi de suite. Ensuite, nous pouvons rechercher quels noms sont associés à des identifiants de caractères individuels. On les appellera des cartes de héros si vous le souhaitez. Dans les noms de tiret Marvel dot txt fichier, c'est très simple. C' est juste un identifiant suivi d'un guillemet,
qui correspond à cet identifiant de héros. Maintenant, une chose qui peut vous monter ici est qu'un héros peut s'étendre sur plusieurs lignes dans le fichier Txt de points graphiques en pointillés Marvel. Donc, certains super-héros apparaissent si souvent qu'ils ont tellement de co-occurrences avec d'autres héros qu'ils ne peuvent pas tous les adapter sur une seule ligne. Donc, dans ce cas, nous pourrions avoir deux lignes ou plus qui commenceraient par le même identifiant de héros. Nous pouvons donc voir comment cela pourrait être intéressant du point de vue du traitement des données. Nous devons les combiner ensemble comme nous le traitons d'une manière ou d'une autre. Et bien, parlons de la façon de faire ça. Notre défi est donc de savoir qui est le super-héros le plus populaire dans le monde de la bande dessinée Marvel. Et nous allons définir populaire par qui apparaît avec le plus d'autres super-héros dans d'autres bandes dessinées ? Qui est, qui contourne le plus dans le monde de la bande dessinée fondamentalement. Voici donc notre stratégie pour vraiment répondre à ce problème. Donc, nous allons charger notre jeu de données à partir du fichier de données là-bas. Et la première chose que nous ferons est de séparer le premier numéro sur chaque ligne parce que c'est l'identité du héros dont nous parlons. Avec cette ligne. Nous allons alors simplement compter le nombre total de nombres séparés par des espaces dans cette ligne. On se fiche de qui sont les connexions. On les compte juste, pas vrai ? Et donc tout ce qui nous intéresse, c'est le nombre de connexions que Héros a. Donc, en prenant ce grand total de combien de choses sont dans cette ligne. Si nous soustrayons juste un pour se débarrasser de cet ID de héros initial qui identifie qui il s'agit, nous obtenons le nombre de connexions à cet ID de héros qui sont représentées par cette ligne de données avec moi jusqu'à présent. Donc on va juste compter. Combien d'autres IDE sont dans cette ligne correspondant à cet ID héros pour obtenir un compte du nombre de connexions représentées par cette ligne de données. Et comme nous l'avons dit, nous pouvons avoir plusieurs lignes pour un identifiant de héros donné, ce qui signifie que nous devons les combiner d'une manière ou d'une autre. Donc, en SQL, nous pouvons faire une commande group BY ou sur notre jeu de données que nous pouvons faire une commande group BY pour réellement les combiner complètement. Ensuite, nous pouvons additionner toutes les connexions pour différents identifiants de héros qui ont été séparés. À ce stade, nous pouvons simplement trier par le total des connexions et arracher le résultat supérieur pour obtenir le super-héros le plus populaire. Et en même temps, nous pouvons avoir un autre jeu de données chargé à partir
du fichier texte des noms Marvel et simplement faire un filtre sur cela par l'ID d'année qui nous intéresse pour obtenir le nom de notre gagnant. Donc, avec cela, allons au code et voyons comment cela fonctionne. Alors
revenons à notre projet ici, ouvrons le script de jeu de données de super-héros le plus populaire et parcourons ce qu'il fait. Nous allons donc faire la même stratégie que celle dont nous avons parlé dans les diapositives ici. Nous commencerons par importer les choses dont nous avons besoin comme toujours et déclarer notre objet. Nous avons deux classes de cas ici, car nous avons deux jeux de données à charger. On va être la base de données des noms de super-héros qui mappe les ID de super-héros, qui sont des entiers, deux noms qui sont des chaînes. Et nous avons aussi juste un jeu de données de super-héros. Et cela va juste être une chaîne parce que nous
ne allons pas réellement nous inquiéter de structurer ces données. Nous allons juste nous inquiéter de, eh bien, quelle est la ligne brute réelle de données d'entrée et combien de choses séparées d'espace sont dedans. Donc on n'a pas besoin d'être fantaisie ici. Nous allons juste importer dans la chaîne réelle de la ligne elle-même dans sa forme brute. Donc, ne pas vraiment utiliser pleinement ce que les jeux de données peuvent faire ici, mais nous n'avons pas besoin de le faire. On n'aime pas faire des analyses de fantaisie ici. Nous comptons juste le nombre de champs dans chaque rangée. Donc avec ça, on va lancer les choses. Notre niveau de journal a donc défini notre session Spark. Et nous commencerons par créer notre schéma de noms de super-héros. Cela nous permettra de charger ce fichier Marvel Dash noms dot txt car il n'a pas de fichier d'en-tête dont nous pouvons déduire le schéma. Nous devons lui dire ce que c'est explicitement. Donc nous allons dire que nous avons deux colonnes dans ce fichier. L' un est l'ID et l'autre est le nom. Et ils seront séparés par un caractère d'espace. Donc, même si nous utilisons le chargeur CSV, nous pouvons utiliser n'importe quel séparateur que nous voulons. Et dans ce cas, ce sera le personnage de l'espace. Et vous pourriez dire à ce stade, mais Frank, et si j'avais un espace à mon nom ? Eh bien, la bonne chose à propos du chargeur CSV est qu'il est intelligent sur les guillemets. Donc, il va réellement gérer cela parce que nos noms sont
entre guillemets dans ce fichier, ce qui est cool. D' accord, alors nous devons charger le fichier de données du graphique Marvel. Et nous allons juste charger ça directement en tant que type de données de super-héros. Donc, pas besoin d'inférer un schéma là parce que nous n'avons qu'une seule ligne, nous prenons juste, disons, ligne brute de données. Donc il n'y a pas de transformation du tout. Nous allons juste charger ça directement dans le jeu de données de super-héros, que nous définissons comme une simple vieille chaîne. Donc, voici où se passe l'action. Nous prenons ce jeu de données de lignes qui contient les données brutes, et nous ajoutons une nouvelle colonne appelée id et tout ce qui va faire est de contenir la toute première entrée sur la ligne. Donc nous utilisons Split ici. Fonction fractionnée en SQL sur la colonne de valeur. Il s'agit du nom par défaut de la colonne importée par DataFrame à l'aide du séparateur d'espace. Et nous allons juste extraire le premier élément numéro 0 de cette opération de scission. Donc, tout ce que cela fait est de dire diviser cette ligne de données
brutes et arracher le premier résultat et appeler que l'ID. Et nous allons mettre ça dans une nouvelle colonne appelée id et ensuite nous faisons quelque chose de similaire pour tout le reste. Donc, nous avons une autre colonne appelée connexions, qui prend juste la taille du nombre de choses qui existent dans cette ligne divisée par des espaces. Alors, allons travailler de l'intérieur ici. Nous commençons par la colonne de valeur, qui est le nom par défaut de la colonne chargée par DataFrame. C' est toutes les données brutes. Nous divisons cela en fonction du caractère de l'espace, puis nous appelons la taille pour compter combien de ces choses existent. Donc, après avoir tout divisé par espace, combien de champs avons-nous ? Nous en soustrayons ensuite un pour soustraire l'ID du héros au début de cette ligne de données. Et c'est notre compte du nombre de connexions associées à cette ligne de données. Et nous allons mettre ce numéro dans notre nouvelle colonne de connexions. Et puis nous allons regrouper par ID. Cela nous permettra de combiner plusieurs lignes pour le même identifiant de héros. Et nous utilisons sont assemblés agrégation Trick ici, nous allons résumer toutes les connexions et toutes les entrées multiples pour un ID de héros donné qui les ajoute tous ensemble. Et nous donnerons ce nouveau résultat pour Tidal, l'alias des connexions. Donc, nous introduisons un nouveau total de somme pour chaque groupe ensemble, ID de héros. Et on va appeler ça les connexions. Donc c'est fondamentalement tout. Nous avons maintenant un jeu de données qui contient chaque ID de héros unique parce que nous avons fait un groupe BY et le nombre total de connexions pour cela ici sont IID sous une colonne de connexions. Tout ce que nous devons faire maintenant pour trouver les super-héros les plus populaires pour les trier. Et c'est ce que nous faisons ici, triant par ordre décroissant. Et nous allons en outre arracher le tout premier résultat, vous obtenez le super-héros le plus populaire. Maintenant, notre jeu de données le plus populaire contient une ligne, qui est le super-héros le plus populaire, avec une colonne pour l'ID et le nombre de connexions que Hero possède. Ensuite, nous devons chercher le nom du gagnant là-bas. Donc ça signifie quelque chose pour nous. Donc, nous pouvons dire le nom le plus populaire. Nous allons prendre ce jeu de données de noms que nous avons chargé plus tôt, filtrer en fonction de l'ID le plus populaire. Donc le 0 le plus populaire va être le premier champ qui est l'ID du héros. Et nous l'utilisons pour filtrer notre jeu de données de noms pour cet ID que nous recherchons. Donc ça va nous rendre cette seule ligne pour la carte d'identité dont nous nous soucions. Nous sélectionnerons ensuite la colonne de nom de ce résultat et arracherons à nouveau le premier résultat dans la situation improbable de cette plus d'une ligne pour le même ID de héros dans cet ensemble de données. Et à ce moment-là, nous pouvons juste imprimer les résultats. Donc, ici, nous arrachons la première et la seule colonne de notre jeu de données de nom le plus populaire là-bas et imprimons le nom en utilisant le format de substitution. Et nous disons que c'est le héros le plus populaire avec le plus populaire qui va arracher le deuxième champ du résultat le plus populaire que nous avons obtenu, qui sera le nombre de connexions que le héros avait. Alors commençons et voyons ce qui se passe. Faites un clic droit Courir. Qui pensez-vous que le super-héros le plus populaire est dans l'univers Marvel ? La réponse pourrait vous surprendre. Il s'avère que c'est Captain America. Je ne l'ai pas vu venir. Mais il s'avère que de tous les super-héros de l'univers Marvel, Captain America apparaît le plus souvent dans toutes les bandes dessinées avec d'autres personnages. Alors il se débrouille, va comprendre, qui savait. Donc, il est là, C'est en utilisant des jeux de données pour résoudre ce problème. Je veux attirer votre attention, cependant, sur
la version RDD du script également. Donc vous remarquerez qu'on a dû faire
des trucs alambiqués ici pour analyser ces données, n'est-ce pas ? Donc, nous avons dû aimer ajouter ces nouvelles colonnes qui ont fait quelques informations assez lourdes là-bas. Nous avons eu une chance de contourner cette ligne de données d'origine tout au long du chemin. Donc, bien que vous puissiez le faire simplement en utilisant des commandes de jeu de données, cela ne signifie pas toujours que c'est la bonne chose à faire. En fait, lorsque vous regardez beaucoup d'exemples en ligne de données d'analyse comme celle-ci, où vous devez faire un vrai nettoyage et réorganiser les données entrant. Souvent, vous verrez qu'ils commencent par charger des éléments à l'aide des interfaces RDD ,
puis convertissent ce RDD en jeu de données pour effectuer une analyse plus approfondie sur celui-ci. Et si vous regardez la version RDD de ceci, c'est le script de super-héros le plus populaire ici. Vous verrez que c'est en fait un peu plus simple. Donc, eh bien, je ne dirais pas plus simple, mais c'est plus simple à certains égards, au moins l'analyse des données. Donc, par exemple, regardons comment nous analysons ce fichier graphique de points Marvel ici dans l'exemple RDD. Ici, nous appelons simplement, rechargeant cela dans un RDD, puis en utilisant une fonction de carte pour compter les co-occurrences. Regardons ce que ça fait. Des trucs assez simples, non ? Donc ici, nous sommes juste en train de diviser la ligne en fonction espaces et nous retournons juste le premier élément, l'ID du héros et les éléments longueur du point moins 1. À bien des égards, c'est plus simple et plus simple que la façon dont nous l'avons fait avec des jeux de données, où nous avons dû faire ce genre de alambiqué avec colonnes en fait deux différentes avec des commandes d'appel, avec toutes ces fonctions SQL imbriquées pour obtenir le même résultat. Donc, sans doute, cela pourrait en fait être plus efficace. Et une fois que nous avons cela, nous pouvons simplement faire un ReduceByKey pour obtenir le grand total d'amis par caractère. Encore une fois, vous savez, parfois les RDD peuvent être plus simples et même plus rapides parfois, mais les jeux de données sont là pour vous aussi. Si vous ne vouliez pas effectuer une analyse de données plus compliquée sur de vraies données structurées, c'est là
que le jeu de données brille vraiment et que leur puissance devient attrayante. Mais rappelez-vous, bien que les jeux de données dans DataFrames soient une sorte de façon moderne d'utiliser Spark. Ce n'est pas toujours le meilleur moyen. Parfois, les RDD vont être plus simples. Donc, vous devriez toujours vous sentir libre de mélanger et de faire correspondre les deux, parce que parfois RDD est la bonne réponse, parfois les jeux de données sont la bonne réponse. Ce n'est pas toujours un jeu de données. Mais là, vous l'avez. Le super-héros le plus populaire, Captain America, n'a pas vu que venir ensuite, Faisons des choses plus compliquées avec cet ensemble de données et extrayons des informations plus intéressantes hors de lui.
33. [Exercice Trouvez les superhéros les plus obscures: Eh bien, cela semble être le bon moment pour vous faire sortir et écrire votre propre code pour un peu ici et obtenir un entraînement pratique. Donc votre défi sera de trouver les super-héros
les plus obscurs par opposition au super-héros le plus populaire. Et j'aime trouver des images de photos de stock de fromage. Parfois, ce super-héros a l'air assez obscure. C' est peut-être un employé de bureau. Je ne sais pas. C' est un peu dérangeant de toute façon. Donc, le problème est que je veux que vous listiez les noms de tous les super-héros de notre jeu de données qui n'ont qu'une seule connexion. Et cela va être un peu plus difficile que cela semble que vous
pourriez penser que vous pourriez juste prendre le script existant que vous
avez pour les super-héros les plus populaires et changer un maximum à un minimum quelque part et être fait avec ou trier par un ordre différent. Mais ce n'est pas si simple parce que le code que je viens vous
donner suppose qu'il n'y a qu'une seule réponse, un seul super-héros le plus populaire. Cependant, dans ce cas, il y a en fait beaucoup de super-héros dans notre jeu de données qui n'ont qu'une seule connexion. Et vous allez les énumérer tous avec leurs noms. Ça rend les choses un peu plus compliquées. Vous devrez joindre un jeu de données à un moment donné avec le
jeu de données de noms afin d'imprimer tous ces noms ensemble à la fois. Je veux dire, vous pourriez le faire après le fait et, vous savez, un peu faire avec la façon dont nous l'avons fait à l'origine et rechercher des noms individuels au fur et à mesure que vous les imprimez. Mais ce ne sera pas aussi efficace que de simplement joindre les noms à un moment donné pour les intégrer tous, d'une manière répartie
dans le cluster. Et pour plus de crédit, Voyez si vous pouvez calculer le plus petit nombre réel de connexions au lieu de simplement supposer qu'il en est une. Si vous pouvez comprendre comment faire la commande min pour déterminer réellement plus petit nombre de connexions dans
l'ensemble du jeu de données, au lieu de simplement le coder en dur sur une seule. Ce serait la chose la plus fondée sur des principes à faire, non ? Mais il s'avère que la réponse est celle qui est le plus petit nombre de connexions. Il n'y en a pas qui ont 0 dans le jeu de données. Ils ont déjà été filtrés apparemment. Et l'un est le nombre magique, mais il serait préférable de calculer ça d'une manière ou d'une autre, non ? Voici donc la stratégie globale que vous voudrez utiliser ici. Commencez par une copie du script de jeu de données de super-héros le plus populaire que nous venons d'examiner. Et si vous faites juste une copie de ce script et d'Intel J, puis collez-le dans le paquet. Cela vous donnera l'occasion de renommer ce script au fur et à mesure que vous le copiez. Alors appelez ça quelque chose comme les superhéros les plus obscurs ou quelque chose comme ça. Et ce script peut être largement inchangé jusqu'
au point où nous construisons le jeu de données de connexions. Cela va vous donner ce jeu de données qui a tous les super-héros et le nombre de connexions qu'ils ont. Et ça va toujours être utile pour cet exercice. Mais à partir de là, ça va être complètement différent. Donc, à ce stade, vous allez vouloir filtrer cela
vers le bas pour ne trouver que les lignes qui ont une connexion. Et puis, lorsque vous filtrez cela vers le bas, vous voulez joindre ces résultats à notre jeu de données de noms pour rejoindre les noms de chaque super-héros dans ce filtre vers le bas dans le jeu de données. Maintenant, notez ici que nous réfléchissons un peu à la performance ici, non ? J' aurais pu rejoindre ce jeu de données de noms avant filtrer toutes les connexions qui ont juste une connexion. Mais cela forcerait mon cluster à faire beaucoup plus de travail qu'il n'en a besoin, non ? Quel est le but de joindre les noms de tous ces super-héros qui ont plus d'une connexion, je ne vais pas les afficher. Donc, parfois même si Spark est optimisé et a beaucoup d'optimisation automatique, vous devez toujours réfléchir un peu aux résultats que vous voulez et au bon ordre pour faire les choses. Très bien, donc une fois que nous avons ça, nous avons juste besoin de sélectionner la colonne des noms et de la montrer. Et c'est à peu près tout. Et si vous voulez quelques conseils supplémentaires
ici, Voici quelques extraits de code qui pourraient vous aider. Encore une fois, si vous voulez filtrer un jeu de données pour un nom de colonne égalant une valeur, cela ressemblerait à quelque chose comme ça. Juste le filtre de points de nom du jeu de données. Rappelez-vous que la syntaxe est le signe dollar, puis le nom de la colonne entre guillemets. Et trois signes égaux à la valeur que vous voulez filtrer. Également pour joindre un jeu de données avec un autre. C' est comme une opération de jointure SQL. Vous pouvez simplement dire le nom du jeu de données, quel qu'il soit, point join, puis spécifier le nom d'un autre jeu de données qui partage un nom de colonne commun que vous pouvez utiliser pour joindre ces jeux de données ensemble. Donc, dans notre cas, ce sera la colonne ID. Et puis vous dites que l'utilisation de la colonne est égale à n'importe quel nom de colonnes communes. Et cela se joindra aux champs du deuxième jeu avec le premier jeu de données où ce nom de colonne commun correspond. Et enfin, si vous voulez le crédit supplémentaire, je ne suis pas en train de suivre votre score ici. C' est totalement sur le système d'honneur. Mais si vous voulez réellement calculer le nombre minimum de connexions trouvées dans le jeu de données, cela ressemblerait à ceci. Sur le jeu de données, vous devez utiliser la commande add et l'utilisation pour contenir la commande minimale sur le nom de colonne que vous souhaitez trouver le minimum qui retournera un jeu de données. Mais si vous voulez réellement récupérer cette valeur réelle dans votre script de pilote en tant que valeur Scala. Pour reconvertir cela, vous devez d'abord appeler dot pour extraire la première ligne de ce résultat. Et il y aura juste une rangée. Et cela vous donnera un type de données de ligne. Et cela ne sera pas utile en soi. Donc, nous allons appeler get long que 0 pour extraire le premier nombre de cette ligne, ce qui sera cette valeur minimale. Donc, la syntaxe est un peu foirée, mais c'est ce que vous devez faire pour récupérer ce nombre à partir
du jeu de données et dans une valeur réelle que vous pouvez ensuite utiliser dans votre opération de filtrage. Alors bonne chance. Wow, s'il y avait un Brocoli Man, je suis presque sûr qu'il serait sur la liste finale de vos résultats. C' est une image super inquiétante. Allons, faisons en sorte que ça disparaisse. Va écrire du code et nous reviendrons à la prochaine conférence et je vais te montrer ma solution.
34. Solution d'exercice : trouvez les superhéros les superhéros les plus obscures: D' accord, j'espère que vous avez eu un coup à cet exercice et voici ma solution au problème. Encore une fois, il y a plusieurs façons de le faire. Tant que tu obtiens les mêmes résultats que moi, c'est ce qui compte. Il y a plusieurs façons d'y arriver. Pensez-vous à l'efficacité de votre solution ? Et on en parlera un peu. Donc, comme je l'ai suggéré, je viens de copier le script de super-héros le plus populaire. Et en faisant cela, j'ai juste cliqué avec le bouton droit sur cela et ladite
copie et copie ou juste Contrôle C. Et puis si vous le collez dans com dot sun dot software dot spark, qui vous a donné l'occasion de dupliquer ce script avec un nouveau nom. Et dans mon cas, je l'ai dupliqué avec le nom des superhéros les plus obscurs, point Scala. Alors allons-y et jetons un coup d'oeil à cela et passons en revue mes changements. La plupart du script est inchangé. Tout ce que j'ai fait était de changer le nom, comme je l'ai dit, et j'ai aussi changé le nom de l'application parce que pourquoi pas ? Et comme je l'ai dit, ce sera le même
jusqu'à la construction de ce jeu de données de connexions. Donc, voici où nous construisons le jeu de données de tous les ID de super-héros et le nombre de connexions qu'ils ont. Et ce nombre de connexions colonne est appelé connexions. Donc, à ce stade, nous avons un jeu de données qui a un ID et des connexions. Donc c'est inchangé. Nous utilisons les mêmes informations pour trouver le super-héros le plus populaire. Mais une fois que nous avons cela, nous devons filtrer cela jusqu'
aux résultats qui ont eu le moins de connexions. Et je sais que le nombre est un, que le nombre le plus bas de connexions dans mon jeu de données est un. Mais si je voulais définir ça algorithmiquement, je pourrais faire quelque chose comme ça. Je pourrais dire Val, compte de connexion min. Et cela va être une valeur scalaire qui contient un
certain nombre égal à des connexions point agg. Nous avons juste besoin de cela pour envelopper cette fonction SQL min. Le nom de la colonne Homme est égal aux connexions. Donc, à ce stade, nous disons connexions AG Min, connexions de nom de colonne, donc nous donnera un jeu de données qui a une seule ligne dedans, contient
encore une colonne qui contient la valeur minimale trouvée dans la colonne connexions. Maintenant, à ce stade, nous avons un DataFrame encore. Et nous voulions retourner ça à notre script de pilote en tant que valeur, n'est-ce pas ? Nous devons donc d'abord appeler dot pour convertir ce jeu de données en une seule ligne. Et puis une fois que nous avons cet objet de ligne, nous appelons getline non-zero pour extraire le premier et le seul champ de cette ligne et le convertir en un entier long. Donc, cette petite expression compliquée ici calcule cette valeur minimale et la convertit en un jeu de données, ramène au script du pilote avec la première commande, puis les appels deviennent longs pour extraire le nombre de ce jeu de données à partir de cette ligne du jeu de données plus spécifiquement. Donc maintenant le nombre de connexions principales sera égal à un. Bon, maintenant que nous savons quel est notre nombre minimum de connexions, nous pouvons filtrer notre jeu de données de connexions dessus en disant que les connexions filtrent point, signe
dollar connexions égal, égal, égal, se souvenir de trois égaux. Une sorte de bizarrerie bizarre de la syntaxe ici, égale le nombre de connexions min, qui sera un. Et si vous avez pris l'approche la plus simple ici et supposé que c'était un, vous auriez pu juste dire égal, égal à 1. Et ça marcherait aussi. Donc, nous prenons ce jeu de données filtré et l'appelons connexions Min. Donc, le jeu de données de connexions hommes contient maintenant seulement les ID de héros. Qui contiennent une connexion. Donc, nous avons toujours la colonne des connexions qui traîne ici. Maintenant, nous devons nous joindre aux noms de ces super-héros pour pouvoir les afficher et avoir des résultats lisibles par l'homme. Et c'est ce qui se passe dans cette ligne ici, nous disons que les connexions min avec les noms sont égales à min connexions point jointure avec le jeu de données de noms en utilisant l'ID de colonne. Vous remarquerez donc que les connexions DataFrame et les noms dataframe ont un champ appelé ID. Et nous allons l'utiliser pour joindre ces deux jeux de données ensemble. Donc, pour chaque ligne de notre jeu de données connexions Min, nous allons essentiellement rechercher l'ID sur cette ligne et rejoindre le nom du jeu de données de nom qui a ce même ID. Tout comme une commande SQL join si vous êtes familier avec cela. Donc, à ce stade, nous allons avoir un jeu de données qui contient non seulement un ID et un nombre de connexions, mais aussi une colonne de nom que nous avons rejoint à partir de ces noms DataFrame. Maintenant, nous pouvons enfin imprimer nos résultats. Donc, tout d'abord, nous allons imprimer un peu d' en-tête juste parce que nous voulons que les résultats soient soignés. Tu n'avais pas à faire ça. Bien sûr, nous allons dire que les caractères suivants ont seulement des connexions de nombre de connexions min. Dans ce cas, je serai 1. Et puis nous disons juste connexions Min avec des noms, point select name pour juste sélectionner cette colonne de nom. Je me fiche de rien d'autre pour la sortie finale. Et les points montrent pour afficher cela comme la sortie de mon script de pilotes. Ça a du sens. Assez simple. Et encore une fois, il y a plus d'une façon de le faire. Mais vous faites une chose à propos de la performance. C' est une bonne façon de le faire. Il pourrait y avoir un moyen plus efficace d'obtenir cette valeur minimale là sans réellement arrêter mon script ici et
arrêter fondamentalement le monde ici pour comprendre quelle est cette valeur minimale à ce stade. Parce qu'il est revenu à mon script de pilote et
que j'utilise cette valeur dans une section ultérieure de mes scripts de pilote. Donc, toute cette section ci-dessus doit s'exécuter est une étape. Il va s'arrêter sur le cluster, attendre que ce résultat revienne pour la valeur minimale, puis lancer les opérations suivantes de l'ensemble de données après cela,
cela pourrait ne pas être entièrement optimal. Mais il y a une meilleure façon de le faire. Je ne l'ai pas compris. Je pense que c'est inévitable dans ce cas. Mais une chose que j'ai fait, comme je l'ai dit dans les diapositives, était de m'assurer que je n'ai fait cette opération de jointure qu'une fois que j'ai filtré les connexions à l'ensemble final de résultats que je voulais, les
jointures sont des opérations coûteuses sur Spark. Donc, vous voulez certainement garder ceux aussi petits et aussi limités que vous le pouvez. Donc, c'était la méthode de ma folie à faire dans cette jointure après l'opération de filtre au lieu d'avant. Et aussi du bruit. Notez que je n'itère pas les résultats finaux en effectuant une recherche de jeu de données sur le jeu de données de noms pour chaque nom unique et le script de pilote. Ce sera encore pire. Donc c'est assez optimal. Alors allons de l'avant et allons voir ce que nous obtenons. La plupart des superhéros obscurs fuient ça va. Et voici des héros obscurs. Les caractères suivants n'ont qu'une seule connexion. Et c'est une liste assez courte. Mais l'ouvrier de Blair, Marvel garçon. Suivi maladroit. Alors que ce sont, vous savez, il y a eu beaucoup de films de super-héros Marvel d'une manière ou d'une autre. Je ne pense pas qu'on en verra un sur le suivi maladroit. C' est une carte assez obscure. Je n'ai entendu parler d'aucun de ces gars, avez-vous si vous avez, disons-le dans les commentaires, pourrait être intéressé d'en entendre parler. Alors oui, quand Marvel commence à faire des films sur ces personnages, vous savez, ils ont vraiment touché le fond du canon. C' était un exemple intéressant. J' espère que vous avez eu du succès avec cet exercice et que vous avez obtenu les mêmes résultats que moi. La commande n'a évidemment pas besoin d'être la même, mais vous devriez avoir la même liste de résultats ici dans ce que vous avez fait. Sinon, revenez à boguer ce que vous avez fait et continuez à itérer dessus jusqu'à ce que vous obteniez la bonne réponse. Et c'est une bonne pratique. Et avec ça, passons à autre chose.
35. Les degrés de superhéros de séparation : Introduire la recherche Breadth-First: Donc, le but de ce prochain exercice est de vous montrer que l'étincelle peut souvent être utilisée pour paralléliser des problèmes que vous ne pensiez pas que Spark pourrait faire. Donc, beaucoup de fois, les gens utilisent Spark pour Data Analytics et spécifiquement pour des choses qui peuvent être exprimées sous la forme d'une commande SQL. Mais il peut faire beaucoup plus si vous pensez simplement de manière créative à ce sujet. Donc, à titre d'exemple, nous allons comprendre les degrés de séparation entre les super-héros dans notre réseau social de super-héros ici, pour récapituler avec l'idée de degrés de séparation est si vous n'êtes pas familier avec elle, eh bien, retour dans Hollywood, il y avait un concept appelé ton numéro de bacon. Et c'était le nombre de degrés de séparation et d'acteur de Kevin Bacon. Il y avait cette légende dans laquelle Kevin Bacon était si bien connecté,
est apparu dans tellement de films différents que presque tous les acteurs pouvaient se remonter à Kevin Bacon d'une manière ou d'une autre. Et c'est vrai en fait. Alors, comment ça marche ? Mettons ça en termes de données sur nos super-héros, non ? Donc, disons que pour des raisons d'argumentation, Spider-Man est apparu dans la même bande dessinée que l'Incroyable Hulk. Et l'Incroyable Hulk apparut à son tour dans la même bande dessinée que Thor. Dans ce cas, on dirait que Spider-Man et Thor sont deux degrés de séparation, non ? Parce que si vous regardez les connexions de Spider Man, le Hulk n'est pas dans cet ensemble immédiat de connexions. Quelqu' un à qui Spider-Man est connecté est connecté au Hulk. Donc c'est à deux pas de Spider-Man ou deux degrés de séparation. Donc c'est une chose intéressante à regarder. Il s'avère que les gens sont plus connectés que vous ne le pensez. Et il s'avère que c'est aussi vrai dans le monde de la bande dessinée. Alors, comment ferons-nous ça ? Eh bien, il y a un algorithme d'informatique appelé recherche large qui résout ce genre de problème pour nous. Et ce n'est certainement pas quelque chose où vous écririez simplement une commande SQL et en aurez fini avec elle pour trouver la réponse, n'est-ce pas ? Nous voulons comprendre pour une personne donnée à un nœud donné, dans ce cas, un super-héros donné dans ce graphique de connexions. À combien de pas un super-héros donné est-il d'un autre super-héros ? Alors, comment ferons-nous cela en utilisant Apache Spark ? Eh bien, avant de parler des détails de l'implémentation, parlons de l'algorithme. Donc, pour comprendre cet exemple, vous devez comprendre la recherche de largeur d'abord ou BFS. C' est un problème d'algorithmes informatiques. Et si vous allez interviewer pour des postes d'ingénieur logiciel, c'est une bonne chose à savoir, même si ce n'est pas directement lié à Spark. Donc, si vous ne suivez pas les détails ici, ne vous accrochez pas trop. Ce n'est pas vraiment pertinent de se déclencher. Je suis juste pertinent pour comprendre cet exemple de la façon dont Spark peut être utilisé pour résoudre des problèmes que vous n'avez peut-être pas pensé que Spark peut être utilisé. Imaginez que cela représente notre réseau. Donc chaque cercle représente ici un super-héros, et chaque ligne entre ces cercles représente un lien entre les super-héros. Donc, cela signifie qu'ils sont apparus dans la même bande dessinée ensemble. Et certains, vous savez, parfois, vous avez beaucoup de liens qui viennent d' un super-héros et parfois il y a beaucoup de routes entre deux super-héros à regarder. Donc le nombre à l'intérieur de chaque cercle représente la distance de
ce super-héros par rapport au superhéros dont nous mesurons les degrés de séparation. Et au départ, nous ne connaissons pas la réponse car nous commençons cet algorithme. Donc tout est réglé à l'infini. Nous supposons qu'ils sont infiniment loin parce que nous ne l'avons pas encore calculé. Donc, pour commencer, nous avons choisi le super-héros avec lequel nous voulons commencer et avec qui nous voulons calculer les degrés de séparation. Disons que Spider-Man, et nous appellerons ça S ici dans cet exemple. Donc, le coup d'envoi, l'algorithme, nous colorions ce noeud initial gris, ce qui
signifie que nous devons explorer cette NOAEL, nous voulons en savoir plus sur les connexions de ce noeud. Et nous avons mis le numéro 0 parce que c'est la distance de la personne que nous commençons par 2, ce nœud. Spiderman est 0 degrés de séparation de Spider-Man parce que Spider-Man est Spider-Man. Donc, que faisons-nous dans l'algorithme BFS, c'est que nous allons chercher des nœuds gris dans notre graphique. Et pour chaque noeud gris que nous trouvons, nous explorons les connexions qui sortent de ce noeud gris. Et quand nous faisons si ce noeud que nous explorons son blanc, ce qui
signifie qu'il a été inexploré précédemment, nous allons le colorer en gris, ce qui
signifie que nous devons explorer ce noeud plus itérativement. Et nous prendrons le noeud que nous venons d'explorer en couleur noir, indiquant que nous avons déjà exploré ce noeud. On n'a pas besoin d'y revenir. Nous incrémentons le nombre actuel de distance. Donc c'était 0 plus un est un. Donc maintenant, nous savons que nous sommes un degré de séparation sur R et W Fait sens. Nous avons donc commencé à explorer cette couleur de noeud gris S au noir parce que nous en avons fini avec. Et pour toutes ses connexions, si elles étaient blanches, nous les rendons grises maintenant et mettons dans le nombre actuel de distance par rapport à ce nœud initial. Donc, dans la prochaine passe, encore une fois, nous cherchons les notes grises et explorons leurs connexions. Alors commençons par w. il va rompre ses connexions. Donc, ils étaient tous les deux blancs à l'origine et maintenant nous allons les
colorer en gris et incrémenter la distance à nouveau. Donc maintenant, nous sommes deux degrés de séparation de S fera la même chose pour la connexion de S à R. Explorer C'est une connexion à v et la couleur gris. Et encore une fois, mettez un deux dedans parce que nous sommes actuellement à l'itération de deux distance de S. Maintenant que nous avons exploré sont en W, nous allons l'appeler devient noir, ce qui
signifie que nous ne devrions pas revoir ceux à nouveau dans l'avenir. Ensuite, nous recommencerons avec T. Nous devons passer par tous les nœuds gris et explorer à nouveau leurs connexions. Maintenant T est connecté à u, qui était blanc, donc nous allons maintenant colorer ce gris et incrémenter à nouveau le nombre de distance à trois. Maintenant. Maintenant, notez que t est également connecté à x et w, Mais ceux-ci ne sont pas blancs. Nous allons essayer de préserver la couleur la plus sombre ici au fur et à mesure que nous traversons. Donc nous n'allons pas nous embêter à revisiter X. Elle est déjà marquée en gris. On ne va certainement pas rendre visite à W parce que c'est marqué noir. Ça veut dire qu'on l'a déjà fait. Nous n'avons pas besoin d'un tel processus du tout. Donc nous pouvons marquer x est en cours d'exploration maintenant, nous avons, nous pouvons marquer ce noir maintenant parce que nous avons déjà déterminé que nous en avons fini. Et passer à autre chose. Nous devons aussi explorer si nous n'avons pas encore fini ça. Donc, on va vérifier que V est noir maintenant aussi. C' était un gris à l'origine. Alors maintenant, l'étape suivante est d'appeler ça noir, qui
signifie que nous avons fini de l'explorer. Maintenant, nous avons juste deux autres nœuds gris à explorer ici. Et ils n'ont aucun noeud nouvellement inexploré qui leur est associé. Donc on va juste les colorer en noir et en avoir fini avec. Donc, l'algorithme global ici pour récapituler, nous commençons par colorier tout blanc avec une distance inconnue. Notre nœud initial est gris, et pour chaque itération, nous recherchons des nœuds gris, explorons leurs connexions. Et pour chaque noeud blanc sortant de ce noeud gris, nous le marquerons comme gris pour exploration
future à moins qu'il n'ait déjà été coloré gris ou noir, où préservant précisément la couleur la plus foncée là-bas au fur et à mesure que nous allons. De plus, nous conservons métrique de distance
la plus basse que nous voyons dans ces nœuds au fur et à mesure que nous allons. Donc on ne va jamais faire quelque chose comme aller de toi à T et dire que t est maintenant une distance de quatre parce qu'on a reculé, ça aurait du sens, non ? Donc, nous garderions toujours cette mesure de distance inférieure pendant que nous traversons le graphique. C' est donc une chose difficile d'envelopper la tête. Et encore une fois, si vous n'avez pas suivi ça, ne vous inquiétez pas trop. Ce n'est pas un cours sur les algorithmes, c'est un cours sur Spark. J' essaie juste de transmettre comment il est possible d'utiliser Spark pour résoudre des problèmes auxquels vous ne penseriez peut-être pas Spark adapté. Vous pouvez réellement paralléliser ce problème assez bien si nous y pensons d'une manière créative. Parlons donc de cette implémentation dans Spark ensuite et faisons cela sur notre Spark Cluster.
36. Les degrés de superhéros de séparation : Accumulateurs et implémenter BFS dans Spark: Parlons donc de la façon d'encadrer cela comme un problème d'étincelle et réellement distribué la recherche d'abord sur l'ensemble de notre cluster potentiellement. Donc, la première chose que nous devons faire est de représenter nos données entrant comme ces nœuds dont nous avons parlé dans la conférence précédente. Ainsi, par exemple, une ligne d'entrée peut être dans ce format, le premier numéro est un ID de héros, suivi d'une liste des autres héros que Hero a apparus avec une autre bande dessinée. Nous voulons donc structurer cela d'une manière qui représente l'
un de ces nœuds dans la recherche de largeur d'abord. Donc, par exemple, nous pourrions structurer cela comme le tuple de tuples suivant, si vous voulez. Où le premier élément est l'ID de héros dont nous parlons. Celui qui est essentiellement représenté par ce nœud, suivi d'une liste de tous les autres identifiants de héros qui sont connectés à ce héros. Imaginez donc une ligne virtuelle entre 59, 83 et 11, soixante cinq, trente huit, trente six, et cetera, et cetera. Ce sont donc toutes les connexions qui sont reliées à notre héros. Et que lui-même est dans son propre tuple. Pour garder tout cela autonome. L' élément suivant de notre tuple représentera la distance associée à ce nœud par rapport au caractère dont nous mesurons la distance. Dans un premier temps, nous avons mis cela à l'infini. n'y a aucun moyen de représenter vraiment l'infini ici, donc nous allons juste le définir sur un nombre vraiment important. Dans ce cas, 99. 99 sera notre stand in pour l'infini comme valeur de distance initiale. Et nous devons associer une couleur. N' oubliez pas que nos notes peuvent être blanches, grises ou noires, où le blanc représente un nœud inexploré. Gray représente un nœud qui doit être exploré, et noir est un non qui a déjà été exploré. Donc, au départ, chaque nœud est blanc. C' est donc un exemple de la façon dont nous pouvons représenter ces lignes dans un format qui est cohérent avec notre concept de nœuds dans une recherche à couper le souffle. Donc maintenant, en passant par cet algorithme de recherche largeur première peut être considéré comme une carte et réduire l'opération. La fonction de mappage prendra soin de convertir ces lignes dans le format de noeud BFS dont nous venons de parler. Et ce code pourrait ressembler à ceci. Nous avons donc juste besoin de le diviser par espaces, convertir les identifiants de héros en entiers et les connexions en entiers
construisent un tableau de connexions qui sont toutes les connexions associées à cette personne. Définissez la couleur initiale sur le blanc. Réglons la distance initiale à 99, 99. Et si l'identité du héros est un, nous commençons par le dossier initial de celui d'où nous partons. Couleur que l'un gris avec une distance de 0, mais tout le reste devrait être blanc avec une distance d'infini comme notre cas initial. Et nous rendons juste notre structure tuplée dont nous avons parlé avec la carte d'identité du héros. Et puis en outre, le tableau des connexions et la distance et la couleur. Maintenant, c'est peut-être une bonne idée de parler un peu de l'histoire de l'informatique distribuée ici. Notez donc que nous utilisons un paradigme MapReduce pour penser à ce problème. D' où vient cette idée ? Donc, au moment où Google s'occupait pour la première fois analyse de données à
grande échelle et de la nécessité traiter des données qui ne pouvaient pas tenir sur une seule machine. Ils ont inventé MapReduce. Et MapReduce était à peu près limité aux fonctions de cartographie et de réduction des fonctions. C' est ce qu'il a fait, non ? Et nous avons vu des exemples de cartographes et de réducteurs dans les exemples précédents dans ce cours, mais il doit être, C'est à peu près le seul truc que nous avions dans nos manches. Hadoop a été construit sur le dessus des concepts que Google est venu avec. Et Hadoop, il a aussi quelque chose appelé MapReduce. Il s'appelle en fait MapReduce, un mot qui est un composant essentiel de Hadoop lui-même. Le problème est que MapReduce n'était pas très intelligent en matière d'optimisation, et c'est là que Spark est arrivé. Donc Spark au départ, c'était juste une sorte d'alternative plus rapide à MapReduce. C' est de là que vient l'interface RDD initiale de Spark. Vous remarquerez que les RDD ont une fonction de carte et une fonction de réduction à leur disposition. Et c'est pourquoi, parce qu'ils essayaient de répliquer la fonctionnalité de Hadoop MapReduce. Maintenant plus tard, au fil du temps, lorsque nous sommes arrivés à Spark Version 2, C'est à ce moment
que les jeux de données et les DataFrames ont été introduits. Dataframes est venu en premier en fait. Et c'est là que nous avons commencé à dire, Hey, pensons à ceux-ci en termes d'opérations SQL. Sql était en quelque sorte devenu le langage commun entre les logiciels d'analyse de données à l'époque. Donc, même pour les choses qui étaient distribuées et techniquement ne convenaient pas aux opérations de base de données relationnelles. Sql était encore en train de devenir la syntaxe commune entre toutes ces différentes plates-formes. Nous avons donc vu cette évolution de MapReduce à étincelle qui a été construite en quelque sorte comme une extension pour rendre MapReduce meilleur. Pour faire de plus en plus une interface SQL SAL. Mais tout n'est pas un problème SQL, n'est-ce pas ? Donc, nous avons encore cette fonctionnalité de niveau inférieur de MapReduce disponible pour nous que nous pouvons utiliser pour résoudre des problèmes plus généraux tels que celui-ci. Je ne peux pas écrire une commande SQL qui dit calculer la distance dans un graphique entre deux nœuds. Mais je peux encadrer cela comme un problème MapReduce. C' est ce qu'on va faire ici. Encore une fois, il s'agit de choisir le bon outil pour le travail, même si nous pouvons le faire avec un jeu de données. Et je vais vous montrer que dans ce cas, l'utilisation de RDD et de leur mappage de niveau inférieur et la réduction des
fonctionnalités va être l'approche la plus simple. Ok, hors de ma plate-forme, parlons de la mise en œuvre un peu plus. Donc, tout comme nous avons parcouru les diapositives pour une recherche large, nous allons passer par les choses itérativement. Et pour chaque étape, chaque distance, nous allons chercher tous les nœuds gris et développer ces nœuds gris. Coloriez le nez. Nous en avons fini avec son noir et continuons à augmenter les distances au fur et à mesure. Donc, vous allez voir une grande boucle qui
passe itérativement à travers ce graphique encore et encore, cherchant des nœuds gris et en traitant ces nœuds gris en conséquence sur la base des règles que nous avons définies dans le BFS algorithme. D' accord, donc encore une fois, nous sommes juste en train de tracer ça comme une carte et un travail de réduction. Ainsi, chaque fois que nous incrémentons à travers notre algorithme, le mappeur incrémente la distance d'un. Et il va chercher des notes grises. S' il trouve un noeud gris, va regarder toutes les connexions de ce noeud gris, les
colorer en gris pour une exploration future. Et au départ, ils n'auront aucune connexion car ils doivent être explorés pour construire ces connexions. Sur l'itération suivante, le grain d'avoine qu'il traite juste sera alors coloré en noir. Et il copiera le nœud lui-même dans les résultats pour s'assurer que nous ne le perdons pas. Le travail des réducteurs sera de traiter tous les cas où nous avons plusieurs chemins allant dans le même nœud, de nombreuses connexions. Nous devons donc combiner tous les nœuds qui existent pour le même identifiant de héros. Et s'il y a un cas où il y a plusieurs connexions, nous voulons préserver la connexion avec la distance la plus courte et la couleur la plus sombre. Et comme cela réduit les choses qui préserveront cette liste de connexions à partir du nœud d'origine pour nous assurer que nous ne perdons pas celles à l'itération suivante. Donc c'est comme ça que tout fonctionne d'un point de vue algorithmique. Mais comment pouvons-nous savoir quand on a fini ? Donc, voici où nous allons introduire un nouveau concept appelé l'accumulateur dans Spark. Donc, un accumulateur est fondamentalement un compteur partagé entre tous les exécuteurs de votre cluster. Donc, si vous avez besoin d'avoir une sorte de compteur communément tenu, si vous voulez, ou un drapeau d'une sorte ou d'une autre. Et l'accumulateur peut le faire. Il permet à de nombreux exécuteurs d'incrémenter une variable partagée sur l'ensemble du cluster. Voici donc un exemple de cette syntaxe. Je pourrais dire que le compteur de frappe est un long accumulateur nommé compteur de frappe. Et par défaut, sa valeur initiale sera 0. Alors que nous traversons notre algorithme, nos itérations vont être distribuées sur toute notre plateforme. Et n'importe quel exécuteur peut frapper le personnage qui nous intéresse. Donc quand ça arrive, cet exécuteur doit signaler d'une manière ou d' une autre
le script du pilote dans son ensemble, Hey, on a fini. On a eu un coup ici. Donc, nous pouvons incrémenter l'accumulateur de compteur de succès dans ce cas pour indiquer qu' il a effectivement trouvé le caractère que nous essayons de trouver la distance entre notre personnage d'origine. Donc, quand nous avons fini avec chaque itération, nous vérifions simplement si le compteur de succès est supérieur à un. Et si c'est le cas, nous savons que nous avons fini et parfois nous obtiendrons un coup de plusieurs directions et que le compteur de coups gênant pourrait être plus d'un. Euh, mais c'est comme ça qu'on sait qu'on a fini. Ces exécuteurs peuvent signaler au script, Hey, j'ai eu un coup. Et il peut garder une trace du nombre de hits en ayant cet accumulateur partagé sur tous les exécuteurs. Donc c'est beaucoup pour vous envelopper la tête. Allons au code et voyons à quoi il ressemble.
37. [Activité] Superhéros de séparation : consultez le code et exécutez !: Alors plongons dans le code, ouvrons des degrés de séparation, pas encore le jeu de données, juste des degrés de séparation. Et nous allons parcourir ce code. Maintenant encore. Le but de cet exercice est juste de vous montrer que vous pouvez faire choses
complexes avec Spark qui ne se limitaient pas aux opérations de style SQL. Donc, si vous voulez faire comme l'analyse de données traditionnelle, génial, utilisez des commandes SQL. Mais pour des choses comme ça, vous devrez peut-être descendre au niveau inférieur de Spark et revenir à l'interface RDD. Et c'est bon, c'est, c'est à votre disposition aussi. Et vous savez, c'est une sorte de pensée créative, c'est vraiment ce que des entreprises comme Amazon,
Google et Apple vont payer aux gens le gros argent pour, non ? Il ne faut pas quelqu'un de vraiment spécial pour écrire une commande SQL et comprendre combien de visites de site Web vous avez eu au cours de la dernière heure. Mais il faut quelqu'un de spécial pour comprendre comment je peux prendre un problème qui n'a jamais été résolu avant d'utiliser Apache Spark et le résoudre. Et voici un exemple de ce fait. Donc, si vous ne suivez pas le code ici, si vous ne suivez pas l'algorithme, ne soyez pas trop stressé à ce sujet. Ce n'est pas vraiment le but de cette activité. Le but est juste de vous montrer qu'il est possible de faire des choses compliquées dans Spark et le parallélisme à travers un cluster que vous n'avez peut-être pas pensé possible. Dans ce cas, nous pensons en quelque sorte plus dans un paradigme MapReduce que dans un paradigme SQL. Et c'est bon. Donc, plonger dans, nous importons toutes les choses que nous avons priées ou de qualité d'objet. Maintenant, la première chose
que nous faisons est de définir le caractère à partir duquel nous partons et le caractère que nous recherchons. Donc, le but de ce script sera de
trouver les degrés de séparation entre Spider-Man, qui est le caractère ID 5306,
il s'avère, et l'atome de caractère 3,031, qui est franchement le caractère le plus obscur I trouver dans le jeu de données, au moins je n'ai jamais entendu parler d'eux. Je n'ai aucune idée de qui c'est. Et son identité de personnage est 14. Donc ce que nous essayons de faire est de trouver les degrés de séparation entre Spider-Man et Adam, 3 031 ici. Et nous avons parlé d'utiliser un accumulateur appelé compteur de coups. Et ça va être comme ça nos dirigeants disent, Hey, en fait, j'ai trouvé l'atome 3,031 en traversant le graphique de Spider-Man. Donc ça va être une sorte de compteur partagé qui dit, hé, j'ai une connexion ici. Ensuite, nous configurons nos types de données ici. Nous avons donc un type de données BFS qui est un tableau d' entiers et un entier et une chaîne qui représentera une liste de connexions, la distance et la couleur associée au nœud. Et le nœud lui-même aura l'ID de héros associé à ce nœud et les données qui lui sont associées. Donc, un nœud BFS va représenter l'un de ces cercles dans nos diapositives qui représente un certain ID de héros. Et les connexions de ce héros ont la distance de Spider-Man. Et enfin, la couleur de ce noeud, qui va être blanc, gris, ou noir. Passons à la fonction principale et travaillons en arrière à partir de là. Donc ici quelque part, nous avons une fonction principale. Commencez par dire le niveau de journal et nous avons mis en place un nouveau contexte Spark. Nous n'utilisons pas de session Spark car nous n'
utilisons pas l'interface du jeu de données dans cet exemple, nous allons simplement utiliser des RDD. Et pour cela, nous avons juste besoin d'étinceler le contexte. Nous initialisons notre accumulateur et lui donnons un nom. Et la première chose que nous faisons est de créer RDD de départ. Donc, cela crée les conditions initiales de notre graphique. Alors voyons ce que ça fait. Où est créer le démarrage de RDD ? Très simple, non ? Donc, tout ce que nous faisons ici est de charger le texte du point du graphique Marvel dans un fichier d'entrée brut RDD. Et puis nous appelons carte avec converge vers BFS pour convertir ces données au format de nœud BFS. Regardons Convertir en BFS. Split la ligne en champs individuels, arrache le premier fait que l'ID héros arrache tous les champs suivants ici et remplit un tableau d'entiers et qui va représenter tous les des liens entre ce héros et d'autres héros. Nous définirons sa couleur par défaut sur le blanc et sa distance par défaut est 99, 99, ce qui est notre représentation de l'infini, sauf si vous êtes Spider-Man. Dans ce cas, nous vous colorions en gris avec une distance de 0. Ce qui signifie que nous voulons commencer par explorer le nœud Spiderman et les degrés de séparation de Spider-Man 2 lui-même est 0. Nous revenons ensuite cette structure de notes BFS dont nous avons parlé, qui est un identifiant de héros, puis un tuple contenant le tableau de connexions, la distance actuelle et la couleur actuelle associée à chaque nœud. Donc, au départ, tout va avoir une couleur blanche, une distance de 99, 99. Et toutes les connexions associées à chaque identifiant de héros lu à partir de ce fichier texte, à l'
exception de Spider-Man, qui sera gris avec une distance de 0. Bon, donc on a fait cette première affaire, ils sont piégés. Que se passe-t-il ensuite ? Donc maintenant, nous passons par cette itération, comme nous l'avons dit, et nous avons choisi dix est une limite supérieure arbitraire. Il s'avère que tu n'en as jamais. C' est en fait dix degrés de séparation dans ce jeu de données particulier qui est plus que suffisant. Nous imprimons le nombre d'itérations que nous avons passées. Donc, cela représente la distance que nous regardons de Spider-Man à cette étape. Et la première chose que nous faisons est de faire une opération de carte. Donc, nous appelons FlatMap sur BF en utilisant la fonction de carte BFS en utilisant cette itération RDD. Donc nous avons commencé je assis itération RDD à cet état initial. Nous appelons ensuite FlatMap sur l'itération RDD. Et FlatMap, comme vous vous en souviendrez, a le potentiel de créer de nouveaux nœuds, n'est-ce pas ? Voyons donc ce qui se passe dans la carte BFS. À faire. Il y a une carte BFS. Très bien, Donc fondamentalement, nous extrayons l'ID de caractère
et les données associées, et nous soufflons ces données aussi pour extraire le tableau de connexions, la distance et la couleur du noeud que nous regardons que nous mappons. Maintenant, comme il s'agit d'un FlatMap, nous pouvons retourner un tableau de nœuds BFS plus d'un si nous voulons ajouter à notre nouveau RDD. Et au fur et à mesure que nous allons, nous cherchons des nœuds gris à chaque fois, non ? Donc, les nœuds gris sont ceux qui doivent être explorés. Donc, si nous rencontrons un noeud gris, nous le traitons. Nous explorons toutes ses connexions et nous créons un nouveau nœud pour cette connexion. Donc, nous pourrions avoir un nouvel ID de caractère, une nouvelle distance, qui est la distance plus 1 d'eux. Sachez que nous avons commencé à partir
de, la nouvelle couleur sera grise. Et si c'est en fait le personnage que nous recherchons, si c'est Adam 3000, 31 ou quoi que ce soit,
alors on va incrémenter notre compteur de coups et dire, Hey, on a trouvé le gars, on a fini. On a trouvé un noeud où cette personne est connectée à Spiderman. Ensuite, nous créons un nouveau noeud basé sur la nouvelle distance dans nouvelle couleur que nous avons calculée et ajoutons cela à notre liste de résultats. Donc, nous avons créé tous ces nouveaux nœuds gris que nous devons explorer
à partir des connexions du gris savoir que nous venons de trouver. Et nous prenons le gris savoir que nous venons d'explorer et de le colorer en noir, indiquant que nous en avons fini avec. D' accord. On retourne juste les résultats et on a fini. Donc encore une fois, si vous ne comprenez pas l'algorithme BFS, ne vous accrochez pas trop. Ce n'est pas vraiment le but de ce cours, mais je voulais juste vous montrer ce que vous pouvez faire. Bon, donc on a fait l'opération de carte. Nous imprimons ensuite notre processus au fur et à mesure et nous
disons que nous avons traité autant de valeurs jusqu'à présent. Et si on a eu un coup, on va dire, Hey, on a trouvé le personnage qu'on cherche. Voici le total réel du nombre de hits que nous avons obtenus de cette itération. Il est donc possible que plus d'un exécuteur traite ce caractère en même temps. Et ils vous ont peut-être donné plusieurs coups
venant de différentes directions et c'est bon. On a le grand total imprimé ici. Si c'est le cas. Maintenant, avant d'itérer plus loin, nous devons combiner les données ensemble. Donc, nous avons peut-être généré de nouveaux nœuds pour le même ID de caractère que nous sommes allés. Donc, alors que nous avons exploré toutes ces connexions, nous pourrions avoir ramifié dans plusieurs directions différentes et
revenir et savoir que nous avons déjà traité, par exemple. Donc, pour gérer ce cas, nous devions faire une opération ReduceByKey. Le ReduceByKey regroupe toutes
les nouvelles notes qu'ils ont pu créer pour le même ID de caractère. Et le travail de la fonction réduite BFS dans la vie est juste de
préserver la distance minimale et la couleur la plus sombre dans ce cas. Donc c'est tout ce qui se passe ici. Je ne vais pas parcourir le code ici en détail parce que ce n'est pas important. Mais c'est le but de cette fonction juste pour gérer les cas où nous avons plus d'une connexion entrant dans le même nœud. Et dans ce cas, préservez la distance minimale et la couleur la plus sombre associée à ce nœud particulier. Donc oui, voyons si ça marche vraiment. Cliquez avec le bouton droit de la souris sur les degrés de séparation et exécutez-le. boulot assez compliqué, non ? Mais Spark peut en faire un court travail. On y va. Déjà si bien fait, nous avons effectivement traité 218 067 connexions là-bas. Mais nous avons constaté que même ce personnage obscur
n'est que deux degrés de séparation de Spider-Man. S' il s'avère que même les super-héros fictifs dans les bandes dessinées sont très bien connectés. Et cela est vrai dans le monde réel. Il s'avère que si vous regardez, vous savez, vrai réseau social comme LinkedIn ou IMDB est la base de données des
connexions des acteurs qui agissent ensemble dans le même film, vous obtenez des résultats similaires. Les gens sont beaucoup plus connectés que vous ne le pensez. C' est un peu intéressant. Alors regarde ça. Ça a marché. Encore une fois assez cool, c'est juste un exemple de la façon dont en
utilisant les fonctionnalités de niveau inférieur de Spark, vous pouvez parfois résoudre des problèmes pour lesquels vous ne pensiez pas que Spark était nécessairement adapté. Il ne s'agit pas seulement de résoudre les problèmes SQL. Tu peux faire plus de choses avec ça que ça. Alors rappelez-vous que vous avez ce pouvoir à votre disposition. Cela ne veut pas dire que je ne pouvais pas avoir encadré cela en termes de jeux de données et d'opérations SQL, vous pouvez, et nous l'avons fait. Examinons donc brièvement la version du jeu de données de ce script. Et ça fait des trucs assez bizarres. Donc, en essayant d'aimer faire MapReduce sans utiliser MapReduce, C'est possible. Ce ne sera pas efficace. Donc si on regarde ça, je ne vais pas entrer dans les détails du script ici, mais vous pouvez voir que nous faisons trucs assez alambiqués ici pour faire les mêmes choses que nous avons faites dans les scripts RDD. Donc, même la création de ces conditions initiales ici, juste une sorte de construction de cette structure de noeud finit par être cette opération compliquée de colonnes de largeur dans les fonctions
SQL pour essayer de répliquer ce que nous avons fait en utilisant, vous savez, le code Scala dans notre carte et réduire les fonctions. Et nous avons tous ces cas spéciaux pour notre personnage de départ. Nous devons essentiellement aimer faire ces filtres et rechercher dans l'ensemble du jeu de données à la recherche de ce cas particulier, au lieu de simplement le manipuler en ligne. Comme nous explorons chaque nœud, à la recherche de nœuds gris, nous devons faire une opération de filtrage et tout pour extraire ces nœuds gris. Sélectionnez les informations dont nous avons besoin. Filtrer à la recherche de l'ID de caractère cible que nous recherchons et gérer cela, en particulier. Donc ça fait la même chose. Eh bien, c'est du code compliqué que je préserve aussi la couleur la plus sombre, pour être juste, c'était assez compliqué dans notre code aussi, mais cela n'impliquait pas de faire une opération de jointure. Bon Seigneur. Et tout ce SQL vraiment fantaisie que ce sera probablement des opérations assez lourdes. Donc, même si nous pouvons, si nous pensons à cela assez dur, encadrer comme un problème SQL, ce n'est pas la façon la plus efficace d'y penser. Et juste pour prouver mon point de vue, faisons ça. Et nous compterons le nombre de secondes qu'il faut pour que cette version du script s'exécute une fois que Spark tourne. Alors on y va. 1, 2, 3, 4, 5, 6, 7. Ça a pris environ sept secondes pour obtenir cette réponse. On a la même réponse. Donc c'est bien. Ça a marché, mais ça a pris sept secondes pour obtenir cette réponse. En revanche, exécutons la version RDD de cela. Une à même pas trois secondes, non ? C' était donc en fait plus de deux fois plus rapide que la version du jeu de données. Encore une fois, il s'agit de choisir le bon outil pour le travail. Les jeux de données sont géniaux pour gérer les problèmes d'analyse de données traditionnels. Si vous pouvez facilement encadrer votre problème en termes de commande SQL, un jeu de données vous donnera probablement les meilleures performances. Mais si vous devez vraiment vous tenir sur votre tête pour essayer de cadrer ce que vous essayez de faire en termes de commandes SQL. Ça ne va pas bien se terminer, non ? Et parfois les RDD sont le meilleur outil. Donc, dans ce cas, en allant à un niveau inférieur en utilisant l'interface RDD de niveau inférieur de Spark, nous avons obtenu de meilleures performances qu'en utilisant l'API du jeu de données. Mais si nous faisions vraiment quelque chose qui était bien adapté à une commande de style SQL implémentant cela en utilisant des jeux de données. Et il y a des fonctions qui ressemblent beaucoup à des commandes SQL, permettent plus d'optimisations et seraient en fait plus rapides pour des problèmes comme ça. Et dans le monde réel, vous savez, c'est probablement le problème le plus courant que vous aurez avec Apache Spark. Habituellement, vous essayez de faire des choses comme répondre à des questions sur les données consignées entrant. Combien d'erreurs ai-je eu au cours du dernier mois ou quoi que ce soit ? Des choses comme ça. Les jeux de données sont géniaux. Mais si vous essayez de faire quelque chose à un niveau inférieur, oubliez pas que les RDD sont là pour vous aussi, et que vous avez cette fonctionnalité à votre disposition.
38. Filtrer collaboratif sur Spark, cache(), et persistez dans Spark(): Donc, comme un autre exemple intéressant de choses
compliquées que vous pouvez faire avec Spark que vous pourriez ne pas avoir pensé que vous pourriez faire avec Spark. Parlons du filtrage collaboratif basé sur les éléments. Il s'agit essentiellement d'un algorithme de moteur de recommandation. C' est la façon dont Amazon avait l'habitude de faire des choses comme les personnes qui acheté ont également acheté ou vous recommander des choses en fonction de vos achats passés. L' idée de haut niveau est que nous pouvons jeter un oeil à ce que vous avez acheté dans le passé, chercher des articles similaires à ceux que vous avez achetés et ensuite nous recommander ces articles, choses qui pourraient vous intéresser. Et nous allons le faire dans le contexte des films utilisant le jeu de données MovieLens. Donc, la chose fondamentale dont nous avons besoin est une mesure de films qui sont similaires les uns aux autres en fonction des évaluations des utilisateurs. C' est ce qu'on va faire ici. Et pendant que nous y sommes, nous allons également introduire le concept de mise en cache de vos ensembles de données pour améliorer les performances. Si des films similaires, c'est une petite capture d'écran et une plus ancienne des sites de GroupLens. Donc, ils ont en fait une interface utilisateur où vous pouvez évaluer les films, leur
dire explicitement les mouvements que la lumière UV, et il vous recommandera de nouveaux films en fonction de ces évaluations. Donc, une façon de le faire est de jeter un oeil à tous les films que vous avez aimé. Et pour tous ces films, regardez les films similaires à ces films. Et ces similitudes seront basées sur d'autres utilisateurs qui aiment les mêmes films que vous aimez. D' accord ? Donc l'algorithme de base ici est que nous allons commencer par trouver chaque paire de films qui ont été regardés par la même personne. Notre objectif ici est de trouver tous les films qui sont semblables à tous les autres films. D' accord ? Pour ce faire, nous allons d'abord décomposer chaque paire de films qui ont été lavés par les mêmes personnes. Donc, si l'utilisateur a et l'utilisateur B ont tous les deux regardé le film et l'ont aimé, ce serait une paire de films. Maintenant, nous pouvons alors rassembler tous les utilisateurs qui aiment ces paires de films et mesurer la similitude de leurs notes parmi tous ceux qui ont regardé ces deux films. Donc, en fonction de chaque utilisateur qui a regardé cette paire de films et l'a aimé, quel point ces films sont-ils similaires en termes de notes ? Ensuite, nous pouvons les regrouper tous par l'ID du film, les
trier en fonction de leur force de similitude. C' est quelque chose que nous calculons sur la base de ces évaluations. Et puis nous avons une liste triée de films qui sont similaires à tous les autres films juste par ce simple algorithme. Donc, c'est juste une façon de le faire. Attention à toi. Il y a beaucoup d'autres techniques là-bas aussi, mais celle-ci est simple et parfois aussi simple que mieux. Il produit de bons résultats si vous avez suffisamment de données. Laissez-moi vous accompagner à travers l'algorithme et plus d'une manière graphique ici. Alors imaginez que N ici regardait à la fois Star Wars et The Empire Strikes Back, qui est le SQL à Star Wars, signifiait que vous les aimez tous les deux. Et puis Bob ici, le gars avec un mohawk, regardait
aussi Star Wars et The Empire Strikes Back et les aimait tous les deux. Donc, d'après ces informations, nous pouvons dire que nous avons une paire de films ici, Star Wars et The Empire Strikes Back. Et ils avaient tous les deux ces deux utilisateurs en commun qui les aimaient tous les deux. Donc pour cette paire, nous savons que l'utilisateur et l'utilisateur Bob
les aiment tous les deux et imaginons qu'ils leur ont donné cinq étoiles. Donc, sur cette base, nous pouvons calculer que ce sont des films
très similaires basés sur ce comportement d'évaluation utilisateur. Des trois personnes de notre jeu de données. Deux d'entre eux ont adoré cette paire de films, non ? Donc, cela donnerait un très bon score de similitude. Cependant, nous pourrions choisir de mesurer cela. Imaginons que Ted arrive en bas et qu'il a seulement regardé The Empire Strikes Back. Peut-être qu'il vient d'emménager ici et vient d'un pays où Star Wars n'est pas une grande chose. C' est bon. Mais d'une manière ou d'une autre, il ne sait pas que le premier film, Star Wars, a New Hope existait réellement. Alors, comment lui recommander ce qu'il pourrait être
intéressé à regarder d'autre en se basant sur les informations que nous avons ici. On peut dire, ok, on connaît Ted, tu aimais Empire Strikes Back. Et nous savons d'après nos calculs précédents que le film le plus similaire,
The Empire Strikes Back est Star Wars a New Hope, le premier film ? Et encore une fois, cette similitude était basée sur le comportement de notation des autres utilisateurs dans notre jeu de données. Donc c'est tout à un niveau élevé. Fondamentalement, nous pouvons recommander des films similaires aux films que vous avez aimés en fonction du comportement d'évaluation des autres personnes de notre jeu de données. Et c'est un filtrage collaboratif basé sur des articles en bref. Donc finalement, ça recommande un bon film à Ted qu'il ne savait peut-être pas avant. Maintenant, nous allons nous concentrer ici dans cette activité sur la partie similarité du film. Donc, nous ne ferons pas vraiment de recommandations complètes pour les gens, mais nous allons calculer cet ensemble de données de similitudes cinématographiques. Quels films sont similaires aux autres films en fonction du comportement de l'utilisateur. C' est le plus dur, non ? Parce qu'une fois que vous avez ces données, vous pouvez faire des recommandations aux gens très rapidement en fonction de ce qu'ils ont aimé auparavant. Alors vous pourriez vous dire, comment diable pouvons-nous faire ça à Spark ? Spark est un peu construit autour d'un paradigme SQL de nos jours, ou peut-être d'un MapReduce au mieux. Comment encadrez-vous cela comme un problème qui s'intègre dans cadre et quelque chose
que vous pouvez paralléliser. Eh bien, tu peux, tu dois juste y penser de façon créative. Et encore une fois, vous savez, être capable de penser à ces problèmes d'une manière créative est ce qu'ils vous payent le gros argent. C' est donc un exemple de la façon dont vous pouvez utiliser cette technologie pour résoudre un problème auquel vous n'auriez peut-être pas pensé qu'elle convenait. Voici l'algorithme général que nous allons utiliser dans notre exemple Spark. Nous allons donc commencer par sélectionner les ID utilisateur, les ID
vidéo et les évaluations. Dans cet exemple, nous ne nous soucions pas vraiment des temps, bien que vous puissiez imaginer un monde où vous utilisez également cette information. Nous trouvons ensuite chaque paire de films qui a été évaluée par le même utilisateur. Et cela peut sembler une chose difficile à faire, mais il s'avère avec une opération auto-adjointe, ce qui est beaucoup une sorte de chose à faire de base de données. C' est exactement ce que ça vous donnera. Fondamentalement, vous prenez l'ensemble des colonnes de film
utilisateur et de notation et rejoignez cela sur lui-même en fonction de l'ID utilisateur. Et cela vous donnera toutes les paires possibles de films qui ont été évalués par la même personne. Donc, à ce stade, nous pouvons recadrer notre jeu de données auto-joint pour avoir un
film, un film à une note et lire deux colonnes qui nous
diront les paires de films et les évaluations associées à chacun. Et encore une fois, à ce stade, cela sera fait pour chaque utilisateur unique qui a évalué ces deux films ensemble. Nous pouvons ensuite passer à travers et filtrer pendant que nous y sommes toutes les paires en double, parce qu'une note de film un pour déplacer les deux est la même chose que film à film un. Donc, nous aurons un peu heuristique là-dedans pour nous assurer que nous ne saisissons qu'une de ces deux variations. Une fois que nous avons cela, nous pouvons parcourir chaque utilisateur qui a évalué cette paire de films et calculer le score de similitude cosinus en fonction de cette information. Je ne veux pas entrer dans les maths de cela parce que ce n'est pas vraiment pertinent pour le développement d'Apache Spark. Mais si vous êtes curieux de savoir comment fonctionne la similitude cosinus, je, il y a un autre cours que j'ai sur systèmes de
recommandation qui pénètre plus en profondeur sur elle. Mais à un niveau élevé, si vous jetez un oeil à toutes les évaluations d'un film, vous pouvez considérer cela comme une sorte de vecteur multidimensionnel. Et un score de similarité de cosinus serait essentiellement l'angle entre deux vecteurs pour deux films différents basés sur les évaluations des utilisateurs qu'ils ont en commun. Donc, une fois que nous avons cela, nous pouvons tout regrouper par le film un, filmer deux paires et nous assurer que nous agrégons tout ensemble pour une paire de films donnée, calcul qui est la similitude cosinus entre tous les utilisateurs qui ont évalué cette paire de films. Donc, à ce stade, nous avons un jeu de données qui contient tous les appariement possibles de films et le score de similitude entre ces paires de films. Nous pouvons alors simplement filtrer et trier et afficher les résultats. Nous pouvons donc les regrouper en fonction de chaque ID de film individuel, filtrer les choses qui sont en dessous d'une
sorte de seuil de similitude pour nous assurer que nous ne saisissons que de fortes similitudes et les
trions en fonction de ce score de similarité et afficher les résultats finaux. Et cela nous donnera finalement le score de similitude d'un film donné à n'importe quel autre film. Donc, avant de plonger dans le code, permettez-moi d'introduire l'idée de mettre en cache des jeux de données parce que cela va arriver dans cet exemple. Souvent, lorsque vous faites des choses compliquées comme celle-ci, vous finissez par interroger ou utiliser un jeu de données plus d'une fois. Et si vous vous trouvez à faire cela, vous devriez explicitement le mettre en cache si vous le pouvez. Sinon, il y a une chance que déclenché finisse par réévaluer l'ensemble de données une seconde fois, juste pour faire cette deuxième opération dessus. Et si vous voulez vous assurer que cela ne se produit pas, vous pouvez utiliser le point cash sur un jeu de données une fois que vous avez terminé calculer pour vous assurer qu'il reste en mémoire. Toutes les opérations ou analyses ultérieures effectuées sur
ce jeu de données se produisent le plus rapidement possible. Il y a aussi ne persiste pas. Persist vous permettra éventuellement d'attraper que non seulement une mémoire, mais aussi sur le disque. Donc, si un nœud échoue ou quelque chose, vous pouvez récupérer à partir de ce point et juste reprendre là où vous vous êtes arrêté. Donc, l'argent sera en mémoire, persiste peut éventuellement être persisté sur le disque ainsi. Et avec ça, sautons au code et voyons à quoi ça ressemble.
39. [Activité] exécutez le script Movies similaires avec le gestionnaire Cluster Manager: Bon, allons entrer dans le code ici pour calculer les similitudes de films en utilisant Spark. Ouvrez donc le script du jeu de données sur les similitudes vidéo ici. Et c'est un cas où l'utilisation d'un jeu de données surpasse l'utilisation d'un RDD. partie la plus compliquée de cet algorithme est cette opération d'auto-jointure, où nous avons essayé de trouver chaque paire unique de films ont été évalués par la même personne. Et c'est une chose très SQL à faire, non ? Une opération d'auto-jointure. Donc, cela s'intègre bien dans les idées d'utiliser un jeu de données dans Spark SQL. Il est également possible de le faire avec des RDD, mais dans ce cas, les jeux de données surpassent les RDD, ce qui est généralement le cas. Nous allons donc nous concentrer sur les jeux de données pour celui-ci. Si vous êtes morbide curieux de savoir comment faire cela avec des RDD, il y a un script de similarité de film ici disponible qui le fait simplement en utilisant des RDD à la place. Mais concentrons-nous sur les jeux de données. Alors qu'est-ce qu'on a ici ? Eh bien, nous commençons par importer tout ce dont nous avons besoin comme d'habitude. Et nous déclarons un objet de jeu de données de similitudes de film qui contient plusieurs classes de cas. Ceux-ci ont défini les différents formats de fichiers que nous allons lire et utiliser pour les jeux de données que nous utilisons tout au long de notre algorithme. Nous avons donc un jeu de données de films qui ne fait que refléter le format des données brutes que nous lisons. Il se compose d'un entier ID utilisateur, d'un entier ID vidéo ou d'un entier de notation, et d'un horodatage long. Nous allons également charger un jeu de données de noms de films afin que nous puissions très facilement afficher les noms lisibles par l'homme de l'ID de film donné. Ça va juste mapper les identifiants de films aux titres de films. Nous aurons également un ensemble de données sur les paires de films en cours de route, et cela incarne une paire unique de films. C' est une sorte de sortie de cette opération d'auto-jointure où nous obtenons chaque ensemble de film qui a été évalué par la même personne. Et cela comprendra à la fois le film un et les identifiants de
film à film et les évaluations associées à chacun de ces films d'un utilisateur donné. Ainsi, une ligne de paires de films sera composée d' une paire de films et de leurs évaluations par un seul utilisateur qui les a regardés tous les deux. ai eu. Et puis nous aurons aussi un jeu de données de similitude de film Paris moment donné qui contient une paire de films, un film 1, un film à une partition de similitude au format double précision, et le nombre de paires qui ont été associées à l'informatique qui est score de similarité. Cela va refléter le nombre d'utilisateurs réellement regardé cette paire de films et les ont cotés ensemble. Passons à la fonction principale et travaillons à partir de là. Nous commençons par définir notre niveau de journal et créer un objet SparkSession. Comme d'habitude. Nous créons ensuite un schéma de noms de films, qui sera utilisé plus tard pour structurer notre jeu de données afin de rechercher les ID de films vers les titres de films. Il dit simplement que notre ID de film sera un entier, et il aura un titre de film pour chaque ID de film qui est une chaîne. Nous allons alors déclarer un schéma pour les données, les données d'évaluation du film elles-mêmes aussi. Cela va avoir l'ID utilisateur, l'ID du film, l'évaluation et l'horodatage dans la structure que nous avons vu précédemment va alors charger ces noms de film. Dans un premier temps, nous importons des implicites, car nous
chargeons un DataFrame d'abord, puis nous le convertissons en un jeu de données. Donc, pour inférer implicitement le schéma d'un DataFrame, même si nous vous en fournissons un, vous devez toujours utiliser des implicites de point Spark pour cette étape. Donc, nous lui disons que fichier de données particulier, vous point point élément est séparé par un délimiteur de tuyau. Il est dans le tiret ISO 8859 un jeu de caractères. Et il utilise le schéma de nom de film que nous fournissons explicitement car il n'y a pas de ligne d'en-tête dans ce fichier que nous pouvons utiliser pour en déduire. Et quand nous en avons fini, nous le convertirons explicitement en jeu de données en utilisant la classe de cas de jeux mobiles pour encore meilleures performances sous Spark. Nous avons ensuite examiné les données de notation de film lui-même, encore une fois est un jeu de données. La même idée ici. Celui-ci est en fait séparé par des tabulations en utilisant le schéma de film que nous avons défini ci-dessus. Et nous allons convertir cela aussi en un jeu de données en utilisant la classe de cas de films. Donc, à ce stade, nous avons un jeu de données de noms de films et nous avons un jeu de données de films qui représente toutes les évaluations individuelles des utilisateurs. Nous sélectionnerons ensuite les informations dont nous nous soucions juste pour nous empêcher de transporter des informations dont nous n'avons pas besoin. Donc, notre ensemble de données d'évaluation sera maintenant seulement l'ID utilisateur, l'ID film et l'évaluation. Laissant de côté la colonne horodatage, parce que nous n'avons pas vraiment besoin de cette information pour ce que nous faisons ici. Maintenant, c'est là que ça devient intéressant. C' est cette opération d'auto-adhésion dont nous avons parlé auparavant. Donc on va avoir un jeu de données de film Paris. L' intention est ici de contenir chaque paire de films évalués par la même personne. Donc la façon dont nous faisons ça c'est d'abord, nous allons prendre notre jeu de données d'évaluation. Nous allons lui donner un alias de notations un pour que nous puissions y faire référence facilement. Et nous allons nous joindre à cela avec une autre copie
du jeu de données de rayon qui est appelé évaluations à. Donc, nous allons faire une jointure entre les notes 1 et les notes auxquelles sont vraiment la même chose. Ils pointent tous les deux vers le jeu de données d'évaluation. C' est pourquoi nous appelons ça une adhésion personnelle. Nous joignons le jeu de données d'évaluation sur lui-même, et nous le rejoindrons en fonction de la colonne ID utilisateur. Ok, Donc nous disons que nous allons rejoindre seulement si un ID utilisateur ou une évaluation correspond à l'ID utilisateur et aux évaluations. Cela aura donc pour effet de
jumeler tous les films qui ont été évalués par la même personne. ai eu. Vous devez comprendre comment fonctionnent les opérations de jointure dans SQL. Et ce n'est pas vraiment une classe SQL, mais le résultat est, c'est ce que vous obtenez de cette expression ici. Chaque paire de films qui ont été évalués par la même personne. Et en outre, pendant que nous y
sommes, nous allons imposer que l'ID du film pour les notes 1 sera inférieur à l'ID du film provenant des évaluations de. Et nous le faisons juste pour éviter les doublons. Donc, encore une fois, nous ne voulons pas avoir une entrée séparée pour les notes une couplée avec les lectures à, comme nous le ferions pour les évaluations avec les notes une. Donc, en faisant cela, nous nous assurons juste que nous ne capturons qu'un seul jumelage unique là. Une fois que nous avons cela, nous pouvons alors renommer les choses pour le rendre plus facile à utiliser. Nous allons donc renommer les notes d'un point d'ID de film en un film, les lectures d'aujourd'hui sur l'ID de film en deux films, notes quand je lis pour en lire un et les notes à point en lecture 2, écrire 2, encore une fois, juste pour le rendre plus facile à travailler avec. Et en outre, nous allons explicitement en faire un jeu de données en utilisant la classe de cas de paires de films que nous avons définie ci-dessus. Maintenant, nous avons à notre disposition ici ce jeu de données de paires de films qui peut douleurs paires de films et leurs évaluations pour chaque utilisateur unique qui a évalué cette paire de films. Compte tenu de cela, nous pouvons maintenant appeler la similarité de
cosinus de calcul pour construire notre jeu de données de similarités de film Paris qui
contiendra pour chaque paire de films comment ils sont similaires les uns aux autres en fonction de tous les utilisateurs qui ont évalué ces films ensemble. Donc, avant d'aller plus loin et de parler de cette opération de cache, voyons ce que fait la similarité de cosinus de calcul. C' est là-haut, quelque part. Il est là. Donc il y a un peu de maths fantaisie qui se passe ici. Je ne veux pas vraiment trop entrer dans la métrique de similarité cosinus elle-même parce que ce n'est pas vraiment quelque chose à voir avec la programmation Spark. Encore une fois, si vous voulez en savoir plus à ce sujet, vous pouvez consulter mon cours sur les systèmes de recommandation. Mais à un niveau élevé, nous créons trois nouvelles colonnes ici. Xx et XY. Cela va calculer x carré, y carré, et x,
y à partir de l'algorithme que nous utilisons pour calculer la similitude cosinus. Encore une fois, c'est juste fondamentalement
un, un angle entre deux vecteurs virtuels dans cet espace vidéo utilisateur. Nous pouvons ensuite calculer ces scores de similarité. En gros, nous utilisons ce nouveau jeu de données appelé scores de Paris. Il a ces termes supplémentaires, il y est annexé. Et puis nous appelons egg pour agréger ensemble toutes les entrées pour chaque paire de films donnée, ils utilisent l'expression suivante. Donc, pour toutes les paires de films, pour tous les utilisateurs à coté ces deux films ensemble. On va les voir tous avec cette fonction agg. Et nous allons résumer les colonnes X, Y et appeler ça le numérateur. Ça va juste être le numérateur de notre expression pour calculer la similitude cosinus. Et puis pour le dénominateur qui vous
achemine que le premier dénominateur qui finira par être la racine carrée de la somme de la colonne XX et racine carrée de la somme de la colonne
y, y ajouté ensemble. Et enfin, nous aurons les non-paires, qui va juste compter combien de la colonne x y existe. C' est juste un raccourci pour savoir
combien d' utilisateurs ont évalué cette paire de films ensemble. Et c'est l'information dont nous avons besoin pour calculer le score de similitude réel, qui est ce qui va atterrir dans ce jeu de données de résultat ici, nous ajoutons juste une nouvelle colonne de score à cela également. Et ce que nous faisons, c'est d'abord nous assurer que nous ne allons pas diviser par 0. Nous vérifions explicitement pour nous assurer que le dénominateur n'est pas 0. Sinon, nous avons juste un résultat nul là. Sinon, nous divisons simplement le numérateur par le dénominateur. Et à ce stade, nous avons notre score de similitude réelle calculé sur la base de la métrique de similarité cosinus. Ensuite, nous nous contentons de réduire cela aux colonnes qui nous intéressent, qui vont être film un et film à la partition de similitude entre eux et le nombre de paires supportant cette partition. Et nous allons forcer cela dans un jeu de données aussi en utilisant la classe de cas de similarité de paires de films ci-dessus et retourner le jeu de données de résultat, qui à nouveau contient juste un film à marquer et des non-paires qui, accord, retour à où cela a été appelé. Nous avons donc maintenant ce jeu de données de tous les scores de similitude entre chaque paire unique de films. Et nous allons probablement l'utiliser plus d'une fois. Alors allons de l'avant et cache cela pour que nous ayons cela en mémoire à portée de main. Peu importe ce qu'on va en faire plus tard. Non seulement nous allons l'utiliser pour afficher nos résultats, mais vous pouvez imaginer que
nous pourrions en fait créer un système de filtrage collaboratif basé sur des éléments en gardant
ce jeu de données sur les similitudes de paires de films en mémoire. Nous pouvons alors prendre l'ensemble de tout ce que n'importe quel nouvel utilisateur a aimé ou exprimé son intérêt, ou bien noté, ce que vous voulez utiliser comme une indication d'intérêt, puis frapper ce film Paris état de similitude est réglé à très récupérer rapidement tous les films similaires aux films AP personne lumière. Donc, encore une fois, cela serait très important pour encaisser si vous construisiez un véritable système de recommandation ici. Mais tout ce qu'on va faire ici, c'est juste essayer d'obtenir les résultats des similitudes les plus importantes pour un film donné. Donc nous allons vérifier que nous passons une dispute ici. Donc, l'idée ici est que nous allons passer en argument à ce script, un ID de film auquel nous sommes intéressés à voir toutes les similitudes avec. Et de plus, nous allons fixer des seuils ici. Donc, nous allons dire qu'à moins qu'il n'y ait un score de similitude de 97% entre deux films, nous ne considérerons pas cela comme assez similaire pour être intéressant. Et nous dirons également que vous devez avoir au moins 50 utilisateurs en commun qui ont évalué ces deux choses ensemble. C' est donc une sorte de soutien minimum dont nous avons besoin pour avoir la certitude qu'il s'agit d'un résultat fiable. Vous ne voulez pas faire de recommandation basée sur ce que deux personnes ont dit. Idéalement, vous voulez beaucoup de gens qui sont d'accord les uns avec les autres pour vous donner un meilleur résultat. Donc ces seuils et un être important pour obtenir résultats de
qualité et ils sont plutôt arbitraires, mais nous reviendrons à cela. Donc nous allons appliquer ces filtres ici. Nous allons filtrer le jeu de données sur les similitudes du film Paris et le
filtrer non seulement pour appliquer ces seuils de score, en nous assurant que le score était supérieur à notre seuil de score scolaire. Et aucune paire n'est supérieure au seuil de début de co-occurrence. Mais nous allons aussi le filtrer vers le bas pour l'ID de film qui nous intéresse. Donc pour le film que nous avons passé en argument, c'est le film que nous voulons voir, des films similaires aussi. Nous appliquons donc que le film un est égal à l'ID du film ou le film deux est égal à l'ID du film. On ne sait pas vraiment si ça va être sur le film un ou le film à côté, ça pourrait être soit en fonction de l'ordre des ID de film, non ? Donc si l'un des films de la paire est celui qui nous intéresse. Nous allons faire avancer cela et nous allons
également vérifier que nos seuils de qualité sont également respectés. Une fois que nous aurons cela, nous allons trier ce descendant en fonction de cette colonne de partition pour obtenir les films les plus similaires à ce film et prendre le top 10. Donc, nous appellerions cela un top n recommandateur dans le langage du système de recommandation parce que nous
prenons les 10 meilleurs résultats en faisant que nos recommandations pour ce film. Et puis nous l'imprimons et nous disons juste d'obtenir les 10 meilleurs films similaires pour quel que soit le nom de ce film pour rendre ce film lisible par l'homme. Encore une fois, en utilisant ce jeu de données de noms de films que nous avons chargé il y
a longtemps pour cet ID de film. Et pour chaque résultat unique que nous obtenons, nous l'itérons et nous extrayons ces films similaires en fonction ID de film qui n'est pas celui que nous avons transmis en paramètre. Imprimez ce résultat ainsi que son score et la force en fonction du nombre de paires qui supportent ce score. Qui ? Donc hé, on dirait que ça devrait marcher. Vous savez, c'était beaucoup à parler, mais si vous regardez le code pour tout ça, c'est vraiment pas beaucoup de code, non ? Ce n'est pas si mal que ça. Je veux dire, il y a des trucs funky qui se passent pour sûr. Ils NED, envelopper votre tête avec ces expressions plus compliquées ici comme cet agrégat ici ou l'opération auto-jointure. Mais une fois que vous avez dépassé ça, ce n'est pas beaucoup de code. Allons-y et lançons et voyons ce qui se passe avant de le lancer cependant, nous devons passer le paramètre de l'ID de film que nous voulons récupérer, n'est-ce pas ? Donc, pour ce faire, nous vous avons montré ce petit peu plus délicat et plus intelligent. Cliquez avec le bouton droit de la souris sur les similitudes de films et nous allons dire Créer des similitudes de films. Cela va créer une configuration d'exécution que nous pouvons configurer explicitement. Et cela a une fente ici pour les arguments du programme. Donc, vous pouvez mettre n'importe quelle carte d'identité de film que vous voulez ici pour n'importe quel film qui vous intéresse, disons 56, quoi que ce soit. Et on dira, d'accord. Et maintenant, nous avons la configuration de tournage de similitudes de films que nous venons de définir. Et on peut appuyer sur le bouton de lecture pour l'exécuter. Alors commençons ça et voyons ce se passe. Il s'en va. Nous avons chargé nos noms de films et maintenant il est hors de calculer ces similitudes. Et là, nous avons nos résultats. Donc c'est plutôt bon. C' était un peu de temps pour une opération très compliquée. Et faire une auto-jointure sur un grand jeu de données n'est pas un petit exploit, n'est-ce pas ? Et oui, on a retrouvé les meilleurs résultats pour Pulp Fiction. Il s'avère que c'est ce qu'est le film ID 56, et c'est un film gourmand. Et ça est revenu avec des films plus grosses. Donc, il semblait vraiment fonctionner. J' ai déjà vu de la fumée avant. Je n'aime pas vraiment la fission par traction, donc je ne suis pas sûr de vouloir regarder ça moi-même, mais Reservoir Dogs, Dani Brass, y va. La vraie romance. Ce sont tous des résultats raisonnables pour un film similaire à Pulp Fiction basé sur d'autres évaluations des utilisateurs. Donc là, vous l'avez. Si vous alliez construire des gens qui ont aimé ce film aussi aimé sur Netflix ou quelque chose comme ça. Vous savez maintenant comment faire cela et vous pouvez réellement mettre à l'échelle cela en utilisant Apache Spark pour gérer un grand nombre de notes ou un grand nombre de films. Parce que vous pouvez lancer un cluster entier à cela maintenant. Donc là, vous l'avez. Un exemple de similitudes de films et de filtrage collaboratif basé sur des éléments, au moins la première moitié de celui-ci en utilisant Apache Spark. Et comme vous le verrez plus loin, Il y a en fait une fonction intégrée dans la bibliothèque d'apprentissage automatique pour Apache Spark qui fait quelque chose de similaire, mais qui ne génère pas de résultats aussi bons avec le jeu de données MovieLens. Donc, parfois, simplement utiliser les outils prêts à l'emploi n'est pas assez bon et vous devez revenir en arrière et
devenir inventif et implémenterde devenir inventif et implémenter nouveaux algorithmes en utilisant Spark qui n'ont peut-être pas été vus auparavant dans Spark, encore une fois, que c'est ce qu'ils vont payer les gros dollars pour les mecs. Mais c'est un bon exemple et nous allons terminer là-dessus. Mais avant qu'on ne le fasse, je vais vous défier de faire mieux. Parlons de ça dans notre prochaine conférence.
40. [Exercice Améliorer la qualité de films similaires: Il s'avère donc que les similitudes cinématographiques sont un peu proches et chers à mon cœur pour quelques raisons. Tout d'abord, la plupart de ce que j'ai fait pendant mon travail chez Amazon.com était travailler dans le domaine du filtrage collaboratif et de leurs systèmes de recommandation d'utilisateurs. J' ai passé beaucoup de temps à essayer d'améliorer ces systèmes là-bas. Et c'était amusant. Il, c'est vraiment un travail intéressant aussi j'ai couru IMDB pendant un certain temps. C' est une sorte de croisement entre le filtrage collaboratif et films qui envahissent beaucoup de mes cours. Donc, mon défi pour vous est d'améliorer les résultats. Et il n'y a vraiment pas de bonne ou de mauvaise réponse à ça, pas vrai. La chose avec les recommandations est qu'elles sont souvent de nature plutôt qualitative. Je veux dire, vous pouvez les mesurer en fonction de la façon dont les gens réagissent à eux dans le monde réel. Mais à la fin de la journée, vous devez juger par vous-même s'ils sont bons ou pas. Donc, ma recommandation voit ce que j'ai fait là-bas. Recommandation, ma recommandation est d'aller trouver un film qui vous passionne et de trouver que dans la recherche MovieLens Dataset, c'est l'ID du film. Et s'il y a un film que vous connaissez vraiment, vous aurez une bonne idée intuitive des bons films similaires à ce film. Alors commencez par exécuter le script que nous venons d'avoir pour cet identifiant de film que vous connaissez et aimez si bien. Et jugez par vous-même si ce sont bonnes recommandations et réfléchissez à comment elles pourraient être meilleures ? Voici donc quelques idées de choses
que vous pouvez faire pour modifier ce script pour améliorer encore la qualité de ces recommandations, une idée serait de simplement ignorer toutes les mauvaises évaluations. Donc, si quelqu'un écrit un film une ou deux étoiles, voulons-nous vraiment que cela influence notre mesure de la similitude du film ? Une sorte de piège de cet algorithme est que les films qui sont similaires en termes de tout le monde les détestait continueraient à apparaître comme des films similaires. Donc, ce n'est pas nécessairement une bonne chose si vous essayez de recommander bons films à tirer qu'ils pourraient vouloir regarder. Donc c'est une idée. Juste introduit un autre filtre qui se débarrasse de toutes les mauvaises notes dès le début et voir quelle différence qui a sur le résultat. Vous pouvez également essayer différentes mesures de similarité. Vous devriez les chercher en ce moment, raison similarité cosinus, mais il y a d'autres mesures là-bas aussi bien que le coefficient de corrélation de Pearson,
le coefficient de Jaccard, ou tout simplement la probabilité conditionnelle. Donc, vous pourriez vouloir les rechercher et essayer d'implémenter cela au lieu de la métrique cosinus et voir si cela fait mieux ou pire. Vous pouvez également jouer avec ces seuils et c'est probablement la chose la plus facile à faire. Peut-être que vous devriez avoir plus de conservateurs minimum ou un score minimum plus élevé pour entrer dans la coupe finale. Cela aura un compromis ou une couverture, vous savez,
si vous avez des films plus obscurs, vous pourriez ne pas avoir assez de données pour faire une recommandation si vous définissez ces seuils trop élevés. Ou vous pouvez inventer votre propre nouvelle
mesure de similarité qui prend en compte un certain nombre de coopérants. Alors peut-être que le nombre de personnes qui ont regardé la paire de films est en soi une indication de la qualité de ces films. Peut-être juste le fait qu'ils sont populaires. Et beaucoup de gens les ont vus tous les deux est quelque chose que vous devriez prendre en compte. Alors peut-être que vous pouvez normaliser cela d'une manière ou d'une autre et introduire cela dans votre métrique de similitude. Et si vous voulez vraiment atteindre ambitieux, vous pouvez même extraire des informations de genre à partir du fichier de données des points UE et du jeu de données MovieLens qui contient un tableau de zéros et de ceux qui indiquent à quels genres et films appartiennent. Et peut-être pourriez-vous filtrer les films qui sont dans différents genres ou augmenter les partitions de similitude des films qui ont beaucoup de genres en commun. Donc quelques idées générales là-bas et comment vous pourriez améliorer les résultats. Encore une fois, il n'y a pas de bonne réponse ici. Je ne peux pas vous montrer la bonne réponse à cette activité. Je veux juste que tu ailles jouer avec et voir si tu peux améliorer les résultats. Et si vous le faites, je serais très curieux d'entendre ce que vous avez fait, soit dans les commentaires, soit dans le Q et un ou tout autre mécanisme que la plate-forme sur laquelle vous regardez ce cours vous donne pour fournir des commentaires. Donc avoir à elle, c'est en fait une activité amusante et un très important pour beaucoup de commerce électronique dépend de faire des recommandations. Donc, si tu peux apprendre à faire ça, c'est une bonne chose. Va jouer avec ça. Et puis nous reviendrons dans la section suivante et parlerons de la mise à l'échelle des choses.
41. [Activité Utiliser spark-submit pour exécuter des scripts pilote Spark: Jusqu' à présent, dans ce cours, nous avons développé sur votre PC de bureau local parce que, eh bien, c'est pas cher et facile, non ? Je ne veux pas dépenser un tas d'argent que vous apprenez cela nécessairement, mais il est temps d'augmenter les choses. Donc, dans cette prochaine section, nous allons parler de l'exécution de Spark sur un vrai cluster B appartenant à un cluster appartenant à
votre accompagnateur ou d'un cluster que vous pourriez louer sur un service comme Amazon Web Services. Il y a quelques considérations particulières lorsque vous
écrivez vos scripts de pilotes pour une utilisation sur un cluster. Et certaines façons que vous allez déployer votre code et empaqueter votre code et exécuter votre code quand il est sur un cluster réel. Nous allons donc entrer dans ces détails et cela devrait vous armer avec les connaissances
dont vous avez besoin pour réellement utiliser Spark dans un environnement de production réel à grande échelle. Jusqu' à présent, dans le cadre de ce cours, nous avons exécuté nos applications Spark sur notre ordinateur de bureau dans l'environnement de renseignement. Et tout cela est bien et bon pour le développement. Mais si vous voulez réellement exécuter une application Spark dans le monde réel, vous allez probablement le déployer un cluster quelque part et pas dans IntelliJ a, vous allez vouloir être en mesure de déclencher cela à partir de une sorte de travail Cron ou une sorte de système de
gestion qui va déclencher votre application Scala sur une sorte de calendrier, n'est-ce pas ? Alors comment on fait ça ? Eh bien, commençons par parler de comment empaqueter et déployer
votre application et l'exécuter à partir de
l'extérieur de l'intelligence et juste à partir d'une ligne de commande quelque part. Donc, dans le monde réel, sur un cluster exécutera nos scripts avec quelque chose appelé Spark dash submit. Ainsi, lorsque vous installez Apache Spark, il est livré avec une application appelée Spark submit. Et son travail est de lire dans un fichier jar qui contient votre application Spark compilée et de le distribuer à l'ensemble de votre cluster pour être exécuté. Et il peut faire tout cela en dehors de l'intelligence. Tout est complètement autonome. Maintenant, avant de le faire, il y a des choses dont vous devez vous assurer. Tout d'abord, assurez-vous que vous n'avez pas laissé de chemin vers votre système de fichiers local à l'intérieur de votre script, n'est-ce pas ? Donc, sur nos exemples jusqu'à présent, nous avons fait référence à des fichiers qui existent sur notre système de fichiers local sur un chemin relatif à partir de l'endroit où se trouve notre projet. Maintenant, dans le monde réel, vous voulez vous assurer que vos fichiers de données sont accessibles à n'importe quel nœud de votre cluster qui exécute votre application, n'est-ce pas ? Donc, de manière générale, vos données seront déployées comme une sorte de système de fichiers partagé. Peut-être que c'est HDFS, peut-être que c'est Amazon S3, quelque chose, mais ce ne sera pas le système de fichiers local. Parce que lorsque vous distribuez ce code, ce système de fichiers local ne sera pas nécessairement disponible pour vous. Donc, tout d'abord, assurez-vous que tous les fichiers passés sont utilisés un système de fichiers distribué ou au moins dans un fichier
accessible où que votre script soit exécuté. Ensuite, nous allons emballer notre projet Scala dans un fichier jar d'une manière ou d'une autre. Et il y a quelques façons de le faire. Pour l'instant, nous allons commencer en ajoutant simplement un artefact jar dans l'intelligence pour réellement exporter notre code d'application réel dans un fichier jar. Cela a cependant des limites, si vous avez des dépendances dans votre script au-delà des bibliothèques Spark stock, cela va être un problème que nous devons réfléchir à la façon de distribuer ces dépendances. Et plus tard, nous parlerons d'utiliser SBT pour le faire. On a fait ça depuis le début. Tu ne le savais pas. Et une fois que nous avons un fichier JAR, nous pouvons utiliser Spark pour demander à soumettre d'exécuter ce script de pilote en dehors de l'IDE. Le format est assez simple. Il suffit de taper Spark pointillé, soumettre, tiret, classe de
tiret, quel que soit le nom de votre classe que vous voulez exécuter qui a votre fonction principale. Si vous avez des dépendances pour d'autres fichiers JAR, vous pouvez utiliser tiret, dash jar est de spécifier où ils peuvent être trouvés. Et vous pouvez également utiliser des fichiers tirets, tirets pour placer automatiquement des fichiers à côté de votre application. Donc, pour les petits fichiers qui peuvent être de petits fichiers de recherche ou quelque chose comme ça, vous pouvez vous en sortir avec l'utilisation de fichiers de tiret pour cela. Et enfin, le chemin d'accès au fichier JAR lui-même qui contient le code que vous voulez exécuter. Donc, avec cela, essayons, va réellement exécuter notre exemple de bonjour monde en remontant au début
du cours en utilisant Spark Dash soumettre en dehors de l'intelligence. Alors je vais vous expliquer comment faire ça. Donc, avant de pouvoir essayer d'exécuter notre application Spark en dehors de l'intelligence, abord, nous avons besoin d'un environnement Spark pour l'exécuter dans. Donc, nous allons en quelque sorte mettre en place un environnement Spark autonome sur notre PC de bureau ici, qui simulera le même environnement que nous pourrions avoir lorsque nous exécutons ceci sur un serveur dans le cloud quelque part. Alors ouvrons notre navigateur Web et dirigez-vous vers Spark dot apache.org. Et c'est là que vous allez télécharger la dernière version d'Apache Spark lui-même. Vous aurez également besoin de 7-Zip si vous êtes sur Windows ou un utilitaire qui peut décompresser les fichiers tar.gz. Donc d'accord, donc si vous êtes sur Windows et que vous n'avez pas déjà un utilitaire qui vous permet de décompresser un fichier dot tar.gz. Je recommande d'installer 7-Zip pour prendre soin de cela en premier. Revenons à Apache Spark. Eh bien, allez à Download Spark, et nous utilisons Spark 3 dans ce cours ici. Donc je vais choisir cette étincelle libérée pour l'instant. Et nous voulons la version pré-construite pour Apache Hadoop 2.7 ou quoi que ce soit. Et nous allons appuyer sur Download Spark 3 utilisera le site miroir suggéré et attendez que cela descend. C' est seulement environ 200 mégaoctets, donc cela ne prendra que quelques secondes ici. Une fois cela fait, nous utiliserons 7-Zip sous Windows pour le décompresser. Ou si vous êtes sur Mac ou Linux, vous pouvez simplement aller à votre ligne de commande et dire, vous savez,
le zip GAN habituel, puis tar dash X,
vf, quelle que soit la commande dont vous avez besoin pour décompresser cela. Je suis sûr que vous êtes déjà familier avec les fichiers T, G, C si vous êtes sur Mac ou Linux. On dirait que c'est téléchargé. Alors allons dans notre dossier de téléchargements et jetons un coup d'oeil. Depuis que j'ai installé 7-Zip, je peux juste faire un clic droit dessus et aller à 7 Zip et dire extrait. Et je crois, euh, comment le refaire ? Oui. Donc, qui a extrait le fichier zip G dans un fichier tar. Ce fichier tar et son tour doivent également être décompressés. Et ici, nous devrions avoir Spark lui-même. Je vais pré-compilé pour nous. Il est construit en utilisant Java, donc c'est en fait une plate-forme indépendante. Donc, nous pouvons nous en sortir avec frontalement sur Windows pour la plupart. Comme vous le verrez, il y a des problèmes. Alors allons de l'avant et contrôlez un et copiez tout cela. Contrôle C. Et je vais aller à mon lecteur C et créer un nouveau dossier appelé Spark et l'ouvrir et le copier et le coller là plutôt. Et si vous êtes sur Mac ou Linux, bien
sûr, vous le feriez simplement en utilisant make dir et la commande cp pour copier ces fichiers là où vous les voulez. Assurez-vous de vous rappeler où vous les avez mis. D' accord, donc nous avons déclenché 3 installé. Ce n'était pas dur, non ? Donc, nous allons réellement créer un fichier JAR et voir si nous pouvons l'exécuter en utilisant cette nouvelle version de Spark que nous avons installée. Revenons à Intel J. Voyons ici. Donc ce qu'on va faire, c'est aller à File et dire la structure du projet. Et on va aller sur les artefacts et cliquer sur le signe plus. Et nous dirons « pot ». Et nous commencerons par un bocal vide. D' abord, donnons-lui un nom. Appelons ça déclenché bien sûr. Et nous devons lui dire ce que nous voulons mettre dans ce bocal. Alors ouvrons ce répertoire de cours Scala éveillé ici. Et vous pouvez voir qu'il y a toutes les dépendances que nous avons importées de Spark lui-même dans le journal pour J et tout ce dont cela dépend. Mais comme nous avons déjà un environnement Spark installé, nous n'avons pas besoin d'empaqueter toutes ces dépendances. Nous avons juste besoin du code pour notre script lui-même. Et cela va vivre dans ces étincelles de gala compiler la sortie. Donc ce sera le bytecode compilé de notre code, le truc réel sous com dot logiciel dot Spark. Alors allons de l'avant et double-cliquez dessus. Et nous l'avons ajouté à notre fichier JAR. Nous allons également cliquer sur include et project construit pour nous assurer qu'il est réellement créé. Et on va cliquer sur OK. Et nous allons cliquer à nouveau sur l'icône Construire pour le forcer à construire cela. Très bien, donc vous pouvez voir le long du chemin qu'il est construit, voir des étincelles, cours de
gala sur les artefacts, Spark Core, Spark course dot jar. C' est donc notre fichier JAR qui contient notre code. Allons le chercher. Si on va voir le cours de gala des étincelles. Il y a notre répertoire OUT, les artefacts, parcours
Spark, et il y a le pot de point étincelle. Donc 399 kilo-octets. Cela semble être à propos de la bonne taille pour tous les compilés par code dans notre projet entier ici. Cela inclut donc toutes les classes que nous avons ici. Allons-y et commençons et voyons si on peut l'utiliser. Maintenant, comme je l'ai dit, vous devez vous assurer que tous les chemins de fichiers seront toujours valides. Donc, vous verrez dans le monde Hello, nous avons un chemin relatif ici pour les données slash m un à k slash u données point. Donc pour que cela fonctionne, je dois m'assurer que je cours ceci à partir du bon endroit où ce chemin sera accessible. Encore une fois, si c'était une vraie application sur un vrai cluster, je voudrais probablement m'assurer que les données étaient sur une
sorte de système de fichiers partagé à la place. Mais pour des raisons d'illustration, en cours d'exécution sur notre bureau ici, nous allons le garder comme ça. Ouvrons une invite de commande. Et encore une fois, sur Mac ou Linux, vous utilisez simplement une invite de terminal. Accédez à notre dossier Matériel de cours. Donc pour moi cette barre oblique inverse du côlon étincelle Scala cours Slash Spark Scala cours. Et à partir d'ici, nous avons ce chemin de données relatif à notre disposition. Donc c'est bien. Alors maintenant, exécutons réellement ces commandes de ask submit déclenchées à partir de notre environnement autonome de Spark que nous avons installé. Donc, si vous vous souvenez pour moi, c'était la barre oblique inverse du côlon Spark slash bin slash Spark pointillée, soumettre. La prochaine chose que nous devons transmettre est le nom de la classe que nous voulons exécuter. Et donc nous allons dire Dash, Dash class, com, logiciel de chiens
Dotson, point spark dot bonjour, monde. Et maintenant, nous devons lui donner le chemin d'accès
au fichier JAR réel que nous voulons soumettre à Spark soumettre. Et ce sera pour moi C colon backslash, étincelle Scala Slash cours Spark Scala slash. C' était des artefacts, parcours
Spark, un pot de départ Spark Core. Ok, donc ça devrait marcher. Ce qu'il va faire à nouveau est de prendre ce fichier JAR de mon compilé par code et de le passer dans Spark lui-même en utilisant Spark Dash submit. Il cherchera le nom de classe que j'ai spécifié et essaiera de l'exécuter. Et encore une fois, si nous étions sur une vraie grappe ici, estimation
déclenchée donnerait tout coup d'envoi. Il distribuerait ce code sur l'ensemble du cluster. Lancez notre gestionnaire de cluster, faites tout ce dont il a besoin pour le distribuer et assurez-vous qu'il fonctionne correctement. Alors appuyez sur Entrée et voyons ce qui se passe. Encore une fois, notez que nous sommes en dehors de intelligent entièrement ici nous utilisons un environnement Spark autonome entièrement différent. C' est tout à fait analogue à ce que vous feriez dans le monde réel. D' accord, donc nous avons des messages d'erreur effrayants, mais ignorez ça pour le moment. Si vous regardez en haut, nous avons obtenu notre sortie. Donc, il est dit Hello World, le fichier de données a 100 mille lignes. Ça a vraiment fonctionné. C'est génial. Maintenant, ne faites pas attention à ces messages d'erreur. Je sais que cela semble vraiment ondulé à la main, mais c'est en fait un bug spécifique à Windows dans Scala lui-même qui a été autour pour toujours. Il y a un problème avec
les autorisations de fichier en fait sur les répertoires temporaires que Spark utilise sous Windows. Et c'est de ça qu'il se plaint. Dans le monde réel. Personne n'exécute vraiment les travaux de production Spark sur Windows, donc personne n'a jamais pris la peine de résoudre ce problème. Donc on va juste l'ignorer pour l'instant. Si vous faites cela sous Linux, vous ne verrez pas qu'en agrandissant, vous exécuterez des tâches Spark sur Linux dans le monde réel, mais le processus sera le même. Vous utiliserez toujours l'estimation déclenchée pour le lancer, même si vous êtes sur un cluster géant, la seule différence est qu'il s'exécutera et vous n'obtiendrez pas ces messages d'erreur bizarres sur les autorisations de fichier lorsque vous avez terminé. Donc là, vous l'avez réellement en utilisant Spark dash soumettre dans une marque chinoise fessée nouvel environnement Spark en utilisant Spark trois, utilisant notre bytecode compilé que nous avons généré à partir d'Intel J. Mais nous ne sommes pas réellement en cours d'exécution dans l'intelligence plus. Donc, où nous avons réellement dépassé les limites de notre IDE, ce qui est important pour les déploiements réels.
42. [Activité] des scripts pilotes avec SBT: Ce ne serait pas génial si nous pouvions empaqueter tout ce dont nous avons besoin, toutes nos dépendances et tout dans un seul fichier JAR et simplement le distribuer au nœud maître de notre cluster et le lancer. Eh bien, c'est ce que SBT ou l'outil de construction simple vous permet de faire. Parlons donc de SBT plus en profondeur et comment nous pouvons emballer votre script et toutes ses dépendances ensemble en l'utilisant. Donc, si vous êtes familier avec Java, vous pourriez être familier avec Maven. Vous pouvez penser que SBT est comme Maven pour Scala. Et ce qu'il fait est de gérer votre arbre de dépendance des bibliothèques pour vous. Donc, si vous avez un script qui dépend d'une bibliothèque Scala ou Java, un fichier JAR, il sortira automatiquement et comprendra non seulement où obtenir cela, comment l'empaqueter dans votre fichier JAR ultime que vous compilez. Mais aussi toutes les dépendances à ce paquet ont trop souvent ces arbres compliqués de dépendances et ces fichiers JAR et tout paquet dont vous dépendrez dépend à son tour d'autres paquets, qui à leur tour peut dépendre d'autres paquets. Donc garder une trace de tout cela à la main est qu'il est hors de main assez rapidement, mais SBT va gérer cette complexité pour vous. Déterminez automatiquement les paquets dont vous avez besoin pour que tout fonctionne et réunissez-les pour vous et empaquez-les. Donc c'est vraiment ce que SBT a. Quatre, rend la vie beaucoup plus facile si vous avez beaucoup de dépendances ou si vous avez une bibliothèque qui a beaucoup de dépendances, c'est beaucoup plus facile que de suivre ces dépendances à la main. Et c'est beaucoup plus facile que de passer une tonne d'options au paramètre de ligne de commande de tiret, dash jars lorsque vous exécutez Spark submit. Donc, au lieu de passer un tas de dépendances
spécifiques sur la ligne de commande avec Spark submit. Nous pouvons les patcher tous dans le fichier jar lui-même afin que nous n'ayons pas
à nous souvenir réellement de ce qu'ils sont et réellement entrer cela sur la ligne de commande. Pour obtenir SVT C'est gratuit, c'est open source. Nous pouvons l'obtenir de Scala dash SBT.org, et nous allons vous le montrer bientôt. L' utiliser est assez simple. Vous avez juste à mettre en place une structure de répertoires qui ressemble à ceci. Donc, au niveau supérieur quelque part, vous aurez un répertoire de projet où il compilera choses et un répertoire source qui, comme vous pouvez le deviner, est l'endroit où votre source ira. Sous votre source, il devrait y avoir un répertoire principal, et sous main il devrait y avoir un répertoire scallop. Et à l'intérieur de ce répertoire Scala est l'endroit où vous allez mettre les fichiers Scala réels que vous voulez compiler. Sbt fera correspondre la compilation pour vous et l'empaqueter dans votre fichier JAR avec toutes les dépendances que vous spécifiez pour l'utiliser. Comme je l'ai dit, vous venez de mettre vos fichiers source et le dossier source assez simple. Mettez-le au bon endroit. Et puis dans votre dossier de projet, nous allons créer un petit fichier SBT point d'assemblage qui contient une seule ligne qui ressemblait à ceci. Maintenant, 0.14.10 peut changer au fil du temps. C' est encore assez courant. Il y a un 15 0 là-bas maintenant, mais il n'est pas encore largement publié. Donc, pour l'instant, nous allons rester avec la version 14 ici du plugin d'assemblage SBT. Mais c'est tout ce que tu as à faire. Cela indique simplement SBT que nous allons utiliser ce plug-in appelé assemblage SBT. Et son travail dans la vie est de créer ce fichier JAR autonome que nous voulons. Le véritable cœur de celui-ci est cependant le fichier de construction SBT. Et c'est construire un point SBT qui devrait être placé à la racine de votre arborescence de répertoire SBT à côté des répertoires source et projet. Voici donc un exemple de ce à quoi on pourrait ressembler. Nous spécifions le nom du Père, nous créons un numéro de version, ce que vous voulez être. Organisation associée à ce package. La version Scala dont il dépend, c'est important d'obtenir le droit. Rappelez-vous que les différentes versions de Spark nécessiteront différentes versions de Scala. Donc, dans cet exemple, nous spécifions une dépendance de bibliothèque d'org dot apache, Spark, spark dash core. Ok, donc ça nous dit que ce scénario populaire que nous avons dans Scala dépend du paquet Spark Core. D' Apache Spark. Et nous spécifions spécifiquement la version 3 avec Spark ici. Donc, parce que nous savons que déclenché trois nécessite Scala version 2.12. C' est pourquoi nous avons Scala version 2.12.3 là-haut ou quoi que ce soit, vous savez, la dernière version pourrait être que vous utilisez. Maintenant, c'est important d'aller droit. Par exemple, nous allons dans la prochaine conférence, télécharger notre fichier JAR sur le service Elastic MapReduce d'Amazon,
qui à partir de cet enregistrement ne prend pas encore en charge Spark 3, ils prennent en charge la version 2.4.5 de Spark, ce qui nécessite Scala version 2.11. Donc, dans cet exemple, nous allons spécifier Spark Core version 2.4.5 au lieu de 3 et Scala version 2.11 quelque chose. Donc tu dois t'assurer qu'ils correspondent ou bien ça ne marchera pas bien ? Notez que les dépendances de bibliothèque ici sont en fait une séquence, donc nous pouvons avoir plus d'une chose là-dedans si nous
avons juste une liste de lignes séparées par des virgules. Donc, en outre, nous pourrions avoir déclenché des bibliothèques SQL ou tierces, même si vous avez besoin pour que votre script s'exécute, vous venez de lister ici et ensuite SBT sortirait et l'obtiendrait et utiliserait African empiling votre code et aussi pour l'empaqueter dans votre fichier JAR final. Maintenant, une chose dont nous voulons parler en particulier, c'est l'article qui y est fourni. Donc fourni signifie que nous pouvons supposer
que ce paquet sera pré-installé partout où nous allons l'exécuter. Donc, parce que je vais déployer ceci sur un cluster qui a déjà installé Spark. n'y a pas besoin pour moi d'inclure le noyau étincelé dans le fichier JAR lui-même parce que cela sera disponible pour le système dans son ensemble, tout prêt. Donc, en disant fourni, cela signifie
que j'ai besoin de ce paquet pour compiler mon code, mais je n'ai pas besoin de l'empaqueter dans mon fichier JAR final car il sera déjà présent partout où je vais l'exécuter. Si vous vouliez réellement inclure le noyau intelligent dans le fichier jar lui-même, je laisserais le fourni et cela regrouperait tout dans un fichier char vraiment autonome. Mais depuis que j'ai déjà Spark installé d'où je vais l'exécuter. Nous n'avons pas besoin de ça, nous pouvons laisser ça dehors avec le drapeau fourni. Donc, comme autre exemple, disons que je dois dépendre de Kafka. En fait, ça ne fait pas partie de Spark. Je pourrais avoir une autre ligne là dans les dépendances de la bibliothèque qui dit ou données apache dot Spark, étincelle Streaming Kafka version, quelle que soit la version de ces paquets dont vous avez besoin. Maintenant, dans ce cas, je ne dirais pas fourni parce que je sais que ce n'est pas pré-installé sur mon système, alors je vais l'exécuter à partir de. Donc, cela empaquerait réellement ce jar Spark Streaming Kafka dans le fichier JAR ultime que je vais
déployer et construire dans mon fichier JAR final. Donc, une fois que vous avez tout en place, tout ce que vous avez à faire est d'exécuter l'assembly SBT à partir du dossier racine. Et il s'en sortira et fera sa magie. Et il va s'éteindre et compiler vos, vos scripts. Il va tout patcher ensemble après avoir rassemblé toutes les dépendances dont il a besoin. Et vous trouverez le fichier JAR final sous les cibles dernier tiret
Scala quelle que soit la version de Scala que vous lui avez dit de construire. Et puis vous avez un fichier jar que vous pouvez faire ce que vous voulez. Et la beauté à nouveau est qu'il est complètement autonome. Tant que vous pouvez obtenir ce fichier JAR
au nœud maître de votre cluster à partir duquel vous allez l'exécuter. Tout ce que vous avez à faire est de dire déclenché comme chemin du sommet vers ce fichier jar et c'est fait. Vous n'avez pas besoin de spécifier la classe, pas de dépendances JAR, rien, c'est tout. Alors allons-y et essayons-le. D' accord, d'abord, passons en revue script
que nous allons réellement emballer ici. Donc, si nous revenons à IntelliJ et recherchons un jeu de données de similitudes de film 1M. C' est ce que nous allons empaqueter ici et finalement envoyer à Elastic MapReduce d'
Amazon pour réellement s'exécuter dans un vrai cluster. Alors passons à travers ce qui est différent ici. Pas vraiment beaucoup, mais il y a quelques choses à parler ici. Tout d'abord, pour le fichier DAT dot films, notez que nous transmettons ceci comme un chemin spécifique aux films dot dat. Cela devrait être à côté de notre endroit où nous exécutons Spark submit, il va supposer que ce fichier est présent sur le système de fichiers local. Comme on l'a déjà dit, ce n'est généralement pas un bon plan. Comme si vous avez un système de fichiers distribué où vous pouvez l'obtenir, ça va être mieux. Mais dans notre cas, films dot dat est un fichier assez petit. Donc, nous pouvons mettre ça autour de nous-mêmes sans beaucoup d'ennuis. Cependant, de manière générale, vous voudriez avoir sur une sorte de système de fichiers distribué à la
place, au lieu de compter sur ce fichier étant présent partout où vous allez exécuter ce script. Nous sommes cependant, en nous assurant que nous avons les notes point
DAT fichier sur un système de fichiers beaucoup plus grand ici. Donc, cela va être sur Amazon a trois, C'est ce
que le préfixe S3 n il se réfère. Donc, euh, donc j'ai un seau S3 nommé Sun dog fait étincelle qui contient le fichier de données Dat de notes là-bas. Et parce que c'est vraiment du Big Data en soi, eh bien, vraiment Nous pourrions gérer cela sur une seule machine, mais pour des jeux de données plus importants comme ça, vous voulez généralement avoir cela sur une sorte de système de fichiers distribué à coup sûr. Donc, dans ce cas, nous avons pris la peine de nous assurer qu'il est disponible sur Amazon S3. Et nous n'allons pas supposer que c'est sur le système de fichiers local. Maintenant, c'est un format quelque peu différent de celui que nous avons vu auparavant pour les jeux de données analyte 100 K. Alors parlons un peu de ça aussi. Allons à Grouplens.org. Et si nous passons aux jeux de données, nous pouvons en savoir plus sur ce jeu de données spécifique d'un million ou il y a un milliard de données maintenant pour, eh bien, si vous voulez vraiment des Big Data, mais il y en a un que nous utilisons dans cet exemple. Donc, si vous allez à Read Me dot text, il vous indique le format de fichier plus en détail. Défilons vers le bas. Ainsi, la description du fichier d'évaluation, par exemple, il vous indique que le format est User ID, film ID, rating,
horodatage, mais dans ce cas, il n'est pas séparé par des tabulations. C' est en fait séparé par ces paires de Coleman. Donc c'est important à réaliser. Aussi les informations de fichier de films est important de savoir
aussi qui est délimité par le double deux-points peu inhabituel. Donc, vous devez vous assurer
de comprendre le format auquel vous avez affaire avant d'écrire votre code. Si nous revenons à l'intelligence, nous pouvons voir que nous avons spécifié ce double deux-points comme séparateur dans les deux cas. Et nous spécifions également le jeu de caractères pour les noms des films. C' est aussi ISO 8859 tiret un. Donc, c'est une différence, juste le format et le chemin que nous
utilisons pour ces fichiers de données pour le jeu de données MovieLens 1 million, nous passons à l'ensemble de données 1 million ici juste pour illustrer réellement le fonctionnement sur le Big Data. Il s'agit donc d'une médiane de tâches à faire sur une seule machine peut être difficile. Donc nous sommes, nous nous attaquons à ça maintenant. Quant à quoi d'autre est différent ? Eh bien, pas beaucoup. reste du code est à peu près le même. Nous devions donc nous assurer que nous obtenons nos données au bon endroit, qu'elles soient dans le bon format. Et en dehors de cela, c'est à peu près le même code que nous avons vu dans l'exemple du jeu de données sur les similitudes de films plus tôt dans le cours. Alors fermons ça maintenant qu'on a fini d'en parler. La première chose que nous devons faire est de télécharger SBT lui-même. Donc, si vous allez à Scala dash SBT.org. Vous devriez voir un bouton de téléchargement quelque part. Je suis sûr que ce site va changer au fil du temps, mais j'espère que vous pouvez le trouver. Pour Windows. Il y a un programme d'installation de Windows, alors allons de l'avant et attrapons cela. Si vous êtes sur Linux ou Mac OS, vous pouvez obtenir un paquet autonome ici à partir du format zip
ou TGC, peu importe ce que vous préférez. Et vous pouvez simplement décompresser cela et être fini avec. Vous trouverez l'exécutable SBT à l'intérieur. Si vous êtes sur Ubuntu et que vous préférez utiliser un gestionnaire de paquets, vous pouvez vous diriger vers la documentation d'un Scala SBT et il vous en dira. Il suffit d'aller à ce lien ici et qui vous guérira à travers comment vous assurer que vous avez le bon référentiel en place et comment l'installer en utilisant app.get. Mais je suis sur Windows, donc je vais juste exécuter le programme d'installation de Windows et en avoir fini avec. Ouais, ouais, je sais. Courez quand même. Cette marche à travers elle. Et la bonne chose est qu'ils devraient mettre SBT sur mon chemin pour moi afin que je n'ai pas à me soucier de l'endroit où Dieu installe deux. D' accord, donc c'est hors du chemin. Ensuite, obtenons réellement nos répertoires SBT afin que nous puissions ajouter quelque chose à empaqueter. Donc, si vous allez sur http media, chiens Dotson, bord, soft.com slash Spark, Scala slash SPT dot zip. D' accord. Allez-y et décompresser. Cependant, vous décomparez les choses sur votre système d'exploitation. Et vous devriez avoir un dossier SBT qui ressemble à ceci. Alors, déplaçons ça un endroit où nous ne le perdrons pas. Je vais couper ça et mettons-le sur mon disque C. Bon, donc maintenant nous avons un dossier SBT et si nous regardons dans son contenu, nous voyons ce que nous attendons à voir, juste il y a ce répertoire de projet. Et à l'intérieur du répertoire du projet est assembly pas SBT. Examinons ça. Et il contient cette ligne dont nous avons parlé plus tôt, en spécifiant
simplement que nous allons utiliser le plug-in d'assembly
SBT avec cette version de celui-ci. Et sous le répertoire source, nous avons un répertoire principal et un répertoire érudit qui contient les similitudes du film. Un fichier Scala point de jeu de données m que nous venons de regarder. Et enfin dans le répertoire supérieur ici, nous avons notre fichier de point de construction magique SBT. Et si nous examinons cela, nous pouvons voir que nous avons un nom qui correspond à notre ClassName, quel que soit le numéro de version que nous voulons lui donner, nom de
notre organisation, la version Scala dont nous dépendons, et les versions de Spark Core et Spark SQL dont nous dépendons pour ce script. Maintenant encore, dans cet exemple sur Amazon EMR, ils sont actuellement sur la version 2.4.5. Donc, c'est ce que j'ai spécifié ici parce que c'est là que je vais déployer cela à la fin. Et je sais que Spark 2.4 repose sur la version 2.11 de Scala. Donc c'est la méthode de toute cette folie. Et encore une fois, notez que je dis fourni parce que je sais que
Spark Core dans Spark SQL va être pré-installé sur mon cluster Amazon EMR. Je n'ai pas besoin de regrouper Spark lui-même dans mon fichier JAR final. Maintenant, c'est une sorte d'exemple inintéressant parce que je n'ai pas de dépendances tierces ici. Donc, à la fin, tout ce que je vais vraiment emballer est le fichier JAR pour mon script lui-même. Mais cela est très utile si vous avez un arbre de dépendance plus compliqué, non ? Donc, pour l'exemple ici, nous ne faisons rien de super compliqué, mais c'est ainsi que vous gérez vos dépendances si vous aviez un paquet tiers qui n'a pas été pré-installé sur votre système. Vous allez l'exécuter à partir de. Vous les listez ici. En outre, assurez-vous qu'il est séparé par des virgules et que vous ne
diriez pas fourni sur ces spécifiques où vous voulez qu'il soit regroupé. Alors voyons si ça marche. Ouvrons une invite de commande, et je vais le faire avec les autorisations d'administrateur juste pour être sûr. Donc, si je descends et Windows, ce serait sous l'invite de commande système Windows, je vais cliquer avec le bouton droit sur cela, dire plus exécuter en tant qu'administrateur. Et naviguons vers ce dossier SBT. C' est là. Maintenant, nous pouvons simplement taper dans l'assemblage SBT. Et il devrait y aller. Et nous aurons réellement besoin de sortir et de récupérer un environnement Scala et Apache Spark et tout ce dont il a besoin pour compiler cela. C' est donc un peu magique comment SBT peut avoir cet environnement autonome qu'il construit à partir de zéro. Et nous l'avons là. On dirait que c'est réussi. Jetons un coup d'oeil et voyons ce que nous avons ici. Donc, si nous y allons et ici, nous avons maintenant un répertoire cible. Voyons ce qu'on a là-dedans. Et il y a un répertoire squelettique 11 et à l'intérieur il y a notre fichier JAR. Très cool. Donc, c'est comme si cela fonctionnait des similitudes de film quand je suis l'assemblage de tableau de bord de jeu ,
tiret 1 pot de point, juste assis là attendant que nous l'utilisions. Donc, dans notre prochaine conférence, Utilisons-le.
43. [Exercer un script avec SBT et it localement avec spark-submit spark-submit: Ok, Donc à ce stade, je vous ai appris à utiliser Spark submit sur une installation locale d'Apache Spark pour exécuter vos scripts. Et je vous ai également montré comment utiliser sbt pour regrouper votre script dans un fichier JAR autonome. Donc, votre défi est de rassembler ces deux choses. Je veux que vous utilisiez sbt pour regrouper un fichier JAR, puis exécuter localement en utilisant Spark das submit sur votre bureau local. Et la stratégie ici, choisissez n'importe quel script que vous voulez. Je m'en fiche, mais je vais choisir le script du jeu de données températures min. Peu importe avec qui vous voulez jouer. Et ce que vous allez devoir faire est de modifier le fichier SBT de construction dans votre arborescence de répertoires SPT et assurez-vous d'utiliser la même version de Spark que vous avez installée localement pour utiliser Spark submit. Et nous devons également nous assurer que nous utilisons une version compatible de Scala pour cette version de Spark. Donc, cela va impliquer de faire un peu de recherche en ligne. Vous allez devoir déterminer quelle version de Spark vous utilisez et quelle version de Scala est compatible avec cette version de Spark. Et une fois que vous avez fait cela, en outre, vous devez comprendre quelle
est la version actuelle de Scala pour cette révision majeure de Scala. Donc, je ne veux pas vous donner trop de conseils ici car être un développeur dans le monde réel c'est souvent de faire ce genre de recherche vous-même et de trouver de nouveaux problèmes vous-même. Tu ne pourras pas aller voir ton patron ou tes collègues pour trouver ça pour toi. Je veux dire, vous pouvez, mais ils vont trouver ça assez ennuyeux et vous ne durerez probablement pas longtemps si vous faites ça tout le temps. Donc je veux que tu t'entraînes et que tu trouves ce truc toi-même. Une fois que vous l'avez cependant, il faut simplement
s'assurer que votre script est au bon endroit dans l'arbre de construction pour sbt. Et assurez-vous également que vous avez le bon Bill dot SBT mis en place pour la bonne version de Spark et Spark Submit. À ce stade, nous pouvons simplement utiliser l'assembly Spark pour le construire et nous assurer que nous exécutons Spark submit à partir du répertoire que le script suppose. Comme vous vous en souvenez, la plupart de nos scripts supposent qu'il existe un répertoire de données local qui contiendra les données que nous voulons sur le système de fichiers local. Nous devons donc nous assurer d'exécuter ce script à partir
du bon endroit où ce sous-répertoire de données existe. Et avec ça, allez-y et donnez-lui un coup de feu. Et dans la prochaine vidéo, je vous expliquerai comment je l'ai fait.
44. Solution d'exercice : Utiliser SBT et spark-submit: Donc, laissez-moi vous expliquer comment j'ai fait empaqueter le script du jeu de données températures min en utilisant SBT et l'exécuter localement en utilisant Spark submit en dehors de l'intelligence. Donc, la première chose que vous voulez toujours faire est de jeter un oeil
au script avant de l'empaqueter et de vous assurer qu'
il n'y a rien à changer avant de l'exécuter dans un environnement différent, non ? Donc, d'abord, notez que nous utilisons l'étoile locale. Maintenant, si je fonctionnais réellement sur un vrai cluster, je veux probablement le supprimer parce que sur un cluster, je
veux utiliser chaque noyau et chaque machine de mon cluster, pas seulement la machine locale sur laquelle j'exécute le script du pilote, mais puisque mon intention est de toujours exécuter ceci juste sur mon PC local qui peut rester inchangé dans ce cas. Faites également attention aux chemins d'accès des fichiers. Cela suppose que nous allons à la barre oblique de données 8800 points CSV pour notre fichier de données là. Et cela implique que je vais devoir avoir un dossier de données sur mon système de fichiers local qui se trouve à côté du même emplacement où j'invoque ce script en utilisant Spark submit. Donc je pourrais changer ça en un chemin absolu si je le voulais. Je pourrais changer cela en un système de fichiers partagé si je le voulais. Mais encore une fois, puisque je suis juste en cours d'exécution sur mon système de fichiers local, je vais juste m'assurer que je me souviens de l'exécuter à
côté du dossier de données où je l'ai déjà installé. Donc, je ne vais pas vraiment changer quoi que ce soit ici, mais vous voulez toujours être conscient de ce genre de problèmes avant d'empaqueter un script avec lequel vous avez joué localement et de l'expédier ailleurs, Ce serait vraiment horrible si j'oubliais de sortir cette ligne maîtresse
là-bas, et de l'expédier à un cluster. J' avais cette énorme grappe et je n'en profiterais pas du tout dans ce cas. Donc soyez toujours prudent de ce genre de chose. Alors commençons par la partie facile. Copions ce script lui-même et mettez-le dans SBT. Donc, minimisons cela dans mon cours Spark Scala, trouvons ce fichier. C' est sous source, scala com principale, quelques logiciels pour chiens, une étincelle. Et qu'est-ce que c'était ? Jeu de données de température min, points, pétoncles, je vais aller de l'avant et copier ça. Et allez dans mon répertoire SBT et allez dans la source principale Scala. Et je vais coller ça ici et supprimer les similitudes
du film 1 million de fichiers de jeu de données que nous avons utilisés dans l'activité précédente. Donc maintenant, je dois m'assurer que j'utilise la bonne version de Spark et la bonne version de Scala pour que cela puisse fonctionner localement sur mon environnement Spark local. Alors revenons au haut de SBT ici et je vais éditer ce projet de loi n'a pas le fichier SBT, utilisez l'éditeur que vous voulez. Pour moi, j'ai quelque chose appelé Notepad Plus, Plus installé. Quelque chose fonctionne, n'est-ce pas ? N'importe quel éditeur de texte fera le travail ici. Nous devons donc spécifier quelle version de Spark nous utilisons et quelle version de Scala. Et ceux-ci doivent être compatibles, non seulement les uns avec les autres, mais aussi avec ce que vous avez installé pour Spark sur votre système local. Notez que nous disons que l'étincelle elle-même est fournie, donc elle ne va pas empaqueter Spark lui-même dans notre fichier jar résultant. Il va utiliser n'importe quelle version de Spark est présente sur mon système de fichiers ici. Donc, je dois m'assurer que cela se construit contre la bonne version de Spark. Commençons par ça. Revenons donc à mon installation d'étincelles et vérifions simplement. J' ai donc installé Spark dans Spark. Et si je regarde la version TextFile là, il me dit que j'utilise Spark 3. Ok, donc c'est une pièce du puzzle. Revenons à mon dossier de facture point SBT sous SBT. Et nous allons changer Spark Core à 3. Et comme j'utilise des jeux de données, j'ai également besoin du paquet Spark SQL. Donc nous allons laisser ça là aussi. Et vous voulez également penser aux autres dépendances que vous
avez dans Spark lui-même à ce stade ou en dehors d'une étincelle. Et dans ce cas, il n'y en a plus. Mais si j'empaquetais, disons, un script d'apprentissage automatique, je pourrais vouloir inclure Spark ML, Spark streaming fichiers faisant du script de streaming d'écran. Assurez-vous donc que vous avez des dépendances dont vous avez besoin là. Bon, maintenant nous devons comprendre quelle version de Scala est compatible avec cette version de Spark. Pour ce faire, il faut un peu de recherche. Allons lancer un navigateur web. Et j'amènerai une fenêtre de nucléon ici. Alors allons à spark dot apache.org. Et si nous regardons Spark trois points, Oh, allez dans la zone Télécharger Spark ici, et nous pouvons voir qu'il nous indique ici quelle version de Scala compatible avec, quelle version de Spark. Donc, il dit non, cette étincelle au point x est pré-construite avec 2.11 sauf pour la version 2.4.2, qui est construite avec le squelette 12. Mais Spark trois points Oh, c'est nous est pré-construit avec Scala à 0,12. Ok, donc je sais que j'ai besoin de la version 2.12 de Spark. Est-ce assez précis ? Eh bien, regardons. Je veux aussi une version mineure. D' accord. Eh bien, nous allons changer le 11 à 12, mais qu'est-ce qui vient après le 12 ? Je ne sais pas. Faisons plus de recherches. Encore une fois, vous devez être débrouillardise parfois. Donc, nous allons juste chercher Scala à 0.12 et voir si nous pouvons comprendre quelle est la version actuelle de cela. On dirait que ça me montre à mettre à l'échelle un line.org en pointillés, qui est la maison officielle de Scala. Et bien que je ne veux pas, il semble que 2.13 soit en fait sorti, mais encore une fois, j'ai besoin d'utiliser 2.12 pour cette version de Spark. Voyons si les notes de publication me disent quelque chose. D' accord. Donc apparemment, la dernière version de 2.12 est 2.12.12. D' accord, allons-y avec ça. Donc, revenons à mon fichier SBT build out, nous allons spécifier 2.12.12 et je vais enregistrer ceci. À ce stade, nous devrions être prêts à emballer cela. Allons de l'avant et ouvrons une invite de commande. Nettoie un peu les choses ici. Alors voyons. Je vais au menu Démarrer. Bien sûr, sur Mac ou Linux, il
suffit d'ouvrir un terminal. Pas grand-chose. Cela va être sous l'invite de commande système Windows et nous voulons l'exécuter en tant qu'administrateur juste pour être sûr. Bon, alors naviguons vers ce dossier SBT. Et nous allons simplement taper dans l'assemblage SBT. Et j'espère qu'il fera ce qu'il faut. Ok, a fait quelque chose ressemble à un bâti contre le squelette 0.12. Donc ça a l'air juste. Allons de l'avant et voyons si nous avons ce fichier jar résultant. Allons dans les cibles squelette 12. Oh, j'ai oublié de changer le nom de ça. D' accord, très bien. Eh bien, revenons à sbt et éditons ce fichier Bill dot SBT à nouveau. J' ai oublié de changer le nom. Donc, vraiment ce devrait être ce qui était cette chose à nouveau, jeu de données de température min. Bon, refaisons-le. Devrait être plus rapide maintenant qu'il est téléchargé toutes ces dépendances. Bon, voyons ce que nous avons maintenant. Ciblez Scala à 12. Le voilà, le tiret d'assemblage du jeu de données de température min 1 O. Donc, copions-le et mettons-le à côté du répertoire de données d'où je veux l'exécuter. Donc, le contrôle C, évidemment, vous pouvez utiliser la commande cp à partir d'une invite de commande si vous le vouliez aussi. Et nous irons dans le cours de gala de voir les étincelles. Et à l'intérieur, il y a le répertoire de données qu'il suppose est local par rapport au script. Allons-y et collons-le ici. Et maintenant devrait être en mesure de naviguer vers là et vous l'exécutez avec Spark soumettre. Alors modifions notre répertoire pour voir Sparks gala cours Slash Spark Scala. Et commençons avec Spark soumettre et voyons ce qui se passe. Donc, Sparks soumet le chemin était sous C étincelle bin, Spark desk soumettre. Assure-toi qu'il soit là, d'accord. Et nous devrions être en mesure de passer dans le jeu de données de température Min tableau de bord assemblage 1 point char. J' utilise juste la touche de tabulation pour compléter automatiquement cela. Et ça devrait marcher. Et nous avons eu un tas d'erreurs lors de l'arrêt. Mais encore une fois, c'est normal. C'est un truc de Windows. Nous avons effectivement obtenu notre sortie cependant. Alors regarde, ça a fonctionné cool. On a notre température minimale pour ces deux stations météorologiques. Et nous avons un emballage réussi de ce qui est bon avec SBT et nous l'exécutons localement en utilisant Spark desk soumettre en prenant soin de la version de Spark que nous avions installée et la version de Scala
qui, cette version de L'étincelle dépend. Donc j'espère que vous avez eu un certain succès avec cela aussi. Sinon, je pense que regarder cette vidéo vous a probablement montré où les choses ont mal tourné. Alors revenez en arrière et réessayez si vous en avez besoin. Et avec ça, continuons.
45. Présentation d'Amazon Elastic MapReduce: Donc, le moment que nous attendons, nous allons réellement exécuter notre script de notation de 1 million de films sur un vrai cluster en utilisant la surface Elastic MapReduce d'Amazon et Hadoop. a plein de mots buzz. Parlons d'un peu plus avant de le faire. Parlons de la façon dont Spark distribué fonctionne réellement. Ainsi, les scripts que vous avez utilisés pour exécuter ces tâches Spark localement sur votre propre PC peuvent être utilisés sur un cluster sans trop de modifications. C' est donc en quelque sorte à Spark soumettre et Spark lui-même de déterminer quel gestionnaire de cluster vous exécutez au-dessus de. Et cela pourrait être le gestionnaire de cluster intégré étincelles. Ça pourrait être le fil d'Hadoop, ça pourrait être Mesos. Et intégrez à cela pour distribuer le travail de tous vos mappers et réducteurs ainsi qu'un CAN dans le cluster que vous avez à votre disposition. Donc, fondamentalement, le script du pilote Spark est en cours d'exécution sur votre nœud maître, votre pilote, ok ? Et cela communique avec votre gestionnaire de cluster pour distribuer le travail qui est dans le script de ce pilote aux différents nœuds exécuteurs, ok ? Et le gestionnaire de cluster est responsable de gérer les défaillances de nœuds
individuels et de cliquer sur les résultats ensemble pour revenir à votre script de pilote lorsque cela est fait. Maintenant quelques autres paramètres Spark Summit dont nous devrions parler. Et d'abord, je dois noter que sur beaucoup de clusters, beaucoup de ces paramètres vont être pré-configurés pour vous automatiquement. Donc, si vous ne spécifiez rien dans votre script explicitement pour ce que le maître va être ou s'il n'est pas spécifié sur la ligne de commande. Il y a aussi un fichier de configuration dans Spark qui peut être configuré pour définir toutes ces choses automatiquement pour vous. Et par exemple, si vous configurez un cluster sur Amazon, Elastic MapReduce, beaucoup de ces éléments seront configurés pour vous et pas déjà de manière optimale. Mais parfois, vous rencontrez des problèmes où les choses ne se terminent pas. Vous manquez de ressources, les choses commencent à s'écouler et vous devez modifier un peu ces choses pour que les
choses fonctionnent de manière plus fiable, donc vous devez savoir qu'elles existent. La première option dont nous ne voulons pas parler est Dash, Dash master. Et ce n'est pas quelque chose que vous pouvez modifier. C' est juste un test pour être réglé à la bonne chose pour quel genre de cluster vous avez. Donc, si vous exécutez sur un cluster Hadoop et que vous voulez
profiter du gestionnaire de cluster de fils de Hadoop qui sera défini sur yarn. Si vous souhaitez utiliser le cluster autonome de Spark, vous devez le définir sur le nom d'hôte et le port de votre nœud maître sur votre cluster Spark. Mesos fonctionne de la même manière. Et encore une fois, si vous avez une étincelle conf ou quoi que ce soit dans votre script lui-même qui remplace cela. Il ignorera ce qui se trouve sur la ligne de commande. Donc, la hiérarchie est tout ce qui est dans votre script, les eaux sur la ligne de commande et les gagnants dans les fichiers de configuration pour les étincelles. N' oubliez donc jamais de vérifier vos scripts pour vous assurer que vous ne codez pas en dur un maître donné. Par exemple, si vous avez cette étoile de parenthèses locales, cela remplacera l'option principale ici. Et si vous exécutiez ce script sur un cluster, ils ne tireraient pas parti du cluster complet. En ce qui concerne la gestion de l'utilisation des ressources sur votre cluster, il existe également des options pour cela. Num exécutors spécifiera le nombre de nœuds exécuteurs que vous souhaitez utiliser. Par défaut, ce n'est que deux. Donc, si vous exécutez sur un cluster plus grand qui a plus de deux nœuds, vous voudrez augmenter ce paramètre. Encore une fois, habituellement cela vous sera fixé par quelqu'un d'autre, par l'administration, mais quelque chose dont vous devez savoir et vous assurer que cela est en fait établi quelque part. La mémoire de l'exécuteur gère la quantité de mémoire disponible pour chaque exécuteur. Et bien sûr, vous voulez vous assurer que cela ne dépasse pas la mémoire physique disponible pour chaque nœud exécuteur individuel. Si vous exécutez sur un cluster dans le Cloud, sont souvent des machines virtuelles qui ont moins de mémoire que vous ne le pensez. Assurez-vous donc que vous êtes au courant de la mémoire disponible pour votre script sur chaque exécuteur. Et vous pouvez également regarder le total des cœurs de l'exécuteur. Si vous avez des multicores sur vos nœuds virtuels, vous pouvez modifier cela pour fixer une limite supérieure sur le nombre,
le nombre cœurs que votre script peut consommer. Ok, Amazon Elastic MapReduce, donc c'est ce que nous allons utiliser dans ce cours. C' est un moyen rapide et facile de faire tourner un cluster Hadoop et vous pouvez en fait lui dire de pré-installé Spark dessus comme pour vous aussi, avec tout configuré automatiquement. Donc, moyen très facile de commencer et d'exécuter votre script sur un vrai cluster où vous venez de louer du temps et de payer pour ce dont vous avez besoin. Et c'est un peu la prémisse d'Amazon Web Services. Vous écrivez simplement du temps et payez
les ressources informatiques dont vous avez réellement besoin pour tout ce que vous faites. Donc, vous êtes facturé essentiellement par l'instance de l'heure, combien de temps vous passez sur le nombre d'ordinateurs d'un type donné. Vous êtes également facturé pour toutes les E/S réseau tout espace de stockage et toutes les E/S de stockage. Donc, vous payez pour ce que vous utilisez. Et d'habitude, ce n'est pas beaucoup. Je pense que j'ai dépensé environ 30 dollars et en fait mettre ce cours ensemble en termes de frais AWS. Mais fais attention. Je recommande juste de me regarder faire ça pour l'instant sauf si vous
avez un compte d'entreprise ou quelque chose où ce n'est pas votre argent sur la ligne. Parce que si vous gâchez, il est très facile d' oublier de mettre fin à votre cluster quand vous avez terminé. Et si vous faites cela, votre cluster continuera à fonctionner pour toujours même si vous ne l'utilisez pas. Et vous allez être construit pour tout ce temps quand vous pourriez même pas le réaliser jusqu'à
ce que vous voyez un débit de carte de crédit pour 1000$. Je ne veux pas que ça t'arrive. Je ne veux pas être responsable de ça. Donc, euh, tu sais, si tu veux jouer avec le MR, n'
oublie pas de mettre fin à tes grappes quand tu auras fini. Si vous ne le faites pas, vos comptes bancaires ne vous aimeront pas et vous ne m'aimerez pas, alors n'y allez pas. D' accord. Donc, avec cela, parlons de l'exécution réelle sur un cluster, parlant de quelques-uns de ces points déjà. Mais encore une fois, ce que EMR met en place pour vous est un cluster Hadoop et vous pouvez exécuter Spark sur le composant fil de Hadoop. Donc, les gens confondent Hadoop et Hadoop fil. Parfois, j'entends beaucoup de gens parler de la façon dont Spark est plus rapide que Hadoop, mais ce n'est pas vraiment l'un ou l'autre. D' accord ? Ce qu'ils signifient vraiment, c'est que Spark est plus rapide que MapReduce, qui est une façon d'exécuter des tâches distribuées sur Hadoop. Mais Hadoop lui-même n'est qu'une technologie pour gérer un cluster. Et un composant de Hadoop est fil, le gestionnaire de cluster, qui étincelle peut fonctionner sur le dessus de très bien. Ok, alors rappelez-vous les différentes pièces comme un pilote Spark est un gestionnaire de cluster et puis il y a le matériel lui-même. Hadoop est juste en train de remplir cette petite pièce du milieu pour toi. Donc Hadoop et Spark ne sont pas mutuellement exclusifs, ce qui est une idée fausse commune. D'accord ? Une autre chose que je tiens à souligner en termes de bonnes pratiques, car courir sur un véritable cluster coûte cher. Ce sont des ressources coûteuses que vous avez affaire ici potentiellement, vous voulez toujours vous assurer de faire votre développement et tester localement sur votre propre PC d'abord, d'accord. Ou un ordinateur de bureau ou un seul ordinateur que vous avez accès à vous et qui ne coûte pas cher. Et une façon de le faire souvent est d'utiliser un sous-ensemble de vos données juste pour le développer avec. Donc, si vous avez affaire à un jeu de Big Data que vous ne pouvez gérer que sur un cluster, envisagez d'utiliser une seule partie de ce jeu de données pour développer et tester la largeur. De cette façon, vous avez plus de chances
d'avoir une exécution réussie lorsque vous louez du temps sur le cluster lui-même, vous voulez vraiment minimiser le temps que vous travaillez sur le cluster si possible. Ok, Donc, en termes de configuration, vous devez commencer par créer un compte Amazon Web Services. Et je suppose que vous pouvez trouver comment faire ça. Depuis encore, je veux juste que tu me regardes faire ça maintenant. La prochaine étape consistera à créer une paire de clés EC2 afin que vous réellement vous connecter à votre cluster une fois que vous l'avez filé de manière sécurisée. Et vous aurez besoin d'un moyen de vous connecter à
cette machine virtuelle réelle à un moment donné en utilisant quelque chose comme du mastic sur Windows, vous avez besoin d'une sorte de terminal pour pouvoir vous connecter à ces machines et exécuter réellement votre script et télécharger les choses dont vous avez besoin pour eux. Alors commençons et voyons comment cela fonctionne.
46. Créer des films similaires à partir de 1 million d'évaluations sur EMR: Alors faisons ça. En fait, générons des similitudes de films basés sur 1 million d'évaluations de films d'utilisateurs et faisons-le pour de vrai. Alors suivez simplement ici et je vais vous montrer comment cela fonctionne en utilisant le service Elastic MapReduce d'Amazon. Maintenant, pour configurer les choses, j'ai déjà chargé des choses dans le service S3 d'Amazon, qui est essentiellement un magasin de fichiers distribué sur lequel vous louez de l'espace. Bon, donc un peu comme HDFS, mais c'est la version Amazon de celui-ci. Une façon d'y penser. J' ai donc déjà créé ce qu'on appelle un seau dans S3 appelé Sunday August Spark. Et j'ai téléchargé quelques choses dont je vais avoir besoin. L' un est les similitudes du film, un M Jar, fichier Jar. Et c'est la même chose que j'ai générée en utilisant SBT plus tôt dans le cours. Je viens de lui donner un nom de fichier légèrement différent. Donc, il a mon script de pilote Spark autonome regroupé dans un fichier jar. Ok, donc ça va être sur S3. Je peux donc le copier rapidement sur mon cluster une fois que j'ai divisé mon cluster pour l'exécuter sur. L' autre chose que j'ai fait est que j'ai déplacé le jeu de données de notation MovieLens 1 million ici aussi. Donc, j'ai créé un dossier MNL dash 1M ici sur mon fils est mort seau S3 intelligent. Et cela va s'assurer que ce système de fichiers distribué de S3 qui contient mes notes de 1 million de films est également accessible à tout mon cluster. Et à l'intérieur, nous avons les différents fichiers qui composent les évaluations des jeux de données. Dot dat est les évaluations réelles des films eux-mêmes et les films dot dat sont toutes les métadonnées associées aux films réels. Donc, si vous vous souvenez,
notre stratégie sera d'exécuter ce fichier JAR à partir du nœud maître de notre cluster. Et il va avoir des films dot dat situés à côté d'elle. Ainsi, il peut réellement construire cette table de recherche d'ID de film pour les noms de film lorsqu'il génère les résultats. Mais tous les besoins du cluster sont les données de classement. Alors allons mettre en place les choses et faire un cluster. Nous avons donc notre beau fichier JAR MovieLens brillant 1 million prêt à être déployé sur notre cluster. Mais d'abord, nous avons besoin d'un cluster pour déployer un deux et en créer un. Je vais utiliser le service AWS Elastic MapReduce pour ce faire. Maintenant, ça coûte de l'argent. Donc, si vous n'aimez pas dépenser de l'argent ou si vous n'avez pas de compte AWS, vous voulez probablement juste regarder ici et ne pas vraiment suivre vous-même. D' accord ? Mais j'ai déjà un compte AWS et un peu de budget à jouer. Donc, je vais aller de l'avant et cliquer sur EMR ici ou simplement taper Elastic MapReduce et trouver des services. Et allez-y et faites tourner une nouvelle grappe ici. Donc, créons un nouveau cluster et appelons-le Spark fun Scala. Je ne sais pas, appelez ce que vous voulez. Et nous allons dire ici que nous utilisons la dernière version d'EMR. Ce n'est pas une bêta du moins. Et ça va utiliser Spark. Nous voulons sélectionner l'application Spark ici. Et vous pouvez le voir en ce moment, ils offrent Spark 2.4.4. Ils n'ont pas encore eu le courage de créer une étincelle 3. Mais au moment où vous regarderez cette vidéo, peut-être que ce sera aussi une option. Mais c'est pourquoi nous emballons nos fichiers JAR spécifiquement pour Spark 2.4.4 et Scala à 0.11. Parce que nous savions que c'est ce que ce cluster va avoir installé dessus. Pour la configuration matérielle, nous pouvons respecter les valeurs par défaut ici. Cela va réellement faire tourner un cluster Spark de trois nœuds. Typiquement, c'est Spark qui s'exécute au-dessus de Hadoop, et ce sera toutes les instances importantes m5 suivantes. Les choses ne sont pas bon marché, elles ne sont pas Frigyes. Donc, même si vous êtes comme un tout nouveau compte où vous parlez de niveau gratuit. ne s'agit pas d'un matériel de niveau gratuit. Donc encore une fois, cela a coûté de l'argent réel à tourner, m'a
coûté environ 30 dollars pour le faire quand je mettais tous ces exercices ensemble. Donc encore une fois, si ça te rend grincheux, ne fais pas ça, regarde juste. Vous devez également spécifier une paire de clés EC2. J' en ai déjà un créé qui s'appelle Sun dog EC2. Et si vous avez besoin d'en créer une nouvelle, vous pouvez simplement suivre ce lien pour apprendre à créer votre propre paire de clés EC2. Donc, vous obtenez une clé publique et une clé privée que vous pouvez utiliser pour réellement vous connecter à ce cluster plus tard, vous aurez besoin de cela pour réellement vous connecter au nœud maître et lancer le script. Les autorisations par défaut sont correctes. Allons de l'avant et appuyez sur Créer un cluster. Et il s'en va. Donc ça va aller et approvisionner tout le matériel dont nous avons besoin. Nous prendrons quelques minutes pour obtenir ce matériel et mettre tout en place et amorcer dessus. Donc nous reviendrons quand ce sera fini de faire l'installation. Ok, donc après environ cinq ou dix minutes, nous voyons que nous avons maintenant nos machines maîtresses et nos machines principales en état de marche ici. Et mon cluster attend juste que je fasse quelque chose. Tellement cool, mon cluster est prêt. Alors faisons quelque chose avec ça. Pour le faire d'abord, je dois me connecter à lui d'une manière ou d'une autre. Donc, vous pouvez voir ici sous le maître DNS public SEC me
donne l'adresse externe disponible du nœud maître. Ensuite, je vais exécuter mon script à partir de. Et si je clique sur ce lien SSH, il vous dira exactement comment vous y connecter. Donc, pour Windows, vous pouvez utiliser quelque chose appelé comme mastic pour un programme de terminal. C'est ce que j'utilise. Et si vous avez besoin de l'installer, Il y a un dandy pratique télécharger le lien là pour vous. Et il vous indique exactement comment vous connecter. En utilisant ça. Si vous êtes sur Mac ou Linux, ils ont également des instructions pour vous. Mais je suis sous Windows. Donc ce qu'on va faire, c'est copier cette adresse pour que je
puisse l'introduire rapidement et ouvrir du mastic. Tapez cette valeur pour le nom d'hôte. Et puis j'ai besoin de spécifier mon fichier APK, ma clé privée pour réellement me connecter à cela. Alors rappelez-vous, je spécifie pendant que je mettais en place un cluster que j' allais utiliser la clé Sun dog EC2. Et c'est là que j'enregistre ce fichier là. Donc maintenant je devrais pouvoir juste frapper Open. Et là, nous sommes connectés à notre nœud maître. Maintenant, en fonction de vos paramètres de sécurité, vous pouvez réellement obtenir un délai d'expiration à ce stade. Donc, si vous essayez de comprendre pourquoi vous ne pouvez pas vous connecter, peu importe ce que vous essayez avec les paramètres de votre pare-feu ou quand vous ne parvenez toujours pas à passer. Azar est bloqué côté serveur. Donc, si vous rencontrez cette astuce rapide, vous pouvez cliquer sur le groupe de sécurité ici pour le nœud maître. Et une fois que vous êtes là, vous pouvez cliquer sur les règles entrantes ici et vous assurer que vous avez un port SSH ouvert. Donc, dans ce cas, j'ai dû ajouter manuellement un port TCP SSH au port 22 à l'adresse IP à partir de laquelle je me connecte. Donc, si vous avez du mal à vous connecter, c'est probablement ce que vous devez faire. Mais revenons à l'endroit où nous
étions, à la console EMR. Et de toute façon, nous sommes maintenant connectés. Maintenant, on peut commencer à faire des trucs amusants. Tout d'abord, voyons où nous en sommes. Nous devrions avoir un petit répertoire personnel ici sous l'utilisateur Hadoop. D' abord, je vais faire est de copier sur notre script de pilote réel dans le fichier jar que nous avons créé en utilisant SBT plus tôt. Donc, continuons et copions cela à partir de S3, EMR et AWS EC2 nœud a un ensemble d' utilitaires intégrés appelés AWS que vous pouvez utiliser pour copier réellement des choses à partir de S3. Et des trucs. Donc, je peux taper AWS, S3, CP, Voyons voir, slash s3 deux-points slash, Sun dog. Je ne peux pas le dire à un parc à chiens. Et qu'est-ce que j'ai appelé le dossier ? La similitude des films est un pot de point m. Les similitudes d'un m point char ici. D' accord, et vous pouvez voir que ça a fonctionné. L' autre chose dont j'ai besoin est le fichier DAT de films. Donc, je peux réellement faire la construction de la table de recherche que les identifiants de film aux noms de film. Et encore une fois, j'ai mis cela dans le tableau de bord ML un sous-dossier m. Donc, copions ça aussi. Aws S3 copie slash s3 deux-points barre oblique, slash Spark ML tiret 1M slash films ont été adaptés au répertoire local. Donc, nous l'avons là. D'accord, j'ai un peu
élargi la fenêtre ici pour mieux voir nos résultats. Et tout ce que je dois faire maintenant est de taper dans Spark Dash, soumettre le nom du fichier jar, similitudes de
film, un pot de point m. Et si vous vous souvenez bien, cette Écriture nécessite un paramètre de ligne de commande de l'ID de film pour lequel nous sommes intéressés à trouver des similitudes. Donc, je sais que Star Wars est 260 dans le jeu de données 1 million. Faisons le coup d'envoi. Bon, donc nous voyons quelques messages d'information d'introduction ici. Et l'une des premières choses que le script fait est de désactiver tout sauf les messages d'erreur. Donc, nous ne devrions pas voir autre chose que les messages de
progression car il brise réellement cela et le répand au cluster. Donc, nous attendons essentiellement qu'il obtienne cette première commande d'action et crée le DAG. J' ai juste chargé les noms des films et il est maintenant en train de les étaler. ce moment, en ce moment,
nous Ence moment, en ce moment,
nouscalculons des films similaires pour Star Wars en utilisant 1 million d'évaluations sur un petit groupe de trois machines. Des trucs plutôt cool. Nous en sommes déjà à l'étape 2 et je me souviens que les étapes sont
divisées par des zones du DAG qui sont divisées par des opérations de mélange de données. Et ces étapes à leur tour sont divisées en tâches. Donc, vous pouvez voir ici dans la deuxième étape où passer 32 tâches, il y aura une autre étape après cela avec un 100 pour la, un 100 partitions que nous avons mis en place. Et dans environ cinq minutes, cela sera fait. Cela ne prend pas si longtemps, sorte de puissance d'un cluster passant à travers un million de notes et chaque permutation possible de chaque paire de films possibles
, puis filtrant les résultats que nous voulons étudiant un beaucoup de travail, mais il le fera assez rapidement. Revenons dans cinq minutes et je vous montrerai les résultats. D' accord, on a presque fini ici. Il est là. Génial. Nous avons donc les meilleurs films similaires pour Star Wars Episode 4 et un nouvel espoir basé sur 1 million de évaluations de films réels. Et ces jours-ci, c'est un peu plus récent depuis 2003. Encore une fois, nous ne verrons pas de films actuels, mais les résultats semblent assez raisonnables. Nous avons un Star Wars Episode 5 et le pouvoir frappe les soutiens de l'Arche Perdue. Retour des Jedi, en quelque sorte obtenir cette raison pour laquelle l'Arche Perdue a été classée plus haut Retour des Jedi. Mais pour être honnête, je pense que j'aurais pu apprécier les Raiders de l'Arche Perdue plus que le Retour des Jedi. Donc ce n'est peut-être pas aussi fou que ça en a l'air. Et le film original d'Indiana Jones, très bonnes recommandations pour quelqu'un qui aime Star Wars. Et puis on commence à se lancer dans d'autres grands films qui étaient bons. La matrice des terminateurs, il y en a quelques, quelques assez bons ici, retour à la future Princesse Mariée, tout fait appel à une sorte de démographie geeky. Très cool. Hey chéri Python et le Saint Graal, même ce sont en fait des recommandations assez sincères raisonnables. Cool, et là tu l'as. C' est donc des recommandations de films, films
similaires et Star Wars en utilisant 1 million d'évaluations de films s'exécutent sur un cluster réel en utilisant Hadoop yarn et ApachesPark. C' est de quoi il s'agit. Maintenant, dernière étape, n'oubliez pas de mettre fin au cluster lorsque vous avez terminé. Donc je vais sortir de là,
mais ce n'est pas suffisant. Et je dois retourner au tableau de bord EMR. Et dans mon cluster hit terminent. Oui, je suis sûr que j'en ai fini. Maintenant, si tu ne fais pas ça, la facture va continuer à courir pour toi. Ce cluster est toujours en cours d'exécution et même si vous ne faites rien avec, vous allez toujours être construit pour le temps sur ce cluster, pour cela tous ces trois ordinateurs ou même plus si vous en configurez plus. Donc encore une fois, si vous faites cela sur votre propre sou et que vous suivez réellement le long, s'il vous plaît rappelez-vous, déterminez votre cluster quand vous avez terminé. Je ne veux vraiment pas en entendre parler. Si vous obtenez une facture pour 1000$ à la fin du mois d'Amazon,
supposé à 10, ce qui est à propos de ce que cela coûte. D' accord. Assurez-vous que cela se termine avec succès, puis il est sûr de le fermer. Mais avec ça, woo hoo, félicitations, c'est un peu l'aboutissement de ce que nous avons fait ici. En fait, nous avons réalisé une véritable
grosse étincelle, un travail Big Data sur un vrai cluster avec succès et nous avons obtenu des résultats vraiment utiles. Des trucs tellement cool. Parlons un peu plus en profondeur dépannage des tâches Spark et de certains des points les plus fins de l'exécution dans le réglage des choses.
47. Partitionnement: Donc, une chose que j'ai vraiment brillé était cette ligne ici dans ces films similarité est un fichier Scala point de jeu de données m ici dont nous n'avons pas parlé. Ceci est différent de notre script original de jeu de données sur les similitudes de films. Cette ligne ici, repartition des partitions num est égale à 100. Nous avons donc appliqué cela à notre auto-joint un DataFrame avant de convertir cela en un jeu de données. Alors, c'est quoi tout ça ? Qu' est-ce que le repartitionnement ? Pourquoi dois-je faire ça ? Eh bien, c'est une opération
vraiment, vraiment lourd ici je fais cette auto-jointure à travers un million de notes va exploser très
vite et c'est plus que ce que vous pouvez vraiment faire sur une seule machine. Donc dans ce cas, on doit dire à Spark, tu veux vraiment diviser cette opération. Et ce paramètre de repartition lui indique combien de façons vous voulez diviser cette opération. Alors parlons de ça un peu plus en profondeur. Donc Spark est généralement assez magique. Il fera automatiquement la bonne chose pour répartir votre travail sur un cluster entier. Mais parfois, vous devez lui donner quelques conseils et parfois vous devez réfléchir un peu à façon dont vos données seront partitionnées entre les différents exécuteurs de votre cluster. Maintenant, l'exécution de ce script de similarité de film comme il était sans cet appel de repartition pourrait ne pas fonctionner du tout seul. C' est une opération vraiment, vraiment coûteuse, et Spark n'est pas toujours assez intelligent pour le distribuer de lui-même de la bonne façon. C' est vraiment la partie la plus exigeante de ce script. Et nous devons donner quelques conseils aux étincelles pour nous assurer que nous ne manquions pas de
ressources en demandant à un seul exécuteur testamentaire de faire plus que ce qu'il peut faire. Donc, en appelant explicitement repartition sur ce DataFrame. Et si vous utilisiez des RDD, il y a une fonction de partition BY qui fait la même chose sur les RDD. Si vous l'utilisez avant d'exécuter une opération de grande envergure qui bénéficie du partitionnement, cela vous assurera que les choses sont divisées d'une manière qui a du sens. Maintenant, certaines opérations qui bénéficient du partitionnement incluent jointure, ce que nous faisons dans cet exemple. Aussi le groupe COGROUP avec cette jointure, jointure externe gauche, Bisk, tout type d'opération jointure ou GroupBy ou réduit par opération ou combiné par opération. La recherche peut également en bénéficier. Donc, si vous appelez l'une de ces méthodes sur un jeu de données très volumineux, vous pouvez penser à le partitionner explicitement en utilisant la fonction de repartition. Et lorsque vous faites cela, les opérations préserveront ce partitionnement et les résultats. Donc, vous obtiendrez vos résultats cassés par ces partitions aussi. Alors gardez ça à l'esprit. Comment choisir une taille de partition ? D' où vient ce numéro 100 ? Eh bien, si vous avez trop peu de partitions, ça ne va pas profiter pleinement de votre cluster, n'est-ce pas ? Donc, si j'ai moins de partitions, alors j'ai des exécuteurs. Cela va laisser certains exécuteurs inactifs sur cette tâche. Donc, je veux certainement au moins autant de partitions que j'ai des exécuteurs sur mon cluster. Sinon, je gaspille des ressources, non ? Donc, pour rendre cela réel, si je prends l'opération auto-jointure que nous utilisons dans ce script. Et je dis repartition deux. Et j'ai cinq noeuds dans mon cluster que trois de ces noeuds vont rester inutilisés. C' est inutile parce que je vais seulement
distribuer ce travail entre deux partitions. Mais si vous en avez trop, cela entraîne trop de surcharge en mélangeant toutes les données autour. Ainsi, déplacer des données autour de votre cluster est également une opération coûteuse. Tu ne veux pas trop faire ça non plus. Donc, vous devez un peu frapper ce point doux où vous tirez pleinement parti des clusters et des exécuteurs que vous avez sur votre, sur votre cluster. Mais ne pas avoir une quantité ridicule de partitions où les frais généraux de gestion de tout devient prohibitif. Donc, en général, vous voulez au moins autant de partitions que vous avez des cœurs ou des exécuteurs qui correspondent à votre mémoire disponible pour votre cluster, 100 est généralement un endroit raisonnable pour commencer pour les opérations volumineuses. C' est ce que nous utilisons ici, ça marche. Ce n'est pas un chiffre fou qui va avoir une tonne de frais généraux. Et c'est probablement un nombre qui est plus que le nombre d' exécuteurs que vous avez sur un cluster typique. Donc c'est généralement un bon point de départ. Mais si vous aviez plus de 100 exécuteurs,
évidemment, vous voudriez utiliser un nombre encore plus élevé là-bas. C' est donc ce qu'est le partitionnement. Encore une fois, si vous utilisez une opération de jointure de très grande taille ou un groupe réduit de, cela peut bénéficier d'un partitionnement explicite. Parfois, cela peut faire la différence entre succès de
votre travail ou le manque de mémoire. Donc, si vous rencontrez des problèmes bizarres où votre script échoue et manque de ressources même si vous avez un énorme cluster disponible. C' est peut-être pourquoi vous pourriez avoir besoin de revenir en arrière et de réfléchir, ai-je besoin de partitionner explicitement ces opérations en utilisant la commande repartition ?
48. Meilleures pratiques pour la course sur un cluster: Allons dans quelques détails plus grossiers de l'exécution sur un cluster. Tout d'abord, assurez-vous d'éviter toujours de spécifier une configuration pour Spark dans le script du pilote lui-même. Cela inclurait la spécification de votre configuration principale. Rappelez-vous, nous mettons normalement des maîtres définis sur étoile
locale pour dire que vous voulez exécuter localement sur votre machine. Évidemment, vous ne voudriez pas le faire sur un vrai cluster. Vous voulez utiliser l'ensemble du cluster, pas seulement un cœur de CPU, même plusieurs cœurs de CPU sur un seul système. Que voulez-vous faire cependant est d'utiliser les valeurs par défaut que Elastic MapReduce configuration à la place si vous exécutez sur Elastic MapReduce et que cela restera vrai sur plupart des clusters que vous pourriez exécuter sur lesquels Spark est pré-installé, les chances sont étincelantes déjà être configurées hors de la boîte sur votre cluster pour avoir le droit de tomber configuration. Et vous voulez également faire attention aux options de ligne de commande que vous transmettez dans Spark desk soumettre à partir de votre nœud maître, vous pouvez les remplacer. De cette façon. La façon dont cela fonctionne est qu'une chose dans votre script de pilote est prioritaire. Après ça. Tout ce que vous transmettez en tant qu'argument de ligne de commande à spark desk submit sera prioritaire. Et enfin, les fichiers de configuration sur le cluster lui-même auraient le dernier mot dans la chaîne de commande là-bas, si vous voulez. Donc, de façon générale, encore une fois, votre cluster sera configuré avec la configuration correcte hors de la boîte. Et cela est vrai pour Elastic MapReduce aussi. Par conséquent, vous ne voulez généralement pas spécifier configurations dans le script du pilote lui-même ou sur la ligne de commande. Il vaut généralement mieux laisser la configuration faire sa magie pour vous. Évidemment, si vous êtes un administrateur système et que
c'est votre travail de configurer cette configuration, alors vous devez y réfléchir. Mais en tant que développeur d'applications généralement, vous ne le ferez pas. Cependant, il y a des situations où vous devez modifier les choses si vous trouvez que vos exécuteurs échouent et un travail important, peut-être que vous devez ajuster la mémoire que chaque exécuteur a. Donc, si vous voyez des messages d'erreur suggérant que vous êtes à court de mémoire sur vos nœuds exécuteurs. Eh bien, tu dois faire quelque chose à ce sujet. Une façon est de simplement augmenter la quantité de mémoire que chaque exécuteur lui a allouée. Ainsi, par exemple, vous pourriez dire estimation déclenchée,
tiret, mémoire de l'exécuteur de tiret un G. Et cela allouerait explicitement un gigaoctet de RAM à chaque exécuteur. Bien sûr, cela suppose que vous avez suffisamment de RAM disponible sur chaque nœud de votre cluster pour tirer cela. Mais, tu sais, c'est une sorte d'approche de force brute, non ? Et peut-être que ce que vous devriez vraiment faire est de penser plus à partitionner et à diviser vos données d'une manière plus efficace. Vous pouvez également spécifier un gestionnaire de cluster sur la ligne de commande. Par exemple, vous pouvez dire tiret, fil maître de tableau de bord. Si vous souhaitez exécuter explicitement en utilisant le fil, un gestionnaire de cluster sur un cluster Hadoop. Mais encore une fois, cela va probablement être configuré pour vous par défaut. Et sur Elastic MapReduce c'est, il va simplement déduire automatiquement que le maître par défaut est
le gestionnaire de cluster de fils parce que Elastic MapReduce est en cours d'exécution sur Hadoop, qui a le gestionnaire de cluster de fils. Donc, vous n'avez pas vraiment besoin de faire quoi que ce soit là, mais vous pouvez spécifier un maître à partir de la ligne de commande si vous voulez avoir cette flexibilité. Et d'autres bonnes pratiques ici, un rappel. Encore une fois, il est très important de s'assurer que vos scripts dans vos données ou un endroit où EMR ou quel que soit le cluster sur lequel vous exécutez peuvent y accéder. Si vous utilisez EMR, vous allez probablement utiliser le service AWS S3. C' est un simple service de stockage. Et si vous faites cela, vous pouvez simplement utiliser le préfixe
d'URL S3, AN pour spécifier le chemin d'accès à votre compartiment S3. Et vous devez juste vous assurer que vos autorisations de fichiers sont accessibles à votre cluster EMR. Cela peut parfois être une chose délicate avec AWS en général, ces autorisations, je veux dire, la chose la plus simple à faire est de simplement rendre votre compartiment accessible publiquement. Mais s'il s'agit de données sensibles, vous
devez penser à des autorisations plus explicites où vous liez choses spécifiquement à l'endroit où votre cluster EMR est en cours d'exécution. Et je ne veux pas entrer dans les spécificités de la sécurité AWS dans ce cours, c'est un tout autre sujet, mais il est possible qu'une fois que vous avez tout ce dont il a besoin, vous puissiez alors faire tourner votre cluster à
l'aide d'AWS ou si vous voulez utiliser l'API, c'est bien aussi. Et dès que vous faites tourner ce cluster, c'est
là que l'horloge démarre. Et rappelez-vous dès que vous faites tourner ce cluster, l'horloge commence à la facturation, peu importe que vous ne l'utilisiez pas, vous serez facturé à l'heure là-bas. Et pour un cluster qui contient de grandes machines et beaucoup d' entre elles qui peuvent devenir extrêmement coûteux, extrêmement rapidement. Alors assure-toi de savoir ce que tu fais là-dedans. Une fois que tu as fait tourner ce cluster, tu dois te précipiter parce que le temps c'est de l'argent, non ? Donc, vous devez obtenir le nom DNS externe pour ce nœud maître. Connectez-vous à l'aide du compte Hadoop et votre fichier de clé privée que vous avez utilisé lors de la configuration du cluster. Une fois que vous êtes en copie sur vos pilotes fichier programme jar et tous les fichiers dont vous avez besoin sur le pilote du script lui-même. Vous pouvez utiliser la commande AWS S3 cp pour copier les éléments que vous téléchargez dans S3 à l'avance, puis exécuter l'estimation déclenchée, et j'espère que cela fonctionne. Et encore une fois, n'oubliez pas de mettre fin à votre cluster lorsque vous avez terminé. Si vous oubliez de fermer votre cluster une fois votre travail terminé, vous aurez une très, très,
très mauvaise surprise sur votre facture de carte de crédit à la fin du mois. Et il est possible d'ailleurs, avec EMR de configurer les choses pour exécuter automatiquement un script dès qu'il tourne et s'éteint automatiquement dès que c'est fait. Donc, une fois que vous avez travaillé les bogues de votre script et vous pouvez l'exécuter de manière fiable. Vous pouvez configurer les choses de sorte que dès
que vous faites tourner ce cluster démarre automatiquement votre travail. Et c'est faire tourner cette grappe quand tu en as fini. Dans certaines situations, cela a du sens. Dans d'autres situations, votre entreprise pourrait avoir assez d'argent pour simplement garder ce cluster en cours d'exécution tout le temps et le garder accessible à son développeur est 24, 7. Mais pour la plupart d'entre
nous, nous n'avons pas ce genre de luxe à notre disposition. Donc, vous devez penser à vous assurer que vous regardez combien de temps d'exécution de votre cluster 4. Et la meilleure façon de minimiser ce coût est de déboguer et de travailler localement les kinks de votre script. Tout d'abord avant d'essayer de l'exécuter sur un cluster réel. C' est ce que nous avons fait tout au long de ce cours. Donc, si vous avez un jeu de données volumineux que vous ne pouvez pas exécuter sur une machine utilise un sous-ensemble de ces données initialement pour résoudre les plis dans votre application. Et encore une fois, assurez-vous que tous les fichiers de données dont vous avez besoin seront accessibles à chaque note d'exécuteur sur chaque machine qui peut être dans votre cluster. Tout ce qui pourrait être référencé ou lu à partir d'un exécuteur distribué doit être accessible au-delà de l'endroit où votre script de pilotes s'exécute. Donc, tant que vous faites attention à ce genre de choses et que vous faites encore attention à ne pas spécifier la configuration spécifique à l'exécution sur un seul ordinateur dans votre script de pilote final, vous devriez être en mesure d'obtenir les choses assez proches de s'exécutant de manière fiable avant de commencer à expérimenter sur le cluster lui-même.
49. Troubleshooting, et gérer les dépendances: Allons donc un peu plus en profondeur sur dépannage de vos tâches une fois qu'elles sont exécutées sur un cluster. Malheureusement, c'est un peu un art sombre. Il peut être très difficile de suivre genre d'erreurs lorsqu'elles s'exécutent dans la complexité de Spark lui-même et de plus sur la complexité d'être distribuées sur plusieurs nœuds. Maintenant, votre maître exécutera une console sur le port 4040 qui vous permettra de voir informations sur ce qui se passe dans ce qui peut parfois conduire à des informations sur les raisons pour lesquelles votre travail échoue. Mais si vous voyez des messages d'erreur dans vos journaux, ce sera un peu difficile de les retrouver pour une chose. Tout d'abord, vous allez voir cette pile d'appels profonde dans vos fichiers journaux si vous avez une erreur, car rappelez-vous que vous exécutez votre code Scala qui est compilé en code Java. Et à travers toutes ces couches de compilation, il est facile de se perdre là où les choses tournent. Donc, généralement, vous verrez des choses mourir comme profondément dans le cadre de Spark lui-même. Et si vous regardez assez dur si finalement, vous devriez voir un message d'erreur ou une sorte d' exception qui vous conduit au problème réel dans votre script, mais vous n'êtes pas toujours aussi chanceux. Cependant, regardons la console principale ici pour voir quelles informations elle nous donne maintenant. Et encore une fois, c'est, cela peut être difficile car un Elastic MapReduce, il est pratiquement impossible de se connecter à cela depuis l'extérieur de votre cluster. Donc, si vous voulez vous connecter à cette console à partir de votre bureau qui s'exécute en dehors de votre environnement EMR. C' est une chose difficile à installer. A peut être fait à travers des choses comme les hôtes proxy et des choses comme ça. Mais c'est dur. Si vous avez votre propre cluster, fonctionnant sur votre propre réseau, la vie va être beaucoup plus facile à cet égard à votre oreille, ces problèmes de sécurité devraient être quelque chose que vous pouvez résoudre un peu plus facilement. Jetons donc un coup d'oeil à la console fonctionnant sur notre propre machine locale pour commencer. Et nous allons en quelque sorte explorer les informations qu'il vous donne. Ok, alors explorons la console Spark dont j'ai parlé. Maintenant, malheureusement, il ne sera disponible que pendant que Spark lui-même est en cours d'exécution. Donc, si je n'exécute pas réellement une interface de base de données constante pour étinceler ou quelque chose comme ça. Je vais seulement pouvoir y arriver pendant que mon script d'étincelle est en cours d'exécution. Donc, pour des raisons d'illustration, lançons ici un script étincelle vraiment charnue qui fonctionnera pendant quelques minutes, donc nous aurons le temps de l'explorer dans le matériel du cours. Il y a un jeu de données de recommandations vidéo, script local. Et cela est configuré pour utiliser le jeu de données de 1 million de ML localement sur votre machine ici. Donc, vous n'avez pas besoin de l'exécuter avec moi nécessairement, mais si vous le voulez, vous verrez que j'ai installé le jeu de données ML tiret 1M ici dans le dossier de données de mes matériaux de cours. Et ce script est destiné à aller l'utiliser. Donc, une fois que j'ai tiré
ça, ça va courir quelques minutes en essayant de trouver films
les plus semblables à Star Wars. Et pendant qu'il le fait, nous pouvons explorer la console. Et j'ai un navigateur web prêt à aller pour ça. Configurez jusqu'à 127 point 0, c'est-à-dire 0 point un deux-points 4040, 127, 100, 000 point un est l'adresse IP de notre hôte local. Et puisque je lance Spark localement sur mon bureau ici, ce sera l'adresse IP que je vais frapper pour la console Spark. Et 40, 40 est le port sur lequel il fonctionne. Donc je vais lancer ça. Et dès que Spark est en cours d'exécution, je rechargerai cette page et nous devrions voir une console. Retournons à IntelliJ et on va lancer ça. Et je vais lui donner un peu de temps pour tourner. On veut s'assurer qu'il a eu le temps de se déclencher. C'est des exécuteurs. Je crois qu'on y est. Revenons à notre tableau de bord ici et rechargez-le. Et je vais aller de l'avant et ouvrir chacun d'entre eux dans un nouvel onglet pour que nous puissions les explorer. Et si vous allez à des emplois, vous pouvez voir que nous pouvons explorer n'importe quel ID de travail individuel ici. Et vous pouvez faire des choses comme visualiser le graphique acyclique dirigé. C' est plutôt cool. Vous pouvez faire la même chose à partir des étapes. Encore une fois, creusez dans n'importe quelle étape que vous voulez. Celle-ci, Prenons par exemple, qu'on n'a pas encore commencé. Alors essayons le premier. Et vous pouvez voir que cela nous donne beaucoup plus d'informations aussi. Encore une fois, il y a une Visualisation DAG disponible ici aussi. Donc, cela peut juste continuer à courir et à faire son truc pendant que nous explorons cela à ce stade. Revenons à l'onglet Jobs ici. Vous pouvez voir qu'il vous donne une sorte de représentation graphique de la chronologie de l'événement. Nous avons donc lancé le pilote à ce stade et il a été
essayé d'exécuter cette action finale et de comprendre ce qu'il doit faire pour réaliser cette dernière action que nous avons dans le script pilote pour obtenir les dix premiers films ressemblants à Star Wars. Donc, cela vous montre les progrès qu'il passe par toutes les tâches pour accomplir cela. Et si vous allez à l'onglet Stages ici, vous pouvez voir qu'il vous montre votre progression dans ce sens. Et rappelez-vous, les étapes représentent chaque point de l'exécution où il doit mélanger les données. Il est donc bon d'obtenir une visualisation sur le nombre d'étapes qui sont réellement impliquées dans l'accomplissement du travail que vous voulez. Parce que plus d'étapes, c'est mauvais. Chaque fois que vous avez un stage, il doit mélanger les données dans le cluster. Et c'est une opération très coûteuse. Donc si vous voyez moins d'étapes, c'est une bonne chose. Et encore une fois, vous pouvez percer dans une étape individuelle. Je pense que c'est fini, donc on peut vraiment regarder ça. Allons de l'avant et recommençons ce script. Ok, on a des résultats pour créer une curiosité. Hé, ça a bien fonctionné. Donc, notre algorithme de filtrage collaboratif de similarité a fonctionné assez bien. Dit le meilleur résultat pour l'épisode de Star Wars, Episode 5, Star Wars, C'est comme nous avions dans nos diapositives. Donc c'est cool à voir. Rays of the Lost Ark, Star Wars épisode 6, Indiana Jones. Toutes les grandes recommandations pour Star Wars, mais donnons le coup d'envoi à nouveau pour que nous puissions jouer avec la console un peu plus. Bon, alors revenez à l'onglet Stages. Je pense que c'est là qu'on jouait. Encore une fois, vous pouvez cliquer sur une étape individuelle. Je devrais recharger ceci pour en savoir plus sur ce qui se passe dedans. Et ça te dit toutes sortes de choses. Combien de temps cela prend pour mélanger ces données. N' oubliez pas que les étapes sont associées à des données de mélange. Nous pouvons visualiser le graphique acyclique dirigé qu'il a trouvé. Donc c'est plutôt cool à voir. Donc, si vous essayez d'optimiser la performance de votre travail, l'affichage, cela peut vous donner un aperçu façon dont il décompose réellement ce que vous lui avez demandé de faire. Et parfois cela peut conduire à une meilleure façon de structurer votre script de pilote pour être plus efficace. Que pouvons-nous regarder d'autre ? Le stockage va probablement être vide. Je ne stocke rien. L' environnement vous donne des informations sur l'environnement d'exécution. Rafraîchissons ça aussi. Et vous pouvez voir que nous fonctionnons sous le JDK, sous JDK 14 sur mon lecteur C. En utilisant cette version Java, cette version Scala, juste quelques informations générales. Nous pouvons également examiner les propriétés du système. Donc, si vous voulez obtenir plus d'informations sur l'environnement sur lequel votre script est en cours d'exécution, vous pouvez le faire. Ils sont sous les exécuteurs. Cela vous montre combien d'exécuteurs sont en cours d'exécution, et cela lui-même est intéressant. Donc, seul un seul exécuteur est en cours d'exécution en ce moment. Donc, cela me dit, par exemple, que même si j'ai plusieurs cœurs CPU sur ma machine ici, il ne l'utilise pas réellement. Donc, cela pourrait être la manière de la nature de me dire que je n'ai pas écrit des choses de telle sorte qu'elles puissent être parallélisées ou qu'il pourrait y avoir quelque chose mal avec ma configuration qui mène à ce problème. Si je l'exécutais sur un vrai cluster et que j'ai vu un seul
exécuteur en cours d'exécution tout au long de cela. Cela me donnerait probablement un indice assez fort que quelque chose ne
va vraiment pas avec la configuration sur mon cluster que je devrais aller comprendre. C' est donc une sorte d'aperçu des choses que vous pouvez voir à l'aide de la console Spark. Avec cela, parlons un peu plus de profondeur sur le dépannage une fois que vous l'avez. Maintenant, lorsque les choses tournent mal, vos journaux en mode autonome seront également disponibles dans cette interface utilisateur Web. Mais si vous êtes en cours d'exécution sur le gestionnaire de cluster de fils comme nous le faisons avec EMR. Ces journaux seront distribués dans chaque nœud individuel de votre cluster. Maintenant, vous pouvez les collecter après le fait en utilisant les journaux de fil tiret, tiret ID d'application. Vous pouvez déterminer l'ID d'application de votre tâche qui s'exécute là. Donc, si vous exécutez dans le Spark Cluster Manager autonome, la vie peut être un peu plus facile. Il y aura juste là dans l'interface utilisateur pour vous. Mais si vous courez sur Hadoop, les choses deviennent compliquées pour trouver ces journaux. Encore une fois, il souligne simplement à nouveau l'importance de déboguer ces problèmes localement sur votre propre machine avant d'essayer de
les déboguer sur un cluster où il est plus difficile d'obtenir ces informations. Maintenant, pendant que votre script de pilote est en cours d'exécution, il enregistre lui-même les erreurs comme les exécuteurs qui ne parviennent pas à émettre des pulsations cardiaques. Donc, c'est un bon signe que votre exécuteur
échoue et se bloque pour une raison quelconque sur un nœud distant. Donc, parfois, la sortie de vos scripts de pilote peut vous donner quelques indices sur ce qui se passe. Si vous voyez des erreurs comme ça, cela signifie probablement que vous demandez trop à chaque exécuteur. Peut-être que vous avez besoin de plus d'entre eux, peut-être que vous avez juste besoin plus de machines dans votre cluster pour gérer le travail que vous faites. Peut-être que vous avez besoin de donner plus de mémoire à chaque exécuteur. Nous avons abordé cela dans la leçon précédente. Comment faire ça ? Cela peut juste être un paramètre de ligne de commande supplémentaire sur Spark submit. Ou peut-être que vous devez utiliser PartitionBy ou repartition pour exiger moins de travail de vos exécuteurs individuels en utilisant des partitions plus petites. Donc jeter plus d'éditeur de machines ou plus de mémoire est une sorte de solution de force brute à des problèmes comme celui-ci. Mais parfois, si vous utilisez simplement explicitement repartition pour diviser le travail en morceaux plus petits, vous pouvez vous en sortir avec moins de matériel ou moins de mémoire. Il faudra juste plus de temps pour terminer le travail. C' est souvent la bonne chose à faire. Donc, ne voyez pas simplement aller jeter plus de matériel au problème si vous n'en avez pas besoin. Si vous effectuez de grandes opérations conjointes dans votre script ou des opérations GroupBy
volumineuses ou si vous réduisez les opérations. Vous pouvez probablement résoudre ces problèmes simplement en utilisant judicieusement
la commande repartition pour diviser les choses en morceaux plus petits. Et rappelez-vous également que vos exécuteurs ne sont pas nécessairement en cours d'exécution sur la même boîte que votre script de pilotes. Vous ne pouvez donc pas supposer que les données en mémoire seront accessibles sur l'ensemble du cluster. Vous devez vous assurer que c'est le cas. Si vous avez besoin de partager des données en dehors de vos RDD sont des jeux de données, vous devrez utiliser des variables de diffusion pour cela. Vous ne pouvez pas simplement stocker cela localement dans votre script de pilote et vous attendre à ce qu'il fonctionne. Si vous avez besoin d'une sorte de package Java ou Scala qui n'est pas préchargé sur votre cluster, assurez-vous que vous les regroupez dans votre jar que vous exécutez en utilisant l'assembly SBT. Vous pouvez également utiliser des bocaux tirets, tirets avec Spark submit pour ajouter bibliothèques
individuelles qui se trouvent sur le nœud maître et qui les distribueront automatiquement aux exécuteurs ER. Mais cela peut devenir vraiment compliqué très rapidement car souvent les pots que vous voulez inclure eux-mêmes ont des dépendances JAR et vous devez spécifier toutes ces dépendances avec elle aussi. Beaucoup plus facile à utiliser simplement sbt pour emballer tout ensemble dans le pot lui-même. Et vous savez, vraiment essayer d'éviter d'utiliser paquets
obscurs dont vous n'avez pas vraiment besoin en premier lieu est probablement le meilleur conseil. Rappelez-vous, le temps est de l'argent sur votre cluster et si vous ne perdez pas
de temps à jouer avec les problèmes de distribution de ces paquets jar dans vos exécuteurs. Et bien, d'autant mieux. Donc, si vous pouvez obtenir en utilisant simplement les paquets Spark de base et un peu plus, ce sera probablement la meilleure stratégie pour simplifier les choses. Rappelez-vous, un simple est bon quand il s'agit de l'ingénierie logicielle en général. Et avec ça, je pense que nous avons parlé de courir sur un cluster en profondeur. Passons donc à notre prochaine section.
50. Présentation MLLib: Cette section suivante est assez excitante pour moi parce que j'aime beaucoup l'apprentissage automatique. C' est une grande partie de ce que j'ai fait dans le passé. Et nous allons parler de la façon d'utiliser l'apprentissage automatique sur Spark. Et c'est super excitant parce que la puissance des algorithmes
d'apprentissage automatique est généralement limitée à une seule machine. Souvent, les gens les développent sur un seul PC qui exécute un ordinateur portable quelque part, n'est-ce pas ? Mais si vous avez un jeu de données massif, que faites-vous ? Eh bien, Spark a en fait une solution pour de nombreux algorithmes d'apprentissage automatique populaires. Voyons donc comment la bibliothèque ML de Sparks vous permet d'appliquer DataFrames sur un cluster entier sur Spark pour résoudre des problèmes complexes d'apprentissage automatique. Des trucs assez puissants. Allons plonger dedans. Parlons de Sparks Machine Learning Library, qui est étonnamment appelé bibliothèque Sparks ML, nom créatif. C' est vraiment cool car il vous permet de distribuer le traitement de jeux de données
massifs et de leur appliquer des algorithmes d'apprentissage automatique
sophistiqués à grande échelle. Il existe donc des moyens plus simples d'appliquer ces algorithmes et techniques aux données sur une seule machine en utilisant simplement du code Python et des Notebooks Jupiter. Mais quand vient le temps de distribuer ces choses sur un cluster entier parce que vous avez un jeu de données vraiment massif. Eh bien, ces outils qui sont si couramment utilisés s'effondrent et nous devons le transformer quelque chose comme Spark ML pour pouvoir gérer ce genre de tâches à grande échelle. Ça doit être un peu difficile de parler de ce que ML fait sans avoir un peu d'expérience dans l'apprentissage automatique. Et si vous êtes curieux de connaître ces algorithmes, je vous encourage certainement à aller suivre un cours dédié à l'apprentissage automatique pour en apprendre davantage. Je vais vous donner un aperçu de très haut niveau d'eux ici et
comme, du mieux que je peux le faire dans une seule diapositive au moins. Ainsi, les fonctionnalités de base du package ML
Sparks ou de l'extraction de fonctionnalités qui inclut quelque chose appelé TF-IDF, c'est la fréquence du terme inverse de document fréquence. Et ce sont des analyses qui sont principalement utilisées pour la recherche. Ainsi, il vous permet de déterminer quels termes sont les plus pertinents pour un document. Manière très facile de le faire. Il a également des statistiques de base intégrées. Si vous le vouliez, comme juste calculer coefficients de
corrélation ou des tests Khi square et des choses comme ça. Il peut le faire à grande échelle. Et puis nous entrons dans les
algorithmes d'apprentissage automatique eux-mêmes , qui sont plus intéressants. Il peut donc faire une régression linéaire et une régression logistique. La régression linéaire est juste fondamentalement ajuster une ligne à un ensemble de données. Par exemple, vous pouvez imaginer que vous disposez d'un jeu de données qui mappe les hauteurs des personnes à leur âge. Et en ajustant une ligne aux données que vous avez observées, vous pouvez réellement adapter de nouveaux points de données à cette ligne pour prédire leur valeur réelle. Donc, si j'ai une ligne qui définit l'âge en fonction de la hauteur, je peux réellement pointer dans de nouvelles hauteurs à ce modèle n'a jamais vu auparavant et prédire leur âge juste en l'extrapolant à travers cette ligne. C' est une régression linéaire. La régression logistique est un peu la même idée sous le capot, mais c'est à des fins de classification. Donc, si je veux prédire si quelqu'un est démocrate ou républicain, par
exemple, vous pourriez utiliser la régression logistique pour le faire. Si je veux prédire si une voiture est une voiture de sport ou une berline basée sur certains attributs. Cela pourrait être un autre exemple de régression logistique. Encore une fois, nous appliquons une fonction mathématique très simple pour prédire les classifications par opposition aux valeurs réelles,
ce que vous ferez avec la régression linéaire. Il peut également prendre en charge les machines vectorielles. C' est une autre façon de faire une classification un peu plus sophistiquée, si vous voulez. Il fonctionne dans ces espaces de dimensions supérieures et peut trouver divisions
plus complexes entre les classifications qui ne sont pas nécessairement linéaires. Il peut également faire Naive Bayes classification. L' enfant de l'affiche d'une application pour un Naive Bayes est la classification du spam. Donc, un exemple très courant de Bayes naïve est de lui fournir un corpus d' e-mails et d'avoir un ensemble de formation qui est marqué comme spam et non comme spam. Et vous pouvez former ce classificateur Naive Bayes à prendre de nouveaux e-mails qu'il n'a jamais vus auparavant et prédire si leur spam ou non basé sur ce modèle naïf de Bayes. Il peut également faire des arbres de décision répartis sur un cluster entier, ce qui est vraiment cool. J' aime les arbres de décision sont juste amusants à regarder leur, ce qu'ils ont l'air. C' est essentiellement cet arbre de décisions. Donc, fondamentalement, vous allez commencer par une décision comme, je ne sais pas, c'est la température à l'extérieur au-dessus de 72 degrés ou moins de 72 degrés. Si c'est au-dessus de 72 degrés, vous allez
peut-être à un autre bloc de décision. Et peut-être cette prochaine décision. Et l'arbre de décision est, il pleut ou pas ? Et peut-être que cela pourrait finalement vous conduire à une décision sur si vous devriez sortir et jouer aujourd'hui si c'est une bonne journée ou pas, non ? C' est un exemple très simple d'arbre de décision. Évidemment, vous pouvez devenir beaucoup plus compliqué et cela peut fonctionner dans des situations
arbitraires où vous avez de nombreuses fonctionnalités qui sont numériques, qui peuvent être comparées à certaines valeurs définies. Et en prenant des décisions dans l'ordre entre ces différentes caractéristiques de vos données, vous pouvez arriver à une décision avec un arbre de décision. K signifie clustering, juste un moyen de regrouper les données en fonction de leurs attributs, fonction de la similitude des choses entre elles. D' un moyen très simple. C' est ce que nous appelons l'apprentissage non supervisé, où nous ne formons pas réellement un modèle basé sur des valeurs connues. Nous essayons de regrouper les choses en fonction leurs propriétés naturelles et de la façon dont les choses sont similaires les unes aux autres. Et il peut également faire l'analyse des composants principaux, connu sous le nom de PCA pour la décomposition des valeurs courtes et singulières, SVD pour l'abrégé. Ce sont ce que nous appelons des techniques de réduction dimensionnelle. Donc, parfois, vous aurez ce problème où vous avez des données qui ont beaucoup de fonctionnalités différentes. Vous savez, différentes choses que nous mesurons pour différents objets. Et il devient, il provoque ce que nous appelons la dimensionnalité cursive. C' est essentiellement un problème de données clairsemées où vous avez trop de fonctionnalités. Ce sont des façons de les réduire aux caractéristiques les plus saillantes. Peut-être que ce sont des caractéristiques synthétiques qui n'existaient même pas du tout dans le monde réel. Mais il s'agit d'un moyen de faire bouillir les données d'entités de dimensions supérieures vers les données d'entités de dimension
inférieure, ce qui facilite le travail. Et enfin, il peut faire des recommandations en utilisant une technique appelée Alternant les moindres carrés. Et nous allons creuser ça dans un peu plus de profondeur très bientôt. Als est cool. Il y avait en fait un concours il y a longtemps qui a été parrainé par Netflix pour développer un meilleur système de recommandation que le leur. Et l'une des entrées gagnantes qu'ils font partie de sa solution était d'utiliser ALS. Donc, donc cela est également disponible pour vous dans Spark ML. Maintenant, c'est une sorte de liste limitée de ce que vous pouvez faire. Je veux dire, il y a d'innombrables algorithmes d'apprentissage automatique là-bas, mais tous ne se prêtent pas vraiment bien à être distribué dans un cluster. Donc encore à ce jour, il y a beaucoup d'algorithmes d'apprentissage automatique là où nous les mettons juste à l'échelle verticale. Nous ne pouvons les faire fonctionner que sur une seule machine. Et nous sommes un peu de retour à l'ancien temps des grandes bases de données monolithiques où la seule façon de faire ces choses est d'avoir une machine vraiment grande pour les exécuter avec beaucoup de GPU, beaucoup de mémoire et tout ce qui est bon. Mais peu de choses ouvrent la voie à une mise à l'échelle horizontale de l'apprentissage automatique. Et c'est vraiment excitant. Maintenant, il y avait une API précédente qui existait dans Spark un et dans Spark appelé ML Lib. Et c'était une API de niveau inférieur qui utilisait des RDD et une structure de données spécialisée est d'effectuer ces algorithmes. Maintenant, dans Spark 3, c'est obsolète et certaines parties ne fonctionnent plus du tout. Et franchement, les responsables de Spark ne s'en
foutent pas parce que c'est juste en mode maintenance à ce stade. Ils veulent donc vraiment que vous passez à la nouvelle bibliothèque ML. La différence est principalement qu'il utilise DataFrames pour tout. Donc, au lieu de passer autour de RDD et de ces structures de données spécialisées, vous allez utiliser des dataframes et des jeux de données, ce qui est vraiment l'API vers laquelle ils veulent pousser tout le monde vers. L' avantage de ceci est qu'en utilisant DataFrames dans tous les différents composants de Spark, vous pouvez transmettre ces DataFrames d'un composant à un autre de manière transparente. Donc c'est un peu plus grande vision. Ils veulent pouvoir prendre un DataFrame qui sort de Spark ML et peut-être, vous savez, le nourrir à Spark SQL et peut-être à GraphX. Qui sait bien ? Cette interopérabilité, qui devient excitante en ayant ce DataFrame à usage général. C' est une sorte de lingua franca de tous ces composants Spark, y compris l'apprentissage automatique. Si vous voulez plus de profondeur, Il y a un livre appelé Advanced Analytics with Spark publié par O'Reilly, probablement un peu obsolète en ce moment, je ne sais pas s'ils ont une version mise à jour pour la nouvelle bibliothèque ML, mais c'est une assez bonne ressource. Tout ce qui vient d'O'Reilly est généralement une bonne lecture. Les exemples les plus opportuns ou vont toujours être dans le SDK étincelle lui-même. Il y a un répertoire d'exemples dans le SDK. Et si vous y plongez, vous trouverez un exemple de chacun de ces algorithmes réellement utilisés. Et encore une fois, pour plus de profondeur sur les algorithmes réels et comment les utiliser et comment ils fonctionnent. Je vais vous référer à un autre cours, pas celui-ci sur l'apprentissage automatique en général. Avec ça, Mettons-le en pratique. Dans notre prochaine conférence, nous allons réellement générer des recommandations de films en utilisant le module ALS dont nous avons parlé dans Spark ML. Et c'est vraiment excitant parce que c'est vraiment, vraiment facile à utiliser. Les systèmes de recommandation sont donc des choses vraiment compliquées et Alterning Most Squares utilise cette méthode de factorisation matricielle. C' est des maths très hardcore sous le capot ici. Mais pour l'utiliser sur Spark et réellement distribué sur un cluster entier, c'est tout le code que vous devez faire. N' est-ce pas génial ? Alors passons un peu à travers ça. Tout ce que nous faisons ici est de charger un fichier de données qui va
être notre jeu de données de notes MovieLens à partir de données u point. Nous mappons ensuite cela en un RDD de notes en utilisant les API de niveau inférieur parce que nous faisons des transformations assez simples ici. Et puis nous convertissons cela en DataFrame pour le rendre compatible avec Spark ML. Ensuite, nous créons simplement un nouvel objet ALS à partir de la bibliothèque ML. Nous définissons ce qu'on appelle quelques hyperparamètres. Petit secret sale de l'apprentissage automatique est beaucoup de ces algorithmes ne sont que aussi bons que les hyperparamètres que vous définissez en eux. Ainsi, le nombre maximal d'itérations, le paramètre de régularisation. Voici deux exemples d'hyperparamètres avec l'algorithme ALS. Et la plupart des algorithmes d'apprentissage automatique ont plusieurs d'entre eux. Et comment ils fonctionnent bien dépend de ces paramètres. Et la petite vérité est qu'il est en grande partie encore une question d'essai et d'erreur de trouver les valeurs de paramètres qui fonctionnent le mieux pour un problème donné. Donc, nous aimons penser que nous comprenons ces modèles très profondément, mais en réalité, beaucoup de choses sont encore des devinettes. Mais une fois que nous avons ces valeurs dedans pour commencer, au
moins nous pouvons créer un nouvel objet ALS. Nous lui indiquons où l'ID utilisateur, ID du
film et les informations de notation se trouvent dans notre DataFrame. Et puis on peut juste appeler en forme sur ce modèle ALS. Et cela va se déclencher et former un modèle en utilisant toutes ces données MovieLens. Et à ce stade, nous pouvons simplement utiliser ce modèle pour faire des prédictions pour les nouveaux utilisateurs que nous n'avons jamais vus auparavant. Donc c'est aussi facile que ça. Jouons avec ça. Allons le faire fonctionner.
51. [Activité Utiliser MLLib pour créer des recommandations de film: Nous allons donc essayer d'utiliser
l' algorithme de recommandation des moindres carrés alternatifs qui est intégré dans le ML Lib, qui fait partie de Spark. Et nous allons regarder le script de jeu de données ALS de recommandations de film pour celui-ci. Maintenant, avant d'entrer dans ce domaine, ce que nous avons fait pour tester cela est de créer
une sorte de fausse personnalité d'un utilisateur dont les goûts que je peux au moins comprendre un peu qui me
donnera sens qualitatif quant à savoir si oui ou non le les recommandations sont bonnes ou non. Donc, pour ce faire, je suis allé dans mon jeu de données MO 100 K et édité le fichier de données u dot. Et ce que j'ai fait est ajouté en trois lignes pour un faux utilisateur 0, l'utilisateur 0 n'existait pas auparavant dans ce jeu de données. Et c'est une personne très simple ici. Fondamentalement, j'ai dit que cet ID d'utilisateur aime beaucoup les éléments 50, l'ID de film 50 et l'ID de film 172. Il leur a donné cinq étoiles. Et ceux-ci correspondent au film Star Wars Episode 4 et Star Wars Episode 5. Un nouvel espoir dans l'Empire frappe en arrière. Nous avons donc établi que cette personne a un très grand fan de science-fiction de Star Wars. Et en revanche, j'ai aussi dit que pour le film 133, qui est Gone With the Wind, Ce n'était qu'une étoile. J' ai donc créé une personnalité très simple ici. Quelqu' un qui aime Star Wars et la science-fiction, mais qui n'est pas fan de vieux drames romantiques, n'est-ce pas ? Et donc c'est quelqu'un que je peux me rapprocher. Cela me donne donc une sorte de sentiment
personnel quant à la question de savoir si ces résultats seront bons ou non. Maintenant, il existe des moyens de mesurer objectivement la qualité d'un ensemble de recommandations. Mais souvent, c'est une sorte de chose qualitative. Vous pouvez essayer de prédire si votre algorithme peut détecter si oui ou non quelqu'un aurait réellement aimé un film qu'il rayonne précédemment. Mais à la fin de la journée, les
recommandations visent à essayer de recommander des choses qu'une personne n'a pas vues auparavant. Et c'est une chose difficile à mesurer pour savoir si c'est un bon résultat ou non. Donc, pour des raisons de démonstration, nous allons juste garder cette évaluation qualitative. Je vais voir si les recommandations que j'en tire ont du sens pour quelqu'un qui aime Star Wars et déteste Gone With the Wind. Alors passons à travers le code lui-même et voyons à quoi il ressemble. Assez facile à utiliser en fait. Donc, nous importons la recommandation de points ML, tout en dessous et les choses habituelles aussi. Nous avons mis en place notre objet et nous avons deux classes de cas ici. Une pour la recherche de noms de films que nous allons simplement utiliser pour rechercher noms de
films pour des ID de film afin d'obtenir des résultats lisibles par l'homme à la fin. Et nous avons également notre petit jeu de données pour les évaluations qui inclut un ID utilisateur est des ID vidéo et des évaluations, notez que nous émettons les horodatages car cela n'a pas d'importance pour cet algorithme. Passons à la fonction principale ici. Commencez par définir notre niveau de journal. Donc, je pense avec la session Spark comme nous le faisons toujours, et nous commençons par charger ce jeu de données de noms de films. Nous fournissons un schéma qui indique qu'il a des ID de film entiers et des titres de chaîne de films. Et pendant que nous y sommes, nous avons dit que le schéma vidéo aussi pour les données d'évaluation réelles que nous allons lire aussi, nous importons des implicites de point d'étincelle parce que nous allons
charger DataFrames initialement et pas un jeu de données. Nous lisons dans le dossier d'élément point de l'UE qui contient ces noms de film à l'aide du schéma de nom de film. Et nous avons jeté cela dans le jeu de données des noms de films en utilisant la classe de cas des noms de films. On a fait
ça un million de fois plus tôt dans le cours, n'est-ce pas ? Nous avons ensuite collecté cela dans Scala dans un objet de liste de noms. Donc, à ce stade, nous avons réellement utilisé Spark juste pour charger ces données et les analyser. En fait, copiez cela dans notre script pilote lui-même. Maintenant on peut s'en sortir parce qu'il
n'y a pas autant de films dans le monde, non ? Nous pouvons mettre cela en mémoire en toute sécurité dans nos scripts de pilotes. Donc ce n'est pas une chose folle à faire en fait donc nous allons juste jeter ça dans une carte Scala ici pour les rechercher quand nous les afficherons à la fin. Cependant, les données d'évaluation vidéo que nous voulons garder distribuées et les conserver sur notre cluster en tant que jeu de données. Et c'est ce que nous faisons ici est de
charger cela en utilisant le schéma que nous avons fourni, le délimiteur d'onglets. Et nous allons lancer cela comme un jeu de données de notation en utilisant la classe de cas de notation que nous avons définie ci-dessus. Et encore une fois, cela va seulement extraire les trois premières colonnes, l'ID utilisateur, l'ID du film, et une évaluation elle-même. On va laisser cet horodatage éteint. Après cela, jetez un oeil à quel point il est facile d'utiliser ML Lib. Nous avons donc mis en place notre modèle ici. Donc, nous disons simplement que la nouvelle ALS pour Alternating Most Squares sort de la bibliothèque d'algorithmes de recommandation ML Lib là-bas. Et nous avons dit quelques hyperparamètres. Nous avons donc fixé nos itérations maximales à cinq. Nous définissons notre paramètre de régularisation sur 0,01. Et vous voudrez peut-être d'où nous avons eu ces chiffres. Eh bien, je les arrache de l'air d'abord en se basant sur des exemples que j'ai vus en ligne, vous trouverez que dans la pratique, une sorte de petit secret sale de l'apprentissage automatique en général, c'est qu'il s'agit de optimisation des hyperparamètres. Et c'est une façon très fantaisiste de dire qu'on va juste deviner quel est le bon numéro jusqu'à ce qu'on obtienne le bon résultat. Donc, c'est une pratique très courante d'avoir juste ces énormes tâches qui essaient beaucoup, beaucoup,
beaucoup de valeurs différentes de ces hyperparamètres comme les itérations maximales et les paramètres de régularisation, et juste de voir lesquelles donnent les meilleurs résultats expérimentalement. n'y a souvent pas d'indications réelles sur
la meilleure valeur qui devrait être pardonnée
et cela varie énormément de l'ensemble de données, le jeu de données. Donc, ce problème de trouver les bons paramètres ici est vraiment au cœur de
l'obtention de bons résultats d'apprentissage automatique dans la pratique. L' autre chose que le noyau est juste de nettoyer vos données, mais ce n'est pas un cours d'apprentissage automatique, donc je ne vais pas m'en mêler trop. Nous lui indiquons quels sont les noms de colonne pour l'ID utilisateur, l'ID de l'élément et l'évaluation. C' est tout ce dont l'algorithme a besoin. Nous avons donc juste besoin de le pointer sur ce que ces colonnes de jeu de données sont réellement nommées, afin qu'il sache d'où récupérer ces informations. À ce stade, tout ce que nous avons à faire est de dire point ajustement sur ce modèle passant dans ce jeu de données de notes. Et c'est cela qui va réellement exécuter ce modèle sur nos données et construire un modèle qui peut prédire recommandations pour les nouveaux utilisateurs de films qu'ils pourraient aimer. Et c'est une sorte de boîte noire à ce moment-là, non ? Donc, l'algorithme ALS est hors de faire quelque chose. Nous savons que c'est l'utilisation des moindres carrés alternatifs qui est à peu près. Pour créer un modèle qui peut prendre un nouvel ID utilisateur et recommander des films que cet utilisateur pourrait souhaiter en fonction de ce qu'il a évalué. Alors faisons ça. Allons de l'avant et sortons de l'argument de ligne de commande. L' ID utilisateur est une personne pour laquelle nous voulons obtenir des recommandations. Dans notre cas, nous transmettrons l'ID utilisateur à partir de la ligne de commande. Ensuite, nous créons simplement un DataFrame vraiment simple qui ne contient rien d'autre que cet ID utilisateur. Et nous passons cela dans les modèles recommandent pour les utilisateurs méthode de
sous-ensemble passant dans ce faux utilisateur DataFrame d'un seul utilisateur que nous n'étions pas résultats. Et nous pourrions en fait transmettre plusieurs utilisateurs et obtenir
des recommandations pour beaucoup de gens à la fois si vous le vouliez. Et nous disons que nous voulons juste les 10 meilleures recommandations pour chaque utilisateur que nous transmettons à ces utilisateurs DataFrame. À ce stade, nous avons nos résultats, nous avons juste à les afficher. Et curieusement, c'est en fait la partie la plus difficile de tout ça, trouver comment extraire cette information. Les recommandations DataFrame que nous avons obtenu. Donc, c'est ce que nous faisons ici et cette petite boucle Ici, nous passons par chaque recommandation dans les recommandations DataFrame que nous avons obtenu de recommandation sous-ensemble congélateur, nous extrayons l'ID utilisateur et les recommandations elles-mêmes. Nous devons dire à Scala ce qu'est cette chose. Nous devons donc lancer explicitement ce résultat comme un tableau enveloppé mutable de type ligne, qui est ce que nous obtenons quand un DataFrame. Nous pouvons ensuite parcourir chaque résultat de recommandation individuel, extraire le film, extraire la note. Ensuite, nous pouvons traduire cet ID de film en un nom de film en utilisant notre fonction get movie name et imprimer les résultats. Enfin, nous arrêtons la session quand nous avons terminé et nous voyons ce qui se passe. Regardez rapidement la fonction get film nommé. Il exécute simplement une information de filtre sur le tableau de noms de films que nous avons transmis et
essaie de trouver l'ID de film qui correspond à celui que nous
recherchons et renvoie le titre du film qui lui est associé. Encore une fois, cela n'utilise pas réellement un jeu de données. C' est en fait juste un tableau que nous avons récupéré de l'ensemble de données à travers l'opération collective. Alors faisons-le et voyons ce qui se passe. Faites un clic droit sur cela. On doit établir un périmètre pour ça. Donc, nous allons dire que Modifier les recommandations de film et s'asseoir dans un argument de programme est 0 parce que je veux des recommandations de zéros d'ID utilisateur. Maintenant, je peux appuyer sur Ok, et il devrait être capable de sélectionner cela maintenant et de l'exécuter. Très bien, c'est hors d'entraîner ce modèle maintenant basé sur ces 100 mille cotes et il y a nos 10 meilleurs résultats. Donc oui, ces résultats sont un peu bizarres. C' est dire ça pour quelqu'un qui aime Star Wars et qui n'aime pas Gone With the Wind. Mon meilleur résultat avec un film de 1994, je n'ai jamais entendu parler, mais ça s'appelle The Endless Summer 2. Je pense que ce n'est pas un film de science-fiction. Presque sûr qu'il soit ou ne pas être de 1942 n'est pas non plus, ni ball2. Je veux dire, il y a des choses ici qui ont du sens Lost in Space. Transformateurs. Je suppose que ça a du sens pour un fan de Star Wars, mais ils pourraient, j'ai eu de la chance. Ces recommandations me semblent plutôt aléatoires. Donc les résultats ici n'ont pas vraiment de sens pour moi. Eh bien, explorons pourquoi ça pourrait être. Donc, comme nous l'avons mentionné précédemment, ces algorithmes ont tendance à être très sensibles aux paramètres hyper que vous choisissez. Souvent, il faut beaucoup de travail pour trouver l'ensemble optimal de paramètres pour le jeu de données que vous utilisez pour obtenir de bonnes recommandations. Donc, une technique est d'utiliser quelque chose appelé test de train, où nous mettons de côté une partie de nos données de notation et nous l'utilisons à des fins de test. Donc, nous tenons certains utilisateurs de notre jeu de données et nous utilisons le modèle formé sur les utilisateurs restants et voyons si notre modèle résultant peut
prédire avec succès quels films les personnes dans l'ensemble de tests ont réellement apprécié, ce qui ils ont aimé, ce qu'ils ont bien évalué. Et vous pouvez l'utiliser pour obtenir une sorte de
mesure quantitative de la qualité des recommandations. Et une fois que vous avez cela, vous pouvez essayer différentes combinaisons d' hyperparamètres et voir quelle combinaison donne les meilleurs résultats et essayer de régler les choses de cette façon. Mais cela devient douteux avec des recommandations. Je veux dire, une bonne recommandation est-elle vraiment mesurée par votre capacité à prédire des choses que quelqu'un a déjà regardé ? Ou est-ce une bonne recommandation si c'est quelque chose qu'ils n'ont pas encore
vu en utilisant des données historiques, il n'y a aucun moyen de le savoir, non ? Donc recommander, les systèmes de recommandation est une sorte de cas bizarre où il est difficile de mesurer
les résultats vraiment en dehors de faire comme des expériences en direct avec de vraies personnes. Mais j'ai passé du temps à faire ça. J' ai donc essayé différentes valeurs de paramètres. Je ne pouvais pas obtenir de meilleurs résultats de cette chose, peu importe ce que j'ai fait. Donc je pense un peu que ce truc ne fonctionne pas comme il le devrait. Donc, je ne suis même pas convaincu que cette chose fonctionne correctement en interne. Au moins pour cet ensemble de données, cet algorithme ne fonctionne pas bien. Et la leçon à tirer ici est que mettre votre foi dans une boîte noire comme celle-ci peut être une proposition douteuse. Vous devez comprendre ce qui se passe dans l'algorithme et comprendre s'il correspond ou non aux données que vous obtenez. Il se peut que notre ensemble de données soit tout simplement trop petit. Il se peut qu'il y ait quelque chose à ce sujet qui
n'est pas particulièrement bien adapté à cet algorithme. J' ai essayé des choses évidentes comme normaliser les notes à 0 contre un. Ça n'a pas aidé non plus. Parfois c'est ce que vous devez faire, mais nous avons obtenu de bien meilleurs résultats en utilisant notre exemple de similitude de film plus tôt dans le cours, non ? Si nous utilisons simplement le filtrage collaboratif basé sur en utilisant des mesures de similarité de cosinus comme nous l'
avons fait auparavant, nous aurions obtenu de meilleures recommandations avec une approche beaucoup plus simple. Et ça a marché. Donc ALS est un algorithme plus compliqué, mais parfois compliqué n'est pas toujours mieux. C' est un bon exemple de cela. Et donc, vous savez, toujours mesurer les résultats, assurez-vous d'obtenir les résultats que vous attendez. Joe dit, ne faites pas simplement confiance aveuglément aux résultats lorsque vous essayez d'effectuer une analyse de données sur des jeux de données volumineux. Parce que les petits problèmes dans les algorithmes peuvent devenir grands que vous lui jetez plus de données. Et très souvent, le véritable problème est la qualité de vos données d'entrée. Maintenant, dans notre cas, ce n'est pas le problème. Les données que nous mettons ont déjà été nettoyées. Il s'agit donc de données de haute qualité. Mais souvent, le dicton Garbage in, ordures out s'applique ici, non ? Donc, si vous transmettez des données non filtrées qui contiennent un tas
d' informations fausses provenant de robots et de choses comme ça, ou des personnes qui ne sont pas de vraies personnes ou qui essaient de jouer sur le système. Ça va foirer tes résultats aussi. Mais c'est d'entrer plus dans la pratique de l'apprentissage automatique que tout autre chose. La leçon ici cependant, est que, même si Spark contient des algorithmes passionnants, ils ne seront pas toujours la bonne solution pour vos données. Donc, ne mettez pas simplement aveuglément votre confiance dans ce que Spark offre dans ML Lib. Cependant, ML Lib est toujours vraiment utile en général. Un peu a commencé avec un mauvais exemple là parce que ALS est un
peu douteux avec lui pour le jeu de données MovieLens de toute façon. Mais le reste des algorithmes sont plus simples et ils feront ce que vous attendez. Donc, allons couper un décalage vers une note plus élevée en utilisant Sparks ML Lib et montrer quelque chose pour lequel il est mieux adapté.
52. Régression linéaire avec MLLib: Donc, passons les vitesses vers un algorithme plus fiable dans la bibliothèque Spark ML, l'algorithme de régression linéaire, c'est assez simple. Qu' est-ce que la régression linéaire ? Eh bien, si vous êtes nouveau dans le monde de l'apprentissage automatique, ça pourrait être un nouveau terme pour vous. En un mot, la régression linéaire ne fait qu'ajuster une ligne à un jeu de données. Et une fois que vous avez cette ligne, c'est une sorte de ligne qui convient le mieux à un ensemble d'observations. Vous pouvez utiliser cette ligne pour prédire de nouvelles valeurs pour des choses que vous n'avez jamais vues auparavant. Par exemple, sur cette petite illustration, nous avons des
mesures du poids des personnes et de leurs hauteurs tracées les unes contre les autres. Donc, vous pouvez imaginer essayer de prédire taille de
quelqu'un en fonction de son poids une fois
que vous avez réellement cette ligne, cette ligne rouge qui est ajustée à ces données d'observation. Fondamentalement, vous prenez tous les points de données observés de la chose que vous essayez de prédire. Dans ce cas, la hauteur basée sur un attribut, qui dans ce cas serait poids. Et si vous tracez tous ces éléments ensemble et trouvez la ligne qui correspond le mieux à ces données. Vous pouvez ensuite utiliser l'équation de cette ligne pour prédire les hauteurs des nouvelles personnes en fonction de leur poids. Donc ça finit avec une sorte de formule point-pente ici pour la ligne, n'est-ce pas ? Donc, fondamentalement, nous disons que nous avons une pente de 0,60 plus une interception y de 1,23. Et nous pouvons utiliser ces attributs pour faire des prédictions à l'avenir. Pourquoi ont-ils appelé ça la régression ? C' est un peu déroutant d'être honnête. régression implique que vous remontez dans le temps, mais ce n'est pas vraiment ce qu'il s'agit. Il y a une certaine histoire derrière ce terme, mais essayez de ne pas vous y accrocher trop. Fondamentalement, la régression linéaire correspond juste à une ligne aux données historiques. Peut-être que vous pouvez considérer cela comme la partie de régression et utiliser cette ligne pour prédire nouveaux points de données pour de nouvelles choses que vous n'avez pas vues auparavant. Comment ça marche ? D' habitude, il utilise quelque chose qui s'appelle les moindres carrés. Il est une technique mathématique pour minimiser l'erreur au carré entre chaque point et la ligne. Donc, quand nous ajustons une ligne à ces points de données observés, pour chaque point, il y aura une erreur entre l'endroit où ce point est vraiment et l'endroit où la ligne dit qu'il devrait être. Et notre objectif en créant cette ligne est de minimiser l'erreur au carré entre chaque point et cette ligne. C' est carré parce que de cette façon, une erreur positive ou négative ne fait pas de différence. C' est la même chose. Donc, c'est un peu intéressant mathématiquement quand vous
pensez à comment cela fonctionne dans deux dimensions en fait. Donc, si vous vous souvenez de l'équation d'interception de pente d'une ligne qui est y égale mx plus b, où m est la pente et b est l'interception y. revenant à l'école secondaire là-bas pour beaucoup d'entre vous, il s'avère que la pente peut être exprimée comme la corrélation entre
les deux variables fois l'écart-type en y divisé par l'écart-type en x. Et c'est un tas de statistiques jumbo pour beaucoup d'entre vous. Mais je pense juste que c'est un peu intéressant comment certains de ces concepts statistiques comme l'écart-type, ont une vraie signification mathématique qui peut être utilisée pour quelque chose d'aussi simple qu'un ajustement d'une ligne aux données. Donc, ce n'est pas que l'écart-type soit une coupure arbitraire que quelqu'un a trouvé. Il a en fait une vraie signification mathématique, ce qui pour moi est intéressant au moins. Et vous pouvez également calculer l'interception comme juste la moyenne de y moins la pente fois la moyenne de x. C'est
donc une autre façon de calculer cela. Donc, compte tenu de ces connaissances mathématiques, il est assez simple d'adapter une ligne à un ensemble de données en deux dimensions. Si vous avez juste affaire à x et y, les choses deviennent un peu plus compliquées lorsque vous ajoutez plus de dimensions dans le mélange. Donc, c'est une sorte d'exemple fabriqué de prédire
simplement attribut basé sur un autre attribut comme la hauteur basé sur le poids. le monde réel, vous avez généralement affaire à plusieurs attributs. Donc vous pourriez essayer de prédire la taille de quelqu'un en fonction de son poids, endroit où ils vivent, de quel âge ils ont, peu importe ce qu'il est, non ? Donc c'est généralement plus d'une chose. Et ça entre dans toute cette bizarrerie multidimensionnelle. Et une façon de faire face à cela est la descente en gradient stochastique. C' est un autre algorithme que vous voyez beaucoup dans le monde de l'apprentissage automatique et aussi dans l'apprentissage profond. Et fondamentalement, je ne veux pas entrer dans les détails de comment ça fonctionne, mais ça cherche ces contours dans des dimensions plus élevées, si vous voulez. Donc, il trouve itérativement le genre de lignes les mieux ajustées à travers cet espace multidimensionnel pour vous. Donc même concept, juste un peu plus compliqué. Mais en utilisant Spark dot HTML, Ce n'est pas compliqué du tout. Vous n'avez pas à vous inquiéter de la façon dont cela fonctionne parce que tout cela fait pour vous. Tout ce que vous avez à faire est de dire Val et de définir une certaine valeur à un nouveau modèle de régression linéaire, définir un tas d'hyperparamètres comme le paramètre de régularisation ou le paramètre de réseau élastique, le nombre maximal d'itérations, la tolérance de convergence . Et comme toujours, l'apprentissage automatique est un petit secret sale est qu'il n'y a pas toujours un bon moyen de deviner quelle devrait être cette valeur pour un jeu de données donné. Souvent, vous arrivez aux bonnes valeurs juste à travers les essais et les erreurs. Mais une fois qu'un modèle de régression linéaire est configuré et configuré, il
suffit de former le modèle et de faire des prédictions en utilisant
des tuples qui se composent d'une étiquette et d'un vecteur des entités qui utilisent pour prédire cette étiquette. Donc, dans ce cas, l'étiquette serait la valeur que vous essayez de prédire. Nous encadrons généralement qui est notre axe Y. Une fonction se trouve sur votre axe des x ou sur les autres axes. Ce sont les choses que vous utilisez pour essayer de faire cette prédiction à partir de. Donc, fondamentalement, vous entraînez le modèle avec un tas de points connus. Ensuite, vous essayez de prédire de nouvelles valeurs d'étiquette y pour des X
donnés ou des valeurs d'entité en utilisant cette ligne pour le modèle créé. Et tu n'as pas à t'inquiéter de ce qu'est cette ligne. Vous pouvez l'obtenir si vous le souhaitez, mais vous savez, c'est comme n'importe quel autre modèle, vous créez simplement le modèle et une fois qu'il est formé, vous l'utilisez pour faire des prédictions. Tout est très simple. Et il peut, comme nous l'avons dit, fonctionner avec plus de deux dimensions si vous avez plusieurs fonctionnalités et c'est là que la puissance de celui-ci intervient vraiment. Maintenant, il y a quelques gotchas utilisant la régression linéaire SGD, qui est ce que cela utilise. La première est qu'elle n'entrave pas bien la mise à l'échelle des entités, donc elle suppose que vos données sont similaires à une distribution normale et comment elles sont disposées. Donc, si ce n'est pas le cas, devrait généralement mettre à l'échelle ces données pour s'adapter
à une plage qui est plus comparable à votre courbe de cloche standard ici. Et vous voulez vous assurer que toutes vos entités sont également mises à l'échelle. Donc, si vous avez une fonctionnalité qui est énorme et une autre qui est une petite valeur. Vous devez tout mettre à l'échelle jusqu'à cette échelle similaire dans la plage similaire pour que l'algorithme fonctionne bien. Cela signifie donc que vous allez devoir mettre à l'échelle vos données vers le bas, puis sauvegarder à nouveau une fois que vous avez terminé. Vous allez donc former votre modèle en fonction de ces données d'entités mises à l'échelle. Et puis vous devez vous rappeler de le redimensionner en utilisant les inverses de cette relation lorsque vous affichez réellement les valeurs finales qui sont prédites par ce modèle. En outre, l'algorithme suppose que votre interception y est égale à 0 sauf si vous appelez Fit Intercept true dessus. Si vous faites face à une situation où vous ne pensez pas que votre ligne d'ajustement le plus approprié passera par l'origine 0, 0, vous devez appeler Fit Intercept true pour obtenir de bons résultats. Alors essayons-le. Ce que nous allons faire, c'est fabriquer des fausses données pour la
vitesse moyenne des pages et les revenus générés par les données de session sur un magasin en ligne. C' est quelque chose que nous devions vraiment faire chez Amazon. Il y avait une hypothèse beaucoup, beaucoup, beaucoup, beaucoup, de nombreuses années, que le temps de chargement de la page avait une relation très directe sur le montant d'argent dépensé par le client. Et nous savons maintenant que c'est vrai et c'est une sorte de sagesse commune dans toute l'industrie maintenant. Mais à l'époque, nous devions le comprendre. Donc nous allons comprendre ça récemment, de fausses données. Donc, nous allons savoir qu'il y a une relation là-dedans
à cause de la façon dont nous l'avons fabriquée. Mais étant donné que nous allons essayer de construire un modèle de régression linéaire en utilisant Spark ML et voir si nous pouvons prédire les revenus en fonction de la vitesse de page en utilisant ce modèle linéaire. Alors plongons et donnons-y un coup de pouce.
53. [Activité] Courir une régie linéaire avec Spark: Nous allons donc parcourir notre exemple d'utilisation de la régression
linéaire dans Spark et voir si cela fonctionne, ouvrez le script de jeu de données de régression linéaire. Et avant de plonger dans le code, regardons les données que nous traitons d'abord, c'est toujours un bon premier pas, non ? Donc, si nous allons dans notre matériel de cours et aller dans le dossier Data, régression dot txt fichier ici. Familiarisons-nous avec ce qu'il y a dedans. Maintenant, comme vous vous en souvenez, ce que nous essayons de faire est de prédire combien les gens dépensent en fonction de PageSpeed. Donc, la chose que nous essayons de prédire est annoncée dépensée et le montant que nous sommes, notre fonctionnalité sur laquelle nous essayons de prédire que sur est PageSpeed. Donc, dans cette première colonne, ces chiffres représentent le montant dépensé, mais il est normalisé et réduit. Donc, cela est normalisé pour tenir dans une distribution de courbe de cloche. C' est pour ça que vous voyez des choses comme des valeurs négatives ici. Même si vous ne verriez pas vraiment un montant négatif dépensé à moins que quelqu'un obtienne un remboursement ou quelque chose comme ça, n'est-ce pas ? Donc, comme nous l'avons dit dans les diapositives, vous devez vous assurer que vous réduisez vos données dans cette plage cohérente. Et puis se souvenir de remonter à l'échelle quand vous avez fini. Cette deuxième colonne va correspondre à nos données d'entités. Donc, dans ce cas, ce sera la vitesse de la page. Encore une fois, nous avons normalisé cela et l' réduit à ce qui pourrait s'intégrer dans une distribution de courbe de cloche. Donc, ces nombres par eux-mêmes ne sont pas des valeurs brutes. Ils avaient été réduits à l'échelle et c'est une sorte d'ingénierie de fonctionnalités que nous appelons dans le monde de l'apprentissage automatique est une étape très importante et obtenir de bons résultats. De nombreux modèles d'apprentissage automatique exigent que vos entités et vos étiquettes soient toutes mises à l'échelle dans des plages similaires, et parfois plus spécifiquement, centrées autour de 0 ou entre 01. Il doit lire la documentation de l'algorithme que vous
utilisez pour s'assurer que vos données sont dans le bon format. Sinon, ça ne marchera pas. Vous obtiendrez des résultats vraiment bizarres et on se demandera pourquoi. Alors n'oublie pas ça. Bon, alors plongons dans le code. Donc notre schéma de régression va
correspondre à nos deux colonnes d'informations à double précision. Là, nous avons l'étiquette, qui correspond encore à notre montant dépensé et nos caractéristiques soulignent RA, ce qui correspond à la vitesse de nos pages. Et encore une fois, ceux-ci sont réduits à une distribution normale. D' accord, on déclenche nos paramètres d'enregistreur, on a parlé de notre SparkSession, rien de nouveau là-bas. Et nous définissons un schéma de régression qui correspond à la classe de cas dont nous venons de parler. Ainsi, nous pouvons importer cela à partir du disque en utilisant une interface DataFrame. Donc, nous disons juste point d'étincelle lu avec un séparateur de virgules utilisant ce schéma. Et nous avons chargé vers le haut à partir du fichier txt de point de régression de données que nous venons de regarder, puis le
lancer
jeu de données en utilisant la classe de cas de schéma de régression. Maintenant, les choses deviennent intéressantes. Donc, le format attendu par cet algorithme dans la bibliothèque ML est très spécifique et souvent vous devez vous référer à l'exemple de code fourni avec Spark pour comprendre exactement ce qu'il veut. C' est comme ça que j'ai réussi à obtenir ce code pour être honnête. Donc, ce qu'il attend est que vous allez créer un objet VectorAssembler, qui fait également partie des bibliothèques d'apprentissage automatique. Et vous voulez définir dans ses colonnes en entrée comme un tableau de vos colonnes d'entités. Maintenant, dans notre cas, nous n'avons qu'une seule colonne d'entités, il s'agit d'entités nommées sous score brut. Donc, nous passons juste dans un tableau avec ce nom de colonne caractéristiques soulignement raw. Si vous aviez plus d'une fonctionnalité, si vous aviez un problème multidimensionnel, vous passeriez également les fonctionnalités supplémentaires ici. Et puis cet assembleur vectoriel sortira dans une nouvelle colonne, quelque chose appelé entités. Et c'est en fait ce que nous allons passer dans notre modèle. Donc, une fois
que nous aurons cet assembleur, c'est cet objet d'assembleur vectoriel, nous allons appeler transformée en alimentant ce jeu de données de nos données brutes. Et cela transformera cela en cette colonne de sortie d'entités. Nous sélectionnerons la colonne d'étiquette et la colonne d'entités qui sont produites. Donc maintenant, nous avons un DataFrame appelé df qui contient juste des étiquettes et des fonctionnalités. Et les étiquettes correspondront à nouveau à notre montant dépensé et colonnes à la PageSpeed. Encore une fois, je vais descendre à une échelle uniforme. Bon, maintenant que nous avons ça,
ce que nous allons faire pour mesurer la performance de cet algorithme, c'est de diviser ces données en deux ensembles. Nous allons mettre de côté la moitié de ces données pour former notre modèle. Et nous allons mettre de côté l'autre moitié pour tester le modèle. Donc, l'idée ici est que nous allons former ce modèle en utilisant seulement la moitié des données que nous avons. Et puis en utilisant ce modèle formé, nous verrons à quel point il peut prédire les valeurs correctes connues sur l'autre moitié des données. Et nous allons mesurer cette erreur pour avoir une idée de la qualité réelle
de notre modèle qui peut nous indiquer si nous devons essayer différents hyperparamètres ou non, par
exemple, ou mieux nettoyer nos données, n'est-ce pas ? Donc, nous extrayons la première scission de cela à partir de scissions aléatoires et appelons que le DataFrame de formation. Et le deuxième bloc de test, il va y avoir le test DataFrame. Donc, la division aléatoire divise simplement un DataFrame en utilisant un tableau de pourcentages que vous lui donnez. Dans ce cas, 5050. Nous prenons ce premier DataFrame résultant et l'appelons formation Tf et le second DataFrame résultant et l'appelons DF test. Et cela est juste basé sur l'attribution aléatoire de chaque ligne de d f dans un ou deux de ces DataFrames. Maintenant, nous avons tout. Nous devons réellement créer notre modèle de régression linéaire. Et nous allons aller de l'avant et le créer. Et la régression linéaire, on l'appellera LIR. Et nous avons dit tous les hyper-paramètres. Encore une fois, je pense que je viens de les arracher de la documentation pour les endroits où vous pourriez vouloir commencer à partir des échantillons. Encore une fois, dans le monde réel, vous voudriez itérer sur ceux-ci et trouver quelle combinaison de paramètres donne les meilleurs résultats. Une fois que nous avons notre objet, nous appelons ajustement sur lui en passant dans notre formation DataFrame ce chemin que nous avons mis de côté pour la formation du modèle. Et puis nous prenons ce modèle formé et faisons des prédictions à ce sujet. Donc, nous prenons notre modèle et nous appelons transform sur elle, en
passant notre test DataFrame. Et cela va créer une nouvelle prédictions complètes DataFrame qui contiendra montant
prévu dépensé en fonction du PageSpeed vu dans le jeu de données de test. Maintenant, ce qui est intéressant ici, c'est que nous pouvons ensuite comparer notre montant prévu dépensé le montant réel dépensé qui vit dans nos valeurs de test DataFrame dans les étiquettes que nous avons là. Notez que je l'attrape ici. Pas strictement nécessaire pour cet exemple simple, mais si vous alliez faire des choses en utilisant ce jeu de données de prédictions complètes à plusieurs reprises, vous voudriez mettre en cache cela pour accélérer cela, n'est-ce pas ? Donc, une fois que vous avez un modèle formé et un ensemble de prédictions basées sur celui-ci, en général, vous voudrez probablement mettre en cache ces résultats afin que vous puissiez les utiliser à plusieurs reprises, non ? Dans ce cas, nous allons juste arracher les prédictions et les étiquettes après avoir cliqué dessus à partir des prédictions complètes DataFrame. Et nous appellerons cela la prédiction et l'étiquette. Et puis on reconnecte ça au script et on les imprime tous. Donc, nous pouvons juste jeter un oeil à ce que les valeurs réelles prédites et réelles où pour chaque point, vous pouvez probablement deviner ce qu'un bon exercice pour le lecteur ici serait en ce qui serait de faire le travail de comparant ces valeurs prédites aux valeurs réelles et mesurant réellement cette erreur à partir du test DataFrame. Mais pour l'instant, nous allons juste regarder les résultats parce que ce n'est pas vraiment un apprentissage automatique correspondant. Il s'agit bien sûr d'utiliser Spark. Nous allons donc cliquer avec le bouton droit de la souris sur le jeu de données de régression linéaire et le
réexécuter . Et ça a marché. Encore une fois, nous n'avons pas ou du moins nous n'avons pas fait le travail pour savoir si ce sont des prédictions raisonnables ou non. Mais ce sont des prédictions. Vous pouvez donc voir la sortie ici. Encore une fois, ils sont réduits à l'échelle quel que soit le facteur de mise à l'échelle utilisé lorsque nous prétraitons les données. Donc, pour en faire un bon usage, nous devrions le remonter à l'échelle. Mais on dirait que ça a marché. Ces valeurs ressemblent à des valeurs réelles et se situent dans une plage raisonnable de valeurs. Donc là, vous l'avez. Régression linéaire dans un jeu de données à l'aide d'Apache Spark. Encore une fois, la puissance de cela est que vous pouvez prendre un jeu de données vraiment massif et effectuer une régression linéaire sur celui-ci et créer un modèle en utilisant toute la puissance de l'ensemble du cluster. Donc le ciel est la limite ici, littéralement. Bon, donc c'est l'apprentissage automatique à Spark. En un mot, vous constaterez que la plupart des modèles fonctionnent de la même manière. Vous créez simplement un objet modèle avec un tas d'hyperparamètres. Vous adaptez ce modèle à certaines données d'entraînement. Ensuite, vous pouvez transformer ce modèle avec des données pour lesquelles vous voulez faire des prédictions. Et c'est assez facile à utiliser. Alors c'est tout. Allons passer à autre chose.
54. [Exercice [Exercise] des valeurs de propriété Real de arbres de décision dans Spark: Donc, pour votre prochain défi, nous allons utiliser Spark avec quelques données du monde réel ici, nous allons essayer de prédire les valeurs d'un immobilier à l'aide d'arbres de décision, qui est une autre technique d'apprentissage automatique similaire à la régression. Il peut également être utilisé à des fins de régression. Et Apache Spark pour pouvoir l'augmenter si nous le devions. Nous obtenons donc notre jeu de données sur un ensemble de données qui a le prix par unité de surface. Ils appellent ça des pings d'où ça vient, sur la
base d'un tas d'attributs de maisons. Et cela vient de Taiwan, de New Taipei City. Ce sont des données réelles et voici le crédit nécessaire pour savoir qui a créé cet ensemble de données. Et si vous voulez en savoir plus sur le jeu de données lui-même et en savoir plus sur son format. Suivez ce deuxième lien qui vient du référentiel de données UCI. C' est un référentiel très utile de jeux de données Machine Learning pour que vous
puissiez l'utiliser pour expérimenter, jouer avec et apprendre avec. C' est donc une bonne ressource là, bougies et d'autres aussi, si vous cherchez plus de sources de jeux de données avec des données du monde réel. C' est donc à quoi ressemblent les données. Je l'ai en fait nettoyé un peu pour vous juste de lui donner noms de colonnes
plus raisonnables et de le convertir au format
CSV pour rendre votre vie un peu plus simple pour cet exercice, il se compose de plusieurs colonnes de données au format CSV. La première colonne est juste appelée numéro est le nombre associé à cette maison. Et puis pour chaque maison, nous avons la date de la transaction à laquelle elle a été vendue, l'âge de la maison, la distance à la MRT, c'est en fait la distance au réseau de transport public local. Le nombre de dépanneurs à proximité,
ce qui, je suppose, est un gros problème à Taiwan, il semble, et la latitude et la longitude de la maison elle-même. Et enfin, la chose que nous essayons de prédire, le prix de la surface unitaire. Et bien sûr, c'est une monnaie locale. Alors ne lisez pas trop ce que cela signifie réellement. Votre défi consiste à prédire le prix par unité de surface en fonction de l'âge de la maison, de la
distance des transports et du nombre de dépanneurs à proximité. Juste pour rendre cela un peu plus facile, je vais jeter certaines des données qui seraient plus difficiles à analyser comme l'emplacement réel et des choses comme ça. Évidemment, le numéro réel de la transaction, cela n'a pas vraiment d'importance, pas plus que la date à nos fins. Nous allons donc garder les choses simples et nous nous contenterons de traiter des données numériques ici. Votre stratégie sera d'utiliser une
régression d'arbre de décision au lieu d'un objet de régression linéaire de Spark dot SML, ils ont fonctionné de la même manière. Si vous le souhaitez, vous pouvez regarder la documentation dans la documentation Spark en ligne, mais c'est à peu près la même syntaxe, juste un nom différent. Alors que la régression linéaire fonctionne en calculant ces pentes et en interceptant les lignes, un arbre de décision fonctionne avec une stratégie différente. Fondamentalement, il construit cet arbre de décisions qu'il prend où, à chaque point de l'arbre, il dit, cet attribut
est-il inférieur ou supérieur à une certaine valeur ? Et il fait son chemin en prenant ces décisions basées sur ces décisions binaires pour essayer d'arriver à une prédiction finale de ce que sera votre étiquette prédite finale. Donc juste une façon différente d'obtenir le même genre de résultat à la fin de la journée, la raison pour laquelle nous allons avec les arbres de décision est double. Un, juste pour vous exposer à un autre algorithme ML disponible dans Spark. Et aussi parce que les arbres de décision sont moins sensibles à l'utilisation de données à différentes échelles. Nous n'avons pas à nous soucier de la mise à l'échelle de toutes nos données pour être normalisées et dans la même plage pour obtenir les meilleurs résultats avec un arbre de décision, il peut gérer cela beaucoup mieux. Donc, pour commencer, commencez par une copie de la classe Scala du jeu de données de régression linéaire que nous avons examinée plus tôt. Et ce sera un point de départ très utile en modifiant juste un peu cela, vous devriez être en mesure de retirer cela. Et notez également que nous avons une ligne d'en-tête dans ce fichier CSV, donc il n'y a pas besoin de code dur est le schéma pour lire que dans, nous pouvons juste avoir le lecteur d'étincelle pour le
faire automatiquement si nous lui disons que l'en-tête existe, quelques extraits utiles que nous obtenons à travers cela. Tout d'abord, dans notre exemple précédent, nous n'avions qu'une seule colonne de fonctionnalité péché et vous n'avez pas besoin d'en avoir une seule. Vous pouvez en fait avoir plusieurs colonnes d'entrée dans un assembleur vectoriel. Alors rappelez-vous que vous pouvez également dire définir le tableau d'appels d'entrée, puis une liste de colonnes, pas seulement une seule colonne si vous avez plusieurs fonctionnalités comme nous le faisons ici. Et rappelez-vous lorsque vous lisez le fichier dans, au lieu de spécifier un schéma réel, vous pouvez simplement dire en-tête true et inférer le schéma true. Et nous allons tout lire tant que ces noms de colonnes d'en-tête correspondent à ce que vous avez dans votre classe de cas, tout fonctionnera très bien. La seule chose à propos de la régression de l'arbre de décision, vous n'allez pas avoir besoin de tous ces hyperparamètres supplémentaires que nous avons spécifiés sur les arbres de décision de régression linéaire ont un ensemble différent d'hyperparamètres, mais il est normal de ne pas spécifier et aller avec les valeurs par défaut. C' est très bien. Ainsi, vous pouvez supprimer tout ce code supplémentaire sur l'exemple de régression linéaire. Et notez également qu'il y a une fonction de col d'étiquette définie. Et cela vous permettra de spécifier une colonne d'étiquette qui n'est pas nommée label. Dans notre cas, il n'est pas nommé label. C' est le prix de la zone unitaire ou quelque chose comme ça. Donc ça devrait être à peu près tout ce dont vous avez besoin. Alors allez-y et donnez-lui un coup d'envoi. Et dans la prochaine conférence, je vais vous guider dans ma solution et voir à quel point vous approchez.
55. Solution d'exercices : Predicting des propriétés commerciales avec des arbres de décisions dans Spark: Bon, passons à travers ma solution pour prédire la valeur d'une maison par zone basée sur des attributs plutôt inhabituels de ces maisons à Taiwan. Comme toujours avec l'apprentissage automatique, vous devriez commencer par étudier la nature des données qui vous sont données. Et à nos fins puisque le statut a déjà été nettoyé, nous voulons principalement cela autour pour avoir une référence pratique à ces noms de colonnes. Parce que faire correspondre ces exactement sera très important car nous écrivons notre petit script ici pour le charger et le convertir au format que notre algorithme attend. Et vous savez, c'est toujours une bonne idée de vérifier
les données, de s'assurer qu'il n'y a rien d'inattendu dedans. Nous supposons que ce sont tous des chiffres. Donc, un balayage rapide juste pour s'assurer que ces nombres semblent tous être dans plus ou moins la même plage et n'ont pas de bizarre comme valeurs
manquantes ou des vallées dans le mauvais format, comme des valeurs de chaîne aléatoires ici et là. Cela vous évitera des ennuis. Cependant, ce jeu de données a déjà été nettoyé pour vous. Donc, la partie difficile de l'apprentissage automatique est déjà prise en charge dans ce cas, avec cette liste, allez au code. Donc, je viens juste de commencer par copier le fichier Scala de jeu de données de régression
linéaire des points de jeu de données et je l'appelle un gala de points immobiliers à la place. Le changement principal ici. Tout d'abord, nous utilisons un algorithme différent pour la régression. Nous importons ou point apache point étincelle point HTML point régression point point de décision régression arbre de décision cette fois, tout comme nous vous avons donné un indice dans les diapositives, si vous vouliez utiliser une régression linéaire encore que vous pourriez, il serait en fait encore travailler. Mais encore une fois, nous voulons juste vous exposer à un nouveau. les arbres de décision sont moins sensibles à la présence de plages de valeurs
différentes dans les entités et les étiquettes. Nous déclarons donc un nouveau schéma de régression ici. Et comme vous pouvez le voir, c'est beaucoup plus compliqué. Toutes nos fonctionnalités ont des noms différents et il y en a plus d'une maintenant. Donc, nous avons en fait chacune des colonnes dans les données d'entrée qui arrivent. Et nous avons cartographié cela de façon similaire. Donc, nous avons le nom de colonne NO, qui signifie nombre. Nous supposons cette date de transaction entière. On va appeler cette maison double, âge du double, et cetera, et cetera. Ces noms sont tous en corrélation avec ces noms de colonnes dans l'en-tête CSV lui-même. D' accord, passer à autre chose. Rien de différent là-bas. Lorsque nous chargeons réellement dans le fichier et que nous allons dire en-tête d'
option true et option dans le premier schéma true, au lieu de lui donner un schéma codé en dur qui permettra de profiter de cette ligne d'en-tête dans le fichier CSV. Donc, ça rend la vie un peu plus simple là-bas. Nous n'avons pas à coder ce schéma deux fois, ce qui est un peu ennuyeux quand cela arrive. Ensuite, nous construisons notre VectorAssembler comme nous l'avons fait auparavant. Et la différence ici est qu'au lieu d'une seule caractéristique, ou je pense que nous l'appelons caractéristiques brutes ou caractéristiques Ron, je pense que nous avons à l'origine trois caractéristiques différentes et cet exemple, âge de la
maison, la distance à MRT et le nombre dépanneurs. Encore une fois, nous faisons correspondre cela à ces noms de classe de cas comme ici. Donc, l'énoncé du problème était de prédire le prix de la superficie unitaire en fonction de l'âge de la maison, distance à MRT un certain nombre de dépanneurs. Donc nous jetons les colonnes supplémentaires, vous n'en avez pas besoin. Nous définissons simplement les colonnes d'entrée à celles dont nous nous soucions que nous voulons réellement utiliser comme entités pour faire une prédiction à partir de. Et nous appellerons la colonne de sortie des entités lorsque nous aurons terminé, c'est très bien. Et nous allons en outre sélectionner le prix de la colonne de surface
unitaire parce que ce sera nos étiquettes. Donc, à ce stade, ce que nous allons finir avec une colonne appelée prix de la surface unitaire. Ce sera la chose que nous essayons de prédire, les étiquettes. Et une colonne d'entités qui contient juste une liste d'entités. Ainsi, cette colonne contiendra au format de liste, l'âge de la maison, la distance à MRT et le nombre de dépanneurs. Et c'est juste le format que notre modèle attend. Nous devons donc nous conformer à cela. Comme précédemment, nous avons divisé cela en un ensemble d'entraînement et un jeu de données de test. Et maintenant, nous allons construire notre modèle qui s'appelle régresseur d'arbre de décision. Je suppose que j'aurais dû changer le nom de la variable à autre
chose que LIR, je suppose que ça aurait dû l'être. Mais peu importe, tout ce que tu veux faire, c'est bien. Nous avons explicitement défini les noms de colonne d'entités et de colonne d'étiquette ici. fonctionnalités sont la valeur par défaut, donc techniquement je n'ai pas eu à le faire, mais la valeur par défaut pour l'étiquette est étiquetée et non pas le prix de la surface unitaire. J' ai donc dû dire explicitement à mon modèle que le nom de ma colonne d'étiquette est le prix de la surface unitaire pour que cela fonctionne. Après cela, tout fonctionne de la même manière. Donc, nous disons juste en forme, en
passant dans notre formation DataFrame. Et nous faisons un ensemble de prédictions en transformant cela avec nos données de test. Et comme avant, nous passons juste par le passé et le sélectionnons. Nous avons changé le nom de la colonne des étiquettes ici à nouveau et l'avons collecté et l'avons parcouru et les avons tous imprimés. Et ce que cela fera comme un commentaire dit, est d'imprimer la valeur prédite et la valeur réelle pour chaque maison dans notre jeu de données de test. Alors voyons si ça marche. Cliquez avec le bouton droit sur l'immobilier et exécutez. Et nous avons de la sortie. Cool. Donc juste en fouettant à travers, beaucoup de ceux-ci ont l'air assez raisonnable. On a prédit qu'il en avait 50 pour ce qui est, et c'est vraiment 55. Et pour la plupart, le modèle a assez bien fonctionné. Je veux dire, il y a évidemment des moyens de quantifier la qualité du modèle en utilisant des mesures comme RMSC. Mais il ne s'agit pas d'un cours de science des données ou d'apprentissage automatique. Donc, je ne vais pas entrer dans ça. Mais j'ai mal compris certains d'entre eux. Donc pour celui-ci, il a prédit une valeur de 36, mais la valeur réelle était un 117. Donc, clairement, il y a plus à ce qui définit la valeur d'un endroit en plus de la proximité d'un dépanneur dans lequel vous êtes. Des choses comme à quel point vous êtes proche de la gare la plus proche. Donc pas trop surprenant que ce n'est pas un modèle génial parce que nous ne lui avons pas donné beaucoup de données impressionnantes, mais cela fonctionne étonnamment bien en fait, en agrandissant, il est devenu assez proche de la plupart de ces résultats si intéressants. Donc là, tu l'as, j'espère que tu l'as traversé. Encore une fois, ce n'est qu'une façon de le faire. Si vous avez adopté une approche différente, c'est bien aussi. Assurez-vous juste que vous avez une sortie similaire et nous l'appellerons bon.
56. L'API DStream pour la diffusion DStream: Et les cas d'utilisation de plus en plus courants Spark traite des données en streaming. Donc, jusqu'à présent dans le cours, nous avons parlé de l'analyse de jeux de données hors connexion par lots. Nous avons donc ces données pilotes et nous voulons les analyser ou les traiter d'une manière ou d'une autre. Mais dans le monde réel, les données ne cessent d'entrer, n'est-ce pas ? C' est là que Spark Streaming intervient. Il vous permet d'ingérer des flux de données en temps réel. Par exemple, vous pouvez disposer d'un parc de serveurs qui génèrent des informations de journal
, qui sont canalisés dans votre cluster Spark qui sont analysés au fur et à mesure. Peut-être que vous transformez ces données et les stockez ailleurs dans une autre base de données. Peut-être que vous êtes en train de l'agréger au fil du temps et que vous
cherchez des choses sur lesquelles vous voulez être alerté au fur et à mesure qu'ils se produisent. Quoi qu'il en soit, le streaming est un cas d'utilisation très important dans le monde des affaires de nos jours. Voyons donc comment Spark Streaming peut être utilisé pour analyser les données telles qu'elles sont créées et prendre les mesures nécessaires. Donc, dans cette section, nous allons vous présenter Spark Streaming. Il s'agit d'un cas d'utilisation très courant pour Apache Spark ces jours-ci, où nous traitons de sources de données en streaming et non seulement de transformer un tas de données en une seule fois dans un processus par lots,
mais de surveiller continuellement les données entrantes et faire quelque chose en temps réel tel qu'il est reçu. Donc, un exemple courant de cela serait le traitement des données
enregistrées provenant d'un site Web ou d'un serveur, ou peut-être toute une flotte de serveurs qui alimentent un site Web. Ces données n'arrêtent jamais d'entrer, non ? Donc, il n'y a pas comme un ensemble vraiment simple de fichiers journaux. Donc, vous pouvez pointer vers et dire, Hey, va analyser ce morceau de données de journal. Il arrive toujours, il y a toujours de nouvelles informations qui sont recueillies tout le temps. Et peut-être que vous voulez agréger et analyser cela à un intervalle donné ou une fenêtre d'information, n'est-ce pas ? Peut-être que vous voulez mettre en place une sorte d'alarme où si vous voyez un tas d'erreurs sur votre site Web, quelque chose est notifié automatiquement, n'est-ce pas ? Donc, au lieu d'attendre une analyse nocturne de ces données, nous analysons continuellement ces données au fur et à mesure qu'elles entrent et faisons quelque chose avec elles. Ces données ne doivent pas nécessairement provenir d'un fichier brut qui peut provenir d'un port qui reçoit des données TCP. Il peut provenir du service Amazon Kinesis. Il peut provenir d'un HDFS ou d'un système de fichiers distribué qui peut provenir de Kafka, venir de Flume et de toutes sortes d'autres sources de données pour que Spark Streaming puisse s'intégrer avec un tas de systèmes différents, pas seulement des fichiers texte et analyser ces données telles qu'elles entrent. Et il ne s'agit peut-être pas seulement d'analyser et d'agréger des données. Il pourrait s'agir de le transformer et de l'envoyer ailleurs. Peut-être que tout ce que Spark Streaming fait dans votre cas consiste à prendre les données de journal entrantes, extraire les informations qui vous intéressent, à
structurer ces données, puis à les stocker dans une base de données quelque part. C' est un cas d'utilisation parfaitement valide pour le streaming Spark. Et la bonne chose à propos de Spark streaming, au lieu de cela, il a une fonctionnalité de pointage de contrôle. Donc, si votre flux tombe en panne, si votre cluster tombe en panne pour une raison quelconque, il dispose d'un moyen facile de récupérer automatiquement de l'endroit où il s'est arrêté automatiquement. Donc c'est une belle fonctionnalité à coup sûr. Commençons donc à parler de l'ancienne API DStream pour Spark Streaming. Fondamentalement, Spark Streaming a un historique historique, si vous voulez, l'interface d'origine où il a été appelé DStreams, et il était basé sur l'ancienne interface RDD. Et parce qu'il était basé sur des RDD, il était centré autour de ce que nous appelons des micro-lots. Donc, il a juste traité ces morceaux de données qui étaient représentés comme des RDD. Et il a complètement traité ces petits morceaux. Donc techniquement parlant, ce n'était pas vrai streaming. Il ne fonctionnait pas réellement sur des données sur une base champ ou ligne par ligne. Ça regroupait les choses en ce qu'on appelle des microlots. Maintenant, dans le monde réel, ce n'est généralement pas vraiment un problème si vous avez une latence de quelques secondes par opposition au traitement immédiat pour la plupart des applications, cela n'a pas vraiment d'importance. Mais c'était l'une des principales choses qui les
poussent à s'éloigner de cette interface au fil du temps. Et bien, des couvertures pour des raisons historiques ici. Mais nous allons passer à l'API de streaming structuré plus moderne après cela. Quoi qu'il en soit, voici un exemple de ce que de Streaming pourrait ressembler. Donc, vous devez configurer un contexte de streaming par opposition à un SparkContext. Et cela signifie que ça va traiter les choses 1 seconde à la fois. Vous aurez donc ces microlots contiennent seconde de nouvelles données que nous allons traiter dans le cadre de notre script. Nous pouvons alors dire flux de texte socket point flux. Et cela va lui dire d'écouter le port 8888 pour les données texte envoyées sur ce port TCP. Et puis tout ce qu'il va faire est de filtrer ces lignes entrantes pour les lignes qui contiennent le mot erreur. Et s'il voit une ligne qui contient le mot erreur, il l'imprimera. Une fois que vous avez configuré cela, il vous suffit d'appeler le point de démarrage de flux pour lancer et diffuser en continu une semaine de fin d'attente pour que quelqu'un l'arrête. Donc c'est un peu magique, peu bizarre d'envelopper la tête autour de ce paradigme, non ? Vous devez donc vous rappeler que nous ne traitons pas un seul morceau de données. Ce graphique acyclique dirigé que nous construisons ici pour traiter ces données dans les données prises et les filtrer et les imprimer si elle, s'il passe ce filtre, cela va être appliqué de façon répétée chaque 1 seconde des données qui sont reçues automatiquement. Nous n'avons pas besoin d'écrire une boucle quelque part qui dit continuer à faire cela toutes les 1 secondes à plusieurs reprises. Spark Streaming fait cela pour vous. Donc, cette syntaxe ici peut sembler un peu étrange et magique au début parce qu'elle fonctionne un peu sur le flux. Vous n'avez pas à y penser trop, mais ça marche. Donc, à un niveau élevé, c'est comme ça que ça marche. Des gotchas. Rappelez-vous donc que vos RDD ne contiennent qu'un petit morceau de données entrantes. Maintenant, ce que vous pouvez faire est des opérations fenêtrées. Avec une opération fenêtrée, vous pouvez combiner automatiquement les résultats de plusieurs lots sur une fenêtre temporelle coulissante. Donc, il y a des fonctions comme fenêtre ou réduite par fenêtre ou ReduceByKey et fenêtre. Donc, ces fonctions de fenêtre vous permettent de faire une réduction sur un certain temps en remontant dans le passé. Donc, je pourrais dire revenir en arrière pour la dernière minute, revenir en arrière pour la dernière heure, revenir en arrière pour la dernière journée, peu importe ce qu'elle est, et réduire mes informations en fonction de cette fenêtre d'information. Donc, cette fenêtre n'a pas besoin de correspondre à la taille de votre lot qui peut être beaucoup plus grande et elle gardera automatiquement une trace de ces résultats RDD, ces micro-lots, et appliquera votre opération sur cette période de temps que vous avez défini. Ainsi, il garde automatiquement ces informations autour de vous afin que vous puissiez les analyser au fur et à mesure. En outre, quelque chose qui vaut la peine de parler est mise à jour état par clé. Cela vous permet de maintenir un état qui s'étend sur de nombreux lots à mesure que le temps passe. Donc, si vous devez suivre une sorte d'état
en cours d'exécution vous traitez ces informations sur Windows ou sur plusieurs lots, vous pouvez le faire avec les mises à jour état par clé. Un bon exemple de cela serait l'exécution d'une sorte de compteur et nombre
continu d'un événement au fil du temps depuis que vous avez commencé le script. Donc, si vous avez besoin de garder une trace de quelque chose que le script s'exécute dans son ensemble plutôt que sur une certaine fenêtre de temps. Mettre à jour l'état par clé, vous permet de le faire. Alors plongons dans un exemple simple ici. Nous allons lancer un script de streaming Spark qui surveille
simplement les tweets en direct de Twitter. Et nous garderons une trace des hashtags les plus populaires lorsque nous recevons de nouveaux tweets. Et pour ce faire, nous devons d'abord créer un compte de développeur Twitter. Maintenant, certaines personnes ont du mal à faire cela dépend du pays ou de la façon dont vous remplissez le formulaire. Quel genre d'humeur pour Twitter est en toute honnêteté, Donc je ne suis pas sûr que vous voulez vraiment passer par cela vous-même. Vous pouvez, si vous voulez simplement aller sur apps dot twitter.com et demander un compte de développeur là-bas si vous voulez suivre le long. Honnêtement, je pense que vous devriez juste me regarder faire cette prochaine activité parce que comme je l'ai dit, DStreams est un peu daté. Maintenant, si vous suivez ce cours dans le but d'obtenir une certification, je peux vous promettre qu'il ne sera pas à l'examen de certification, donc vous voudrez peut-être juste me regarder faire cette activité suivante au lieu de suivre. Mais si vous le faites, vous pouvez simplement aller à apps dot twitter.com connexion pour le compte développeur. Ensuite, vous pouvez créer les clés d'API et les jetons d'accès dont vous avez besoin pour interroger Twitter et le diriger vers le streaming Spark. Donc, pour stocker ces informations, leurs informations d'identification, vous devrez créer un fichier txt twitter dot. Et je vais vous montrer où c'est quand nous marchons à travers,
il va juste avoir un nom de votre clé consommateur et accéder aux informations de jeton sur chaque ligne et notre script de pilote, nous allons le lire dans et l'utiliser pour nous authentifier avec Twitter. Notre stratégie globale ici, une fois que nous aurons ce flux Twitter établi, nous allons simplement extraire les messages eux-mêmes. Il y a un tas de métadonnées que Twitter vous donne aussi. Mais nous allons créer un flux Twitter utils point créer qui va utiliser une bibliothèque tierce que j'ai inclus avec le cours pour
réellement connecter Twitter et le faire ressembler à un DStream. Et puis nous appellerons tweets dot map pour extraire le champ de texte sur cela en appelant le point d'état GetText. Donc, à ce stade, nous aurons un nouveau RDD, un micro lot, si vous voulez, qui ne contient que les messages d'état de chaque tweet reçu. Ainsi, par exemple, peut-être qu'un tweet dit Voter pour le hashtag buldface. Et quelqu'un pourrait dire un livre pour que j'aime les grosses bottes et je ne peux pas mentir et pas voter pour hashtag. Quel iceberg ? Et quelqu'un d'autre pourrait dire, qu'est-ce que tu es fou ? Hashtag, Bodhi MAC, gras tout le chemin. Et si vous vous demandez de quoi je parle ici, c'était une méchante il y a plusieurs années. Fondamentalement un, J'oublie ce que la marine c'était, mais ils ont organisé un concours en ligne pour laisser l'Internet nommer leur nouveau navire. Et bien sûr, c'était une idée horrible. Le gagnant, bien sûr, était podium micro en gras, qu'ils n'ont pas utilisé. Mais je pense qu'ils l'ont collé sur un peu comme un petit résumé ou quelque chose qui était sur le vaisseau ou quelque chose comme ça. Quoi qu'il en soit, cet exemple nous essayons de garder une trace des hashtags les plus populaires, non ? Donc, dans ce cas, nous aurions hashtag Boolean avec les deux faces apparaissant comme nombre, le résultat numéro un avec deux apparences et hashtag, quel iceberg serait le deuxième résultat avec une apparence. Nous avons donc établi notre flux de messages d'état. Ensuite, nous pouvons utiliser flatmap pour diviser cela en mots individuels. Donc, en appelant FlatMap sur ce micro batch statuts, nous allons ensuite le souffler dans un RDD plus grand qui a une ligne pour chaque mot qui apparaît. Ainsi, par exemple, le vote de message pour son hashtag Buddy macrophase, serait simplement divisé en trois lignes distinctes. Votez pour le hashtag bas des buffets. Et puisque tout ce qui nous intéresse, ce sont les hashtags, c'est la seule chose que nous mesurons. Nous pouvons ensuite appeler filter pour filtrer toutes les lignes qui ne commencent pas par le symbole hashtag. Donc, cela réduira les choses à juste les hashtags qui apparaissent. Et à ce stade, nous pouvons faire notre vieille astuce de retour dans la section un ou la section à quoi qu'il s'agisse, où nous pouvons les convertir en un RDD de paires de valeurs clés, où la clé est le hashtag réel et la valeur est le numéro un. Cela nous permettra plus tard de faire une
opération de réduction pour les compter tous avec juste ce qui se passe ici. Et on va le faire sur une fenêtre coulissante pour rendre les choses intéressantes. Donc, l'opération de réduction va additionner tous ces éléments ensemble et nous
donner un nombre total pour le nombre de fois que ce hashtag apparaît. Mais on utilise un flux ici, donc on ne va pas dire réduire par clé. Nous devons dire sur quelle période de temps. Et pour ce faire, nous dirons ReduceByKey et fenêtre pour effectuer que réduire l'opération sur une fenêtre donnée et intervalle de diapositive. Donc, nous allons dire ReduceByKey et fenêtre, en
gros tout additionnant. Et quand passez-vous cela, vous devez explicitement lui donner une fonction pour ajouter et supprimer des éléments au fur et à mesure. C' est ce qui se passe ici dans cette syntaxe. Et nous allons dire que nous allons appliquer ça sur une fenêtre de 300 secondes. C' est les cinq dernières minutes avec une diapositive d'une seconde. Nous allons donc faire glisser notre fenêtre sur une toutes les 1 secondes et regarder les cinq dernières minutes de données. Donc, ce que cela va faire est de recalculer cette réduction des hashtags COUNTIF toutes les secondes, revenant pendant cinq minutes. Et nous devrions obtenir un résultat qui ressemble à ça si c'était nos données d'échantillon réelles. Donc, enfin, nous avons juste besoin de trier et de produire les résultats. Nous appellerons une transformation pour trier ce RDD en fonction du deuxième champ, qui est le nombre, et les imprimerons. Et ça devrait être tout. Alors allons le voir en action. Notez que nous avons quelques bibliothèques supplémentaires que nous utilisons, certaines bibliothèques tierces. Je vais vous montrer comment ça est arrangé. Et oui, plongons dans le code et voyons si ça marche. Ça pourrait être intéressant.
57. [Activité] Surveillance en temps réel des hashtags les plus populaires sur Twitter sur Twitter: Bon, Alors passons à travers cet exemple d'utilisation de l'ancienne API DStream et l'utiliser pour trouver les hashtags les plus populaires sur Twitter en ce moment. Et si vous voulez suivre, vous pouvez essayer si vous vous dirigez vers apps dot twitter.com ou dot développeur twitter.com, vous atterrissez sur le portail des développeurs pour Twitter. Et si vous n'avez pas déjà de compte développeur, il vous guérira tout au long du processus de demande. Et encore une fois, je ne suis pas sûr que ça vaut la peine de passer à travers ça. Tout d'abord, ils rendent de plus en plus difficile d'obtenir un compte développeur ces jours-ci parce que tant de gens les utilisent pour faire des choses maléfiques avec des bots et autres. Mais si vous voulez le suivre, si vous dites simplement que vous le faites à des fins
éducatives pour un cours en ligne et listez le nom de ce cours. Ils vous en donneront probablement un assez vite. Donc, si vous voulez le faire, allez-y et demandez un compte. Une fois que vous avez cela, vous serez en mesure de créer à la fois un ensemble de clés d'accès. Alors regardons à quoi ça ressemble. Donc, si vous cliquez sur les clés et les jetons, cela vous amènera à un endroit où vous pouvez obtenir à la fois vos clés d'accès du consommateur, la clé publique et secrète, et aussi un ensemble de jetons pour une application. Et une fois que vous en
aurez, vous allez ouvrir votre fichier txt twitter dot dans votre matériel de cours et les mettre là dedans. Donc le mien ressemble à ça. Évidemment, j'ai floue les clés réelles parce que je ne veux pas utiliser les miennes. Mais il suffit de coller votre clé de consommateur et le secret du consommateur et votre jeton d'accès et le secret du jeton d'accès ici pour votre propre compte si vous suivez le long. Et puis le code, nous allons juste ramasser ça et l'utiliser pour s'authentifier avec Twitter. Faites attention cependant, assurez-vous que vous n'avez pas de lignes supplémentaires, n'avez pas d'espaces supplémentaires avant ou après ces choses qui vont gâcher les choses. problème numéro un que les gens ont avec celui-ci. Une fois que vous avez cela, revenons à l'intelligence et ouvrons des hashtags populaires. Et passons à travers ce qui se passe ici. Donc encore une fois, cela utilise quelques API plus anciennes ici, DStreams et RDD. Donc, nous avons une fonction séparée ici pour gérer notre niveau de journal ici, pour le faire d'une manière un peu plus détaillée. Il y aura un marché. Nous appelons notre fonction principale. La première chose que nous faisons est d'appeler set-up Twitter. Tout ce qui fait est d'ouvrir ce fichier txt twitter dot et d'extraire toutes ces clés d'authentification. Il définit donc simplement les propriétés système dont client de
Twitter aura besoin pour vous permettre de vous connecter à Twitter. Et sous le capot, c'est en utilisant des bibliothèques tierces que j'ai incluses avec le matériel de cours. C' est probablement un bon moment pour mentionner que tout
cela est construit en utilisant SBT sous le capot dans l'intelligence. Si vous allez réellement construire sur SBT ici, vous pouvez voir les paquets que nous incluons réellement pour le matériel de cours lui-même. Donc, ici, nous disons explicitement, nous utilisons Scala version 2.12, Spark version 3. Nous importons Spark Core Spark SQL, Spark, MLLib, Spark Streaming. C' est comme ça que tout a travaillé par magie jusqu'à présent tout au long du cours. C' est ainsi que nous avons eu Spark à notre disposition. Même si nous n'avons pas réellement installé Spark explicitement. Sbt est sorti et a obtenu ça pour nous automatiquement. Et aussi, nous obtenons le Twitter pour J core et Twitter pour les paquets de flux J. Ce ne sont que des fichiers JAR Twitter qui vous permettent de diffuser des données Twitter à partir de l'API Twitter. Une fois que vous avez défini ces variables d'environnement à une puce, il s'authentifie pour vous. Donc, en définissant cela dans nos dépendances de bibliothèque, il récupère automatiquement la version correcte des bibliothèques Twitter pour nous permettre connecter et de diffuser ces données pour la version donnée que nous voulons ici. Il y a aussi une bibliothèque séparée que nous allons convertir ce flux Twitter de l'API Twitter en un flux D pour le streaming Spark. Et nous venons d'inclure cela dans la librairie. Et nous l'incluons simplement dans les bibliothèques incluses dans le projet ici. Si vous allez ici et allez dans le dossier lib, c'est ce
que le fichier Jar Twitter DStream dash est là aussi. Il a été explicitement construit sur la version spécifique de Spark et Scala et Twitter que nous spécifions dans ce fichier SBT. Et la façon dont SBT fonctionne est que s'il y a quelque chose dans le dossier lib, il le place automatiquement comme une sorte de dépendance locale. C' est ainsi que tout fonctionne sous le capot. Retournez au code cependant. Donc, au lieu de Twitter a mis en place toute l'authentification qu'il aura besoin pour se connecter. Et une fois que nous avons cela, nous pouvons configurer notre contexte de streaming avec une taille de lot d'une seconde de données entrant. Nous allons configurer notre journalisation pour définir le niveau du journal. Et puis nous appelons Twitter utils. C' est appeler dans cette bibliothèque locale que nous y avons incluse. Et nous allons appeler create stream sur elle pour créer
un DStream à partir de Twitter en utilisant cette bibliothèque tierce, nous passons simplement dans notre contexte de streaming et un paramètre facultatif dont nous n'avons pas besoin. Une fois que nous avons cela, nous pouvons simplement appeler status to status dot getText et l'utiliser comme fonction de carte sur ce DStream. Donc, tout ce qui fait est d'extraire le champ de texte de chaque tweet. Donc on se fiche de qui l'a tweeté. On se fiche de l'heure où ils l'ont tweeté. Tout ce qui nous intéresse, c'est le tweet lui-même. Et c'est ce qui va dans nos nouveaux statuts, D-string. Et ici, une fois que nous avons cela, nous utilisons flatmap pour le souffler en mots
individuels après les avoir divisés en fonction du caractère de l'espace, nous filtrons tout ce qui ne commence pas par un hashtag. Donc, maintenant, il nous reste juste avec des hashtags qui sont apparus dans nos tweets qui arrivent à travers ce flux. Nous mappons ensuite cela à ces tuples du hashtag réel lui-même et le numéro 1. Et puis nous pouvons utiliser ReduceByKey et fenêtre pour vérifier toutes les 1 secondes, revenant cinq minutes pour additionner tous ceux pour chaque hashtag individuel et le réduire par cette clé de hashtag. Encore une fois, c'est un format que nous n'avons pas vu auparavant avec ReduceByKey. Parfois, ils veulent avoir les deux en opération pour ajouter quelque chose dans une opération pour enlever quelque chose. Donc, dans ce cas, si vous ajoutez quelque chose, nous voulons l'ajouter. Si tu veux sortir quelque chose, on le soustrait. Habituellement, ce sera le cas, mais il y a des cas d'utilisation bizarres où vous voulez faire quelque chose de plus compliqué. Une fois que nous avons cela, il suffit de le trier et d'afficher les résultats, d'imprimer le top 10. D' accord, pour le lancer, on a dit un répertoire de point de contrôle. On n'a pas beaucoup parlé de ça dans les diapositives. Mais cela est en fait de définir un dossier de point de contrôle sur mon lecteur C. Si vous êtes sur un autre système d'exploitation, vous voudrez probablement changer cela en un chemin logique sur votre système d'exploitation qui ne fonctionnerait pas sur Linux ou Mac bien sûr, mais vous pourriez changer cela pour couper les utilisateurs quel que soit votre nom d'utilisateur est, votre répertoire personnel si vous voulez réduire le point de contrôle. Et cela fonctionnerait aussi bien. C'est là qu'il va stocker un magasin les données dont il a besoin pour ramasser là où il s'est arrêté. Si quelque chose de mauvais arrive à ce script de façon inattendue pendant qu'il est en cours d'exécution, il peut
donc reprendre à partir de ce point de contrôle. Une fois que nous avons cette configuration, nous commençons simplement notre contexte de streaming et nous le laissons faire son truc. Il va continuer à faire ce qu'on lui a dit de faire. Réduire toutes les 1 secondes au cours des cinq dernières minutes ce qu'est le hashtag le plus populaire, et nous continuerons à le faire jusqu'à ce que quelqu'un mette explicitement fin au script. Alors voyons si ça marche. Cliquez sur les hashtags populaires, cliquez avec le bouton droit et exécutez. Et voilà. Et chaque fois que je lance ça, on me rappelle que Twitter est une plateforme mondiale. Nous voyons beaucoup de choses de langues étrangères et de références culturelles qui ne signifient rien pour moi. Partout dans le monde entier. Nous regardons chaque tweet qui sort publiquement
au moins et ajoutons les hashtags qui apparaissent le plus souvent. Alors, laissons cela courir pendant un peu et voyons quels résultats intéressants nous obtenons. Élargissons un peu cela pour que nous puissions en voir plus. On y va. Donc, en ce moment, BTS est à la mode en tant que hashtag supérieur. Je n'ai aucune idée de ce que ça veut dire. Je vais devoir aller chercher ça plus tard. Il représente quelque chose d'
important sur le plan culturel en ce moment qui suscite l'enthousiasme des gens. Les gens sont à la place de la crème glacée. La crème glacée est prise en charge. La crème glacée vient d'être rattrapée pour le numéro un, très excitante. Hey, qui n'aime pas la glace jusqu'à IP3, quoi que ce soit, c'est. Toujours ensemble. Très dynamique, non ? La crème glacée cependant, tenir seul. Comme une guerre entre la crème glacée et le BTS. Bts vote à l'avance. Quoi qu'il en soit, tu pourrais courir ça toute la journée si tu veux, et je te garantis que tu verras quelque chose de différent si tu fais ça toi-même parce que ça change chaque jour, chaque instant, ça dit quoi que le monde parle en ce moment. Et heureusement, je ne pense pas qu'on voit quelque chose d'offensant ici. D' habitude, tu le fais. Bien que pour être juste, je ne sais pas ce qu'est BTS ou ce que cette langue étrangère où il est qui continue à apparaître soit encore ensemble. Je ne sais pas à quoi ça fait référence. Mec, je dois sortir plus. Mais de toute façon, vous l'avez là. On peut aller de l'avant et annuler ça. Appuyez sur le bouton rouge ici pour arrêter. C' est ça. On dirait qu'après ce temps, le gagnant était tout ce que cela signifie dans n'importe quelle langue,
peut-être que quelqu'un dans les commentaires peut me le dire. Je ne sais pas. Peut-être que je ne veux pas savoir. Ça devrait être, ça pourrait être quelque chose de méchant. Mais c'est un exemple plutôt cool, amusant, non ? Donc, nous avons réellement utilisé l'API DStream ici pour aller et se connecter à de vrais
flux Twitter et garder une trace du hashtag le plus populaire au fil du temps. Et si je devais faire ça pendant cinq minutes, on aura cinq minutes de données. Et nous aurions alors une fenêtre coulissante des cinq dernières minutes avenir alors que nous continuons à exécuter ce script. Donc, ça pourrait être amusant de courir pendant un moment et juste voir ce qu'il fait. Donc, là, vous avez une sorte d'exemple du monde réel utilisant des données du monde réel. C' est la partie amusante, mais comme nous l'avons dit, DStreams est un peu l'ancienne façon de le faire. Alors plongons dans la nouvelle façon de faire les choses avec le streaming structuré suivant.
58. Streaming structuré: Donc, comme je l'ai mentionné, DStreams était l'API de streaming d'origine pour Apache Spark. De nos jours, les gens utilisent autre chose. Ça s'appelle « Streaming structuré » parfois. Donc, vous courez toujours dans des bibliothèques qui attendent DStreams comme cette bibliothèque Twitter que je viens d'utiliser. Il est donc toujours utile de savoir que c'est là et comment ça marche. Mais vous constaterez que le streaming structuré est l'API la plus moderne pour le streaming et Spark. Et il est également plus facile d'utiliser ses idées selon lesquelles il utilise des jeux de données comme API principale au lieu de RDD sont des DStreams qui ressemblent à des RDD. Et comme je l'ai dit précédemment, grande partie de Spark va de la manière d'utiliser des jeux de données et dans Scala ou DataFrames en Python comme API principale. Et la beauté de ceci est qu'il est assez élégant pour la diffusion en continu parce que vous pouvez imaginer un jeu de données qui ne cesse d'être ajouté à jamais et que vous l'interrogerez quand vous le souhaitez, comme n'importe quel autre jeu de données. Donc, la partie streaming est juste que nous continuons à ajouter de
plus en plus de lignes à ce jeu de données en temps réel lorsque de nouvelles informations sont reçues. Et ça rend les choses beaucoup plus faciles. Cela signifie que vous pouvez utiliser ces jeux de données doivent beaucoup comme n'importe quel autre jeu de données. Donc, en fait, ce n'est pas beaucoup pour nous de parler dans cette conférence. Une fois que vous avez configuré les choses, vous l'utilisez simplement comme n'importe quel autre jeu de données. Tous les autres éléments que nous avons appris dans le cours s'appliquent exactement de la même manière à un jeu de données en streaming qu'à un jeu de données lu à partir d'un processus de traitement par lots. Et l'autre chose agréable est qu'en faisant cela, streaming est maintenant vraiment en temps réel. C' était un vrai point de blocage avec beaucoup de gens. Et pendant un certain temps, les gens disaient que le streaming Spark était inférieur aux autres plateformes de streaming à cause de cela. Eh bien, maintenant ils ne peuvent plus dire ça parce qu'avec Structured Streaming, streaming est maintenant vraiment en temps réel. Au fur et à mesure que de nouvelles données sont reçues, elles seront immédiatement ajoutées à ce jeu de données et vous y aurez accès immédiatement. Donc, nous ne sommes plus basés sur ces micro-lots de petits RDD
comme des minuscules contiennent une seconde de données. On n'a pas à penser à ça. Ce niveau de pensée n'est plus requis dans notre code. Le mettre en place, c'est super facile. Tout ce que nous devons faire est de dire le flux de lecture de point d'étincelle au lieu de Spark dot read, lorsque nous configurons un DataFrame ou un jeu de données. Et tu peux dire quoi ? Par exemple, si vous vouliez simplement le lire dans des fichiers JSON à partir d'un compartiment de journaux sur Amazon S3, vous pouvez simplement dire que les journaux JSON S3 de flux à points pointus et que cela resterait
là et surveillerait ce compartiment de journaux dans S3 toute la journée, 24 , 7, à la recherche de nouveaux fichiers JSON à lire et à analyser. Et il continuerait à ajouter chaque nouvelle ligne dans chaque nouvel enregistrement JSON qui y a été trouvé dans cette entrée DataFrame. Et ensuite tu pourras faire ce que tu veux. Vous pouvez le regrouper par, vous savez, un peu d'action. Vous pouvez faire une fenêtre comme nous l'avons vu dans DStream. Donc, si vous voulez spécifier une fenêtre de temps, vous pouvez simplement passer ce paramètre de fenêtre supplémentaire là pour spécifier la, la période de temps sur laquelle vous voulez aller. Et vous pouvez le compter, à droite, le flux dehors où vous voulez. Dans ce cas, nous allons le formater en une connexion JDBC et simplement écrire dans une base de données MySQL quelque part et le coller dans une base de données. Donc, c'est vraiment tout le code spécifique du streaming que vous verrez juste l'actif spécifiant réellement cette fenêtre, établissant le flux et où vous écrivez le flux. En dehors de cela, c'est juste un vieux dataframe ou un jeu de données habituel, selon la façon dont vous l'utilisez et tout ce que vous
feriez normalement avec le DataFrame où le jeu de données s'applique également ici. Nous allons donc faire un petit exemple ici de fichiers journaux en streaming. J' ai donc inclus un fichier journal d'accès Apache dans votre matériel de cours. Et ce que nous allons faire est juste de mettre en place un petit répertoire dans notre matériel de cours et copier ce fichier journal et voir si notre application de streaming le ramasse et le traite. Donc, pour ce faire, nous allons juste dire spark dot read stream
dot txt parce que ce ne sont que des fichiers texte brut, fichiers
journaux avec un chemin de répertoire vers le dossier journaux dans mes matériaux de cours. À ce stade, je peux simplement utiliser des opérations SQL pour analyser les données de ces lignes de journal en utilisant des expressions régulières. Vous pouvez l'utiliser avec une opération de carte si vous le vouliez également. Et puis utilisez simplement group BY pour
regrouper les choses sur une fenêtre si vous voulez diffuser la sortie, dans ce cas sur notre console, mais il pourrait tout aussi facilement aller à une base de données ou tout ce que vous voulez. Alors plongons dans et écoutons quelques journaux. Pas ce genre de journal.
59. [Activité] avec la streaming structuré pour les analyses de log en temps réel: Bon, Alors jouons à nouveau avec le streaming structuré, un peu la façon moderne de faire le streaming ces jours-ci et Spark. Allons ouvrir le script de streaming structuré ici et voir comment cela fonctionne. Tout d'abord, vous voyez que c'est en fait assez simple. Je veux dire, à part les expressions régulières réelles d'analyse de ces données de journal, le code Spark lui-même n'est pas beaucoup. C' est assez concis. Alors passons à travers ça ici. Bon, donc on a des choses importantes. Nous avons besoin d'un objet cratère ici, définir le niveau du journal, créer une session Spark. Jusqu' à présent, rien n'est différent. La première chose qui est différente cependant est qu'au lieu de dire point d'étincelle, texte de
point, nous allons dire étincelle point de lecture de flux point txt. C' est ça. Cela dit, nous allons en faire un flot d'
informations ininterrompu au lieu de simplement lire dans un bloc d'informations à partir d'un fichier texte statique. Et le chemin que nous passons ici est en fait un chemin de répertoire. Et dans ce cas, il sera sur notre système de fichiers local. Mais vous pouvez tout aussi facilement surveiller un compartiment S3 ou un système de fichiers distribué si vous le souhaitez. Donc il va juste rester ici à regarder mon répertoire de données slash pour les nouveaux fichiers texte. Et lorsque de nouveaux fichiers texte y sont découverts, il ajoutera chaque ligne de ce fichier texte dans les lignes d'axe DataFrame. Ok, c'est aussi simple que ça. Maintenant, le reste de ce code compliqué ici est vraiment juste d'analyser ces données. Donc, les journaux d'accès Apache sont un format assez bizarre et il faut expressions régulières assez compliquées pour extraire l'information et transformer ces données de fichier journal
non structuré en informations structurées. Donc, je ne vais pas entrer dans les détails de la façon dont ces expressions régulières fonctionnent, mais elles sont destinées à extraire les informations dont nous avons besoin de chaque champ de ce journal d'accès Apache. Et nous appliquons ces expressions régulières ici dans cette grande ancienne déclaration select. Donc, nous prenons que les lignes d'axe DataFrame et nous appelons select dessus. Maintenant, par défaut, chaque nouvelle ligne de texte entrant dans les lignes d'axe sera dans une colonne appelée valeur. Donc, pour chacun de ces exemples, nous faisons un extrait reg ex sur la colonne de valeur. Cela signifie qu'il va prendre la ligne brute de données, appliquer une expression régulière à elle. Dans ce cas, l'expression hôte, qui est destinée à extraire le nom d'hôte. Et nous allions lui donner un alias d'hôtes. Donc, cela va essentiellement créer une nouvelle colonne hôte qui contient l'hôte extrait de cette ligne. Et nous faisons la même chose pour l'horodatage de la méthode, pour le point de terminaison du protocole, pour le code d'état et la taille du contenu. À ce stade, tu peux faire ce que tu veux, n'est-ce pas ? Donc, dans notre exemple simple ici, tout ce que nous allons faire est de regrouper PAR le statut et comptabiliser au fil du temps. Nous allons donc garder un compte en cours d'exécution sur le temps du
nombre de fois que chaque code d'état apparaît dans ces fichiers journaux. Donc, c'est qu'il va rester là à nouveau en attendant que de nouveaux fichiers journaux soient déposés dans le répertoire du journal des slash de données. Et il va se regrouper au fil du temps, combien de fois chaque code d'état apparaît. Nous devons lui dire où mettre cette information. Donc, nous construisons ce qu'on appelle une requête. Et nous disons juste état compte DataFrame, C'est notre compte final DataFrame là. Nous allons écrire ce flux avec le mode de sortie suivant. Nous allons dire que nous voulions terminer la sortie formatée en allant à la console. Et nous donnerons à cette requête un nom appelé count. Et nous allons juste appeler l'amidon pour réellement démarrer ce flux de sortie. D' accord. Nous avons donc défini notre flux d'entrée ici avec Spark dot read stream dot txt. C' est ce qui va surveiller. Nous avons défini une série d'opérations qui ont finalement conduit au
compte d'état DataFrame qui est calculé à partir de ce flux d'entrée. Et puis nous créons un flux de sortie ici appelé requête. Ensuite, nous attendons juste la résiliation. Il va juste courir ça pour toujours jusqu'à ce que nous l'arrêtions explicitement. Et quand quelqu'un fait ça, nous appelons Stop sur la session pour terminer les choses. Alors allons le lancer et voir si ça marche. Tout d'abord, il suffit de l'exécuter. Nous nous permettons d'afficher un début il
n'y a rien dans ce répertoire et donc nous devons mettre choses là-dedans pour qu'il fasse quelque chose d'intéressant, non ? Alors faisons ça. Allons à notre matériel de cours ici et allons dans les données. Et vous verrez qu'il y a un fichier journal d'accès ici qui contient un journal d'accès Apache réel à partir d'un de mes sites Web. Copions cela et ouvrons le répertoire Logs et collez-le dedans. Et ce qui devrait arriver, c'est que notre script devrait prendre ça. J' entends mon ventilateur CPU en cours d'exécution, ça fait quelque chose. Et ça a marché. Donc il a récupéré ce nouveau dossier et a compté tout le code de l'air. Donc, nous pouvons voir que nous avons réellement une erreur de 500 code d'erreur ici, ils apparaissent beaucoup. Donc, ce serait m'alerter d'un vrai problème sur mon site si c'était une vraie application, n'est-ce pas ? Peut-être que je pourrais avoir une sorte de seuil sur le nombre de 500 erreurs et m'alerter si cela dépasse un certain seuil au fil du temps. Voyons si cela fonctionne avec car plus de données y sont jetées. Revenons donc aux données et faisons une copie de notre fichier journal d'accès. Je vais juste copier et coller. Donc maintenant, nous avons la copie de tiret de journal d'accès. Copions cela aussi dans nos journaux. Et ce que nous devrions voir, c'est tous ces chiffres, double lot 1, nous avons un autre lot d'informations qui est arrivé. Et bien sûr, tous ces nombres ont doublé parce que je viens de copier ce même fichier journal. Et encore une fois, donc là vous l'avez. Appuyez sur le bouton X ici pour arrêter le flux. Et oui, c'est Spark streaming et action, des trucs assez cool. Ainsi, comme vous pouvez le voir, Structured Streaming est vraiment facile à utiliser. Si vous pouvez utiliser un jeu de données, vous pouvez utiliser le streaming structuré et vous n'êtes plus limité au traitement des données par lots. Vous pouvez le traiter comme il arrive,
en temps réel, ce qui est très excitant. Très bien, c'est Spark en streaming en un mot. Allons passer à autre chose.
60. [Exercice] des opérations avec Streaming structuré: Donc, ce prochain exercice vraiment intéressant. Je veux que vous gardiez une trace des URL les plus consultées dans mes journaux d'événements pour mes journaux d'accès Apache. Et gardez une trace de ça. Donc, au lieu d'afficher le nombre de codes d'état au fil du temps, je veux que vous affichiez
le nombre des URL supérieures affichées à partir des données du journal à la place. Et pour le rendre encore plus intéressant, je ne veux pas que tu le mesures depuis le début des temps. Je veux juste que vous regardiez en arrière ces 30 dernières secondes et me disiez quels étaient les meilleurs résultats au cours des 30 dernières secondes. Maintenant, pour ce faire, vous devez introduire le concept d'opérations fenêtrées dans le streaming Spark. Laissez-moi vous le présenter très rapidement. Une opération fenêtrée est juste regarder en arrière sur une certaine période de temps. Par exemple, si je ne veux considérer que les événements qui se sont produits au cours des 10 dernières minutes, j'aurais une fenêtre de 10 minutes. Et l'intervalle de diapositives définit la fréquence à laquelle nous évaluons cette fenêtre. Donc, nous avons une fenêtre de 10 minutes, disons de 12 heures à 12 heures 10. Si nous avions un intervalle de cinq minutes, cela signifie
que nous évaluerons cette fenêtre à 1205121012151220. Chaque fois en regardant la dernière fenêtre de 10 minutes dans laquelle nous sommes. Pour rendre cela un peu plus concret, permettez-moi de vous montrer un diagramme qui vient directement de la documentation Spark ici. Et ici, nous avons une fenêtre de 10 minutes avec un intervalle de cinq minutes. Donc nous commençons ce truc à 12 heures dans cet exemple hypothétique. Nous avons donc des fenêtres qui fonctionnent de 12 heures à 12 heures dix, de 1205 à 1215, de 1210 à 12, 20 et ainsi de suite et ainsi de suite. Donc toutes les cinq minutes, nous avons une nouvelle fenêtre de 10 minutes en cours de définition. Et au fil du temps, nous agrégons les résultats sans à travers ces fenêtres. Et nous continuons à ajouter les résultats de ces fenêtres à notre tableau de résultats au fur et à mesure que nous allons. Donc, dans cet exemple, nous avons un flux de noms d'animaux qui arrivent apparemment. Donc, un 1202 et 12 03, nous avons chien chat et chien entrent. Donc un 12 05, nous avons un léger intervalle qui est touché. Donc ça va regarder la fenêtre de 12h à 1210 parce que c'est juste notre première fenêtre que nous avons depuis que nous avons commencé à courir. Et ce que nous avons jusqu'à présent, c'est un chat et trois chiens qui ont été reçus. A 1207, on a un hibou et un chat. Donc, quand nous courons notre prochain intervalle de diapositives à 1210, nous allons maintenant aussi regarder les fenêtres de 12h à 12h 10 et les fenêtres de 1205 à 1215. Maintenant, il s'avère que notre chat a réellement été ajouté dans ces 12 heures à 12 heures, 10 fenêtres. Nous allons donc l'ajouter à notre tableau de résultats et le mettre à jour. Et nous allons également créer une nouvelle fenêtre dans notre tableau de résultats pour 1205 à 1215 dont nous allons garder une trace. Et ça continue et continue, non ? Donc un 1215, nous allons maintenant obtenir une nouvelle fenêtre de 1210 à 1220 que nous allons regarder. Et nous allons revenir en arrière et mettre à jour toutes les fenêtres précédentes si nécessaire pour tenir compte des nouvelles données. Donc nous avons un autre chien et une autre heure entre les deux. Et si vous regardez de près, vous pouvez le comprendre. Mais fondamentalement, l'idée est que la fenêtre est la période de temps sur laquelle vous agrégez des choses. Et l'intervalle des diapositives est la fréquence à laquelle vous évaluez cela. Le codé pour le faire est assez simple. Vous dites simplement « group BY » si vous voulez faire une sorte d'agrégation sur une colonne, dans ce cas, la colonne que nous regroupons par le nom de cette colonne. Et syntaxiquement il disait fenêtre. Et puis spécifiez un appel avec le nom de colonne qui représente l'horodatage définit quand cette chose s'est produite, non ? Ainsi, le code fenêtré dans le
streaming Spark ne suit pas automatiquement quand les événements ont été reçus. Il va regarder une colonne spécifique dans vos données qui est ingérée. Ok, alors gardez ça à l'esprit. Vous savez, vous allez être défini sur les données qui sont dans le flux lui-même, pas sur quand cela a été effectivement reçu par Spark streaming. Différence si subtile mais importante, surtout dans notre exemple ici, parce que nous utilisons de très vieux journaux Apache qui ont des horodatages d'il y a des années et des années. Donc, cela va affecter la façon dont nous abordons réellement ce problème. Ensuite, vous dites que la durée de la fenêtre est égale à la durée de la fenêtre que vous voulez. Et c'est juste spécifié en anglais comme 10 minutes,
30 secondes, tout ce que vous voulez là-bas. Je pense qu'il y a une limite d'un mois à cela. Et la durée de la diapositive est également spécifiée en anglais simple. Donc syntaxiquement, c'est ce que vous devez savoir sur la façon de faire des agrégations fenêtrées. Donc, votre défi à nouveau, modifiez ces scripts de streaming structurés sur lesquels nous venons de
travailler pour garder une trace des URL les plus consultées. Et c'est en fait appelé endpoints dans ce script particulier. Même chose. Et je voulais calculer ça avec une fenêtre de 30 secondes et assister à la deuxième diapositive. Maintenant, vous êtes sur a besoin de quelques petits extraits de code pour le faire. Tout d'abord, encore une fois, je vais juste répéter cet extrait de code sur la façon de spécifier
réellement syntaxiquement cette fenêtre. Donc, c'est à quoi ressemblerait ce code. Ce n'est pas la ligne entière dont vous aurez besoin dans le script réel, mais c'est une bonne partie de celui-ci. Je suis en train de regrouper ce n'est pas suffisant. Vous devez aussi compter combien sont dans ce groupe, n'est-ce pas ? Vous avez donc vu comment le faire dans des exemples précédents. Aussi, comme je l'ai dit, vous allez avoir un problème parce que les exemples de journaux Apache que je vous ai donnés sont très vieux, ils ont des années. Et ça ne marchera pas avec une fenêtre tendue de 30 secondes, n'est-ce pas ? Donc, si vous regardez en arrière 30 secondes sur un journal qui capturait des données d'il y a trois ans, ça ne marchera pas si bien. Donc, ce que vous pouvez faire est de fabriquer une nouvelle colonne dans votre jeu de données qui correspond à l'heure actuelle à laquelle il a été ingéré. Et la syntaxe pour cela est ce deuxième bloc, leur colonne de largeur de point de logs df ajoutera une colonne appelée temps d'
événement comme égale à l'horodatage actuel. Donc, cela vous donnera une nouvelle colonne que vous pouvez utiliser pour l'heure actuelle. Ce sera un peu plus utile pour cet exercice. Et enfin, vous allez vouloir vous assurer que vous
commandez les dénombrements dans l'ordre décroissant. Donc, à un moment donné, vous devrez dire l'ordre par compteur d'appel, quoi que vous appelez ce point de colonne de comptage DESC pour spécifier que vous voulez cela dans ordre
décroissant afin que vous voyez les meilleurs résultats en premier et pas vice versa. Alors allez-y et avez à elle,
c' est un peu plus difficile, pourrait vous obliger à faire un peu plus de réflexion créative ou à regarder des choses en ligne. Mais c'est comme ça que fonctionne le monde réel. Alors donne-le un coup d'envoi. Et quand on reviendra, je te montrerai comment je l'ai fait.
61. Solution d'exercice : Top URL's une fenêtre de 30 secondes: Très bien, alors faisons quelque chose d'un peu plus fantaisiste avec streaming
structuré et jetez un oeil à ma solution pour garder trace des URL les plus consultées à partir de nos journaux d'accès Apache en utilisant une fenêtre coulissante de 30 secondes, au lieu de juste depuis le début des temps. Donc, je viens de commencer avec une copie de ces scripts Scala de point de streaming structuré comme je vous ai conseillé de le faire. Et pas beaucoup de changements tant que nous n'arriverons pas à cette ligne sur la ligne 42. Maintenant, comme je l'ai mentionné, c'est une très vieille loi d'accès Apache que je vous ai donnée dans le matériel de cours. Et si nous allons faire des fenêtres de temps coulissantes depuis les 30 dernières secondes. Eh bien, nous devons fabriquer de nouveaux événements qui sont plus actuels, n'est-ce pas ? Donc, c'est tout ce que fait cette ligne ici, prend nos journaux df dataframe et ajoute une nouvelle colonne en utilisant avec la colonne appelée événement time qui est envoyé à l'horodatage actuel chaque fois que ces données sont réellement ingérées. Et nous allons faire demi-tour et appeler les journaux DataFrame résultants df2. Bon, maintenant les choses deviennent intéressantes. Donc, gardons un compte courant de ces points finaux. Donc, dans notre nomenclature ici, et le point final est fondamentalement la même chose qu'une URL. Donc, nous avons une méthode GET suivie du point final, qui va être l'URL sur notre site Web que quelqu'un a frappé. Pour ce faire, nous allons utiliser la même syntaxe que celle dont nous avons parlé dans les diapositives pour établir cette fenêtre de 30 secondes avec une durée de diapositive de 10 secondes. Nous disons juste les journaux df2, appel de la fenêtre groupby. Le nom de la colonne ici est l'heure de l'événement. C' est le, c'est l'horodatage sur lequel nous allons faire une fenêtre. D' accord ? Nous spécifions une durée de la fenêtre de trente secondes et nous enregistrons, à jour ces fenêtres toutes les 10 secondes. Et le deuxième paramètre de la commande group BY va être appelé point de terminaison. Nous allons donc grouper par les points de terminaison, regroupant tous ces points de terminaison communs ensemble. Et puis une fois que vous aurez regroupés dans cette fenêtre et sur la durée de la diapositive, nous allons les compter. Donc, ce que fait cette seule ligne de code est de compter combien de chaque URL a été rencontrée toutes les 10 secondes, regardant la fenêtre actuelle de 30 secondes que nous sommes dans la droite ? Maintenant, ce n'est pas suffisant. Je veux également trier ceux-ci, donc je vois les URL les plus populaires. Je ne veux pas voir de listes non ordonnées. Donc, je vais en outre prendre ces points de fin, compte DataFrame et le trier en disant point OrderBy appel cout nom égal count, va être le nom de la colonne count qui est créée par cette commande Cal point DSC, pour dire que je voulue dans l'ordre décroissant. Donc, les URL les plus populaires sont en haut, et c'est tout. Le reste du code est fondamentalement le même. Nous sommes sortis sur la console là-bas et le coup d'envoi fondamentalement. Et un peu à part ici, une dernière note, si vous vouliez écrire ceci dans une base de données ou un fichier ou quelque chose comme ça, vous devriez juste définir le mode de sortie est autre chose et le format est autre chose. Donc, si vous regardez la documentation là-bas, vous pouvez voir comment nous pouvons écrire dans une base de données ou un fichier texte, un fichier parquet ou tout ce que vous voulez. Ça n'a pas besoin d'être sur la console. Ça va être beaucoup plus pratique de stocker ces données quelque part, n'est-ce pas ? Et ce que nous stockons, c'est cette table de résultats. Nous allons donc obtenir ces, ce tableau de résultats pour chaque fenêtre mise à jour,
pour chaque durée de diapositive. Donc, le résultat que nous allons voir est un tableau qui garde une trace des résultats que nous voyons dans chaque fenêtre, chaque fenêtre de 30 secondes que nous avons. Voyons si je te mens ou non. Laissons ça et voyons ce qui se passe. Donc, les URL supérieures vont permettre que cela tourne et je vais
agrandir cette fenêtre pour que nous puissions voir ce qui se passe. D' accord, donc il est assis là à attendre les données. Je vais retourner à mes journaux ici dans mon matériel de cours. Et vous pouvez voir que j'ai en fait trois copies de mon journal d'axe ici pour jouer avec. Commençons par un. Nous devons copier ça et le jeter dans mon dossier de journaux ici. Donc, comme nous diffusons en temps réel, il devrait prendre en compte l'existence de ces nouvelles données et aller de l'avant et mettre à jour tout. Il s'enfuit en ce moment. Vous pouvez entendre mon ventilateur de CPU. Et là, nous l'avons. Donc, nous pouvons voir que ces intervalles de diapositives de 10 secondes, nous calculons cette valeur de fenêtre à chaque fois et nous obtenons un résultat cohérent parce que nous n'avons pas encore
fonctionné depuis plus de 30 secondes. Alors allons de l'avant et jetons quelques données là juste pour s'assurer que cela fonctionne comme prévu. Donc, notez ici que nous voyons que 0, je devrais maintenant voir le lot 1. Et il y a le premier lot. Fait intéressant, c'est le même numéro qu'avant, non ? Parce que plus de 30 secondes se sont écoulées depuis ce premier lot. Donc, ce premier lot d'informations a effectivement expiré. Il est tombé du bout de ma fenêtre. Donc si nous n'avions pas fenêtré, nous aurions vu tous ces chiffres doubler, pas vrai. Mais ils ne l'ont pas fait parce que ces trente secondes de données ont expiré. Je ne pense pas que 30 secondes se soient encore écoulées, alors voyons si je peux vraiment obtenir un plus grand nombre là-bas. Si je suis assez rapide, nous le mettrons en troisième exemplaire. Et ici, nous voyons un patch pour que je n'ai pas été assez rapide, est tombé de la fin là de la fenêtre de 30 secondes. Mais si vous avez votre propre version de cette course, hésitez pas à jouer avec elle ou à ajuster ces temps de fenêtre pour être un peu plus convivial avec vous et comment vous travaillez. Et une bonne façon d'avoir une idée de la façon dont Windows et les intervalles de diapositives fonctionnent est expérimenter avec elle et de simplement jouer avec elle comme nous le faisons en ce moment. Vous avez donc appris à propos de Spark Streaming maintenant et comment gérer les données en temps réel au fur et à mesure qu'elles entrent en ligne de compte.
62. GraphX, Pregel et Breadth-First Search avec Pregel.: Donc, dans cette section, nous allons présenter Graphx, qui est une API pour traiter les graphiques
d'information comme notre réseau de super-héros plus tôt dans le cours. Graphics est un peu un beau-enfant négligé de smart, pour être honnête, il n'a pas vu beaucoup de développement ces derniers temps et il est toujours coincé sur l'ancienne API RDD. Il existe une version plus récente de celui-ci en développement appelée trames graphiques, mais elle n'est pas encore prête pour les heures de grande écoute. Donc, pour l'instant, juste pour l'exhaustivité, je vais parler du graphe x et de sa forme actuelle, qui utilise l'interface RDD, mais vous verrez qu'il est encore assez puissant. Et l'utiliser ressemble un peu plus à SQL un moment. Voyons donc comment les graphiques peuvent vous aider à résoudre des problèmes massifs distribués à l'aide de graphiques d'informations. Plongons brièvement dans le monde de GraphX, le dernier composant central de Spark lui-même. Et quand nous parlons de graphiques, nous ne parlons pas de graphiques linéaires, de graphiques ou de quelque chose du genre. On parle de graphiques au sens de l'informatique. Ainsi, par exemple, notre réseau social de super-héros que nous avons vu plus tôt dans le cours. C' est un exemple du graphique dont nous parlons, où nous avons des sommets qui, dans ce cas, représentent superhéros
individuels et des arêtes entre ces sommets qui représentent les relations entre eux. Le graphisme est un peu cool, mais c'est vraiment utile seulement pour une chose spécifique. Donc en soi, il ne peut pas vraiment répondre aux questions
auxquelles nous répondions dans le code que nous avons écrit pour analyser notre réseau de super-héros. Mais il peut faire des choses comme mesurer la connectivité, la distribution des degrés, longueur
moyenne du chemin, le nombre de triangle, sorte de mesures de haut niveau du graphique dans son ensemble. Il peut faire des choses comme compter tous les triangles dans le graphique et appliquer l'algorithme PageRank à l'inégal. Donc, je pense que c'est vraiment la force motrice derrière GraphX lui-même. C' est le plus utile pour implémenter quelque chose comme PageRank, qui est évidemment un cas d'utilisation important. Et c'est aussi un problème qui implique une échelle massive, bien
sûr, où la puissance de Spark est utile. Donc c'est un peu fait pour ça plus que tout le reste. Vous pouvez également faire des choses comme joindre des graphiques ensemble et transformer ces graphiques très rapidement d'une manière distribuée. Mais pour des choses comme nos degrés de séparation exemple où nous essayons de
comprendre combien de degrés de séparation en tant que super-héros est de Spider-Man. Vous ne trouverez pas de support intégré pour des opérations comme ça. Cependant, il prend en charge l'API Pregel pour parcourir un graphique. Et cela vous permet d'écrire votre propre code et développer vos propres algorithmes qui vivent en quelque sorte dans les graphiques. Et cela vous donne la flexibilité de faire ces choses plus compliquées que vous pourriez imaginer. Ils ne sortent pas de la boîte. Vous devez y réfléchir et penser de manière créative comme nous devions le faire lorsque nous le
faisons en utilisant des dataframes ou des RDD. Ainsi, les graphiques introduisent quelques nouveaux types de données, le sommet RDD et le RDD de bord, ainsi que le type de données de bord. Et c'est ainsi que nous représentons les sommets et les bords entre eux qui forment un graphique. Maintenant, Graphics est un peu un holdout. Il est toujours écrit sur l'API RDD, même si Spark lui-même a essayé de
migrer de plus en plus vers des dataframes et des jeux de données. Honnêtement, GraphX est tombé au bord du chemin. Il n'a pas encore vu beaucoup de développement actif. C' est toujours un élément central de Spark lui-même, donc je le couvre ici. Mais vous voyez de plus en plus être remplacé par d'autres choses sont tout simplement pas utilisés du tout dans le monde réel. Il s'avère, n'a pas vraiment beaucoup d'utilité pour les graphiques. Et en conséquence, c'est un peu négligé en toute honnêteté. GraphX est donc toujours construit sur les RDD. Encore une autre raison d'apprendre les RDD, il existe un autre paquet appelé
trames graphiques qui est construit sur la nouvelle API DataFrame. Mais ce n'est pas encore vraiment sorti. C' est la version définie comme 0.8 la dernière fois que j'ai vérifié. Donc, à un moment donné, nous pourrions voir des cadres graphiques remplacés des graphiques et des
étincelles, mais pour l'instant nous avons les graphiques basés sur RDD pour travailler avec. Et vous trouverez que le code graphique ressemble beaucoup n'importe quel autre code d'étincelle RDD pour la plupart. Et en fait, une fois que vous avez construit un graphique, traiter avec cela ressemble beaucoup à Spark SQL de toute façon, donc ce n'est pas aussi mauvais que ça en a l'air. Créer un sommet RDD est assez simple, vraiment. Vous avez juste à retourner un tuple qui inclut un ID de sommet, un identifiant numérique unique comme premier champ. Et quelles que soient les données que vous voulez associer à cela
dans ce petit extrait de code ici que nous prenons de notre exemple. Vous voyez qu'on est en train d'envelopper ça dans une option. Et c'est ainsi que nous traitons les valeurs nulles dans Scala. Nous n'en avons pas vraiment parlé auparavant, mais vous voyez que nous définissons une option d'un ID de sommet et d'une chaîne, et cela signifie que nous avons la possibilité de ne rien retourner. Donc, vous verrez que dans le cas où nous avons un résultat valide, nous en retournons certains avec un tuple qui se compose d'un ID de sommet et les données associées à ce sommet. Si nous avons une entrée non valide, nous ne retournons aucune. Et cela signifie juste qu'il n'y a pas de résultats. C' est essentiellement l'équivalent Scala de null. Et c'est utile parce que si vous appelez FlatMap sur un RDD et
que votre fonction ne renvoie aucun, cela est juste éliminé et c'est correct. C' est donc une façon de traiter le cas de ne pas renvoyer quoi que ce soit d'une opération FlatMap. Dans le cas de nos données, nous devions avoir des lignes de données non valides. Il s'avère que tout ID de héros au-dessus de 6486 n'est pas un vrai personnage, donc nous devons les rejeter. Et c'est le cas où nous n'en avons rendu aucun dans ce cas. Créer une arête est également assez simple. Tout ce que vous faites est de créer un objet Edge contenant une liste des nœuds qu'il connecte. Donc, dans cet exemple ici, vous pouvez voir que nous créons un bord entre un ID de héros donné qui commence le début d' une ligne sur notre fichier de données pour le jeu de données de super-héros Marvel. Et nous construisons un nouvel avantage entre cela dans chaque super-héros ce héros est connecté, défini par cette ligne de texte. Donc un bord, très simple. Il s'agit simplement d'un objet Edge qui se compose de deux ID
de sommet et d'informations supplémentaires que vous pouvez associer à cela également. fois assez simple. Et construire un graphique, encore une fois, c'est simple. Vous construisez simplement un objet graphique et vous le construisez avec la liste des sommets que vous voulez y avoir, ces deux arêtes entre ces sommets. Et c'est à peu près tout. Vous voudrez probablement mettre en cache ce graphique parce que vous allez probablement vouloir faire un tas d'opérations dessus. Et en le mettant en cache qui garantit qu'il restera en mémoire, ce qui peut aider à générer des choses optimisées lorsque vous faites des choses avec ce graphique plus tard. Donc, faire des choses avec un graphique est également assez simple une fois que vous l'avez construit, bien qu'il soit parfois utile de voir un exemple de code à partir de. Par exemple, si vous voulez prendre les 10 héros les plus connectés, nous pourrions appeler graphe docteur accepte d'obtenir ces degrés de connexion et de rejoindre ceux avec les sommets eux-mêmes. Trier les résultats donnés par le champ qui correspond au nombre de connexions qu'ils ont dans l'ordre décroissant. Prenez le top 10 et vous avez fini. C' est donc un moyen facile de déterminer qui
sont les super-héros les plus connectés dans une seule ligne de code une fois que vous avez construit ces objets graphiques, donc un peu plus facile. La syntaxe est un peu plus difficile à suivre ici, donc c'est un peu le jury est sorti, je pense, sur si c'est en fait une façon plus simple de le coder, mais cela fonctionne. C' est donc une façon d'utiliser GraphX. Mais comme nous l'avons dit précédemment, c'est beaucoup plus flexible lorsque nous avons introduit l'API Pregel en plus de GraphX. Parlons donc de cela ensuite et comment nous pouvons réellement étendre le graphique x pour dupliquer les résultats que nous avons obtenus dans notre exemple de degrés de séparation plus tôt dans le cours.
63. Utiliser l'API Pregel avec Spark GraphX: Voyons donc plus en profondeur comment l'API Pregel nous donne plus de flexibilité. plus des graphiques, nous pouvons réellement recréer ce que nous avons fait avec l' algorithme de
recherche large en trouvant les degrés de séparation entre deux super-héros dans notre graphique de superhéros Marvel qui apparaissent ensemble et Des bandes dessinées. Et la façon dont Pregel fonctionne à un niveau élevé est fondamentalement chaque sommet a la capacité d'envoyer des messages à tous ses sommets voisins. Et chaque graphique est ensuite traité dans une itération appelée superstep. Et à chaque superstep, trois choses arrivent. Les messages de l'itération précédente vont être reçus par chaque sommet. Chaque sommet exécutera ensuite un programme pour se transformer en fonction de ces messages. Et puis chaque sommet enverra des messages à d'autres sommets s'il veut être ramassé à l'étape suivante. Et si vous vous souvenez de la façon dont nous avons implémenté l'algorithme de recherche
large, vous pensez probablement déjà, Hey, qui correspond assez bien à la façon dont cet algorithme fonctionne. Et en fait, c'est le cas. Donc, nous pouvons initialiser notre graphique assez simplement ici, si vous vous souvenez bien, nous commençons juste par définir toutes les distances à l'infini sauf pour le point de départ à partir duquel nous mesurons les distances. Et pour celui-ci, nous allons définir la distance à 0, bien
sûr, parce que la distance entre quelque chose et lui-même est 0. Nous pouvons le faire avec une seule ligne de code et de graphiques. Nous pouvons simplement dire des sommets de la carte de points graphiques et vérifier si l'ID est égal à l'idée du héros que nous voulons commencer à partir de l'endroit où nous mesurons. Si c'est le cas, nous définissons la distance initiale à 0. Sinon, nous définissons ces attributs de sommet à l'infini positif. Ensuite, nous profitons de cette capacité de messagerie pour sortir de ces notes initiales. Nous partons donc de notre point de départ initial. Et nous avons rétro ajouter un peu de code pour définir ce qui se passe lorsque nous envoyons ces messages au cours de cette étape de messagerie. Donc, dans ce cas, nous recherchons des nœuds qui ne sont pas l'infini positif, un que nous venons de traiter. Et pour ceux-ci, nous allons ventiler leurs ID de destination,
leurs voisins, en passant le long de l'attribut de ce nœud initial plus 1. Donc, cela va incrémenter le nombre de distance au fur et à mesure que
nous allons et envoyer le prochain tour et les messages pour ce sursaut. Donc, essentiellement, Pregel va travailler son chemin à travers ce graphique, en élargissant son chemin. Et sur le chemin, il recherche des nœuds qui ne sont pas infini. Et il va de l'avant et les supporte plus loin, augmentant la distance au fur et à mesure qu'il trouve son chemin. Donc Pregel gère un peu beaucoup d'entre eux mécanique de traverser le graphique pour nous, qui est pratique pour quelque chose comme ça. Maintenant, ne soyez pas trop raccroché si vous ne suivez pas ça, vous n'aurez probablement jamais à faire exactement le même algorithme et le monde réel, n'est-ce pas ? Le point le plus important ici est que si vous avez un graphique d'informations que vous devez traiter dans Spark, et que les fonctionnalités intégrées des graphiques ne font pas ce que vous voulez. Parfois, l'API Pregel vous permet de le
faire si vous pensez juste un peu plus de créativité à ce sujet,
c' est juste un autre outil à avoir dans votre coffre à outils. L' autre chose que nous devons faire dans BFS est préservée la distance minimale à chaque étape. Donc, nous voulons nous assurer que nous ne sommes pas en arrière sur nous-mêmes et d'obtenir ces distances erronément élevées entre les nœuds parce que nous avons trouvé ces chemins plus longs pour y arriver. Donc, nous pouvons écrire un programme de sommet qui va vérifier pour cela. Et il préservera la distance minimale entre celui qui reçoit et ce qu'il a. Donc, comme il reçoit ces messages de ses nœuds voisins, s'il obtient une distance qui est en fait plus grande que ce qui est déjà là, il préservera la plus petite de ces deux distances. Et en outre, nous faisons également une opération de réduction. Donc, si nous avons effectivement plusieurs messages reçus pour le même sommet dans la même passe, cela va également attraper ce cas et préserver la distance minimale dans ce cas également. Donc, tout mettre ensemble est assez simple. Ce n'est pas beaucoup de code vraiment. Donc, nous pouvons simplement dire définir notre graphique initial et graphiques avec la distance définie à 0 où nous commençons par sinon c'est l'infini. Nous appelons ensuite point graphique initial Pregel. Et cet appel de fonction nous permet de définir tous les attributs de particule dont nous avons besoin. Donc, nous passons dans ce programme de sommet qui maintient que nous conservons toujours la valeur minimale reçue pour la distance là-bas. Nous avons mis en place ce système de messagerie où nous disons que nous allons chercher nœuds
non infinis et que les fans sont des moyens de sortir d'eux en incrémentant cette distance au fur et à mesure que nous allons. Et enfin, nous avons cette opération de réduction qui dit que si vous avez plus d'un message à la fois, encore une fois, nous allons préserver la distance minimale qui arrive. Donc, ces trois composants de régulier sont passés en
tant qu' appel de fonction unique à l'API Pregel là-bas. Encore une fois, nous avons le programme de sommet. abord, nous avons la fonction de messagerie, puis nous avons l'opération de réduction. Et c'est tout ce que vous devez faire. Alors sortons et voyons si ça marche.
64. [Activité] Superhéros de la séparation, à l'aide de GraphX: Nous allons donc plonger et utiliser la puissance des graphiques et de Pregel pour résoudre nos problèmes de séparation en utilisant des graphiques. Alors ouvrez le script graphique ici et nous allons jeter un coup d'oeil. Voyons ce qui se passe ici. C' est un peu plus simple que l'implémentation basée sur RDD, mais il y a encore une bonne quantité de code à parler ici, non ? Alors passons à travers ça. Donc, nous allons descendre à la fonction principale et commençons là. Nous avons mis en place notre contexte Spark est le temps. N' oubliez pas que GraphX est toujours construit sur l'API RDD, donc nous n'utilisons pas de SparkSession ici. Nous utilisons un SparkContext à la place. Encore une fois, il y a une nouvelle version appelée graphes en développement, mais elle n'est pas encore officiellement publiée. Donc, encore une fois, les graphiques peu négligés, mais les cadres de graphiques sont en route, espérons-le. Cependant, les graphiques sont toujours utiles et comme vous pouvez le voir, ce n'est pas si difficile à utiliser. Donc, nous commençons par lire dans le fichier de noms de tiret Marvel ici, et nous appelons la fonction de noms d'analyse ici avec un FlatMap. Vous pouvez voir que tout se passe ici. Donc, renvoyant un tuple de l'id de sommet, qui est notre ID de super-héros, et une chaîne qui correspond au nom de cet ID. Rien de fantaisie. Nous venons de le diviser en fonction du caractère de citation pour extraire le nom. Et si nous avons plus d'un champ, nous faisons juste un petit contrôle de santé mentale sur les données là-bas. Nous coupons ce champ initial vers le bas pour supprimer tous les espaces étrangers convertis en un entier long. Et vérifiez qu'il s'agit d'une pièce d'identité valide. Si c'est le cas, nous renvoyons cet entier avec le nom de ce héros associé à cet ID. Et encore une fois, nous utilisons le format d'option ici pour dire qu'aucun n'est un résultat valide. Donc, en disant somme, cela signifie
que cette fonction renvoie un résultat valide, mais nous pouvons aussi retourner aucun. Il se peut que cette ligne représente un ID de héros non valide ou des données mal formatées. Et dans ce cas, en renvoyant la valeur none dans le cadre de notre option, cela indique à FlatMap que nous voulons juste ignorer cette ligne et
n' ajoutons rien au RDD résultant. Ensuite, qu'est-ce qu'on fait ? Nous construisons nos bords. Donc maintenant, nous allons analyser le fichier Txt de graphique de tiret Marvel. Et si vous vous souvenez, ce n'est qu'une liste de lignes qui ont un ID ici suivi d'une liste de toutes les identifiants de ce héros a été vu dans la même bande dessinée. Donc faire des bords prend soin de cela. Il ne se passe pas beaucoup ici non plus. Fondamentalement, nous prenons que toute la ligne d'entrée est une chaîne et elle renvoie une liste d'arêtes qui se compose d'entiers qui correspondent aux ID de sommet réels pour chaque héros. Nous allons donc créer un tampon de liste ici et remplir cette liste avec des objets Edge. Donc, c'est fondamentalement le format que le graphe x va attendre de nous. Nous divisons cette ligne d'entrée brute en champs individuels. Et pour chaque domaine que nous avons, nous extrayons le premier qui va être notre origine, celui dont nous parlons. Ensuite, pour chaque champ suivant, nous créons un nouvel objet de bord qui se compose de l'ID de sommet du super-héros à partir duquel nous commençons,
et de l'ID de sommet de chaque connexion que ce héros possède. Nous retournons ensuite la liste des arêtes résultantes à notre script principal ici. Maintenant, nous pouvons construire le graphique lui-même, ce qui est assez simple. Nous construisons simplement un nouvel objet graphique, en lui donnant la liste des sommets et des arêtes que nous avons spécifiés. Et nous passons juste dans ces sommets comme tuples essentiellement où la première valeur est l'ID de sommet. C' est une chose valable à faire ici. Ça marche juste. Et nous avons encaissé le graphique résultant parce que nous allons
probablement faire beaucoup de travail avec ce graphique et nous voulons garder ça en mémoire. Comme nous l'avons vu dans les diapositives, nous pouvons rapidement calculer les 10 superhéros les plus connectés avec cette seule ligne de code que nous appelons juste le médecin graphe accepte et rejoint la liste entière des sommets, ce qui
signifie que nous voulons obtenir les connexions pour chaque sommet que nous connaissons et trier les résultats obtenus par le champ correspondant au nombre de connexions. Prends le top 10, imprimez-les, c'est tout. Et maintenant, nous pouvons réellement faire une recherche large en utilisant Pregel, ce qui n'est en fait pas si difficile. Donc, nous commençons par définir l'ID de notre sommet racine ici. Donc nous savons que l'ID de sommet 5306 correspond à Spider-Man. Et nous pouvons itérer à travers le calcul des distances si tout le monde à Spiderman. Maintenant, nous commençons par initialiser le graphique. Encore une fois, nous faisons juste une opération de sommets de carte ici, en vérifiant chaque sommet et en voyant si l'ID est égal à Spiderman. Si c'est le cas, nous définissons la distance initiale à 0, sinon nous la définissons à l'infini. Et maintenant, dans cette commande, nous avons mis en place tout le monde Pregel, si vous voulez. Nous appelons point graphique initial Pregel et nous passons dans cette fonction qui contient, tout d'
abord, notre programme de sommet. Donc encore une fois, son but dans la vie est juste de maintenir la distance minimale que les messages sont reçus entre le message entrant et la valeur actuelle d'un nœud donné. Nous définissons également notre SendMessage, comme nous l'avons déjà dit. Cela va se propager à tous les voisins avec la distance incrémentée d'un. Donc, pour tout nœud qui a une distance actuelle associée, nous nous sommes trouvés incrémentant cette distance au fur et à mesure que nous allons. Et enfin, nous définissons une opération de réduction qui préservera la valeur minimale de ces messages reçus par un sommet si plusieurs messages sont reçus par un sommet dans la même passe. Donc, nous avons deux bits différents ici qui peuvent contenir que nous maintenons
toujours distance la plus courte que nous rencontrons lorsque nous traversons le graphique. Et ce petit extrait définit ici comment nous traversons le graphique et incrémentons cette distance d'un à chaque passage. À ce moment-là, nous pouvons sortir et imprimer les 100 meilleurs résultats là-bas. On peut dire que les sommets de points BFS, les points rejoignent les verts à nouveau, juste en disant que nous voulons évaluer ce graphique sur tous nos super-héros. Prenez le top 100 et imprimez-les et nous verrons à quoi ça ressemble. Et si nous voulons recréer spécifiquement les résultats de nos degrés d'exercice de séparation que nous utilisons pour utiliser des RDD sans graphiques, nous pouvons simplement faire une petite opération de filtre là pour arracher le résultat pour le super-héros ID 14, qui est l'atome de caractère 3,031 et imprimez cette ligne spécifiquement. Alors commençons ça et voyons si ça marche. Graphiques exécutés. Et ce qui est cool, c'est que c'est assez rapide aussi. Donc, une fois que ça va, on ne devrait pas attendre trop longtemps du tout. Il s'en va. Et nous avons notre top 10 le plus connecté et nous avons nos degrés de séparation. Donc, si je me souviens bien, c'est beaucoup plus rapide que notre implémentation en utilisant directement RDD. Donc GraphX fait évidemment quelques optimisations assez cool. Ils sont aussi sous le capot. Vérifions nos résultats, assurez-vous qu'ils ont du sens. Donc je vais faire défiler vers le haut. Top 10 le plus connecté au meilleur résultat est toujours Captain America. C' est ce que nous avons vu plus tôt dans le cours. Alors que les contrôles et les degrés de séparation de Spiderman pour tout le monde. Fait intéressant, c'est un ou deux pour tout le monde. Je pense. Tu sais que la légende selon laquelle tout le monde est lié à Kevin Bacon est probablement vraie, non ? Oh, on dirait que boom est en fait assez loin avait trois. Il est plus obscur. Encore plus obscur qu'Adam, 3,031, qui revient à nouveau comme deux degrés de séparation de Spiderman. Aussi le même résultat que nous avons obtenu avant. Donc c'est assez excitant. On a eu le même résultat. Ça marche. Et c'est un peu plus d'une façon simple et basée sur des principes de calcul de cette opération graphique pour les degrés de séparation en utilisant GraphX et l'API Pregel. Et avec cela, nous avons couvert tous les composants principaux de Spark. Félicitations, avec GraphX, nous allons finir les choses. Alors parlons d'où aller d'ici.