[PYTHON] Verwendung von cuML SVC als Gridsearch-CV-Klassifikator

Artikelübersicht

Wenn Sie die SVM (SVC) von cuML als Schätzer an den Gridsearch-Lebenslauf von scikit-learn übergeben, Da ein Fehler aufgetreten ist, werde ich eine Lösung hinterlassen. Da dies der erste Beitrag von Qiita ist, würde ich mich freuen, wenn Sie auf Fehler oder Punkte hinweisen könnten, die schwer zu verstehen sind.

Nur die Schlussfolgerung zuerst

Fehlerursache

GridsearchCV von scikit-learn nimmt ein numpy-Array als Rückgabewert von Estimator.predict () an. Da der Rückgabewert von SVC.predict () von cuML jedoch eine Reihe von cuDF ist, tritt in Gridsearch CV ein Fehler auf.

Wenn Sie GridsearchCV nicht verwenden, können Sie es lösen, indem Sie den Rückgabewert jedes Mal in ein Numpy-Array konvertieren. Wenn Sie jedoch GridsearchCV verwenden, können Sie diese Methode nicht verwenden. (Da jede Instanz der SVC-Klasse an GridsearchCV übergeben werden muss)

Lösung

--Erstellen Sie eine Klasse, die cuml.svm.SVC erbt

Implementierungsbeispiel

Dieses Mal verwenden wir als Beispiel SVM, um "5" und "8" im MNIST-Datensatz zu klassifizieren. Der Grund ist wie folgt.

--MNIST ist einfach zu erhalten und zu formatieren, und die Anzahl der Daten ist genau richtig Der SVC von --cuML unterstützt derzeit nur die Klassifizierung in zwei Klassen

Ausführungsumgebung

Datensatzerstellung

Erstellen Sie zunächst einen Datensatz. Nehmen Sie nur MNIST 5 und 8 heraus Ändern Sie die Bezeichnung in binär (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

Unterschied zwischen __sklearn.svm.SVC.predict () __ und ** cuml.svm.SVC.predict () **

Überprüfen Sie die Differenz im Rückgabewert der Vorhersagemethode, die die Fehlerursache ist. Wie im folgenden Code gezeigt, kann der SVC von cuML grundsätzlich genauso behandelt werden wie der SVC von sklearn. Ich bin froh, dass die Einführung einfach ist.

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)

Wenn Sie dies tun, sieht die Ausgabe folgendermaßen aus:

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

Wie ich oben geschrieben habe, können Sie sehen, dass der Rückgabewert unterschiedlich ist. Zusammenfassend sieht es so aus.

Von diesen wird aufgrund des ersteren, wenn der Rückgabewert von cuml.svm.SVC.predict () an die Bewertungsfunktion von sklearn übergeben wird, wie es ist, Ich ärgere mich über ValueError: Expected array-like (Array- oder Nicht-String-Sequenz). [^ 1]

[^ 1]: Letzteres scheint ohne Erlaubnis gegossen zu werden, und es wird funktionieren, wenn nur Ersteres behoben ist. Es ist jedoch unangenehm, so dass der folgende Code es explizit in den Typ int umwandelt.

Dies selbst kann gelöst werden, indem es in ein Numpy-Array konvertiert wird. Wenn Sie also nach cuML SVC klassifizieren, Setzen Sie den Rückgabewert der Vorhersagemethode auf cudf.core.series.Series.to_array (). Nach der Konvertierung in ein Numpy-Array mit to_array) Lassen Sie es uns an die Bewertungsfunktion von scikit-learn übergeben. [^ 2]

[^ 2]: Natürlich ist die Evaluierungsfunktion von cuML mit der Reihe von cuDF kompatibel, aber es gibt derzeit nur wenige Typen, und ich denke, dass in der Praxis die Evaluierungsfunktion von scikit-learn wahrscheinlich in vielen Fällen verwendet wird.

Verwenden Sie Gridsearch CV mit cuML

Nun zum Hauptthema. Wenn Sie die Hyperparameter von SVC durch Rastersuche ermitteln möchten Vielleicht fällt Ihnen als Erstes ein, wie Sie den Gridsearch-Lebenslauf von Scikit-learn verwenden. Versuchen wir zunächst SVC von Scikit-Learn als Schätzer.

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)

Ich denke es wird so sein.

Da der SVC von cuML eine Klasse mit den erforderlichen Methoden wie .fit () und .predict () ist, erfüllt er die Anforderungen von Gridsearch CV als Schätzer.

In der Realität ist der Rückgabewert der Vorhersagemethode jedoch die cuDF-Serie, was zu einem Fehler bei der Auswertung des Ergebnisses führt. Da jede Instanz von SVC an GridsearchCV übergeben werden muss, ist es nicht möglich, bei jedem Aufruf der Vorhersagemethode die Methode to_array zu konvertieren.

Um dieses Problem zu lösen, können Sie die Vorhersagemethode überschreiben, sodass der Rückgabewert ein Numpy-Array ist.

Ich werde im Detail erklären. Es ist einfach, definieren Sie einfach eine neue Klasse wie folgt:

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

Sie können diesen MySVC anstelle des SVC von cuml an GridsearchCV übergeben. Ich glaube nicht, dass ich es schreiben muss,

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)

Es ist so. Sie sollten jetzt in der Lage sein, Gridsearch CV mit cuML zu verwenden! Es ist lange her, aber danke fürs Lesen!

Bonus

Da es eine große Sache ist, werde ich den Unterschied in der Ausführungszeit bei Verwendung von scicit-learn und bei Verwendung von cuML veröffentlichen.

--scikit-learn: 1348,87 [s](ungefähr 22,5 Minuten) --cuML: 270,06 [s](ungefähr 4,5 Minuten)

Da jeder Versuch nur einmal durchgeführt wird, dient er nur als Referenz, aber mit scicit-learn dauerte es ungefähr fünfmal länger. Immerhin ist cuML schnell!

Verweise

Recommended Posts

Verwendung von cuML SVC als Gridsearch-CV-Klassifikator
Verwendung von Fujifilm X-T3 als Webcam unter Ubuntu 20.04
So verwenden Sie eine andere Datei als .fabricrc als Konfigurationsdatei
So tarnen Sie eine ZIP-Datei als PNG-Datei
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Wie benutzt man Seaboan?
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Verwendung von OptParse
Verwendung von return
Wie man Imutils benutzt
Hinweise zur Verwendung von AIST Spacon ABCI
Ein Memorandum zur Verwendung von Keras 'keras.preprocessing.image
So zeigen Sie DataFrame als Tabelle in Markdown an
[Tipps] Verwendung des iPhone als Webkamera unter Linux
Verwendung der Python-Multiprocessing (Fortsetzung 3) apply_async in einer Klasse mit Pool als Mitglied
Verwendung von GitHub auf einem Server für mehrere Personen ohne Kennwort
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verstehen Sie, wie man Django-Filter verwendet
Verwendung des Generators
So importieren Sie NoteBook als Modul in Jupyter (IPython)
[Python] Verwendung von Liste 1
Verwendung der Methode __call__ in der Python-Klasse
So rufen Sie eine Funktion auf
Verwendung von FastAPI ③ OpenAPI
So drucken Sie Zeichen als Tabelle mit der Druckfunktion von Python
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
Verwendung von Redispy-Wörterbüchern
Wie man ein Terminal hackt
Python: Wie man pydub benutzt
[Python] Verwendung von checkio