[PYTHON] J'ai essayé de mettre en place une validation contradictoire

Quel est cet article

Après avoir expliqué ce qu'est la validation contradictoire, j'écrirai le code que j'ai essayé d'implémenter. Je vais l'écrire ici sous forme de mémoire et d'organisation des connaissances.

Le code auquel j'ai fait référence lors de la publication de cet article est ici

Qu'est-ce que la validation contradictoire?

Si la distribution des données de train est différente de celle des données de test, la distribution des données de validation sera également plus proche de la distribution des données de train, et les données de test peuvent ne pas être bien prédites. L'une des méthodes utilisées à l'époque est la validation contradictoire.

La validation contradictoire consiste à créer un modèle qui classe les données de train et les données de test, et à l'utiliser pour créer des données de validation avec une distribution aussi proche que possible des données de test.

la mise en oeuvre

Création de la variable objectif

Créez une nouvelle colonne dans les données de train et les données de test, et mettez 0 dans les données de train et 1 dans les données de test.


import pandas as pd

train['target'] = 0
test['target'] = 1

train_test = pd.concat([train, test], axis=0).reset_index(drop=True)
train_test.head()

Apprentissage et classification

Cette fois, j'ai utilisé lightgbm pour construire le modèle. Une vérification de croisement est effectuée et la probabilité des données de test est mesurée pour toutes les données de train.

import numpy as np
import lightgbm as lgb
from sklearn.model_selection import StratifiedKFold

params = {'objective': 'binary',
          'max_depth': 5,
          'boosting': 'gbdt',
          'metric': 'auc'}

features = [col for col in train_test.columns if col not in ('target',)]
oof_pred = np.zeros((len(train_test), ))
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

for fold, (train_idx, val_idx) in enumerate(cv.split(train_test, train_test['target'])):
    x_train, x_predict = train_test[features].iloc[train_idx], train_test[features].iloc[val_idx]
    y_train = train_test['target'][train_idx]

    train_set = lgb.Dataset(x_train, label=y_train)

    model = lgb.train(params, train_set)
    oof_pred[val_idx] = model.predict(x_predict).reshape(oof_pred[val_idx].shape)

Créer des données de validation

Trier la valeur de probabilité par ordre décroissant, obtenir n'importe quel nombre de données par ordre décroissant (probablement test) et créer des données de validation

train_test['probability'] = oof_pred
train = train_test[train_test.target==0].drop('target', axis=1).sort_values('probability', ascending=False)

valid_idx = int(len(train)) / 5 #Cette fois, il est décidé d'être le top 20%

validation_data = train.iloc[:valid_idx]
train_data = train.iloc[valid_idx:]

J'ai essayé de le mettre ensemble dans une classe

class Adversarial_validator:

    def __init__(self, train, test, features, categoricals):
        self.train = train
        self.test = test
        self.features = features
        self.categoricals = categoricals
        self.union_df = self.train_test_union(self.train, self.test)
        self.cv = self.get_cv()
        self.models = []
        self.oof_pred = self.fit()
        self.report_plot()

    def fit(self):
        oof_pred = np.zeros((len(self.union_df), ))

        for fold, (train_idx, val_idx) in enumerate(self.cv):
            x_train, x_predict = self.union_df[self.features].iloc[
                train_idx], self.union_df[self.features].iloc[val_idx]
            y_train = self.union_df['target'][train_idx]
            train_set = self.convert_dataset(x_train, y_train)
            model = self.train_model(train_set)
            self.models.append(model)

            oof_pred[val_idx] = model.predict(
                x_predict).reshape(oof_pred[val_idx].shape)
        self.union_df['prediction'] = oof_pred
        return oof_pred

    def train_test_union(self, train, test):
        train['target'] = 0
        test['target'] = 1
        return pd.concat([train, test], axis=0).reset_index(drop=True)

    def get_cv(self):
        cv = StratifiedKFold(n_splits=5,
                             shuffle=True, random_state=42)

        return cv.split(self.union_df, self.union_df['target'])

    def convert_dataset(self, X, y):
        return lgb.Dataset(X, label=y, categorical_feature=self.categoricals)

    def train_model(self, train_set):
        return lgb.train(self.get_params(), train_set)

    def get_params(self):
        param = {'num_leaves': 50,
                 'num_round': 100,
                 'min_data_in_leaf': 30,
                 'objective': 'binary',
                 'max_depth': 5,
                 'learning_rate': 0.2,
                 'min_child_samples': 20,
                 'boosting': 'gbdt',
                 'feature_fraction': 0.9,
                 'bagging_freq': 1,
                 'bagging_fraction': 0.9,
                 'bagging_seed': 44,
                 'verbose_eval': 50,
                 'metric': 'auc',
                 'verbosity': -1}
        return param

    def report_plot(self):
        fig, ax = plt.subplots(figsize=(16, 12))
        plt.subplot(2, 2, 1)
        self.plot_feature_importance()
        plt.subplot(2, 2, 2)
        self.plot_roc_curve()
        plt.subplot(2, 2, 3)
        plt.hist(self.union_df['target'] - self.oof_pred)
        plt.title('Distribution of errors')
        plt.subplot(2, 2, 4)
        plt.hist(np.random.choice(self.oof_pred, 1000, False))
        plt.title('Distribution of oof predictions')

    def get_feature_importance(self):
        n = len(self.models)
        feature_imp_df = pd.DataFrame()
        for i in range(n):
            tmp = pd.DataFrame(zip(self.models[i].feature_importance(
            ), self.features), columns=['Value', 'Feature'])
            tmp['n_models'] = i
            feature_imp_df = pd.concat([feature_imp_df, tmp])
            del tmp
        self.feature_importance = feature_imp_df
        return feature_imp_df

    def plot_feature_importance(self, n=20):
        imp_df = self.get_feature_importance().groupby(
            ['Feature'])[['Value']].mean().reset_index(False)
        imp_top_df = imp_df.sort_values('Value', ascending=False).head(n)
        sns.barplot(data=imp_top_df, x='Value', y='Feature', orient='h')
        plt.title('Feature importances')

    def plot_roc_curve(self):
        fpr, tpr, thresholds = metrics.roc_curve(
            self.union_df['target'], self.oof_pred)
        auc = metrics.auc(fpr, tpr)

        plt.plot(fpr, tpr, label='ROC curve (area = %.2f)' % auc)
        plt.legend()
        plt.title('ROC curve')
        plt.xlabel('False Positive Rate')
        plt.ylabel('True Positive Rate')

