実施日: 2025年12月14日
コンペティション: Kaggle House Prices Advanced Regression Techniques
目標: 住宅価格予測モデルの構築と精度向上
本コンペティションは、アメリカ・アイオワ州エイムズ市の住宅販売データを用いて、住宅価格を予測する機械学習モデルを構築するものです。住宅価格予測は不動産業界において極めて重要な課題であり、適切な価格設定は売買双方にとって公平な取引を実現します。
住宅価格は単一の要因で決まるものではなく、立地(近隣地域の質、学区、交通アクセス)、物理的特性(広さ、築年数、部屋数、設備)、市場要因(経済状況、季節性)など、多数の要因が複雑に絡み合って決定されます。これらの要因を適切にモデル化することで、精度の高い価格予測が可能になります。
エイムズ市のデータセットは、2006年から2010年にかけての住宅販売記録を含んでおり、実際の不動産市場を反映した現実的なデータセットとなっています。このデータセットは、Dean De Cock教授によって教育目的で作成され、従来のボストン住宅データセットに代わる現代的なデータセットとして広く使用されています。
コンペティションで提供されるデータは以下の通りです。
| ファイル | 件数 | 説明 |
|---|---|---|
| train.csv | 1,460件 | 学習用データ(価格情報あり) |
| test.csv | 1,459件 | テスト用データ(価格情報なし) |
| sample_submission.csv | 1,459件 | 提出フォーマットのサンプル |
| data_description.txt | - | 各特徴量の詳細説明 |
データセットには80個の特徴量が含まれており、数値特徴量が37個、カテゴリ特徴量が43個あります。数値特徴量には、床面積(GrLivArea、TotalBsmtSF、1stFlrSF、2ndFlrSFなど)、築年数(YearBuilt、YearRemodAdd)、部屋数(BedroomAbvGr、KitchenAbvGr)、品質評価(OverallQual、OverallCond)などが含まれます。
カテゴリ特徴量には、近隣地域(Neighborhood:25種類の地域)、建物タイプ(BldgType:一戸建て、タウンハウスなど)、外装材(Exterior1st、Exterior2nd)、屋根材(RoofStyle、RoofMatl)、基礎タイプ(Foundation)、暖房タイプ(Heating)、ガレージタイプ(GarageType)などが含まれます。
データの特徴として、欠損値が多数存在します。例えば、PoolQC(プール品質)は99.5%が欠損、MiscFeature(その他設備)は96.3%が欠損、Alley(路地アクセス)は93.8%が欠損しています。これらの欠損は、該当する設備が存在しないことを意味する場合が多く、欠損値処理が重要な前処理ステップとなります。
予測精度は**RMSE(Root Mean Squared Error)**で評価されます。ただし、価格の対数変換後の値に対してRMSEを計算します。
RMSE = sqrt(mean((log(predicted) - log(actual))^2))
この評価方法には重要な意味があります。通常のRMSEでは、高額物件の予測誤差が低額物件の予測誤差よりも大きく評価されてしまいます。例えば、10万ドルの物件を9万ドルと予測した場合(誤差1万ドル)と、50万ドルの物件を49万ドルと予測した場合(誤差1万ドル)では、相対的な誤差率は前者が10%、後者が2%ですが、通常のRMSEでは同じ1万ドルの誤差として扱われます。
対数変換を行うことで、相対的な誤差率を評価できるようになります。log(90000) - log(100000) ≈ -0.105とlog(490000) - log(500000) ≈ -0.020では、前者の方が大きな誤差として評価されます。これにより、高額物件と低額物件の予測誤差が公平に評価され、モデルは全価格帯で均等に良好な予測を行うよう学習されます。
全ての実験で統一した前処理を適用しました。
データ型に応じて異なる戦略を採用しました。
数値データは中央値(median)で補完しました。中央値を選択した理由は、外れ値の影響を受けにくいためです。平均値(mean)を使用すると、極端に大きな値や小さな値に引っ張られてしまいます。例えば、LotAreaの平均値は10,516.8平方フィートですが、中央値は9,478平方フィートです。最大値が215,245平方フィートという極端な外れ値が存在するため、平均値は実際の典型的な値よりも大きくなっています。
カテゴリデータは"Missing"という文字列で補完しました。これは、欠損自体が情報になる場合があるためです。例えば、PoolQC(プール品質)が欠損している場合、それは「プールが存在しない」ことを意味します。"Missing"という明示的なカテゴリを作成することで、モデルはこの情報を学習できます。
| データ型 | 処理方法 | 理由 |
|---|---|---|
| 数値 | 中央値で補完 | 外れ値の影響を受けにくい |
| カテゴリ | "Missing"で補完 | 欠損自体が情報になる場合がある |
ドメイン知識に基づいて4つの派生特徴量を作成しました。
TotalSFは、地下室面積(TotalBsmtSF)、1階面積(1stFlrSF)、2階面積(2ndFlrSF)を合計した総床面積です。この特徴量を作成した理由は、住宅価格は個別の階の面積よりも総床面積と強い相関があると考えられるためです。
実際、TotalSFの特徴量重要度は0.087で、全特徴量中3位となりました。これは、元の個別面積特徴量(TotalBsmtSF: 0.042、1stFlrSF: 0.039)よりも高い重要度です。総床面積という統合された指標が、モデルにとってより有用な情報となったことが分かります。
HouseAgeは、売却年(YrSold)から建築年(YearBuilt)を引いた築年数です。一般的に、築年数が古いほど住宅価格は下がる傾向があります。ただし、歴史的価値のある住宅や、適切にメンテナンスされた住宅は例外となる場合があります。
元のYearBuilt特徴量は建築年そのものですが、HouseAgeは売却時点での築年数を表します。これにより、時間経過による価値の減少をより直接的に表現できます。HouseAgeの特徴量重要度は0.029で、トップ10に入りました。
RemodAgeは、売却年(YrSold)からリフォーム年(YearRemodAdd)を引いた、リフォームからの経過年数です。リフォームは住宅価値を向上させますが、その効果は時間とともに減少します。最近リフォームされた住宅は、古いリフォームの住宅よりも高い価値を持つ傾向があります。
YearRemodAddは、リフォームが行われていない場合はYearBuiltと同じ値になります。RemodAgeを計算することで、リフォームの新しさを数値化できます。
TotalBathは、フルバスルーム(BsmtFullBath、FullBath)とハーフバスルーム(BsmtHalfBath、HalfBath)を合計した総バスルーム数です。ハーフバスルームは0.5として計算しました。
バスルーム数は住宅の快適性と価値に直接影響します。複数のバスルームがある住宅は、家族構成が大きい場合や、ゲストを頻繁に招く場合に便利です。個別のバスルーム数よりも、総数として統合することで、モデルにとってより理解しやすい特徴量となります。
| 特徴量 | 計算式 | 意図 | 重要度 |
|---|---|---|---|
| TotalSF | 地下+1階+2階の床面積 | 総床面積が価格に影響 | 0.087(3位) |
| HouseAge | 売却年 - 建築年 | 築年数が価格に影響 | 0.029(10位) |
| RemodAge | 売却年 - リフォーム年 | リフォームからの経過年数 | - |
| TotalBath | 全バスルーム数の合計 | バスルーム数が価格に影響 | - |
43個のカテゴリ特徴量をOne-Hot Encodingで数値化しました。One-Hot Encodingは、カテゴリ変数を機械学習モデルが理解できる数値形式に変換する標準的な手法です。
例えば、Neighborhood(近隣地域)という特徴量は、"CollgCr"、"Veenker"、"Crawfor"など25種類の値を持ちます。One-Hot Encodingでは、各値に対して個別のバイナリ特徴量を作成します。"CollgCr"の住宅の場合、Neighborhood_CollgCr=1、他の全てのNeighborhood_*=0となります。
One-Hot Encodingの利点は、カテゴリ間に順序関係を仮定しないことです。例えば、Label Encoding("CollgCr"=0、"Veenker"=1、"Crawfor"=2など)を使用すると、モデルは"Veenker"が"CollgCr"と"Crawfor"の中間であると誤解する可能性があります。One-Hot Encodingでは、各カテゴリが独立した特徴量として扱われます。
この結果、最終的に314個の特徴量を使用しました(元の数値37個 + 派生数値4個 + One-Hot化カテゴリ273個)。特徴量数が増加すると、モデルの複雑性が増し、過学習のリスクが高まりますが、LightGBMは正則化機能により過学習を抑制できます。
価格の分布を正規化するため、log1p変換を適用しました。log1p(x) = log(1 + x)は、xが0の場合でも定義される対数変換です(通常のlog(x)はx=0で未定義)。
住宅価格の分布は、通常、右に歪んだ分布(right-skewed distribution)を示します。つまり、低価格帯に多くのデータが集中し、高価格帯に少数の外れ値が存在します。このような分布では、線形回帰や勾配ブースティングなどのモデルが適切に学習できません。
log1p変換により、分布を正規分布に近づけることができます。これにより、モデルは全価格帯で均等に学習でき、予測精度が向上します。学習時にはy_train = log1p(SalePrice)として対数変換し、予測時にはSalePrice = expm1(prediction)として元のスケールに戻しました。expm1(x) = exp(x) - 1は、log1pの逆変換です。
機械学習モデルとしてLightGBMを使用しました。LightGBMは、Microsoft社が開発した勾配ブースティングフレームワークで、以下の特徴があります。
LightGBMは、Histogram-based algorithmとLeaf-wise tree growthを採用しており、従来のXGBoostよりも高速です。Kaggleコンペティションで多くの優勝実績があり、表形式データに対して優れた性能を発揮します。
基本設定: objective=regression, metric=rmse, learning_rate=0.05, n_estimators=20000, num_leaves=31, max_depth=-1, min_child_samples=20, subsample=0.8, colsample_bytree=0.8, early_stopping_rounds=100
5-Fold KFoldで交差検証を実施しました。
データを5分割し、各Foldで訓練データ80%(4/5)、検証データ20%(1/5)として学習と評価を行いました。5回の学習を行い、各回で異なるFoldを検証データとして使用します。最終スコアは5つのFoldの平均RMSEとしました。
Fold 1: [Train: Fold 2,3,4,5] [Validation: Fold 1]
Fold 2: [Train: Fold 1,3,4,5] [Validation: Fold 2]
Fold 3: [Train: Fold 1,2,4,5] [Validation: Fold 3]
Fold 4: [Train: Fold 1,2,3,5] [Validation: Fold 4]
Fold 5: [Train: Fold 1,2,3,4] [Validation: Fold 5]
shuffle=True、random_state=42を設定しました。
各実験で有効にした機能を一覧表にまとめました。〇は機能が有効、×は無効を示します。
| ID | 価格を対数化 | 交差検証 | 欠損値対応 | カテゴリ変換 | 派生特徴量 | 外れ値処理 | 特徴量整理 | モデル調整 | 学習高度化 | 正則化 |
|---|---|---|---|---|---|---|---|---|---|---|
| T01 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × | × |
| T02 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × | × |
| T03 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × |
| T04 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × |
| T05 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × |
| T06 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | × | × | × |
| T07 | 〇 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | × | × |
| T08 | 〇 | 〇 | 〇 | 〇 | 〇 | × | 〇 | × | × | × |
| T09 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | 〇 | × | × |
| T10 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | 〇 | 〇 | × |
| T11 | 〇 | 〇 | 〇 | 〇 | 〇 | × | × | 〇 | 〇 | 〇 |
各列の説明:
11個の実験を実施し、learning_rate、n_estimators、max_depth、num_leaves、正則化パラメータ(reg_alpha、reg_lambda)、派生特徴量の組み合わせを変えながら、最適な設定を探索しました。
| ID | モデル | 変更内容 | learning_rate | n_estimators | max_depth | num_leaves | reg_alpha | reg_lambda | 派生特徴量 |
|---|---|---|---|---|---|---|---|---|---|
| T01 | LightGBM | デフォルト設定 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | なし |
| T02 | LightGBM | T01の再現実験 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | なし |
| T03 | LightGBM | TotalSF追加 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | TotalSF |
| T04 | LightGBM | HouseAge, RemodAge追加 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | HouseAge, RemodAge |
| T05 | LightGBM | TotalBath追加 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | TotalBath |
| T06 | LightGBM | 4つの派生特徴量を統合 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T07 | LightGBM | GrLivArea > 4500を除外 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T08 | LightGBM | importance < 0.001を削除 | 0.05 | 20000 | -1 | 31 | 0.0 | 0.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T09 | LightGBM | num_leaves=64, max_depth=8 | 0.05 | 20000 | 8 | 64 | 0.0 | 0.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T10 | LightGBM | learning_rate=0.01, n_estimators=50000 | 0.01 | 50000 | -1 | 31 | 0.0 | 0.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T11 | LightGBM | max_depth=6, reg_alpha=0.1, reg_lambda=1.0 | 0.03 | 30000 | 6 | 31 | 0.1 | 1.0 | TotalSF, HouseAge, RemodAge, TotalBath |
| T12 | Ensemble (LightGBM + CatBoost) | T11ベースのアンサンブル(重み50:50) | 0.03 | 30000 | 6 | 31 | 0.1 | 1.0 | TotalSF, HouseAge, RemodAge, TotalBath |
まず基準となるモデルを構築した。派生特徴量は一切追加せず、LightGBMのデフォルトパラメータをそのまま使用した。この実験の目的は、後続の実験で行う改善の効果を測定するための基準値を確立することだった。
結果、CV RMSEは0.13180となった。これは対数スケールでの誤差なので、元の価格スケールに戻すと平均的な予測誤差は約$23,000に相当する。中央値価格が$163,000なので、約14%の誤差率となる。
T01と全く同じ設定で実験を再実行し、結果の再現性を確認した。機械学習モデルは乱数シードによって結果が変わる可能性があるため、同じ設定で同じ結果が得られるかを検証する必要があった。
結果、CV RMSEは0.13180でT01と完全に一致した。これにより、random_state=42の設定が正しく機能し、実験結果が再現可能であることが確認できた。
住宅価格は個別の階の面積よりも総床面積と強い相関があると考え、TotalSF(地下室+1階+2階の合計面積)を新しい特徴量として追加した。個別の面積特徴量(TotalBsmtSF、1stFlrSF、2ndFlrSF)は残したまま、統合指標としてTotalSFを追加することで、モデルがより有用なパターンを学習できると期待した。
結果、CV RMSEは0.13047に改善し、ベースラインから-1.0%の改善を達成した。TotalSFの特徴量重要度は0.087で全特徴量中3位となり、元の個別面積特徴量(TotalBsmtSF: 0.042、1stFlrSF: 0.039)よりも高い重要度を示した。これは、総床面積という統合指標がモデルにとって有用であることを示している。
T03-T05で個別に試した派生特徴量(TotalSF、HouseAge、RemodAge、TotalBath)を全て同時に追加した。個別では効果が小さかった特徴量も、他の特徴量と組み合わせることで相互作用が生まれ、より大きな効果を発揮すると期待した。
結果、CV RMSEは0.12864に改善し、ベースラインから-2.4%の改善を達成した。これはT03の-1.0%からさらに-1.4%の追加改善となる。特徴量間の相互作用により、個別では効果が小さかったHouseAge、RemodAge、TotalBathも、TotalSFと組み合わせることで予測精度向上に寄与したと考えられる。
データを可視化したところ、GrLivArea(地上居住面積)が4500平方フィート以上の物件が2件あり、これらは価格に対して異常に大きな面積を持っていた。これらの外れ値がモデルの学習を歪めている可能性があると考え、除外することでモデルの頑健性が向上すると期待した。
結果、CV RMSEは0.12481に改善し、T06から-3.0%の大幅な改善を達成した。これは全実験を通じて最大の改善幅となった。外れ値2件を除外するだけでこれほどの効果があったことから、異常値がモデルの学習に大きな悪影響を与えていたことが分かる。
314個の特徴量の中には、重要度が極めて低く、ノイズとして機能している可能性がある特徴量が含まれていると考えた。importance < 0.001の低重要度特徴量を削除することで、モデルがより重要な特徴量に集中でき、予測精度が向上すると期待した。
結果、CV RMSEは0.12864でT06と完全に同じとなり、効果は見られなかった。低重要度特徴量を削除してもモデルの性能は変わらなかったことから、LightGBMは自動的に重要度の低い特徴量を無視する能力があり、明示的に削除する必要はないことが分かった。
モデルの表現力を高めるため、木の構造パラメータを変更した。num_leavesを31から64に、max_depthを-1(無制限)から8に変更することで、より複雑なパターンを学習できると期待した。
結果、CV RMSEは0.13338に悪化し、T06から+3.7%悪化した。これは明らかな過学習の兆候である。訓練データには適合したが、検証データでの汎化性能が低下した。モデルの表現力を高めすぎると、訓練データのノイズまで学習してしまい、未知のデータに対する予測精度が低下することが確認できた。
learning_rateを0.05から0.01に下げ、n_estimatorsを20000から50000に増やすことで、より細かいステップで最適解に近づけると期待した。学習率を下げると1回の更新幅が小さくなるため、より慎重に最適解を探索できる。ただし、同じ学習量を得るには木の数を増やす必要がある。
結果、CV RMSEは0.12850に改善し、T06から-0.1%のわずかな改善を達成した。early_stopping_rounds=100により約160回で学習が終了したため、実際には50000本の木を全て使うことはなかった。学習率を下げることで、より細かく最適化できたが、改善幅は小さかった。
過学習を抑制するため、max_depthを6に制限し、L1正則化(reg_alpha=0.1)とL2正則化(reg_lambda=1.0)を追加した。max_depthを制限することで木の深さを抑え、正則化パラメータで重みにペナルティを課すことで、モデルが訓練データに過度に適合するのを防ぐと期待した。
結果、CV RMSEは0.12857となった。T06の0.12864とほぼ同じ性能を維持しながら、標準偏差が0.01673とT06の0.01748より小さくなった。これは、正則化によってFold間のスコアのばらつきが減少し、モデルの安定性が向上したことを示している。
| Try | CV RMSE | 予測誤差($) | 主な変更点 | Δ誤差 (vs T01) |
|---|---|---|---|---|
| T01 | 0.13180 | $23,000 | ベースライン(デフォルト設定) | - |
| T02 | 0.13180 | $23,000 | CV設定明示(シード固定: random_state=42) | $0 |
| T03 | 0.13047 | $22,800 | 特徴量追加: TotalSF(総床面積) | -$200 |
| T04 | 0.13170 | $23,000 | 特徴量追加: HouseAge + RemodAge(築年数関連) | $0 |
| T05 | 0.13214 | $23,100 | 特徴量追加: TotalBath(総バスルーム数) | +$100 |
| T06 | 0.12864 | $22,400 | 特徴量統合: T03~T05の全特徴量 | -$600 |
| T07 | 0.12481 | $21,800 | 外れ値除外: GrLivArea > 4500を除外 | -$1,200 |
| T08 | 0.12864 | $22,400 | 特徴量選択: 重要度0.001未満を削除 | -$600 |
| T09 | 0.13338 | $23,300 | 構造調整: num_leaves=64, max_depth=8 | +$300 |
| T10 | 0.12850 | $22,400 | 学習調整: 学習率0.01, 木数50,000 | -$600 |
| T11 | 0.12857 | $22,400 | 最適化版: 学習率0.03, 深さ6, 正則化強化 | -$600 |
| T12 | 0.12282 | $21,400 | アンサンブル: LightGBM + CatBoost(50:50) | -$1,600 |
| 段階 | 実験ID | CV RMSE | 予測誤差($) | 主な変更 |
|---|---|---|---|---|
| 1 | T01 | 0.13180 | $23,000 | ベースライン |
| 2 | T03 | 0.13047 | $22,800 | TotalSF追加 |
| 3 | T06 | 0.12864 | $22,400 | 全特徴量統合 |
| 4 | T10 | 0.12850 | $22,400 | 学習率最適化 |
| ID | CV RMSE (log) | Public RMSE (log) | Public 誤差($) | 差分 |
|---|---|---|---|---|
| T01 | 0.13180 | 0.12894 | $22,500 | -0.00286 |
| T03 | 0.13047 | 0.12804 | $22,300 | -0.00243 |
| T06 | 0.12864 | 0.12725 | $22,200 | -0.00139 |
| T07 | 0.12481 | 0.12899 | $22,500 | +0.00418 |
| T10 | 0.12850 | 0.12758 | $22,200 | -0.00092 |
| T11 | 0.12857 | 0.12658 | $22,100 | -0.00199 |
| T12 | 0.12282 | 0.12350 | $21,500 | +0.00068 |
注: Public誤差($)は、RMSE (log)から概算した実際の価格誤差(中央値価格$163,000を基準)
T03はCV/Public共に良好。T07はCV最良だがPublicで悪化(外れ値除外が過学習を引き起こした可能性)。T12(アンサンブル)が最良Public RMSE 0.12350(約$21,500の誤差)を達成。LightGBMとCatBoostの組み合わせにより、単一モデルよりも優れた汎化性能を実現。
12個の実験を実施し、ベースラインのCV RMSE 0.13180から最終的にT12のアンサンブルで0.12282まで改善した(-6.8%)。Kaggle Public Scoreでは、T12(LightGBM + CatBoostアンサンブル)が0.12350で最良のスコアを記録した。
効果的だった手法:
アンサンブルにより、単一モデル(T11: Public 0.12658)から約2.4%の追加改善を達成し、異なるアルゴリズムの強みを組み合わせることで汎化性能が大幅に向上した。
作成日: 2025年12月14日
最終更新: 2025年12月14日
バージョン: 2.1
著者: Kaggle House Prices Competition 参加者