[PYTHON] Vorhersage der Immobilienpreise (maschinelles Lernen: zweite Hälfte) ver1.1

Einführung

Ausgehend vom letzten Mal möchte ich diesmal eine Vorhersage treffen, indem ich verschiedene Modelle des maschinellen Lernens für das Problem der Vorhersage des Hauspreises (Hauspreises) kombiniere, der als Tutorial in Kaggle verwendet wird.

Letztes Mal https://qiita.com/Fumio-eisan/items/061695b2e3b53ac2a750

Bibliothek für maschinelles Lernen


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


Informationen zur Kreuzvalidierung des Modells

Die Kreuzvalidierung (CV) ist eine Technik zur Schätzung von Modellvorhersagefehlern und wird häufig beim maschinellen Lernen verwendet.

  1. Teilen Sie die Trainingsdaten in mehrere Teile (jeweils als Falte bezeichnet).
  2. Verwenden Sie eine davon als Validierungsdaten und den Rest als Trainingsdaten zum Lernen und Bewerten. Dann wird die Punktzahl der Validierungsdaten berechnet.
  3. Ändern Sie die Validierungsdaten so oft wie die Anzahl der Unterteilungen und wiederholen Sie Schritt 2.
  4. Bewerten Sie die Qualität des Modells, indem Sie diese Werte mitteln.

Referenz-URL 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)

Dieses Mal implementieren wir mit 5 Falten.

Informationen zum Bewertungsindex (RMSLE)

Diesmal wird RMSLE (Root Mean Squared Logarithmic Error) als Bewertungsindex angewendet. Dieser Wert wird durch die Quadratwurzel des Durchschnitts der Differenzen berechnet, nachdem jedes Protokoll des neuen Landes und der vorhergesagte Wert genommen wurden.

RMSLE = \sqrt{\frac{1}{n}\sum_{i=1}^{n} (log(y_{i}+1)-log(y_{pred}+1))^2} \\
n:Nummer\\
y_{i}:Gemessener Wert\\
y_{pred}:Voraussichtlicher Wert

Über die Kombination von Modellen

Erstellen Sie ein Vorhersagemodell, indem Sie insgesamt 6 Modelle kombinieren. Das Bild ist unten. 012.png

Die elastische Netzregression, die Kernel-Ridge-Regression, die LASSO-Regression und die Gradienten-Boosting-Regression werden kombiniert, um ein gestapeltes gemitteltes Modell zu bilden. Kombinieren Sie es dann mit XGBoost und Litht GBM, um die endgültigen Ensemble-Modelle zu erstellen. Es gibt viele unklare Punkte bei der Optimierung dieser Kombinationen, daher werde ich sie weiter lernen und zusammenfassen.

Referenz-URL https://blog.ikedaosushi.com/entry/2018/10/21/204842?t=0

Erstellen eines gestapelten gemittelten Modells


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)

Instanziieren Sie zunächst die Modelle LASSO-Regression, Elastic Net Regression, Kernel Ridge Regression und Gradient Boosting Regression. Berechnen Sie dann jeden RMSLE-Wert für das Modell.

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)

ist geworden. Lassen Sie uns nun ein Modell erstellen, das diese Modelle sammelt. Erstens einfach durchschnittlich.

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) Sie können sehen, dass der Wert besser ist, auch wenn er einfach gemittelt wird (diesmal ist kleiner besser).

Referenz-URL 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) Der Wert hat sich etwas weiter verbessert.

XGBoost-Modellinstanziierung


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)

Instanziierung des LightGBM-Modells

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))

Stapeln - Erstellen Sie ein Emsemble-Modell

Dieses Lernmodell verwendet mehrere Lernmodelle als Ensemble-Lernen. Dies ist die Summe der gewichteten (koeffizientenmultiplizierten) Versionen jedes Trainingsmodells.

y_{prediction}=w_{1}∗XGB+w_{2}∗LGB+w_{3}∗StR\\
w_{1}+w_{2}+w_{3} = 1\\
\\
y_{prediction}:Voraussichtlicher Wert\\
w_{1~3}:Koeffizient\\
XGB:Voraussichtlicher Wert von XGB\\
LGB:Voraussichtlicher Wert von LightGBM\\
StR:Voraussichtlicher Wert von Stacked Regressor\\

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

Es ist auf einen sehr kleinen Wert gefallen.

Am Ende

Dieses Mal wurde die Datenvorverarbeitung in der ersten Hälfte und das Lernen in der zweiten Hälfte durchgeführt. In Bezug auf die Datenvorverarbeitung wurde festgestellt, dass es darum geht, fehlende Werte und kategoriale Variablen in einem Zustand zu behandeln, in dem Trainingsdaten und Testdaten kombiniert werden. Der richtige Umgang mit Features ist ein sehr wichtiger Weg, um die Genauigkeit eines Modells zu bestimmen. Ich fand es wichtig, nicht nur die fehlenden Werte auszufüllen, sondern sich auch auf die erwarteten Kausalzusammenhänge zu konzentrieren. In Bezug auf das Modelllernen konnte ich das Konzept des Stapelns und die Bewertungsmethode von RMSLE lernen. Für ein optimales Stapeln ist es notwendig, die Eigenschaften jedes Modells genau zu verstehen.

Das vollständige Programm finden Sie hier. https://github.com/Fumio-eisan/houseprice20200301

Recommended Posts

Vorhersage der Immobilienpreise (maschinelles Lernen: zweite Hälfte) ver1.1
Vorhersage der Immobilienpreise (Datenvorverarbeitung: erstes Halbjahr) ver1.1
Amateur-Vermarkter für maschinelles Lernen forderten Kaggles Hauspreise heraus (Teil 1)
Kontrolle eines Sandwich-Mannes durch maschinelles Lernen ver4
Maschinelles Lernen
Python-Standardbibliothek: zweite Hälfte (Python-Lernnotiz ⑨)
Vorhersage der Immobilienpreise (Rendite durch lineare Regression (kaggle)) ver1.0
[Memo] Maschinelles Lernen
Klassifikation des maschinellen Lernens
Beispiel für maschinelles Lernen