[PYTHON] Prix des logements: techniques de régression avancées

0.Intro C'est difficile de tout commencer, et puis je pense que c'est une montagne pour l'amener à un endroit où «c'est ma propre forme» et «un peu tout à fait». Il semble qu'il ait soumis Titanic il y a 7 mois. Cela fait plus de six mois depuis. Ce n'est pas que je n'ai rien fait, mais je n'ai pas pu avoir assez de temps. Cependant, heureusement ou malheureusement, j'ai eu un peu de longues vacances (environ un mois), alors j'ai voulu profiter de cette occasion pour façonner quelque chose à la manière de Kaggle, alors j'ai repris mes efforts. En conséquence, j'ai pu créer une seule forme, j'ai donc décidé de l'écrire sous forme d'article.

1. Avant de commencer

L'apprentissage automatique doit être de la programmation, mais il semble être assez différent de la programmation dite ordinaire. Après tout, la programmation ordinaire est flagrante sur les données, mais comme vous le savez, la programmation d'apprentissage automatique a un poids extrêmement important de traitement de données. Par conséquent, il a fallu un certain temps pour que le travail soit réalisé d'une manière parfaitement adaptée.

1.1. Environnement de développement

J'ai mis Ubuntu dans WSL sur Windows 10 cette fois et y ai construit l'environnement d'Anaconda. Le codage et l'exécution du code sont effectués avec VScode, et la confirmation des données, etc. est effectuée avec le notebook Jupyter. Ce serait dommage si nous pouvions le développer fermement à l'avenir, mais comme il existe une machine serveur avec un grappin, j'aimerais déplacer l'environnement de développement vers cela.

1.2. Structure du code

Si vous ne pouvez pas imaginer tout le code, cela signifie que vous ne pouvez pas imaginer ce que vous allez faire, et vous ne pouvez pas faire du bon travail avec cela. Résultats du référencement de divers noyaux Kaggle

def feature_create(train,test):
#Nettoyage des données
#Créer des données telles que la simulation de variables

def model_create(train):
#Divisez les données créées en variables objectives et autres,
#Standardisez et créez un modèle.


if __name__ == "__main__":
#Logique principale, importer les données ici et la fonction ci-dessus
#feature_create(train,test)Et modèle_create(train)Appel
#Enfin, appliquez le modèle aux données de test et obtenez le résultat de la prédiction
#Créez des données csv à soumettre.

Sous la forme de, le contour est composé de trois étapes. Je viens d'ajouter quelques sous-programmes cette fois, mais il semble que les fonctions principale et deux peuvent être utilisées.

1.3. Style de développement

Le développement de l'apprentissage automatique est fortement orienté vers la manière de traiter les données, il n'est donc pas possible de continuer en regardant uniquement l'éditeur. À la suite de divers essais et erreurs, le formulaire consiste à vérifier les données avec le notebook Jupyter, à vérifier le code pour modifier les données et à ajouter le code réussi à la fonction feature_create dans la configuration ci-dessus. Ça avait l'air bien.

2. Programme complet

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import  cross_val_score

