[PYTHON] Je ne veux pas rechercher de para haut parce que c'est IQ1 (comment utiliser lightgbm_tuner)

Cet article a été publié dans 2e calendrier de l'Avent de l'IQ1 2019.

Apprentissage automatique IQ1

Le prétraitement des données et la recherche à haut niveau de para du modèle sont inévitables pour l'apprentissage automatique. Mais comme IQ est 1, je ne veux pas le faire si je peux prétraiter les données et rechercher un para élevé. Si vous placez les données de prétraitement dans cet algorithme de système d'arborescence d'amplification de gradient gradué (lightgbm, etc.), vous pouvez gérer les valeurs manquantes telles qu'elles sont, et vous n'avez pas à pré-traiter les variables catégorielles, ce sera donc un monde relativement convivial pour IQ1. J'ai fait. D'autre part, une recherche de para élevé est trop difficile pour IQ1. C'est très difficile car vous devez savoir ce qu'est chaque para haut du modèle et quelle distance rechercher.

lightgbm_tuner Récemment, optuna a publié un module appelé «optuna.integration.lightgbm_tuner» pour automatiser la recherche haute para de lightgbm. Ce module est également compatible avec IQ1 pour diverses raisons.

  1. Recherche entièrement automatique de para
  2. Recherche par étape (recherche de chaque paramètre), de sorte que vous pouvez rechercher à grande vitesse
  3. Vous pouvez l'utiliser immédiatement en réécrivant le code lightgbm existant à plusieurs endroits (décrit plus loin).

Recherche automatique de haut para IQ1

Veuillez installer la dernière version d'optuna. Je pense que c'était 0.19.0. Entrez avec pip install optuna --upgrade.

Préparation du jeu de données

L'ensemble de données utilisé cette fois est celui des prix des maisons de Kaggle. (https://www.kaggle.com/c/house-prices-advanced-regression-techniques/overview) Cet ensemble de données est un ensemble de données qui prédit le prix de la maison à partir d'informations sur le terrain ou sur le bâtiment.

Tout d'abord, téléchargez les données à l'aide de l'API de kaggle

$ kaggle competitions download -c house-prices-advanced-regression-techniques

Si vous décompressez le zip correctement, train.csv et test.csv apparaîtront. Cette fois, soumettre est ennuyeux, donc je n'utiliserai que train.csv. Vous pouvez utiliser n'importe quel notebook jupyter, alors ouvrez python et lisez-le avec des pandas.

import pandas as pd

df=pd.read_csv("train.csv")
print(df.shape)

.out


(1460, 81)

Nous avons constaté qu'il y avait 81 colonnes dans les 1460 données. Étant donné que le SalePrice qui prédit l'ID est inclus dans cela, le montant de la fonctionnalité qui peut être utilisé est de 79 dimensions.

Supprimons les colonnes qui ne sont pas nécessaires pour le moment et définissons la variable objectif séparément

y=df.SalePrice
X=df.drop(["Id","SalePrice"],axis=1)

Ensuite, vérifiez les valeurs manquantes. Cependant, il ne traite pas car il plonge dans lightgbm. Juste confirmation.

X.loc[:,pd.isnull(X).any(axis=0)].columns

.out


Index(['LotFrontage', 'Alley', 'MasVnrType', 'MasVnrArea', 'BsmtQual',
       'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2',
       'Electrical', 'FireplaceQu', 'GarageType', 'GarageYrBlt',
       'GarageFinish', 'GarageQual', 'GarageCond', 'PoolQC', 'Fence',
       'MiscFeature'],
      dtype='object')

Ensuite, label encode la colonne dont l'élément est «String» en tant que variable catégorielle dans lightgbm, puis définissez dtype sur «category». En un mot, l'encodage des étiquettes remplace simplement la chaîne par une valeur entière afin que les éléments ne soient pas dupliqués.

from sklearn.preprocessing import LabelEncoder

for name in X.columns:
    if X[name].dtype=="object":
        #NaN ne peut pas être entré dans LabelEncoder"NAN"À
        X[name]=X[name].fillna("NAN")
        le = LabelEncoder()
        le.fit(X[name])
        encoded = le.transform(X[name])
        X[name] = pd.Series(encoded).astype('category')

Apprenez avec la lumière ordinaire GBM

