中古マンション価格予測データ分析コンペティションで扱ったコード解説

## はじめに
Nishika主催の中古マンション価格予測データ分析コンペに参加した際、上位入賞を果たしたコードを解説します。本記事では、コードを3つのパートに分けて、それぞれ詳細な解説と改善点について説明します。

https://competition.nishika.com/competitions/mansion_pra/summary

## ① データ前処理
```

def data_pre(df):

  nonnull_list = []
  for col in df.columns:
    nonnull = df[col].count()
    if nonnull == 0:
      nonnull_list.append(col)
  df = df.drop(nonnull_list, axis=1)

  df = df.drop("種類", axis=1)

  dis = {
    "30分?60分":45,
    "1H?1H30":75,
    "2H?":120,
    "1H30?2H":105,
  }

  df["最寄駅：距離（分）"] = df["最寄駅：距離（分）"].replace(dis).astype(float)

  df["面積（㎡）"] = df["面積（㎡）"].replace("2000㎡以上", 2000)
  df["面積（㎡）"] = df["面積（㎡）"].astype(float)

  y_list = {}
  for i in df["建築年"].value_counts().keys():
    if "平成" in i:
      num = float(i.split("平成")[1].split("年")[0])
      year = 33 - num
    elif "令和" in i:
      num = float(i.split("令和")[1].split("年")[0])
      year = 3 - num
    elif "昭和" in i:
      num = float(i.split("昭和")[1].split("年")[0])
      year = 96 - num
    y_list[i] = year
  y_list["戦前"] = 76

  df["建築年"] = df["建築年"].replace(y_list)

  year = {
    "年第1四半期": ".25",
    "年第2四半期": ".50",
    "年第3四半期": ".75",
    "年第4四半期": ".99"
  }

  year_list = {}
  for i in df["取引時点"].value_counts().keys():
    for k, j in year.items():
      if k in i:
        year_rep = i.replace(k, j)
        year_list[i] = year_rep

  df["取引時点"] = df["取引時点"].replace(year_list).astype(float)

  for col in ["都道府県名", "市区町村名" , "地区名", "最寄駅：名称", "間取り", "建物の構造", "用途", "今後の利用目的" , "都市計画", "改装", "取引の事情等"]:
    df[col] = df[col].astype("category")

  return df

df = data_pre(df)
df.info()

```

このコードは、Nishika中古マンション価格予測コンペで使用するデータの前処理を行います。具体的には、以下の処理を実施します。

・欠損値が多い列を削除する
・不要な列を削除する
・カテゴリ変数を数値に変換する
・特殊な値（"2000㎡以上"など）を数値に変換する
・建築年を数値に変換する
・取引時点を数値に変換する
・これらの処理により、モデル学習に適したデータ形式に変換します。

改善点

・欠損値の処理方法について、単純に削除するだけでなく、補完する方法も検討する。
・カテゴリ変数の扱いについて、one-hot encodingなど、他の方法も検討する。
・特殊な値の処理方法について、他の方法も検討する。

## ② モデル学習（続き）
```

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error as mae

df_train, df_val = train_test_split(df, test_size = 0.2)

col = "取引価格（総額）_log"
train_y = df_train[col]
train_x = df_train.drop(col, axis = 1)

val_y = df_val[col]
val_x = df_val.drop(col, axis = 1)

trains = lgb.Dataset(train_x, train_y)
valids = lgb.Dataset(val_x, val_y)

params = {
    "objective": "regression",
    "metrics": "mae",
    "early_stopping_round": 100,
    "max_bin": 1024
}

model = lgb.train(params, trains, valid_sets=valids, num_boost_round = 1000)

vals = model.predict(val_x)
mae(vals, val_y)

```

このコードは、LightGBMを用いて中古マンション価格を予測するモデルを学習します。具体的には、以下の処理を実施します。

・データを訓練データと検証データに分割する
・目的変数を対数変換する
・LightGBMの学習を行う
・検証データでモデルの精度を評価する

改善点

・LightGBMのパラメータを調整し、精度向上を目指す。
・他の機械学習モデルも試し、比較検討する。
・アンサンブル学習も検討する。

## ③ テストデータへの適用
```
df_test =  pd.read_csv("test.csv" , index_col= 0)
df_test = data_pre(df_test)

predict = model.predict(df_test)
df_test["取引価格（総額）_log"] = predict
df_test["取引価格（総額）_log"] .to_csv("submit_test.csv")
```

このコードは、学習済みモデルをテストデータに適用し、価格予測を行います。具体的には、以下の処理を実施します。

・テストデータの前処理を行う
・モデルで価格を予測する
・予測結果をCSVファイルに出力する

改善点

・テストデータの前処理方法を、訓練データの前処理方法と一致させる。
・予測結果の信頼区間を計算し、出力する。

## まとめ
本記事では、Nishika中古マンション価格予測コンペで上位入賞を果たしたコードを解説しました。コードは3つのパートに分かれており、それぞれ詳細な解説と改善点について説明しました。

これらの解説を参考に、ご自身の中古マンション価格予測モデルの改良に役立てていただければ幸いです。