0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kaggle「House Prices」の分析を通して

Posted at

1.はじめに

実務では教育用データを扱っていますがそこには連続値だけでなくカテゴリ変数も多くあります。
例えば「英語がどのくらい得意か」「授業理解度が概ね満足しているかしていないか」など
Kaggleにはあまり教育データがないので代用として「House Prices - Advanced Regression Techniques」のデータを使い、「ベースライン → 特徴量エンジニアリング → モデルの改善 → アンサンブル」 と段階を踏んで精度を高めていきました。
また実務ではよくあるドキュメントの知識を使って特徴量エンジニアリングをするのでそこも意識しています。

この記事では、そのステップごとの工夫と改善プロセスを紹介します。

完成版コード:GitHub

2.分析内容

Step 1: データの可視化とEDA

データ読み込み

python
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
train.describe()
corr = train.corr()
sns.histplot(train["SalePrice"], kde=True)
sns.heatmap(corr, cmap="coolwarm", annot=False)

※ 最初に相関を可視化することで「どの特徴量がSalePriceと強い関係があるか」を把握。
※ 目的変数の歪みを確認→対数変換を実施
※ OverallQual(家の品質評価)と目的変数(SalePrice)にはある程度強い正の相関があること、OverallQualが上がると価格が一気に上昇することを可視化で確認
→ベースラインに使用検討

GitHub:01_EDA_and_Preprocessing

Step 2: 線形回帰・対数変換のベースライン

python
# OverallQualだけを使った単回帰
folds = KFold(n_splits=n_splits, shuffle=True, random_state=random_state)
X = train[["OverallQual"]]
y = np.log1p(train["SalePrice"])
def rmsle(y_true, y_pred):
    y_pred[y_pred < 0] = 0
    return np.sqrt(mean_squared_log_error(y_true, y_pred))
linearmodel = LinearRegression()

※ ベースライン(面積のみLinear)のRMSLE: 0.23(CV)

GitHub:02_Baseline_Linear

Step 3:LightGBMのベースライン

まずはデータをそのままLightGBMに学習させてみます。
(欠損値や外れ値の処理は一切しません)

python
import lightgbm as lgb
model = lgb.LGBMRegressor()
model.fit(X_train, np.log1p(y_train))
preds = np.expm1(model.predict(X_valid))
print("Baseline RMSLE:", rmsle(y_valid, preds))

※ ベースライン(面積のみlgbm)のRMSLE: 0.23(CV)
※ 線形回帰・対数変換とスコアが変わらず→アンサンブルも検討

Step 4: lgbmにおけるSHAP値の確認

LabelEncodingを行い、
各重要度のSHAP値を可視化し、すべての変数(Idと目的変数は除く)を説明変数としたときの精度も確認

python
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
shap.summary_plot(shap_values, X, max_display=max_display)

※ OverallQual,GrLivAreaなど重要度が高い変数を確認
※ labellgbmのRMSLE:0.1305(CV)
  0.23 → 0.1305まで向上
※ その後、説明変数を重要度が高い変数のみで同じくモデル化しても精度はほぼ変わらず
image.png

GitHub:03_Label_Lgbm_SHAP

Step 5: 特徴量エンジニアリング

住宅価格に効きそうな特徴量を作成します。

特徴量の追加

python
TotalSF = GrLivArea + TotalBsmtSF
OverallQual × GrLivArea
def create_features(df):
    df['TotalSF'] = df['GrLivArea'] + df['TotalBsmtSF']
    df['OverallQual_x_GrLivArea'] = df['OverallQual'] * df['GrLivArea']
    return df

欠損値処理

次に欠損値を補完します。
Garage や Basement の欠損は「存在しない」と解釈して None や 0 に。
LotFrontage は Neighborhood ごとの中央値で補完。

python
def fill_missing_values(df):
    df['GarageType'] = df['GarageType'].fillna('None')
    df['GarageCars'] = df['GarageCars'].fillna(0)
    df['LotFrontage'] = df.groupby('Neighborhood')['LotFrontage'].transform(lambda x: x.fillna(x.median()))
    return df

外れ値の除去

GrLivArea > 4000 なのに SalePrice < 300000 という極端なデータを除外します。

python
train = train.drop(train[(train['GrLivArea'] > 4000) & (train['SalePrice'] < 300000)].index)

image.png

※ 特徴量エンジニアリング後のRMSLE: 0.1301(CV)
※ 0.1305 → 0.1301へ

GitHub:04_Feature_Engineering

Step 6: One-Hot化と線形モデルの追加(Ridge/Lasso)

非線形モデルだけでなく、リッジ回帰やラッソ回帰も試してみました。
シンプルながら、カテゴリ変数のOne-Hot化との相性が良いです。

python
from sklearn.linear_model import Ridge, Lasso
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, np.log1p(y_train))
ridge_preds = np.expm1(ridge.predict(X_valid))
combined = pd.concat([X_train, test], axis=0).reset_index(drop=True)
combined = pd.get_dummies(combined, dummy_na=True)

Step 7: アンサンブル

LightGBM・Ridge・Lassoを組み合わせて最終的なアンサンブルを構築しました。

python
ridge_oof, lasso_oof = run_linear_models(X_train, y_train_log)
lgbm_cv_rmsle, lgbm_oof, lgbm_model = run_lgbm_cv(X_train, y_train)
ensemble_oof = (lgbm_oof * 0.5 + ridge_oof * 0.25 + lasso_oof * 0.25)

※ 結果: Ensemble RMSLE 0.115(CV)
Kaggle Testデータでは 0.131 でした。

GitHub:Final_Ensemble_Model

3.まとめ

特徴量エンジニアリングをしていると、「この変数を新しく作ると精度あがるかな」と思っても全く制度が変わらなかったり、逆にhotencodingするだけで精度が格段に向上したりと、やってみないとわからない面白さ・奥の深さを改めて実感しました。
なぜその作業をするのか、1つ1つ説明できるようにさらに技量をあげていきたい

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?