From scikit-learn to Spark ML
From scikit-learn to Spark ML
Yoann Benoit PartagerTweeter+ 1E-mailDans un récent billet de blog de Databricks et Olivier Girardot,?From Pandas to Apache Spark’s DataFrame, les auteurs nous montraient comment transposer le traitement et l’analyse de données faites avec la librairie Python?pandas?en?DataFrames PySpark. L’article prouvait que, bien que quelques différences techniques existent dues au fait que les objets traités ne sont pas les mêmes, le passage à l’échelle en Spark DataFrame est relativement simple et intuitif pour les utilisateurs de pandas.
Nous allons ici proposer une démarche similaire afin de montrer comment passer de la librairie?scikit-learn?de Python à?Spark ML?pour la réalisation de pipelines complexes de Machine Learning. L’objectif étant de présenter au lecteur les principaux concepts introduits par Spark ML et de montrer les différences et similitudes avec scikit-learn, nous allons supposer que les notions de DataFrame (pandas et Spark) sont déjà connues, sans toutefois qu’il y ait besoin d’en conna?tre les moindres détails. Le cas échéant, nous vous invitons à lire l’article de blog mentionné plus haut, ainsi que de parcourir rapidement la documentation de pandas et de Spark DataFrame. Notre précédent article de blog sur?Python Data Tools?peut aussi être une bonne base de travail.
Un peu d’histoire
Créée en 2007,?scikit-learn?est l’une des librairies open-source les plus populaires pour le Machine Learning en Python, et est en particulier très prisée par les Data Scientists. Bénéficiant d’une communauté extrêmement active, elle regroupe tous les principaux algorithmes de Machine Learning (classification, clustering, régression) ainsi que de nombreux modules pour la réduction de dimension, le Feature Engineering et l’évaluation de modèles.
Dévoilée à partir de la version 1.2 de Spark,?Spark ML?est l’une des deux librairies de Machine Learning sous Spark. Cette librairie a été créée en parallèle à?MLlib, la librairie historique de Spark pour le Machine Learning, dans le but de contrer certains des problèmes de cette dernière, notamment son manque occasionnel d’homogénéité dans la manière d’entra?ner et de chainer les algorithmes, et l’obligation de fournir en entrée des RDD avec des types bien particuliers.
Spark ML a été con?ue dans le but de standardiser les APIs de Machine Learning, afin entre autres de faciliter la combinaison de plusieurs algorithmes au sein d’une même Pipeline. Dans sa conception et sa logique, Spark ML se rapproche de manière très flagrante de scikit-learn, librairie ayant maintenant fait ses preuves dans le domaine. scikit-learn et Spark ML étant relativement proches dans leur fonctionnement global, le passage de l’une à l’autre pour des analyses à grande échelle n’en est que simplifié.
NB: Lors de l’écriture de cet article, Spark ML est un composant en version beta inclus dans Spark, donc toujours soumis à des développements intensifs. Toutes les fonctionnalités de MLlib, et de manière plus importante de scikit-learn, ne sont pas encore présentes, ce qui n’enlève rien à sa puissance et son potentiel.
scikit-learn & Spark ML: Des APIs aux structures similaires
Comme expliqué dans le paragraphe précédent, Spark ML a été con?u en gardant en mémoire la structure des API de Machine Learning les plus utilisées, dont scikit-learn fait partie. La structure des deux APIs est donc très similaire,?rassemblant les différents algorithmes en packages par grandes fonctionnalités. Cependant, les packages de scikit-learn sont plus nombreux car correspondent à un maillage plus fin des algorithmes.
Comme on peut le constater, les modules de scikit-learn sont très nombreux et permettent de répondre à tous types de problématiques, des plus simples aux plus complexes. Spark ML a une structure générale moins dense, mais certainement plus simple à appréhender car regroupant les algorithmes en grandes catégories d’application. Si on prends l’exemple des algorithmes de classification, on peut voir que scikit-learn dispose de nombreux packages selon le type d’algorithme, alors que Spark ML propose un même et unique package classification regroupant tous les algorithmes dédiés à cette tache.
Tous ces packages permettent de gérer toutes les étapes d’une pipeline complexe de Machine Learning:?Feature Engineering?(passage de données brutes à des features exploitables par des algorithmes de Machine Learning),?Apprentissage / Modelling?etPrédiction. Ces différentes étapes sont rappelées dans le schéma ci-dessous, inspiré de la documentation de scikit-learn.
Les principales abstractions
Données d’entrée
La plupart des algorithmes de scikit-learn utilisent des jeux de données sous forme de tableaux (ou de matrices) à deux dimensions, qui sont du type numpy.ndarray ou scipy.sparse. En pratique, il est aussi possible d’utiliser directement une DataFrame pandas, en fournissant à l’algorithme son attribut?values?pour fournir les données à l’algorithme sous forme d’un numpy.ndarray, en faisant bien attention que les colonnes sélectionnées du DataFrame soient bien numériques.
De la même manière que l’on utilise souvent des DataFrames pandas comme entrée des algorithmes de scikit-learn (avec l’attribut values),?ceux de Spark ML utilisent des DataFrames Spark comme données d’entrée. Les DataFrames on pour avantage le fait que les colonnes d’une même DataFrame peuvent être de types différents, correspondant plus à la réalité des données brutes collectées.
Estimators et Transformers
Toutes les opérations sur les données au sein d’une Pipeline de Machine Learning peuvent se résumer en deux catégories:
-
Opérations lignes par lignes:?Transformations
-
Opérations nécessitant au préalable un passage sur toutes les lignes du dataset pour fournir un modèle permettant de faire ensuite des opérations ligne par ligne:?Estimations + Transformations
Le point clé se trouve donc dans le fait de savoir si il est nécessaire ou non de passer au préalable sur toutes les lignes du dataset afin de transformer les données. Cette distinction est présente en Spark ML sous les notions primordiales de?Transformer?et d’Estimator.
Un?Transformer?est un algorithme transformant un DataFrame en un autre, typiquement contenant une ou plusieurs colonnes supplémentaires. La transformation se fait à l’aide de la méthode?transform(), et se fait donc ligne par ligne.
Un?Estimator?est un algorithme utilisant des DataFrames en entrée pour produire un?Model, qui est un?Transformer. Tout algorithme d’apprentissage est implémenté en utilisant cette abstraction. La phase d’apprentissage se lance à l’aide de la méthode?fit(), et va donc parcourir toutes les données pour créer le Model (nécessitant donc des échanges de données dans le cas de données sur un cluster), qui sera ensuite utilisé en tant que Transformer pour rajouter une ou plusieurs colonnes, ligne par ligne.
En scikit-learn, la notion de Transformer n’est pas aussi explicite. Dans la plupart des cas, qu’il y ait besoin de passer sur toutes les données au préalable ou non, on retrouve des classes?Estimator, qui possèdent une méthode?fit(). Selon le cas d’usage de la classe, on retrouvera de plus une méthode?predict()?pour prédire de nouveaux labels une fois le modèle appris,?ou?transform()?pour transformer le jeu de données. C’est la même instance qui est utilisée pour la phase d’apprentissage (fit) et de prédiction (predict / transform). Pour les opérations ne nécessitant pas de passer au préalable sur toutes les lignes du dataset, on retrouve en général tout de même une méthode fit, mais qui ne modifie rien. Cette méthode est présente afin de garder la consistance de l’API pour produire des pipelines.
Prenons un exemple pour illustrer ces propos. On a à notre disposition un jeu de données (Iris dans cet exemple), et on cherche à binariser l’une des variables selon un certain seuil. Ceci est faisable grace à la classe?Binarizer, présent dans scikit-learn et Spark ML.
scikit-learn
| 1 2 3 4 5 6 7 8 9 10 | importpandas as pd fromsklearn.datasets importload_iris # Load data in pandas DataFrame data=pd.DataFrame(data=load_iris().data, columns=['sepal_length','sepal_width','petal_length','petal_width']) # Binarizer fromsklearn.preprocessing importBinarizer binarizer=Binarizer(threshold=5) binarizer.fit_transform(data.sepal_length) |
Spark ML
| 1 2 3 4 5 6 7 | # Create DataFrame df=sqlContext.createDataFrame(data) # Binarizer frompyspark.ml.feature importBinarizer binarizer=Binarizer(threshold=5.0, inputCol='sepal_length', outputCol='sepal_length_bin') binarizer.transform(df).show(5) |
Comme on peut le constater, la démarche globale est exactement la même pour les deux librairies: Instancier la classe Binarizer avec le seuil souhaité, et utiliser la méthode transform pour faire la transformation.
Quelques différences importantes subsistent tout de même:
- En scikit-learn,?transform?renvoie uniquement la ou les colonnes transformées, alors que Spark ML renvoie un DataFrame contenant toutes les colonnes initiales auxquelles sont rajoutées la ou les colonnes transformées. Cela est d? au fait que les DataFrames, comme tout RDD, est immuable. Il est impossible de transformer directement un DataFrame, il faut alors en créer un nouveau. Cela permet cependant de garder au sein de la même structure les données initiales et les données transformées, ce qui est utile si les données initiales doivent être réutilisées pour d’autres transformations.
- Lors de l’instanciation de Binarizer, Spark ML oblige à?stipuler à minima le nom de la colonne à transformer. Ce n’est pas le cas en scikit-learn, pour lequel le choix de la ou des colonnes se fait au moment du transform.
Ces différences se retrouveront de manière générale à chaque comparaison entre scikit-learn et Spark ML.
Nous proposons maintenant de parcourir les similitudes et différences entre scikit-learn et Spark ML à travers un exemple complet comprenant toutes les étapes d’une cha?ne de traitement de Machine Learning. Nous verrons que, même si certaines abstractions et utilisations diffèrent, le fonctionnement global des deux librairies est, de manière très flagrante, similaire.
Préparation des données
Nous allons utiliser un dataset nommé?20 NewsGroup, contenant des commentaires d’articles de journaux pour de nombreuses catégories, allant de l’automobile à la politique, en passant par la science et le hardware. L’objectif est alors de construire un modèle permettant de prédire, à partir de son contenu, à quelle catégorie l’article appartient.
NB: Cet exemple est largement inspiré d’un?tutoriel de scikit-learn, ce qui permet d’avoir une base d’exemple pour présenter les concepts de Spark ML.
scikit-learn possède une méthode permettant d’accéder directement à ces données. Nous allons l’utiliser pour créer notre table, ainsi que notre DataFrame Spark.
scikit-learn
| 1 2 3 4 5 6 7 8 9 10 | # Import data fromsklearn.datasets importfetch_20newsgroups categories=['rec.autos','rec.sport.baseball','comp.graphics','comp.sys.mac.hardware', ??????????????'sci.space','sci.crypt','talk.politics.guns','talk.religion.misc'] newsgroup=fetch_20newsgroups(subset='train', categories=categories, shuffle=True, random_state=42) printnewsgroup.data[0] # Create pandas DataFrames for values and targets importpandas as pd pdf_newsgroup=pd.DataFrame(data=newsgroup.data, columns=['news'])# Texts pdf_newsgroup_target=pd.DataFrame(data=newsgroup.target, columns=['target'])# Targets |
Spark ML
| 1 2 3 4 5 6 7 | frompyspark.sql importSQLContext sqlContext=SQLContext(sc) # Create DataFrame df_newsgroup=sqlContext.createDataFrame(pd.concat([pdf_newsgroup, pdf_newsgroup_target], axis=1)) df_newsgroup.printSchema() df_newsgroup.show(3) |
Une différence notable est qu’en scikit-learn, les caractéristiques sont généralement séparées de leurs targets?(les classes à prédire dans notre cas), alors qu’en Spark ML, la colonne de target doit se trouver dans le même DataFrame que le reste des données.
Pour pouvoir tester les performances de nos classifications, il est important de séparer au préalable notre dataset en deux: un?training set?qui servira de base d’entra?nement des algorithmes, et un?test set?qui correspondra à nos “nouvelles données” pour lesquelles on fera une prédiction et on pourra les comparer avec les catégories réellement observées. On utilisera la fonction?train_test_split?pour scikit-learn, et?randomSplit?pour Spark ML.
scikit-learn
| 1 2 | fromsklearn.cross_validation importtrain_test_split X_train, X_test, y_train, y_test =train_test_split(newsgroup.data, newsgroup.target, train_size=0.8, random_state=42) |
Spark ML
| 1 | (df_train, df_test) =df_newsgroup.randomSplit([0.8,0.2]) |
Feature Engineering
Le?Feature Engineering?permet de?transformer,?extraire?et?sélectionner des caractéristiques (features)?afin de tirer le maximum d’information des données pour optimiser les performances des algorithmes de Machine Learning. En particulier, la plupart des algorithmes de Machine Learning prennent en entrée des données numériques.
Dans notre exemple, nos données d’entrée sont textuelles, il faut donc les transformer pour créer des features numériques qui les caractérisent au mieux. Nous allons ici effectuer les transformations suivantes:
- Tokenizing: Transformation d’un texte en une liste de mots
- Term Frequency: Plus un terme est fréquent dans un même document, plus il a de chances d’être révélateur de l’information contenue dans celui-ci (sauf si c’est un stop-word)
- Inverse Document Frequency: Si un terme appara?t dans la plupart des documents du corpus, il y a peu de chance qu’il soit utile pour les distinguer et les classer
Comme nous allons pouvoir le constater, les outils employés par scikit-learn et Spark ML pour réaliser ces transformations sont extrêmement ressemblant, et s’utilisent de la même manière.
Pour scikit-learn, nous allons utiliser les estimators?CountVectorizer?(qui joue le r?le de Tokenizer, avec d’autres fonctionnalités) et?TfIdfTransformer. Ces deux éléments possèdent une méthode fit() et transform(), ainsi qu’une méthode les rassemblant: fit_transform().
Pour Spark ML, nous allons utiliser les Transformers?Tokenizer?et?HashingTF, et l’Estimator?IDF. L’Estimator nécessite une étape d’apprentissage sur toutes les données (fit) pour construire un modèle qui sera ensuite appliqué ligne par ligne (transform). Comme son nom l’indique, HashingTF incorpore une notion de ??hashing??, qui est utilisé pour passer d’une chaine de caractères à une valeur numérique qui sera utilisée comme indice pour la construction de la matrice d’appartenance des termes à un document pour gagner en espace mémoire. L’utilisation de fonction de hash entra?ne une probabilité de collision de hash entre deux termes (même valeur de hash pour termes différents), qui est de plus accentuée par le fait que l’on puisse se restreindre à un certain nombre de features. Cependant, ces collisions ont un impact extrêmement restreint sur les performances globales du modèle.
NB: Les classes?utilisés pour les deux librairies pour cet exemple n’étant pas exactement les mêmes, les résultats fournis peuvent donc être différents. C’est la démarche d’utilisation de Spark ML que nous cherchons à présenter, et sa similarité d’utilisation avec scikit-learn.
scikit-learn
| 1 2 3 4 5 6 7 8 9 | # Tokenizing and Occurrence Counts fromsklearn.feature_extraction.text importCountVectorizer count_vect=CountVectorizer() X_train_counts=count_vect.fit_transform(X_train) # TF-IDF fromsklearn.feature_extraction.text importTfidfTransformer tfidf_transformer=TfidfTransformer() X_train_tfidf=tfidf_transformer.fit_transform(X_train_counts) |
Spark ML
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Tokenizing frompyspark.ml.feature importTokenizer tokenizer=Tokenizer(inputCol='news', outputCol='news_words') df_train_words=tokenizer.transform(df_train) # Hashing Term-Frequency frompyspark.ml.feature importHashingTF hashing_tf=HashingTF(inputCol=tokenizer.getOutputCol(), outputCol='news_tf', numFeatures=10000) df_train_tf=hashing_tf.transform(df_train_words) # Inverse Document Frequency frompyspark.ml.feature importIDF idf=IDF(inputCol=hashing_tf.getOutputCol(), outputCol="news_tfidf") idf_model=idf.fit(df_train_tf) # fit to build the model on all the data, and then apply it line by line df_train_tfidf=idf_model.transform(df_train_tf) df_train_tfidf.show(5) |
Création d’un Modèle de Machine Learning
Les données étant maintenant prêtes à être exploitées par un algorithme de Machine Learning, nous pouvons passer à la phase de modelling. Nous allons utiliser un modèle simple dans notre exemple: un Arbre de Décision. Ils sont utilisables grace aux classes?DecisionTreeClassifier?de scikit-learn et Spark ML.
Les paramètres de ce classifier sont les mêmes pour les deux librairies, mais avec des noms légèrement différents. De même, leur utilisation est exactement la même quelle que soit la librairie utilisée.
A noter cependant que, bien que scikit-learn comprenne que le label fourni correspond à des classes (puisque l’on utilise un Classifier), ce n’est pas le cas de Spark ML. Il faut donc lui spécifier que les valeurs de la colonne de label sont des classes et non des entiers. Il faut aussi que ces valeurs soient de la forme 0, 1, 2, …, num_labels-1. Cette transformation est faite à l’aide de?StringIndexer. C’est un estimator, car il faut d’abord passer par toutes les données pour savoir combien de classes il y a dans le dataset, et ensuite indexer les valeurs. Pour le reste, le fonctionnement est le même.
Pour rappel, la phase d’apprentissage se fait sur le training set, alors que la phase de prédiction se fait sur le test set. Il faut de plus bien faire attention à appliquer toutes les transformations faites précédemment sur le test set, pour pouvoir effectuer les prédictions.
scikit-learn
| 1 2 3 4 5 6 7 8 9 10 | # Training a Decision Tree on training set fromsklearn.tree importDecisionTreeClassifier clf=DecisionTreeClassifier(max_depth=10).fit(X_train_tfidf, y_train) # Transform test set X_test_counts=count_vect.transform(X_test) X_test_tfidf=tfidf_transformer.transform(X_test_counts) # Predictions on the test set y_test_pred=clf.predict(X_test_tfidf) |
Spark ML
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # Indexing the target frompyspark.ml.feature importStringIndexer string_indexer=StringIndexer(inputCol='target', outputCol='target_indexed') string_indexer_model=string_indexer.fit(df_train_tfidf) df_train_final=string_indexer_model.transform(df_train_tfidf) # Training a Decision Tree on training set frompyspark.ml.classification importDecisionTreeClassifier dt=DecisionTreeClassifier(featuresCol=idf.getOutputCol(), labelCol=string_indexer.getOutputCol()) dt_model=dt.fit(df_train_final) # Transform the test set df_test_words=tokenizer.transform(df_test) df_test_tf=hashing_tf.transform(df_test_words) df_test_tfidf=idf_model.transform(df_test_tf) df_test_final=string_indexer_model.transform(df_test_tfidf) # Preditions on the test set df_test_pred=dt_model.transform(df_test_final) df_test_pred.select('news','target','prediction','probability').show(5) |
Construction de Pipelines
Si on résume les actions faites jusque là, nous avons:
- Transformation des textes en listes de mots (CountVectorizer / Tokenizer)
- Transformation Term Frequency – Inverse Document Frequency (TfidfTransfofmer / HashingTF + IDF)
- Apprentissage d’un Arbre de Décision (DecisionTreeClassifier)
Le nombre d’étapes peut être relativement important en fonction de l’application. Encha?ner toutes les étapes sur le training set pour entra?ner un modèle, puis les reprendre toutes sur le test set pour faire les prédictions peut être long et fastidieux. C’est pourquoi la notion de?Pipeline?est présente pour alléger l’écriture. Une Pipeline est une classe?dans laquelle on va regrouper toutes les étapes de transformation de la donnée, pour ne créer qu’un seul et unique estimateur, qui sera ensuite utilisé sur les données brutes des training et test sets.
La démarche est alors la suivante:
Lors de l’appel à?fit(), l’instance de?Pipeline va appeler, tour à tour pour chaque étape, la méthode?fit()?de l’estimator si s’en est un, puis sa méthode?transform().
scikit-learn
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | fromsklearn.feature_extraction.text importCountVectorizer, TfidfTransformer fromsklearn.tree importDecisionTreeClassifier fromsklearn.pipeline importPipeline # Instanciate a Pipeline text_clf=Pipeline([('vect', CountVectorizer()), ?????????????????????('tfidf', TfidfTransformer()), ?????????????????????('clf', DecisionTreeClassifier(max_depth=10)), ????????????????????]) # Transform the data and train the classifier on the training set text_clf=text_clf.fit(X_train, y_train) # Transform the data and perform predictions on the test set y_test_pred=text_clf.predict(X_test) |
Spark ML
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | frompyspark.ml.feature importTokenizer, HashingTF, IDF, StringIndexer frompyspark.ml.classification importDecisionTreeClassifier frompyspark.ml importPipeline # Instanciate all the Estimators and Transformers necessary tokenizer=Tokenizer(inputCol='news', outputCol='news_words') hashing_tf=HashingTF(inputCol=tokenizer.getOutputCol(), outputCol='news_tf', numFeatures=10000) idf=IDF(inputCol=hashing_tf.getOutputCol(), outputCol="news_tfidf") string_indexer=StringIndexer(inputCol='target', outputCol='target_indexed') dt=DecisionTreeClassifier(featuresCol=idf.getOutputCol(), labelCol=string_indexer.getOutputCol(), maxDepth=10) # Instanciate a Pipeline pipeline=Pipeline(stages=[tokenizer, ????????????????????????????hashing_tf, ????????????????????????????idf, ????????????????????????????string_indexer, ????????????????????????????dt]) # Transform the data and train the classifier on the training set pipeline_model=pipeline.fit(df_train) # Transform the data and perform predictions on the test set df_test_pred=pipeline_model.transform(df_test) df_test_pred.show(5) |
Evaluation de modèle
Une fois notre Pipeline construite, il est temps d’évaluer les résultats obtenus et de mesurer les performances de notre modèle prédictif. C’est à ce moment que le test set est crucial. Les prédictions sont faites sur ce dernier, en faisant comme s’il s’agissait de nouvelles données dont on ne conna?t pas la classe, pour ensuite comparer les prédictions avec les classes réelles. Si nous faisions cela sur le training set, les résultats seraient alors biaisés car l’évaluation serait faite sur des données qui ont servi à l’apprentissage. Le fait de garder un test set pour lequel les données n’ont pas servi à l’apprentissage permet de mesurer la?capacité de généralisation?du modèle créé.
Pour mesurer les performances dans notre cas, nous allons utiliser la précision comme métrique, c’est à dire le pourcentage global de bonnes prédictions. Cette métrique est présente dans scikit-learn avec la méthode precision_score, et dans Spark ML avec la classe?MulticlassClassificationEvaluator.
scikit-learn
| 1 2 3 4 | fromsklearn.metrics importprecision_score # Evaluate the predictions done on the test set precision_score(y_test_pred, y_test, average='micro') |
Spark ML
| 1 2 3 4 5 6 7 | frompyspark.ml.evaluation importMulticlassClassificationEvaluator # Instanciate a MulticlassClassificationEvaluator with precision metric evaluator=MulticlassClassificationEvaluator(predictionCol='prediction', labelCol='target_indexed', metricName='precision') # Evaluate the predictions done on the test set evaluator.evaluate(df_test_pred) |
Tuning de paramètres
Nous voudrions maintenant chercher à améliorer le score de notre modèle. Une manière de faire cela est de?tuner les paramètres, afin de trouver la combinaison donnant les meilleures capacités de généralisation. Le tuning est généralement fait en utilisant les outils suivants:
- Grid Search: Spécifier toutes les valeurs de chaque paramètre que l’on souhaite tester
- Cross Validation: Test à plusieurs reprises de toutes les combinaisons de paramètres, sur différentes séparations du training set
En scikit-learn, on peut utiliser pour cela la classe?GridSearchCV. En Spark ML, c’est une classe?CrossValidator. Dans chaque cas, trois informations sont à fournir:
- La grille de paramètres (on utilise pour cela un?ParamGridBuilder?en Spark ML)
- L’estimator (ou la pipeline)
- La fonction de scoring pour décider quelle combinaison donne le meilleur score
scikit-learn
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | fromsklearn.grid_search importGridSearchCV # Create the parameters grid parameters={'tfidf__use_idf': (True,False), ??????????????'clf__max_depth': (10,20) ?????????????} # Instanciate a GridSearchCV object with the pipeline, the parameters grid and the scoring function gs_clf=GridSearchCV(text_clf, parameters, score_func=precision_score, n_jobs=-1) # Transform the data and train the classifier on the training set gs_clf=gs_clf.fit(X_train, y_train) # Transform the data and perform predictions on the test set y_test_pred=gs_clf.predict(X_test) # Evaluate the predictions done on the test set precision_score(X_test_pred, y_test, average='micro') |
Spark ML
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | frompyspark.ml.tuning importParamGridBuilder frompyspark.ml.tuning importCrossValidator # Instanciation of a ParamGridBuilder grid=(ParamGridBuilder() ????????.baseOn([evaluator.metricName,'precision']) ????????.addGrid(dt.maxDepth, [10,20]) ????????.build()) # Instanciation of a CrossValidator cv=CrossValidator(estimator=pipeline, estimatorParamMaps=grid, evaluator=evaluator) # Transform the data and train the classifier on the training set cv_model=cv.fit(df_train) # Transform the data and perform predictions on the test set df_test_pred=cv_model.transform(df_test) # Evaluate the predictions done on the test set evaluator.evaluate(df_test_pred) |
Conclusion
Cet article avait pour but d’introduire les principales notions utilisées en Spark ML, et de montrer à quel point le passage de scikit-learn à cette librairie de Machine Learning distribué est simplifié. Il y a quelques différences notables entre les deux librairies, en termes d’implémentation ainsi que dans la manière de traiter la donnée, mais elles sont minimales. Spark ML a été construit de manière à avoir une utilisation proche de scikit-learn, et cela aide énormément lorsque l’on passe à l’échelle avec Spark pour constuire des pipelines complexes de Machine Learning.
Spark ML est toujours en développement actif, et a encore pour le moment un nombre limité d’algorithmes implémentés en comparaison avec scikit-learn. La liste va s’étendre de plus en plus à chaque nouvelle version de Spark, et il sera alors encore plus simple de passer de scikit-learn à Spark ML pour tous types d’applications.
L’intégralité du code de cet article est disponible dans un?notebook sur Github.?Pour aller plus loin avec Spark ML, les DataFrames et la data science en général sur Spark nous vous recommandons la?formation Analyse de données et Machine Learning avec Spark, donnée par nos Data Scientists.
Billets Sur Le Même Thème :
原文:http://blog.xebia.fr/2015/10/08/from-scikit-learn-to-spark-ml/
總結
以上是生活随笔為你收集整理的From scikit-learn to Spark ML的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 毫无疑问计算机犯罪是一个很严重的问题英语
- 下一篇: uni-app是什么有啥子用?