[PYTHON] Comment utiliser cuML SVC comme classificateur CV Gridsearch

Résumé de l'article

Si vous passez le SVM de cuML (SVC) comme estimateur au CV de gridsearch de scikit-learn, Puisqu'une erreur s'est produite, je vais laisser une solution. Comme il s'agit du premier article de Qiita, je vous serais reconnaissant de bien vouloir signaler les erreurs ou les points difficiles à comprendre.

Seule la conclusion d'abord

Cause d'erreur

GridsearchCV de scikit-learn suppose un tableau numpy comme valeur de retour de estimator.predict (). Cependant, comme la valeur de retour de SVC.predict () de cuML est Series of cuDF, une erreur se produit dans Gridsearch CV.

Si vous n'utilisez pas GridsearchCV, vous pouvez le résoudre en convertissant la valeur de retour en un tableau numpy à chaque fois, mais si vous utilisez GridsearchCV, vous ne pouvez pas utiliser cette méthode. (Parce qu'il est nécessaire de passer chaque instance de la classe SVC à GridsearchCV)

Solution

--Créez une classe qui hérite de cuml.svm.SVC

Exemple d'implémentation

Cette fois, à titre d'exemple, nous utiliserons SVM pour classer «5» et «8» dans le jeu de données MNIST. La raison en est la suivante.

--MNIST est facile à obtenir et à formater, et le nombre de données est juste Le SVC de --cuML ne prend actuellement en charge que la classification à deux classes --Il semble que ce soit le plus difficile à classer "5" et "8" (Référence)

Environnement d'exécution

Création de l'ensemble de données

Tout d'abord, créez un ensemble de données. Sortez uniquement les MNIST 5 et 8 Changez l'étiquette en binaire (5 → 0, 8 → 1).

dataset_maker.py


import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

def dataset_maker():
    mnist = fetch_openml('mnist_784', version=1)
    data_58 = []
    label_58 =[]
    for data,target in zip(mnist.data, mnist.target):
        if target=='5':
            data_58.append(data/255)
            label_58.append(0)
        elif target=='8':
            data_58.append(data/255)
            label_58.append(1)

    data_58 = np.array(data_58)
    label_58 = np.array(label_58)
    X_train, X_test, y_train, y_test = train_test_split(data_58, label_58)

    return X_train, X_test, y_train, y_test

Différence entre __sklearn.svm.SVC.predict () __ et ** cuml.svm.SVC.predict () **

Vérifiez la différence dans la valeur de retour de la méthode prédire, qui est la cause de l'erreur. Comme indiqué dans le code ci-dessous, le SVC de cuML peut fondamentalement être géré de la même manière que le SVC de sklearn. Je suis heureux que l'introduction soit facile.

sklearn_vs_cuML.py


from sklearn.svm import SVC as skSVC
from cuml.svm import SVC as cuSVC

def classify_sklearn(X_train, X_test, y_train, y_test):
    clf = skSVC()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)

    print("skSVC output_type:{}".format(type(y_pred)))
    print("skSVC y_pred:{}".format(y_pred[0:10]))

def classify_cuml(X_train, X_test, y_train, y_test):
    clf = cuSVC()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)

    print("cuSVC output_type:{}".format(type(y_pred)))
    print("cuSVC y_pred:{}".format(y_pred[0:10]))


if __name__ == "__main__":
    X_train, X_test, y_train, y_test = dataset_maker()
    classify_sklearn(X_train, X_test, y_train, y_test)
    classify_cuml(X_train, X_test, y_train, y_test)

Lorsque vous faites cela, la sortie ressemblera à ceci:

skSVC output_type:<class 'numpy.ndarray'>
skSVC y_pred:[0 0 0 1 0 0 0 0 1 0]
cuSVC output_type:<class 'cudf.core.series.Series'>
cuSVC y_pred:0    0.0
1    0.0
2    0.0
3    1.0
4    0.0
5    0.0
6    0.0
7    0.0
8    1.0
9    0.0
dtype: float64

Comme je l'ai écrit ci-dessus, vous pouvez voir que la valeur de retour est différente. En résumé, ça ressemble à ça.

Parmi ceux-ci, en raison du premier, si la valeur de retour de cuml.svm.SVC.predict () est passée à la fonction d'évaluation de sklearn telle quelle, Je me fâche avec ValueError: Attendu de type tableau (tableau ou séquence non-chaîne). [^ 1]

[^ 1]: Ce dernier semble être jeté sans permission, et il fonctionnera si seulement le premier est corrigé. Cependant, c'est désagréable, donc le code ci-dessous le convertit explicitement en type int.

