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.
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)
--Erstellen Sie eine Klasse, die cuml.svm.SVC erbt
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
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
Ü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.
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!
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!
Recommended Posts