def feature_create(train,test):
    df_train = train.copy()
    df_test = test.copy()
    df_train["evel_set"] = 0
    df_test["evel_set"] = 1
    df_temp = pd.concat([df_train,df_test])
    del df_train,df_test
    df_temp.drop(["MiscFeature","MiscVal","PoolQC","PoolArea","Fireplaces","FireplaceQu","Alley","Fence"],axis=1,inplace=True)
    df_temp["MasVnrType"][df_temp["MasVnrType"].isnull()==True]="None"
    df_temp["MasVnrArea"][df_temp["MasVnrArea"].isnull()==True] = df_temp["MasVnrArea"].mean()
    df_temp["BsmtQual"][df_temp["BsmtQual"].isnull()==True] = "TA"
    df_temp["BsmtCond"][df_temp["BsmtCond"].isnull()==True] = "TA"
    df_temp["BsmtExposure"][df_temp["BsmtExposure"].isnull()==True] = "No"
    df_temp["BsmtFinType1"][df_temp["BsmtFinType1"].isnull()==True] = "Unf"
    df_temp["BsmtFinType2"][df_temp["BsmtFinType2"].isnull()==True] = "Unf"
    df_temp["Electrical"][df_temp["Electrical"].isnull()==True] = "SBrkr"
    df_temp["GarageType"][df_temp["GarageType"].isnull()==True] = "Attchd"
    df_temp["GarageYrBlt"][df_temp["GarageYrBlt"].isnull()==True] = df_temp["GarageYrBlt"][df_temp["GarageYrBlt"] > 2000].mean()
    df_temp["GarageFinish"][df_temp["GarageFinish"].isnull()==True] = "Unf"
    df_temp["GarageQual"][df_temp["GarageQual"].isnull()==True] = "TA"
    df_temp["GarageCond"][df_temp["GarageCond"].isnull()==True] = "TA"
    df_temp["BsmtFinSF1"][df_temp["BsmtFinSF1"].isnull()==True] = 0
    df_temp["BsmtFinSF2"][df_temp["BsmtFinSF2"].isnull()==True] = 0
    df_temp["BsmtFullBath"][df_temp["BsmtFullBath"].isnull()==True] = 0
    df_temp["BsmtHalfBath"][df_temp["BsmtHalfBath"].isnull()==True] = 0
    df_temp["BsmtUnfSF"][df_temp["BsmtUnfSF"].isnull()==True] = 0
    df_temp["Exterior1st"][df_temp["Exterior1st"].isnull()==True] = "VinylSd"
    df_temp["Exterior2nd"][df_temp["Exterior2nd"].isnull()==True] = "VinylSd"
    df_temp["Functional"][df_temp["Functional"].isnull()==True] = "Typ"
    df_temp["GarageArea"][df_temp["GarageArea"].isnull()==True] = 576
    df_temp["GarageCars"][df_temp["GarageCars"].isnull()==True] = 2
    df_temp["KitchenQual"][df_temp["KitchenQual"].isnull()==True] = "TA"
    df_temp["LotFrontage"][df_temp["LotFrontage"].isnull()==True] = 60
    df_temp["MSZoning"][df_temp["MSZoning"].isnull()==True] = "RL"
    df_temp["SaleType"][df_temp["SaleType"].isnull()==True] = "WD"
    df_temp["TotalBsmtSF"][df_temp["TotalBsmtSF"].isnull()==True] = 0
    df_temp["Utilities"][df_temp["Utilities"].isnull()==True] = "AllPub"

    #df_temp.drop(["MSSubClass","MSZoning","Street","LotShape","LandContour","Utilities","LotConfig","LandSlope","Neighborhood","Condition1","Condition2","BldgType","HouseStyle","OverallCond","RoofStyle","RoofMatl","Exterior1st","Exterior2nd","MasVnrType","ExterQual","ExterCond","Foundation","BsmtQual","BsmtCond","BsmtExposure","BsmtFinType1","BsmtFinType2","BsmtFinSF2","BsmtUnfSF","Heating","HeatingQC","CentralAir","Electrical","LowQualFinSF","BsmtFullBath","BsmtHalfBath","HalfBath","BedroomAbvGr","KitchenAbvGr","KitchenQual","Functional","GarageType","GarageYrBlt","GarageFinish","GarageQual","GarageCond","PavedDrive","EnclosedPorch","3SsnPorch","ScreenPorch","MoSold","YrSold","SaleType","SaleCondition"],axis=1,inplace=True)

    df_temp = pd.get_dummies(df_temp)
    
    df_train = df_temp[df_temp["evel_set"]==0]
    df_test = df_temp[df_temp["evel_set"]==1]
    df_train.drop("evel_set",axis=1,inplace=True)
    df_test.drop("evel_set",axis=1,inplace=True)
    del df_temp
    return df_train,df_test

def model_create(train):
    sc_x = StandardScaler()
    sc_y = StandardScaler()
    x_train = train
    y_train = train["SalePrice"]
    x_train.drop("SalePrice",axis=1,inplace=True)
    x_train.drop("Id",axis=1,inplace=True)

    x_train_std = sc_x.fit_transform(x_train)
    y_train_std = sc_y.fit_transform(y_train[:,np.newaxis]).flatten()

    gbrt = GradientBoostingRegressor(n_estimators=1000, learning_rate=.03, max_depth=3, max_features=.04, min_samples_split=4,
                                    min_samples_leaf=3, loss='huber', subsample=1.0, random_state=0)
    cv_gbrt = rmse_cv(gbrt,x_train_std, y_train_std)
    gbrt.fit(x_train_std, y_train_std)
    print('GradientBoosting CV score min: ' + str(cv_gbrt.min()) + ' mean: ' + str(cv_gbrt.mean()) 
        + ' max: ' + str(cv_gbrt.max()) )

    return gbrt,sc_y


def rmse_cv(model,X,y):
    rmse = np.sqrt(-cross_val_score(model, X, y, scoring = "neg_mean_squared_error", cv = 5))
    return(rmse)


if __name__ == "__main__":
    df_train_org = pd.read_csv("~/kaggle_train/House_Prices_Advanced/train.csv")
    df_test_org = pd.read_csv("~/kaggle_train/House_Prices_Advanced/test.csv")

    df_train,df_test = feature_create(df_train_org,df_test_org)
    del df_train_org,df_test_org
    
    model,scaler = model_create(df_train)
    sc_x = StandardScaler()
    df_test_Id = df_test["Id"]
    df_test = df_test.drop("Id",axis=1)
    df_test.drop("SalePrice",axis=1,inplace=True)

    df_test_std = sc_x.fit_transform(df_test)
    pred = model.predict(df_test_std)
    pred = scaler.inverse_transform(pred)
    df_sub_pred = pd.DataFrame(pred).rename(columns={0:"SalePrice"})
    df_submit = pd.DataFrame({
        "Id": df_test_Id,
        "SalePrice": df_sub_pred["SalePrice"]
    })
    df_submit.to_csv('submission.csv', index=False)

