不動産価格はいくらになる?
chun1182
import pandas as pd import numpy as np import sklearn import sklearn.metrics import category_encoders as ce import matplotlib.pyplot as plt import lightgbm as lgb %matplotlib inline
path='' test_data = pd.read_csv(path+'test_data.csv') train_data = pd.read_csv(path+'train_data.csv') published_data = pd.read_csv(path+'published_land_price.csv') print(test_df.shape, train_df.shape, published_df.shape)
(34844, 27) (356344, 28) (2602, 116)
plt.hist(train_data['y'], bins=20) plt.show()
plt.hist(np.log10(train_data['y']), bins=20) plt.show()
pd.cut(train_data['y'], [-1, 1, 10, 100, 1000, 10000, 100000]).value_counts(normalize=True)
(10, 100] 0.838403 (100, 1000] 0.078741 (1, 10] 0.076123 (1000, 10000] 0.004771 (-1, 1] 0.001830 (10000, 100000] 0.000132 Name: y, dtype: float64
train_data['最寄駅:距離(分)'] = train_data['最寄駅:距離(分)'].replace('30分?60分','45') train_data['最寄駅:距離(分)'] = train_data['最寄駅:距離(分)'].replace('1H?1H30','75') train_data['最寄駅:距離(分)'] = train_data['最寄駅:距離(分)'].replace('1H30?2H','105') train_data['最寄駅:距離(分)'] = train_data['最寄駅:距離(分)'].replace('2H?','120') train_data['最寄駅:距離(分)'] = pd.to_numeric(train_data['最寄駅:距離(分)'], errors='coerce')
train_data['建築年'] = train_data['建築年'].dropna() train_data['建築年'] = train_data['建築年'].str.replace('戦前','昭和20年') train_data['年号'] = train_data['建築年'].str[:2] train_data['和暦年数'] = train_data['建築年'].str[2:].str.strip('年').fillna(0).astype(int) train_data.loc[train_data['年号']=='昭和','建築年(西暦)'] = train_data['和暦年数'] + 1925 train_data.loc[train_data['年号']=='平成','建築年(西暦)'] = train_data['和暦年数'] + 1988
l = ['最寄駅:距離(分)','容積率(%)','建築年(西暦)'] for name in l: mean = np.nanmean(train_data[name], axis=0) std = np.nanstd(train_data[name], axis=0) train_data[name] = (train_data[name] - mean)/std train_data.describe()
#使用する説明変数・目的変数を代入 model_input = train_data[['最寄駅:名称','最寄駅:距離(分)','容積率(%)','建築年(西暦)','y']] #説明変数・目的変数についてnull値を含むレコードを除外 model_input = model_input.dropna(how='any', axis=0) #目的変数と説明変数を代入 X = model_input[['最寄駅:名称', '最寄駅:距離(分)', '容積率(%)', '建築年(西暦)']] X = pd.get_dummies(X, drop_first=True).values y = model_input['y'].values print(X.shape, y.shape)
(262610, 648) (262610,)
----ここまではtutorialと同様-----
#5foldでモデルを作成、評価 from sklearn.model_selection import KFold kf = KFold(n_splits=5, shuffle=True, random_state=1) s = list(kf.split(X, y))
import sklearn from sklearn.linear_model import LinearRegression as LR from sklearn.metrics import mean_squared_error for train_i, val_i in s: model = LR() model.fit(X[train_i], y[train_i]) y_pred = model.predict(X[val_i]) y_val = y[val_i] print('y_valの数:{}, 1000以上のy_valの数:{}, 100以下のy_valの数:{}'.format(len(y_val), len(y_val[y_val>1000]), len(y_val[y_val<100]))) print('RMSE:', np.sqrt(mean_squared_error(y_val, y_pred))) print('1000以上をすべて当てた場合のRMSE:', np.sqrt(mean_squared_error(y_val, np.where(y_val>1000, y_val, y_pred)))) print('100以下をすべて当てた場合のRMSE:', np.sqrt(mean_squared_error(y_val, np.where(y_val<100, y_val, y_pred)))) break
y_valの数:52522, 1000以上のy_valの数:223, 100以下のy_valの数:48934 RMSE: 223.67193030133276 1000以上をすべて当てた場合のRMSE: 79.60272441095651 100以下をすべて当てた場合のRMSE: 218.30752617076064
今回の評価指標(RMSE)では全体の90%以上の100以下の値を推論するのはほとんど効果がなく、 全体の5%程度の1000以上の値を予測するのに注力した方が良いと考えられる
こんな感じで考えているのですが、ご意見、コードのミスなどありましたらご指摘お願いします。 1000以上の値は5%じゃなくて0.5%ですね・・・