[PYTHON] Scikit-learn revisité

Prenez note des nouvelles connaissances sur l'API utile de scikit-learn. J'ai écrit un mémo dans $ HOME / Desktop / memo.md, mais je l'ai accidentellement modifié, alors j'ai essayé d'utiliser Qiita. J'ajouterai de nouveaux apprentissages au besoin.

(Je vous serais reconnaissant si vous pouviez signaler toute erreur. Merci.)

Prétraitement des données

Dieu habite dans le module de prétraitement de la bibliothèque, et nous devons remercier les committers lors de l'importation.

Réduction de la dimension de l'identité

Sélectionnez k éléments. Le premier argument de SelectKBest est une fonction, et f_classif etc. peut être utilisé en plus de chi2. Il existe d'autres RFECV pour réduire la dimension de l'élément, mais je ne sais pas en quoi ils diffèrent, alors j'aimerais enquêter à l'avenir.

from sklearn.feature_selection.univariate_selection import SelectKBest, chi2

fselect = SelectKBest(chi2 , k=2000)

Référence: [Comment utiliser correctement SelectKBest, GridSearchCV et la validation croisée dans le package sklearn ensemble?](Https://www.quora.com/How-do-I-properly-use-SelectKBest-GridSearchCV-and- validation croisée dans le package sklearn ensemble)

Traiter les données qui ont des valeurs manquantes

Une arme moderne appelée Pandas a rendu le prétraitement des données beaucoup plus facile. Cela va bien avec le notebook Jupyter et supprime les données contenant NaN sur une ligne. NaN et, dans certains cas, 0, etc. sont appelés valeurs manquantes.

Les valeurs manquantes peuvent également être supprimées avec scikit-learn. Un extrait d'un échantillon d'article de référence (document officiel). Lorsque imp.fit () est exécuté, la valeur moyenne et la valeur médiane sont calculées, et lorsque imp.transform () est exécuté, la valeur manquante est remplacée par la valeur moyenne et la valeur médiane.

import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit([[1, 2], [np.nan, 3], [7, 6]])

X = [[np.nan, 2], [6, np.nan], [7, 6]]
print(imp.transform(X)) 
# [[ 4.          2.        ]
#  [ 6.          3.666...]
#  [ 7.          6.        ]]

Référence: document officiel scikit-learn

Normaliser les données

J'ai toujours écrit la normalisation moi-même (bien que je n'appelle que quelques méthodes numpy), mais scikit-learn le fait pour moi. La norme L1 et la norme L2 peuvent être utilisées. Extrait de l'exemple de code du document.

X = [[ 1., -1.,  2.],
     [ 2.,  0.,  0.],
     [ 0.,  1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')

print(X_normalized)
# array([[ 0.40..., -0.40...,  0.81...],
#       [ 1.  ...,  0.  ...,  0.  ...],
#       [ 0.  ...,  0.70..., -0.70...]])

Référence: document officiel scikit-learn

Mettre les données à l'échelle

Je trouve que le japonais est étrange. Comment appelle-t-on la mise à l'échelle en japonais? Traitez les données de manière à ce que la moyenne soit de 0 et la variance de 1.

Échantillon (ry

Comme indiqué dans la documentation, il peut être combiné avec Pipeline.

from sklearn import preprocessing
import numpy as np
X = np.array([[ 1., -1.,  2.],
              [ 2.,  0.,  0.],
              [ 0.,  1., -1.]])
X_scaled = preprocessing.scale(X)

print(X_scaled)
# array([[ 0.  ..., -1.22...,  1.33...],
#       [ 1.22...,  0.  ..., -0.26...],
#       [-1.22...,  1.22..., -1.06...]])

Il existe différents types tels que StandardScaler et MinMaxScaler. Veuillez lire le document suivant (fit, l'API de transformation se développe).

Référence: document officiel scikit-learn

Validation du modèle

K Pliez tout en améliorant le rapport d'étiquette

Lorsque KFold appelle split (), il suffit de saisir un tableau de plusieurs dimensions de l'échantillon, mais StratifiedKFold doit saisir un tableau d'étiquettes. Pourquoi donc? En effet, cela rend le ratio d'étiquettes des données des enseignants satisfaisant.

from sklearn.model_selection import StratifiedKFold
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = np.array([0, 0, 1, 1])
skf = StratifiedKFold(n_splits=2)
skf.get_n_splits(X, y)

print(skf)  

for train_index, test_index in skf.split(X, y):
   print("TRAIN:", train_index, "TEST:", test_index)
   X_train, X_test = X[train_index], X[test_index]
   y_train, y_test = y[train_index], y[test_index]

Référence: document officiel scikit-learn

Pré-traitement-> apprentissage transparent

Lorsqu'il s'agit de données nécessitant un prétraitement, il semble que le code sera propre si le prétraitement et l'extraction des fonctionnalités peuvent être effectués dans model.fit (). Un système appelé Pipeline rend cela possible. Cela reste le nom.

Before

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC

# build the feature matrices
ngram_counter = CountVectorizer(ngram_range=(1, 4), analyzer='char')
X_train = ngram_counter.fit_transform(data_train)
X_test  = ngram_counter.transform(data_test)

# train the classifier
classifier = LinearSVC()
model = classifier.fit(X_train, y_train)

# test the classifier
y_test = model.predict(X_test)

After

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC

# build the pipeline
ppl = Pipeline([
              ('ngram', CountVectorizer(ngram_range=(1, 4), analyzer='char')),
              ('clf',   LinearSVC())
      ])

# train the classifier
model = ppl.fit(data_train)

# test the classifier
y_test = model.predict(data_test)

Le code est tiré du billet de blog ci-dessous, mais il existe également une Union des fonctionnalités au bas de l'article.

Référence: Utilisation des pipelines et des FeatureUnions dans scikit-learn

Index d'évaluation

Perte logistique

Je veux utiliser l'écosystème scicit-learn même avec mon propre appareil d'apprentissage

Si vous devez utiliser un modèle non fourni par scikit-learn, vous devez l'implémenter vous-même. Après avoir implémenté le modèle, il est nécessaire d'effectuer une validation croisée et une recherche de grille pour l'évaluation. Si vous pouvez accéder au rail de model_selection de scikit-learn, vous pouvez ignorer cette implémentation. Cela peut être réalisé en héritant de BaseEstimator lors de l'implémentation du modèle.

Le code indiqué dans l'article de référence ci-dessous est cité.

from sklearn.base import BaseEstimator

class MyEstimator(BaseEstimator):
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2

    def fit(self, x, y):
        return self 

    def predict(self, x):
        return [1.0]*len(x) 

    def score(self, x, y):
        return 1

    def get_params(self, deep=True):
        return {'param1': self.param1, 'param2': self.param2}

    def set_params(self, **parameters):
        for parameter, value in parameters.items():
            setattr(self,parameter, value)
        return self

En passant, si vous héritez de ClassifierMixin et RegressorMixin, vous pouvez utiliser model.score implémenté du côté scikit-learn. Je veux monter sur les rails de manière positive.

Référence: Implémenter un estimateur auto-créé minimum (Estimator) avec scikit-learn

Recommended Posts

Scikit-learn revisité
Isomap avec Scikit-learn
Erreur d'importation scikit-learn
DBSCAN avec scikit-learn
Clustering avec scikit-learn (1)
Mettez facilement à jour Scikit-learn.
Clustering avec scikit-learn (2)
PCA avec Scikit-learn
kmeans ++ avec scikit-learn