adv = Adversarial_validator(train, test, features, categoricals)

adv_output.png

Les données utilisées proviennent du 2019 Data Science Bowl du concours kaggle.

Utilisation autre que la création de données de validation

Résumé

J'ai brièvement présenté la validation contradictoire. J'espère que cela aidera ceux qui liront cet article.

Recommended Posts

J'ai essayé de mettre en place une validation contradictoire
J'ai essayé d'implémenter PCANet
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé d'implémenter Deep VQE
J'ai essayé d'implémenter Realness GAN
J'ai essayé d'implémenter PLSA en Python
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé d'implémenter la permutation en Python
J'ai essayé d'implémenter PLSA dans Python 2
J'ai essayé d'implémenter ADALINE en Python
J'ai essayé d'implémenter PPO en Python
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai essayé de déboguer.
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'implémenter TOPIC MODEL en Python
J'ai essayé d'implémenter le tri sélectif en python
J'ai essayé de mettre en œuvre le problème du voyageur de commerce
J'ai essayé d'apprendre PredNet
J'ai essayé d'organiser SVM.
J'ai essayé de réintroduire Linux
J'ai essayé de présenter Pylint
J'ai essayé de résumer SparseMatrix
jupyter je l'ai touché
J'ai essayé de mettre en œuvre la gestion des processus statistiques multivariés (MSPC)
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé d'implémenter le poker de Drakue en Python
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé d'implémenter GA (algorithme génétique) en Python
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé d'implémenter SSD avec PyTorch maintenant (Dataset)
J'ai essayé d'implémenter le calcul automatique de la preuve de séquence
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé de mettre en œuvre le modèle de base du réseau neuronal récurrent
J'ai essayé de créer l'API Quip
J'ai essayé d'implémenter la détection d'anomalies par apprentissage de structure clairsemée
J'ai essayé de toucher Python (installation)
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
J'ai essayé de mettre en œuvre une évasion (type d'évitement de tromperie) avec Quantx
[Django] J'ai essayé d'implémenter des restrictions d'accès par héritage de classe.
J'ai essayé d'expliquer l'ensemble de données de Pytorch
J'ai essayé l'authentification vocale Watson (Speech to Text)
J'ai touché l'API de Tesla
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
J'ai essayé de mettre en œuvre le chapeau de regroupement de Harry Potter avec CNN
J'ai essayé de m'organiser à propos de MCMC.
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
J'ai essayé d'implémenter le blackjack du jeu Trump en Python
J'ai essayé de déplacer le ballon
J'ai essayé d'estimer la section.
J'ai essayé d'implémenter SSD avec PyTorch maintenant (édition du modèle)
[Python] J'ai essayé d'implémenter un tri stable, alors notez
J'ai essayé de mettre en œuvre un jeu de dilemme de prisonnier mal compris en Python
J'ai essayé d'implémenter la classification des phrases par Self Attention avec PyTorch
J'ai essayé de créer un linebot (implémentation)