4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

分析コンペに挑戦してみた

Posted at

問題

不動産の価格予測の問題に取り組んでみた。
https://competition.nishika.com/competitions/mansion_pra/summary

データ分析の流れや考え方を学ぶために取り組んだ。
流れを振り返るためにも備忘録としてアウトプットする。

取り組み方

下記の流れで取り組んだ。

1. データの確認(データ型、欠損値の量、データ量とカラム)

スクリーンショット 2023-08-08 1.06.33.png

2. 使うデータを絞る。

絞り方は下記にあてはまるものを削除した。
・nullが半分以上あるもの
・カテゴリー変数かつ取る値が多すぎて、数値化しても無意味そうなもの

よって使えそうなカラムは下記と考えた。

スクリーンショット 2023-08-08 1.11.33.png

3. カテゴリー変数を数値に変換する。

便利なLabelEncoderを使った。

from sklearn.preprocessing import LabelEncoder

realestate_data = df.copy()
def encode_categorical(df, columns):
    for col in columns:
        LE = LabelEncoder()
        df[col] = LE.fit_transform(df[col])
    return df

realestate_data = encode_categorical(realestate_data,['都道府県名','間取り', '建物の構造','用途','都市計画','改装'])

4.文字列として入力されている値を数値に変換する。

和暦で記載されている部分を西暦に変換する。
ロジックが非常に勉強になった。
applyで定義した関数をデータフレームに適用できることもわかった。

import unicodedata
import re
import datetime

# 各年号の元年を定義
eraDict = {
    "明治": 1868,
    "大正": 1912,
    "昭和": 1926,
    "平成": 1989,
    "令和": 2019,
}

def japanese_calender_converter(text):
    # テキストがNaNやNoneの場合の処理
    # テキストがNaNやNone、または文字列でない場合の処理
    if pd.isna(text) or text is None or not isinstance(text, str):
        return None
    
    # 正規化
    normalized_text = unicodedata.normalize("NFKC", text)
    
    # 年のみを抽出する正規表現
    pattern = r"(?P<era>{eraList})(?P<year>[0-9]{{1,2}}|元)年".format(eraList="|".join(eraDict.keys()))
    date = re.search(pattern, normalized_text)
    
    # 抽出できなかったら終わり
    if date is None:
        # print(f"Cannot convert {text} to western year")
        return None

    # 年を変換
    era = date.group("era")
    if date.group("year") == "":
        year = eraDict[era]
    else:
        year = eraDict[era] + int(date.group("year")) - 1

    return year

realestate_data['建築年'] = realestate_data['建築年'].apply(japanese_calender_converter)

四半期などの文字を数値に変換。

def convert_quarter_to_decimal(text):
    # 年と四半期を抽出
    match = re.search(r'(\d+)年第(\d)四半期', text)
    if match:
        year = int(match.group(1))
        quarter = int(match.group(2))

        # 四半期を小数点の形式に変換
        decimal = (quarter - 1) * 0.25
        return year + decimal
    else:
        return None

値の文字も数字に変換

ここは地道に変換していったが、値の数が多くなると取れない手段だったので
もっといい方法があるのだと思う。

realestate_data.loc[realestate_data['最寄駅:距離(分)'] == '30分?60分' , '最寄駅:距離(分)'] = 45
realestate_data.loc[realestate_data['最寄駅:距離(分)'] == '1H?1H30' , '最寄駅:距離(分)'] = 75
realestate_data.loc[realestate_data['最寄駅:距離(分)'] == '1H30?2H' , '最寄駅:距離(分)'] = 105
realestate_data.loc[realestate_data['最寄駅:距離(分)'] == '2H' , '最寄駅:距離(分)'] = 120

realestate_data['最寄駅:距離(分)'] = pd.to_numeric(realestate_data['最寄駅:距離(分)'],errors='coerce')

5. 欠損値の処理

勉強のついでにと2パターン試してみた。

①平均値で欠損値を埋めるパターン
中央値やランダムが良いパターンも有る。

mean_value = realestate_data['最寄駅:距離(分)'].mean()
realestate_data['最寄駅:距離(分)'].fillna(mean_value, inplace=True)

②欠損値を削除するパターン
あんまり使うことがよくなさそうな印象。
とはいえ有効なタイミングもあると思うので、使い分けれるようにデータ理解を深める必要がある。

realestate_data = realestate_data.dropna(subset=['建築年'])

6. テストデータを機械学習に入れてみる。

何やら使い勝手が良いらしい、GBDTを使う。

import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# データの分割
X = realestate_data.drop(columns=['ID', '取引価格(総額)_log'])
y = realestate_data['取引価格(総額)_log']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# XGBoostの設定
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

params = {
    "objective": "reg:squarederror",
    "eval_metric": "rmse",
    "booster": "gbtree"
}

# トレーニング
num_round = 100
bst = xgb.train(params, dtrain, num_round, evals=[(dtrain, 'train'), (dtest, 'eval')], early_stopping_rounds=10)

# 予測
y_pred = bst.predict(dtest)
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse}')

7. 提出用データでモデルから予測し、csv化して提出

結果は下記。
どれだけ悪いのかよくわかんないけど、順位は下の方。

スクリーンショット 2023-08-08 1.38.24.png

わかったこと

・機械学習は実装するだけではだめっぽい。
・「モデルの使い分けや学習をどのように進めるか」「同じデータからどんな特徴量を見出すか」にデータ分析の能力の違いが出るのかな。

今後は分析コンペの参加の仕方やGBDTの流れを体験できたので、
次は学習を特徴量に着目してモデルを作成してみる。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?