2.1.feature_create Comme mentionné ci-dessus, j'ai utilisé la méthode de vérification du code avec le bloc-notes Jyupter et de collage du code réussi dans cette fonction. Le cahier Jyupter que j'ai créé localement en travaillant était comme ça. House_Prices_Advanced_Regression_Techniques

Tout d'abord, les données d'entraînement et les données de test sont combinées, mais de nombreuses personnes les combinent telles quelles, et les données d'entraînement et les données de test sont divisées en fonction du nombre de cas car l'ordre est garanti. Cependant, personnellement, cela semble un peu désagréable, j'ai donc créé une colonne appelée "evel_set" et stocké les données d'entraînement sur 0 et les données de test sur 1. Plus tard, j'ai adopté la méthode de division de la colonne en m'appuyant sur elle, puis en laissant tomber la colonne.

Le nettoyage des données cette fois n'est que l'achèvement des données manquantes. Pour les valeurs de catégorie

  1. Vérifiez le type de données existantes et le nombre de fois qu'elles apparaissent.
  2. Entrez la valeur la plus fréquente Est répété. Dans le cas de valeurs numériques, j'entre parfois la valeur moyenne.

Je sais que je dois faire plus, mais j'aimerais en faire ma prochaine tâche.

Quant à la dernière carte de chaleur, j'ai mis les données préparées au début dans la fonction de carte de chaleur telle quelle. Cependant, la bonne réponse était de passer df_temp.corr () et un DataFrame avec uniquement le coefficient de corrélation à la fonction de carte thermique. Cela a également été monté seul.

En outre, dans DataFrame, vous pouvez voir tous les noms de colonnes, le nombre de valeurs non NAN (c'est-à-dire le nombre de NAN) et le type avec info (). Je le savais pour la première fois cette fois.

2.2.model_create

Obtention des données d'entraînement préparées, mise toutes les données d'entraînement dans la variable objective "SalePrice" y_train une fois, et suppression du "Id" inutile et de la variable objective "SalePrice" comme variables dépendantes. Vient ensuite la normalisation. Cette fois, j'ai utilisé Standard Scaler. À cette époque, au début, seul x_train était standardisé et y_train était resté tel quel. En conséquence, cela n'est pas devenu une valeur d'évaluation décente ... Lorsque x_train et y_train ont été normalisés, cela est devenu une valeur décente. C'était un piège.

Cette fois, j'utilise le code que j'ai choisi pour la modélisation. En fait, je devrais trouver les paramètres par moi-même par recherche de grille, etc., mais cette fois je l'ai plié.

2.3.if name == "main": Les données elles-mêmes sont lues et transmises à la fonction feature_create. Transmettez les données modifiées renvoyées au model_create suivant pour obtenir un instant StandardScaler qui renvoie le modèle entraîné et les objectifs standardisés. Modifiez ensuite les données de prévision. Étant donné que l'identifiant des données de test est nécessaire pour la soumission, il n'est pas nécessaire pour la sauvegarde et la prévision, alors supprimez-le. De plus, "Prix de vente", qui ne devrait pas être vrai lors de la première inscription, est également créé sous forme de colonne, alors supprimez-le également. StandardScaler n'est-il pas une spécification qui autorise inverse_transform uniquement pour les données dans le même format de données après un ajustement unique? Cette fois, j'ai fait une façon un peu maladroite de le réaliser en obtenant une instance de fit_transformed y_train. Puisque model.predict renvoie un tableau unidimensionnel, une autre instance peut-elle être inverted_transform après avoir ajusté un tableau unidimensionnel approprié? Je voudrais réessayer (plutôt, je devrais vérifier comment utiliser correctement Standard Scaler). Convertissez la valeur prédite en DataFrame avec un nom de colonne. Créez un DataFrame pour Soumettre. Créez avec DataFrame tel quel avec le "Prix de vente" de DataFrame qui contient l'ID et la valeur prévue des données de test enregistrées précédemment. La gamme est garantie, c'est donc un moyen de réussir. Le reste est sorti avec to_csv et la fin.

3. Résultat

EfS3QVZUEAAiGsD.jpg Le résultat était que. Puisqu'il est 1638e sur 5222, je sens que je participe correctement, donc je pense que je peux obtenir un prix de participation w Le résultat du [Concours des prix du logement pour les utilisateurs de Kaggle Learn] soumis il y a 8 mois était d'environ 43000 sur 43230, il semble donc qu'il vaut mieux ne rien faire, donc je pense qu'il a fait beaucoup de progrès à partir de là.

3.1. Problèmes futurs

Puisque la classification est abordée par Titanic, je voudrais travailler sur des données de séries chronologiques. Après cela, j'aimerais vraiment exécuter EDA et pouvoir ajuster les données et ajouter de nouvelles fonctionnalités. Ensuite, j'aimerais passer au Deep Learning. Mais il vaut peut-être mieux passer à l'analyse des données en termes de travail, mais w

Recommended Posts

Prix des logements: techniques de régression avancées
Challenge Kaggle [Prix de la maison]
Prix Kaggle House ③ ~ Prévisions / Soumission ~
Apprendre avec l'enseignant (retour) 2 édition avancée
Prix des maisons Kaggle ① ~ Ingénierie des fonctionnalités ~