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.
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)
--Créez une classe qui hérite de cuml.svm.SVC
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)
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
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.
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!
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!
Recommended Posts