From scikit-learn to Spark ML

Yoann Benoit

PartagerTweeter+ 1E-mail

Dans 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 tâche.

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 grâce à 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])
Passons maintenant aux différentes étapes essentielles de constitution d’une Pipeline complète de Machine Learning, afin d’observer la facilité de passage de scikit-learn à Spark ML.

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)

Comme on le voit, HashingTF et IDF renvoient un DataFrame avec des colonnes supplémentaires de type SparseVector: On spécifie sa taille (ici 10000), la liste des positions pour lesquelles la valeur du vecteur est non nulle, puis la liste des valeurs non nulles. Cela permet de ne pas encoder complètement le vecteur lorsqu’il contient énormément de 0.

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 grâce 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:

  1. Créer une instance de chaque Transformer / Estimator à utiliser
  2. Les regrouper dans une instance de Pipeline
  3. Appeler la méthode fit() de Pipeline pour lancer la transformation et l’apprentissage sur le training set
  4. Appeler la méthode transform() pour réaliser les prédictions sur le test set

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相关推荐

  1. 用户画像之Spark ML实现

    用户画像之Spark ML实现 1 Spark ML简单介绍 Spark ML是面向DataFrame编程的.Spark的核心开发是基于RDD(弹性分布式数据集),但是RDD,但是RDD的处理并不是非 ...

  2. 机器学习与Scikit Learn学习库

    摘要: 本文介绍机器学习相关的学习库Scikit Learn,包含其安装及具体识别手写体数字案例,适合机器学习初学者入门Scikit Learn. 在我科研的时候,机器学习(ML)是计算机科学领域中最 ...

  3. scala-MLlib官方文档---spark.ml package--ML Pipelines+Collaborative Filtering+Frequent Pattern Mining

    三. ML Pipeline Main concepts in Pipelines(管道中的主要概念) MLlib对用于机器学习算法的API进行了标准化,从而使将多种算法组合到单个管道或工作流中变得更 ...

  4. 【scikit-learn】如何用Python和SciKit Learn 0.18实现神经网络

    本教程的代码和数据来自于 Springboard 的博客教程.本文的作者为 Jose Portilla,他是网络教育平台 Udemy 一门数据科学类课程的讲师. GitHub 链接:https://g ...

  5. Spark ml 特征工程

    参考:https://www.jianshu.com/p/e662daa8970a https://blog.csdn.net/qq_34531825/article/details/52415838 ...

  6. spark ml中一个比较通用的transformer

    spark ml中有许多好用的transformer,很方便用来做特征的处理,比如Tokenizer, StopWordsRemover等,具体可参看文档:http://spark.apache.or ...

  7. 基于Spark ML 聚类分析实战的KMeans

    2019独角兽企业重金招聘Python工程师标准>>> 聚类分析是一个无监督学习 (Unsupervised Learning) 过程, 一般是用来对数据对象按照其特征属性进行分组, ...

  8. Scikit Learn: 在python中机器学习

    Warning 警告:有些没能理解的句子,我以自己的理解意译. 翻译自:Scikit Learn:Machine Learning in Python 作者: Fabian Pedregosa, Ga ...

  9. 使用spark ml pipeline进行机器学习

    一.关于spark ml pipeline与机器学习 一个典型的机器学习构建包含若干个过程 1.源数据ETL 2.数据预处理 3.特征选取 4.模型训练与验证 以上四个步骤可以抽象为一个包括多个步骤的 ...

  10. [转载]Scikit Learn: 在python中机器学习

    原址:http://my.oschina.net/u/175377/blog/84420 目录[-] Scikit Learn: 在python中机器学习 载入示例数据 一个改变数据集大小的示例:数码 ...

最新文章

  1. Mat, vectorpoint2f,Point3d Iplimage等等常见类型转换
  2. R语言forestmodel包使用教程
  3. python输入数据的维度_keras分类模型中的输入数据与标签的维度实例
  4. 查询Windows api
  5. 2.使用windows下的客户端连接虚拟机上的oracle连不上的时候的解决方案
  6. 单片机课程设计数字心率计_光学心率传感器详细使用教程
  7. 检测和语义分割_分割和对象检测-第1部分
  8. java out.flush_java中基本输入输出流的解释(flush方法的使用)
  9. docker开启mysql的binlog日志
  10. C语言之字符串探究(八):strchr、strstr、strtok
  11. 代码整洁之道(二)优雅注释之道
  12. 初中生学python教材推荐_推荐中学生看的几本书
  13. Exception.ToString()使用及其他方法比较
  14. vb.net 教程 11-1 打印组件 1 基础
  15. 深信服SCSA安全认证工程师
  16. ClearCase的一些基本概念
  17. 分享几个设计精美电路图的工具
  18. 整理:Github上最受欢迎的仓库(截至2021年12月26日)
  19. 【day13】【洛谷算法题】-P5713洛谷团队系统-刷题反思集[入门2分支结构]
  20. 教我简单学计算机初步,零基础教你用电脑:常用简单操作介绍

热门文章

  1. Python-Flask开发微电影网站(九)
  2. Vue ElementUI el-button 修改样式
  3. 布隆过滤器误判怎么办为什么会_五分钟小知识:布隆过滤器原理和应用分析
  4. AES加密c语言实现
  5. 中国经济学家与管理学家的错位
  6. 大数据离线流程(小练习)
  7. Ubuntu USB设备端口号绑定
  8. Android群英传读书笔记-2D绘图基础
  9. win10 win 7系统 windows无法访问\\请检查名称拼写(基本上非重装系统外的终极解决方式)win7 , win10均可
  10. 考研英语单词-近义词分类-Fifth Day