Puisque le prétraitement est terminé, laissez lightgbm apprendre. Ce code est quand je me suis précipité dans un gbm léger normal

import lightgbm as lgb
from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=1)

train_dataset=lgb.Dataset(X_train,y_train)
valid_dataset=lgb.Dataset(X_test,y_test,reference=train_dataset)

#Pour la mesure du temps
#%%time
params={"objective":"regression",
                    "learning_rate":0.05}
model=lgb.train(params,
                train_set=train_dataset,
                valid_sets=[valid_dataset],
                num_boost_round=300,
                early_stopping_rounds=50)

.out


...(réduction)...
Early stopping, best iteration is:
[113]	valid_0's l2: 6.65263e+08
CPU times: user 3.11 s, sys: 537 ms, total: 3.65 s
Wall time: 4.47 s

J'ai pu apprendre. Le temps d'apprentissage était de 4,47 secondes. Au fait, lorsque j'ai tracé le résultat de la prédiction, cela ressemblait à ceci. L'axe horizontal est la valeur prédite et l'axe vertical est la valeur vraie. image.png

Apprenez avec lightgbm_tuner

Réécrivez le code ci-dessus pour rechercher IQ1 high para

import lightgbm as lgb
import optuna.integration.lightgbm_tuner as lgb_tuner
from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=1)

train_dataset=lgb.Dataset(X_train,y_train)
valid_dataset=lgb.Dataset(X_test,y_test,reference=train_dataset)

params={"objective":"regression",
                    "learning_rate":0.05,
                    "metric":"l2"}
model=lgb_tuner.train(params,
                      train_set=train_dataset,
                      valid_sets=[valid_dataset],
                      num_boost_round=300,
                      early_stopping_rounds=50)

Savez-vous où il a été réécrit? Recherche d'erreurs dans IQ1.

Les lieux réécrits sont les 3 lieux suivants

  1. Ajouter une instruction d'importation
  2. Passer de «lgb.train» à «lgb_tuner.train»
  3. Ajoutez la valeur «metric» à optimiser en «paramètres»

À propos, le temps d'apprentissage est le suivant. C'était plus lent que prévu ...

.out


CPU times: user 3min 24s, sys: 33.8 s, total: 3min 58s
Wall time: 3min 48s

Le score des données de validation est le suivant.

model.best_score

.out


defaultdict(dict, {'valid_0': {'l2': 521150494.1730755}})

En comparant les résultats de cette expérience, cela ressemble à ceci. Après le réglage, les performances se sont correctement améliorées.

lightgbm lightgbm_tuner
Temps d'étude 4.47 s 228 s
exactitude des données valides(MSE) 6.65263e+08 5.21150e+08

Même si vous regardez l'intrigue, vous pouvez voir que celui avec le prix le plus élevé (celui de droite) est meilleur. image.png

fin

Si vous l'utilisez, il semble que vous puissiez faire du machine learning même avec IQ1! !! Au fait, lorsque j'ai soumis le modèle réalisé avec cela, il était environ 2000e. (Étant donné que le nombre de participants est sample_submission.csv ou plus et 4900 personnes, il y avait beaucoup de personnes avec un QI 1 ou moins)

Postscript

Quand j'ai essayé la recherche de para haut en utilisant optuna dans mon humeur, le score de validation a augmenté, mais le score de soumission s'est un peu détérioré. (Lors de la soumission, réapprendre avec learning_rate = 0.05, num_boosting_round = 1000, early_stopping_rounds = 50) Avez-vous surajusté les données de validation? Après tout, il est difficile de rechercher un para élevé dans IQ1.

** Si vous avez des conseils pratiques d'exploration de haute para, veuillez commenter! !! ** **

La stratégie de réglage cette fois est la suivante.

――Les paramètres qui peuvent être réglés sont alignés dans une large gamme. --Définissez grossièrement learning_rate pour augmenter le nombre d'essais

