[PYTHON] Prédire les prix des logements (apprentissage automatique: deuxième semestre) ver1.1

introduction

Dans la continuité de la dernière fois, je voudrais cette fois faire une prédiction en combinant divers modèles d'apprentissage automatique pour le problème de la prédiction du prix de l'immobilier (prix de l'immobilier) utilisé comme tutoriel dans kaggle.

Dernière fois https://qiita.com/Fumio-eisan/items/061695b2e3b53ac2a750

Bibliothèque pour l'apprentissage automatique


from sklearn.linear_model import ElasticNet, Lasso,  BayesianRidge, LassoLarsIC
from sklearn.ensemble import RandomForestRegressor,  GradientBoostingRegressor
from sklearn.kernel_ridge import KernelRidge
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import RobustScaler
from sklearn.base import BaseEstimator, TransformerMixin, RegressorMixin, clone
from sklearn.model_selection import KFold, cross_val_score, train_test_split
from sklearn.metrics import mean_squared_error
import xgboost as xgb
import lightgbm as lgb


A propos de la validation croisée du modèle

La validation croisée (CV) est une technique d'estimation des erreurs de prédiction de modèle et est largement utilisée dans l'apprentissage automatique.

  1. Divisez les données d'entraînement en plusieurs parties (chacune appelée pli)
  2. Utilisez l'une d'entre elles comme données de validation et les autres comme données de formation pour l'apprentissage et l'évaluation. Ensuite, le score des données de validation est obtenu.
  3. Modifiez les données de validation autant de fois que le nombre de divisions et répétez l'étape 2.
  4. Évaluez la qualité du modèle en faisant la moyenne de ces scores.

URL de référence https://note.com/naokiwifruit/n/nc90ca48f16e5 https://qiita.com/LicaOka/items/c6725aa8961df9332cc7


n_folds = 5

def rmsle_cv(model):
    kf = KFold(n_folds, shuffle=True, random_state=42).get_n_splits(train.values)
    rmse= np.sqrt(-cross_val_score(model, train.values, y_train, scoring="neg_mean_squared_error", cv = kf))
    return(rmse)

Cette fois, nous mettons en œuvre avec 5 plis.

À propos de l'indice d'évaluation (RMSLE)

RMSLE (Root Mean Squared Logarithmic Error) est cette fois appliquée comme indice d'évaluation. Cette valeur est calculée par la racine carrée de la moyenne des différences après avoir pris chaque log du nouveau terrain et la valeur prédite.

RMSLE = \sqrt{\frac{1}{n}\sum_{i=1}^{n} (log(y_{i}+1)-log(y_{pred}+1))^2} \\
n:nombre\\
y_{i}:La valeur de mesure\\
y_{pred}:Valeur prédite

À propos de la combinaison de modèles

Créez un modèle de prédiction en combinant un total de 6 modèles. L'image est ci-dessous. 012.png

Elastic Net Regression, Kernel Ridge Regession, LASSO Regression et Gradient Boosting Regression sont combinés pour former un modèle moyen empilé. Ensuite, combinez-le avec XGBoost et Litht GBM pour créer les modèles d'ensemble finaux. Il y a de nombreux points peu clairs sur l'optimisation de ces combinaisons, je vais donc continuer à les apprendre et à les résumer.

URL de référence https://blog.ikedaosushi.com/entry/2018/10/21/204842?t=0

Création d'un modèle moyenné empilé


lasso = make_pipeline(RobustScaler(), Lasso(alpha =0.0005, random_state=1))
ENet = make_pipeline(RobustScaler(), ElasticNet(alpha=0.0005, l1_ratio=.9, random_state=3))
KRR = KernelRidge(alpha=0.6, kernel='polynomial', degree=2, coef0=2.5)
GBoost = GradientBoostingRegressor(n_estimators=3000, learning_rate=0.05,
                                   max_depth=4, max_features='sqrt',
                                   min_samples_leaf=15, min_samples_split=10, 
                                   loss='huber', random_state =5)

Tout d'abord, instanciez les modèles de régression LASSO, Elastic Net Regression, Kernel Ridge Regression et Gradient Boosting Regression. Calculez ensuite chaque valeur RMSLE par le modèle.

score = rmsle_cv(lasso)
print("\nLasso score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(ENet)
print("ElasticNet score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(KRR)
print("Kernel Ridge score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))
score = rmsle_cv(GBoost)
print("Gradient Boosting score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))

Lasso score: 0.1115 (0.0074) ElasticNet score: 0.1116 (0.0074) Kernel Ridge score: 0.1153 (0.0075) Gradient Boosting score: 0.1177 (0.0080)

est devenu. Maintenant, faisons un modèle qui rassemble ces modèles. Tout d'abord, simplement moyenne.

class AveragingModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, models):
        self.models = models
        
    # we define clones of the original models to fit the data in
    def fit(self, X, y):
        self.models_ = [clone(x) for x in self.models]
        
        # Train cloned base models
        for model in self.models_:
            model.fit(X, y)

        return self
    
    #Now we do the predictions for cloned models and average them
    def predict(self, X):
        predictions = np.column_stack([
            model.predict(X) for model in self.models_
        ])
        return np.mean(predictions, axis=1)   
averaged_models = AveragingModels(models = (ENet, GBoost, KRR, lasso))

score = rmsle_cv(averaged_models)
print(" Averaged base models score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))

Averaged base models score: 0.1091 (0.0075) Vous pouvez voir que la valeur est meilleure même si elle est simplement moyenne (plus petite est meilleure cette fois).

URL de référence https://blog.ikedaosushi.com/entry/2018/10/21/204842?t=0

class AveragingModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, models):
        self.models = models
        
    # we define clones of the original models to fit the data in
    def fit(self, X, y):
        self.models_ = [clone(x) for x in self.models]
        
        # Train cloned base models
        for model in self.models_:
            model.fit(X, y)

        return self
    
    #Now we do the predictions for cloned models and average them
    def predict(self, X):
        predictions = np.column_stack([
            model.predict(X) for model in self.models_
        ])
        return np.mean(predictions, axis=1)   

averaged_models = AveragingModels(models = (ENet, GBoost, KRR, lasso))

score = rmsle_cv(averaged_models)
print(" Averaged base models score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()))

Averaged base models score: 0.1091 (0.0075)


class StackingAveragedModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, base_models, meta_model, n_folds=5):
        self.base_models = base_models
        self.meta_model = meta_model
        self.n_folds = n_folds
   
    # We again fit the data on clones of the original models
    def fit(self, X, y):
        self.base_models_ = [list() for x in self.base_models]
        self.meta_model_ = clone(self.meta_model)
        kfold = KFold(n_splits=self.n_folds, shuffle=True, random_state=156)
        
        # Train cloned base models then create out-of-fold predictions
        # that are needed to train the cloned meta-model
        out_of_fold_predictions = np.zeros((X.shape[0], len(self.base_models)))
        for i, model in enumerate(self.base_models):
            for train_index, holdout_index in kfold.split(X, y):
                instance = clone(model)
                self.base_models_[i].append(instance)
                instance.fit(X[train_index], y[train_index])
                y_pred = instance.predict(X[holdout_index])
                out_of_fold_predictions[holdout_index, i] = y_pred
                
        # Now train the cloned  meta-model using the out-of-fold predictions as new feature
        self.meta_model_.fit(out_of_fold_predictions, y)
        return self
   
    #Do the predictions of all base models on the test data and use the averaged predictions as 
    #meta-features for the final prediction which is done by the meta-model
    def predict(self, X):
        meta_features = np.column_stack([
            np.column_stack([model.predict(X) for model in base_models]).mean(axis=1)
            for base_models in self.base_models_ ])
        return self.meta_model_.predict(meta_features)
stacked_averaged_models = StackingAveragedModels(base_models = (ENet, GBoost, KRR),
                                                 meta_model = lasso)

score = rmsle_cv(stacked_averaged_models)
print("Stacking Averaged models score: {:.4f} ({:.4f})".format(score.mean(), score.std()))

Stacking Averaged models score: 0.1085 (0.0074) La valeur s'est améliorée un peu plus.

Instanciation du modèle XGBoost


model_xgb = xgb.XGBRegressor(colsample_bytree=0.4603, gamma=0.0468, 
                             learning_rate=0.05, max_depth=3, 
                             min_child_weight=1.7817, n_estimators=2200,
                             reg_alpha=0.4640, reg_lambda=0.8571,
                             subsample=0.5213, silent=1,
                             random_state =7, nthread = -1)

Instanciation du modèle LightGBM

model_lgb = lgb.LGBMRegressor(objective='regression',num_leaves=5,
                              learning_rate=0.05, n_estimators=720,
                              max_bin = 55, bagging_fraction = 0.8,
                              bagging_freq = 5, feature_fraction = 0.2319,
                              feature_fraction_seed=9, bagging_seed=9,
                              min_data_in_leaf =6, min_sum_hessian_in_leaf = 11)
def rmsle(y, y_pred):
    return np.sqrt(mean_squared_error(y, y_pred))

Empiler - Créer un modèle Emsemble

Ce modèle d'apprentissage utilise plusieurs modèles d'apprentissage comme apprentissage d'ensemble. Il s'agit de la somme des versions pondérées (multipliées par coefficient) de chaque modèle de formation.

y_{prediction}=w_{1}∗XGB+w_{2}∗LGB+w_{3}∗StR\\
w_{1}+w_{2}+w_{3} = 1\\
\\
y_{prediction}:Valeur prédite\\
w_{1~3}:coefficient\\
XGB:Valeur prédite par XGB\\
LGB:Valeur prédite par LightGBM\\
StR:Valeur prédite par le régresseur empilé\\

print('RMSLE score on train data:')
print(rmsle(y_train,stacked_train_pred*0.70 +
               xgb_train_pred*0.15 + lgb_train_pred*0.15 ))
ensemble = stacked_pred*0.70 + xgb_pred*0.15 + lgb_pred*0.15

RMSLE score on train data: 0.07530158653663023

Il est tombé à une très petite valeur.

À la fin

Cette fois, le prétraitement des données a été effectué au premier semestre et l'apprentissage au second semestre. En ce qui concerne le prétraitement des données, il a été constaté qu'il s'agissait de gérer les valeurs manquantes et les variables catégorielles dans un état où les données d'apprentissage et les données de test sont combinées. Une bonne gestion des fonctionnalités est un moyen très important de déterminer la précision d'un modèle. J'ai senti qu'il était important non seulement de renseigner les valeurs manquantes, mais aussi de se concentrer sur les relations causales attendues. En ce qui concerne l'apprentissage des modèles, j'ai pu apprendre le concept d'empilement et la méthode d'évaluation de RMSLE. Pour un empilement optimal, il est nécessaire de bien comprendre les caractéristiques de chaque modèle.

Le programme complet est ici. https://github.com/Fumio-eisan/houseprice20200301

Recommended Posts

Prédire les prix des logements (apprentissage automatique: deuxième semestre) ver1.1
Prédiction des prix des logements (prétraitement des données: premier semestre) ver1.1
Un spécialiste du marketing amateur en apprentissage automatique a contesté les prix des maisons de Kaggle (partie 1)
Faire le contrôle d'un homme sandwich par l'apprentissage automatique ver4
Apprentissage automatique
Bibliothèque standard Python: seconde moitié (mémo d'apprentissage Python ⑨)
Prédiction des prix des logements (retour par régression linéaire (kaggle)) ver1.0
[Memo] Apprentissage automatique
Classification de l'apprentissage automatique
Exemple d'apprentissage automatique