Cela lui-même peut être résolu en le convertissant en un tableau numpy, donc lors de la classification par cuML SVC, Définissez la valeur de retour de la méthode prédire sur [cudf.core.series.Series.to_array ()](https://rapidsai.github.io/projects/cudf/en/latest/api.html#cudf.core.series.Series. Après la conversion en un tableau numpy à l'aide de to_array) Passons-le à la fonction d'évaluation de scikit-learn. [^ 2]

[^ 2]: Bien sûr, la fonction d'évaluation de cuML est compatible avec la série de cuDF, mais il en existe peu de types actuellement, et je pense qu'en pratique, la fonction d'évaluation de scikit-learn est probablement utilisée dans de nombreux cas.

Utiliser Gridsearch CV avec cuML

Maintenant le sujet principal. Si vous souhaitez déterminer les hyper paramètres de SVC par recherche de grille Peut-être que la première chose qui me vient à l'esprit est de savoir comment utiliser le CV Gridsearch de Scikit-learn. Tout d'abord, essayons SVC de scikit-learn comme estimateur.

classify_sklearn_grid.py


def classify_sklearn_grid(X_train, X_test, y_train, y_test):
    parameters = {'kernel': ['linear', 'rbf'],
                  'C': [0.1, 1, 10, 100],
                  'gamma': [0.1, 1, 10]}

    clf = GridSearchCV(skSVC(), parameters, scoring='accuracy', verbose=2)
    clf.fit(X_train, y_train)
    y_pred = clf.best_estimator_.predict()

if __name__ == "__main__":
    X_train, X_test, y_train, y_test = dataset_maker()
    pred_sk_grid = classify_sklearn_grid(X_train, X_test, y_train, y_test)

Je pense que ce sera comme ça.

Puisque SVC de cuML est une classe avec les méthodes nécessaires telles que .fit () et .predict (), il répond aux exigences de Gridsearch CV en tant qu'estimateur.

Cependant, en réalité, la valeur de retour de la méthode prédire est cuDF Series, ce qui provoque une erreur dans le processus d'évaluation du résultat. Puisqu'il est nécessaire de transmettre chaque instance de SVC à GridsearchCV, il n'est pas possible de convertir en utilisant la méthode to_array à chaque fois que la méthode prédire est appelée.

Pour résoudre ce problème, vous pouvez remplacer la méthode prédire afin que la valeur de retour soit un tableau numpy.

Je vais vous expliquer en détail. C'est facile, définissez simplement une nouvelle classe comme celle-ci:

MySVC.py


from cuml.svm import SVC

class MySVC(SVC):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def predict(self, X):
        y_pred = super().predict(X).to_array().astype(int)
        return y_pred

Vous pouvez transmettre ce MySVC à GridsearchCV au lieu du SVC de cuml. Je ne pense pas avoir besoin de l'écrire,

classify_MySVC.py


from MySVC import MySVC

def classify_cuml_grid(X_train, X_test, y_train, y_test):

    parameters = {'kernel': ['linear', 'rbf'],
                  'C': [0.1, 1, 10, 100],
                  'gamma': [0.1, 1, 10]}

    clf = GridSearchCV(MySVC(), parameters, scoring='accuracy', verbose=2)
    clf.fit(X_train, y_train)
    y_pred = clf.best_estimator_.predict(X_test)

    return y_pred

if __name__ == "__main__":
    X_train, X_test, y_train, y_test = dataset_maker()
    pred_cu_grid = classify_cuml_grid(X_train, X_test, y_train, y_test)

C'est comme ça. Vous devriez maintenant pouvoir utiliser Gridsearch CV avec cuML! Cela fait longtemps, mais merci d'avoir lu!

prime

Comme c'est un gros problème, je publierai la différence de temps d'exécution lors de l'utilisation de scicit-learn et lors de l'utilisation de cuML.

--scikit-learn: 1348,87 [s](environ 22,5 minutes) --cuML: 270,06 [s](environ 4,5 minutes)

Étant donné que chaque essai n'est qu'une seule fois, ce n'est qu'à titre de référence, mais avec scicit-learn, cela a pris environ 5 fois plus de temps. Après tout, cuML est rapide!

Les références

Recommended Posts

Comment utiliser cuML SVC comme classificateur CV Gridsearch
Comment utiliser Fujifilm X-T3 comme webcam sur Ubuntu 20.04
Comment utiliser un fichier autre que .fabricrc comme fichier de configuration
Comment déguiser un fichier ZIP en fichier PNG
Comment utiliser Python-shell
Remarques sur l'utilisation de tf.data
Comment utiliser virtualenv
Comment utiliser Seaboan
Comment utiliser le shogun
Comment utiliser Pandas 2
Comment utiliser Virtualenv
Comment utiliser numpy.vectorize
Comment utiliser pytest_report_header
Comment utiliser partiel
Comment utiliser Bio.Phylo
Comment utiliser SymPy
Comment utiliser x-means
Comment utiliser IPython
Comment utiliser virtualenv
Comment utiliser Matplotlib
Comment utiliser iptables
Comment utiliser numpy
Comment utiliser TokyoTechFes2015
Comment utiliser venv
Comment utiliser le dictionnaire {}
Comment utiliser Pyenv
Comment utiliser la liste []
Comment utiliser python-kabusapi
Comment utiliser OptParse
Comment utiliser le retour
Comment utiliser pyenv-virtualenv
Comment utiliser imutils
Remarques sur l'utilisation d'AIST Spacon ABCI
Un mémorandum sur l'utilisation de keras.preprocessing.image de Keras
Comment afficher DataFrame sous forme de tableau dans Markdown
[Astuces] Comment utiliser l'iPhone comme caméra Web sous Linux
Comment utiliser le multitraitement python (suite 3) apply_async en classe avec Pool en tant que membre
Comment utiliser GitHub sur un serveur multi-personnes sans mot de passe
Comment utiliser Qt Designer
Comment utiliser la recherche triée
[gensim] Comment utiliser Doc2Vec
python3: Comment utiliser la bouteille (2)
Comprendre comment utiliser django-filter
Comment utiliser le générateur
Comment importer NoteBook en tant que module dans Jupyter (IPython)
[Python] Comment utiliser la liste 1
Comment utiliser la méthode __call__ dans la classe Python
Comment appeler une fonction
Comment utiliser FastAPI ③ OpenAPI
Comment imprimer des caractères sous forme de tableau avec la fonction d'impression de Python
Comment utiliser Python Argparse
Comment utiliser IPython Notebook
Comment utiliser Pandas Rolling
Comment utiliser les dictionnaires redis-py
Comment pirater un terminal
Python: comment utiliser pydub
[Python] Comment utiliser checkio