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()
id | 市区町村コード | 最寄駅:距離(分) | 前面道路:幅員(m) | 建ぺい率(%) | 容積率(%) | y | 和暦年数 | 建築年(西暦) | |
---|---|---|---|---|---|---|---|---|---|
count | 356344.000000 | 356344.000000 | 3.462150e+05 | 193279.000000 | 350958.000000 | 3.509580e+05 | 356344.000000 | 356344.000000 | 2.735030e+05 |
mean | 178172.500000 | 13140.019052 | -1.358520e-13 | 6.257812 | 62.005482 | -3.166953e-13 | 65.434766 | 20.850894 | 3.455073e-15 |
std | 102867.796499 | 46.206047 | 1.000001e+00 | 4.902258 | 13.125221 | 1.000001e+00 | 315.011339 | 19.644583 | 1.000002e+00 |
min | 1.000000 | 13101.000000 | -1.096071e+00 | 1.000000 | 30.000000 | -1.343050e+00 | 0.000500 | 0.000000 | -3.782092e+00 |
25% | 89086.750000 | 13110.000000 | -5.877202e-01 | 4.000000 | 60.000000 | -7.157682e-01 | 21.000000 | 3.000000 | -6.865983e-01 |
50% | 178172.500000 | 13117.000000 | -2.827096e-01 | 5.000000 | 60.000000 | -4.021274e-01 | 35.000000 | 17.000000 | 2.492487e-01 |
75% | 267258.250000 | 13201.000000 | 2.256414e-01 | 6.000000 | 80.000000 | 2.251542e-01 | 53.000000 | 27.000000 | 7.531663e-01 |
max | 356344.000000 | 13421.000000 | 1.110435e+01 | 90.000000 | 80.000000 | 6.497971e+00 | 61000.000000 | 64.000000 | 1.545037e+00 |
#使用する説明変数・目的変数を代入
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以上の値を予測するのに注力した方が良いと考えられる
chun1182
こんな感じで考えているのですが、ご意見、コードのミスなどありましたらご指摘お願いします。 1000以上の値は5%じゃなくて0.5%ですね・・・