(Plus le score est bas, mieux c'est)

import optuna

def objective(trial):
    '''
    trial:set of hyperparameter    
    '''
    # hypyer param
    bagging_fraction = trial.suggest_uniform("bagging_fraction",0,1)
    bagging_freq = trial.suggest_int("bagging_freq",0,10)
    feature_fraction = trial.suggest_uniform("feature_fraction",0,1)
    lambda_l1 = trial.suggest_uniform("lambda_l1",0,50)
    lambda_l2 = trial.suggest_uniform("lambda_l2",0,50)
    min_child_samples = trial.suggest_int("min_child_samples",1,50)
    num_leaves = trial.suggest_int("num_leaves",2,50)
    max_depth = trial.suggest_int("max_depth",0,8)
    params={"learning_rate":0.5,
                    "objective":"regression",
                    "bagging_fraction":bagging_fraction,
                    "bagging_freq":bagging_freq,
                    "feature_fraction":feature_fraction,
                    "lambda_l1":lambda_l1,
                    "lambda_l2":lambda_l2,
                    "min_child_samples":min_child_samples,
                    "num_leaves":num_leaves,
                    "max_depth":max_depth}

    model_opt = lgb.train(params,train_set=train_dataset,valid_sets=[valid_dataset],
                          num_boost_round=70,early_stopping_rounds=10)
 
    return model_opt.best_score["valid_0"]["l2"]

study = optuna.create_study()
study.optimize(objective, n_trials=500)
...(réduction)...
[I 2019-12-01 15:02:35,075] Finished trial#499 resulted in value: 537618254.528029. Current best value is 461466711.4731979 with parameters: {'bagging_fraction': 0.9973929186258068, 'bagging_freq': 2, 'feature_fraction': 0.9469601028256658, 'lambda_l1': 10.1589501379876, 'lambda_l2': 0.0306013767707684, 'min_child_samples': 2, 'num_leaves': 35, 'max_depth': 2}.

Le score de validation était de 4,61467e + 08

Recommended Posts

Je ne veux pas rechercher de para haut parce que c'est IQ1 (comment utiliser lightgbm_tuner)
Comment utiliser la recherche triée
[NetworkX] Je souhaite rechercher des nœuds avec des attributs spécifiques
Je ne tweet pas, mais je souhaite utiliser tweepy: affichez simplement les résultats de la recherche sur la console
Je ne savais pas comment utiliser l'instruction [python] for
Je souhaite spécifier un fichier qui n'est pas une certaine chaîne de caractères comme cible logrotate, mais est-ce impossible?
Comparaison des services informatiques GCP [Je souhaite l'utiliser sans serveur]
Comment utiliser l'API Bing Search
Pour le moment en utilisant FastAPI, je veux montrer comment utiliser l'API comme ça dans swagger
Conseils pour manipuler numpy.ndarray à partir de c ++ -Je veux utiliser un itérateur-
Lorsque vous souhaitez l'utiliser tel quel lorsque vous l'utilisez avec lambda memo
Je ne veux pas l'admettre ... Représentation dynamique du système de Neural Network
N'est-il pas recommandé d'utiliser pip directement?
[Pandas] Qu'est-ce que set_option [Comment utiliser]
Je veux savoir comment fonctionne LINUX!
Si vous ne savez pas comment dessiner le graphique que vous voulez avec matplotlib, il est pratique de regarder la galerie
Je veux utiliser jar de python
Je veux utiliser Linux sur mac
[Python] Organisation de l'utilisation des instructions
Comment utiliser "deque" pour les données Python
Comment utiliser l'authentification par empreinte digitale pour KDE
Comment utiliser is et == en Python
python Je ne sais pas comment obtenir le nom de l'imprimante que j'utilise habituellement.
Conseils pour ceux qui ne savent pas comment utiliser is et == en Python
Parce que je ne veux pas sortir avec des gens dont le bureau est sale
Créer un outil de génération de documents Python car il est difficile d'utiliser sphinx
Je veux utiliser MATLAB feval avec python
Comment utiliser Template Engine pour Network Engineer
Je ne veux pas passer un test de codage
Comment utiliser les outils d'analyse de données pour les débutants
Je souhaite utiliser le répertoire temporaire avec Python2
Je veux utiliser le solveur ceres de python
Je souhaite utiliser ip vrf avec SONiC
Comment installer le détecteur Cascade et comment l'utiliser
Je souhaite utiliser la fonction d'activation Mish
Comment utiliser pip, un système de gestion de paquets indispensable pour utiliser Python
[Python] Je souhaite utiliser uniquement l'index lors de la mise en boucle d'une liste avec une instruction for
Comment vérifier s'il est dans le type de dictionnaire (Dictionary, Hash) en utilisant tout ou partie
Je ne sais pas ce qu'est HEIC. Mais pour le moment, utilisons le PNG!