chun1182
#インポート
import pandas as pd
import numpy as np
import sklearn
import sklearn.metrics
import matplotlib.pyplot as plt
import lightgbm as lgb
# published リネーム準備
pair = [("所在地コード","市区町村コード"),("建蔽率","建ぺい率(%)"),("容積率","容積率(%)"),("駅名","最寄駅:名称"),
("地積","面積(㎡)"),("市区町村名","市区町村名"),('前面道路の幅員','前面道路:幅員(m)'),
("前面道路の方位区分","前面道路:方位"),("前面道路区分","前面道路:種類"),("形状区分","土地の形状"),
("用途区分","都市計画"), ('用途','地域')]
pair_dict = {key:value for key, value in pair}
# データ読み込み
path='./'
test_df = pd.read_csv(path+'test_data.csv')
train_df = pd.read_csv(path+'train_data.csv')
published_df = pd.read_csv(path+'published_land_price.csv', dtype={'利用の現況': str})
published_df = published_df.rename(columns=pair_dict)
print(test_df.shape, train_df.shape, published_df.shape)
(34844, 27) (356344, 28) (2602, 116)
# train testを結合
train_df['logy'] = np.log1p(train_df['y'])
test_df['y'] = -1
train_df['logy'] = -1
all_df = pd.concat([train_df, test_df])
all_df = all_df.reset_index(drop=True)
print(all_df.shape)
(391188, 29)
all_df.columns
Index(['id', '種類', '地域', '市区町村コード', '都道府県名', '市区町村名', '地区名', '最寄駅:名称', '最寄駅:距離(分)', '間取り', '面積(㎡)', '土地の形状', '間口', '延床面積(㎡)', '建築年', '建物の構造', '用途', '今後の利用目的', '前面道路:方位', '前面道路:種類', '前面道路:幅員(m)', '都市計画', '建ぺい率(%)', '容積率(%)', '取引時点', '改装', '取引の事情等', 'y', 'logy'], dtype='object')
#all_df 前処理1
all_df['取引時点'] = all_df['取引時点'].str.replace('年第','.').str.replace('四半期','').str.replace('1','0').str.replace('2','25').str.replace('3','5').str.replace('4','75')
all_df["取引時点"] = pd.to_numeric(all_df["取引時点"], errors='raise')
all_df['面積(㎡)'] = all_df['面積(㎡)'].str.replace('000㎡以上','500')
all_df["面積(㎡)"] = pd.to_numeric(all_df["面積(㎡)"], errors='raise')
all_df.loc[(all_df['種類']=='林地') | (all_df['種類']=='農地'), '面積(㎡)']*=0.1
all_df['最寄駅:距離(分)'] = all_df['最寄駅:距離(分)'].replace('30分?60分','45').replace('1H?1H30','75').replace('1H30?2H','105').replace('2H?','120')
all_df["最寄駅:距離(分)"] = pd.to_numeric(all_df["最寄駅:距離(分)"], errors='raise')
all_df['間口'] = all_df['間口'].str.replace('0.0m以上','5')
all_df["間口"] = pd.to_numeric(all_df["間口"], errors='raise')
# all_df.loc[all_df['間口'].isna(), '間口'] = -(-(all_df.loc[all_df['間口'].isna(), '面積(㎡)']+1)**0.5//5)*5
#all_df 前処理2
all_df['延床面積(㎡)'] = all_df['延床面積(㎡)'].str.replace('㎡以上','').replace('10m^2未満','5')
all_df["延床面積(㎡)"] = pd.to_numeric(all_df["延床面積(㎡)"], errors='raise')
all_df['地域'] = all_df['地域'].str.replace('住宅地','0').str.replace('商業地','005').str.replace('宅地見込地','003').str.replace('工業地','009')
all_df["地域"] = pd.to_numeric(all_df["地域"], errors='raise')
#all_df 前処理3
all_df['最寄駅:名称'] = all_df['最寄駅:名称'].fillna('なし')
all_df['最寄駅:名称'] = all_df['最寄駅:名称'].str.replace('(東京)','').str.replace('(神奈川)','').str.replace('ケ','ヶ')
all_df['最寄駅:名称'] = all_df['最寄駅:名称'].str.replace('(メトロ)','').str.replace('(都電)','').str.replace('(つくばEXP)','')
all_df['最寄駅:名称'] = all_df['最寄駅:名称'].str.replace('(千葉)','').str.replace('(東京メトロ)','').str.strip('()')
#all_df 前処理4
all_df["地区詳細"] = all_df['市区町村名'] + all_df['地区名']
all_df["地区詳細"] = all_df["地区詳細"].str[:5]
all_df['市区町村名'] = all_df['市区町村名'].str.strip('市区町村').str.strip('西多摩郡東京')
#all_df 前処理5
all_df['建築年'] = all_df['建築年'].str.replace('戦前','昭和20年')
all_df['年号'] = all_df['建築年'].str[:2]
all_df['和暦年数'] = pd.to_numeric(all_df['建築年'].str[2:].str.strip('年'), errors='raise')
all_df.loc[all_df['年号']=='昭和','建築年(西暦)'] = all_df['和暦年数'] + 1925
all_df.loc[all_df['年号']=='平成','建築年(西暦)'] = all_df['和暦年数'] + 1988
#all_df 前処理6
all_df['間取り'] = all_df['間取り'].str.replace('オープンフロア','0、O').str.replace('スタジオ','0、T').str.replace('メゾネット','0、M')
all_df['間取り'] = all_df['間取り'].str.replace('L','、L').str.replace('D','、D').str.replace('K','、K').str.replace('S','、S').str.replace('R','、R')
all_df['間取り'] = all_df['間取り'].str.replace('1','1').str.replace('2','2').str.replace('3','3').str.replace('+','')
all_df['間取り'] = all_df['間取り'].str.replace('4','4').str.replace('5','5').str.replace('6','6').str.replace('7','7')
#published_df 前処理
published_df["面積(㎡)"] = published_df["面積(㎡)"].clip(0, 3000)
['その他', '住宅', '店舗', '事務所', '作業場', '倉庫', '共同住宅', '工場', '駐車場']
[ '住宅', '店舗', '事務所', '銀行', '旅館', '給油所', '工場', '倉庫', '農地', '山林', '医院', '空地', '作業場', '原野', 'その他', '用材', '雑木']
riyo_list = np.array(['住宅', '店舗', '事務所', '_', '_', '_', '工場', '倉庫', '_', '_', '_', '_', '作業場', '_', 'その他', '_', '_'])
riyo_list
riyo_now = [[0]*(17 - len(num))+list(map(int, list(num))) for num in published_df['利用の現況'].values]
riyo_now = np.array(riyo_now)
riyo_lists = ['、'.join(riyo_list[onehot.astype('bool')]) for onehot in riyo_now]
for i in range(len(riyo_lists)):
if 'その他' in riyo_lists[i]:
riyo_lists[i] = riyo_lists[i].replace('その他', published_df.loc[i, '利用状況表示'])
riyo_lists[i] = riyo_lists[i].replace('_', 'その他').replace('、雑木林', '').replace('、診療所', '').replace('、車庫', '').replace('、集会場', '')\
.replace('、寄宿舎', '').replace('、駅舎', '').replace('、劇場', '').replace('、物置', '').replace('、集会場', '').replace('、映画館', '')\
.replace('、遊技場', '').replace('兼', '、').replace('、建築中', 'その他').replace('、試写室', '').replace('、寮', '').replace('、保育所', '')\
.replace('、治療院', '').replace('、診療所', '').replace('、荷捌所', '').replace('建築中', 'その他').replace('事業所', '事務所').replace('、営業所', '')
published_df['利用の現況'] = riyo_lists
#最信念を取り出してpublished_df2を作成
kakakus = []
for i, year in enumerate(published_df.columns[-37:-38:-1]):
df = pd.merge(published_df[published_df.columns[:-75:]], published_df[published_df[year]>0][['id', year]], on='id')
df['取引時点'] = 2019-i
df = df.rename(columns={year: 'y'})
df['y'] = df['y'] /100000
kakakus.append(df)
published_df2 = pd.concat(kakakus)
published_df2.shape
(2602, 43)
#published_df前処理1
published_df2['最寄駅:距離(分)'] = published_df2['駅距離']//50
published_df2.loc[:, '最寄駅:距離(分)'][published_df2['最寄駅:距離(分)']>120] = 120
published_df2['間口(比率)'] = published_df2['間口(比率)'].clip(10, 100)
published_df2['奥行(比率)'] = published_df2['奥行(比率)'].clip(10, 100)
published_df2['間口'] = np.sqrt(published_df2['面積(㎡)']/published_df2['間口(比率)']/published_df2['奥行(比率)'])*published_df2['間口(比率)']
C:\Users\we_lo\AppData\Local\Continuum\anaconda3\envs\gpu\lib\site-packages\ipykernel_launcher.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy This is separate from the ipykernel package so we can avoid doing imports until
#published_df前処理2
published_df2['種類'] = np.nan
published_df2['建築年(西暦)'] = np.nan
published_df2['建物の構造'] = published_df2['建物構造'].str.replace('SRC','SRC').str.replace('RC','RC').str.replace('W','木造').str.replace('LS','軽量鉄骨造').str.replace('S','鉄骨造')
published_df2['建物の構造'] = published_df2['建物の構造'].str.replace('[0-9]','').str.replace('FB','').str.replace('B','_').value_counts()
published_df2['最寄駅:名称'] = published_df2['最寄駅:名称'].str.replace('ケ','ヶ')
#published_df前処理3
se = published_df2['住居表示'].str.strip('東京都').str.replace('大字', '').str.replace('字', '')
for num in ['1', '2', '3', '4', '5', '6', '7', '8', '9']:
se = se.str.split(num).str[0].str.strip()
published_df2['地区詳細'] = se
published_df2['地区詳細'] = published_df2['地区詳細'].str[:5]
published_df2['市区町村名'] = published_df2['市区町村名'].str.strip('市区町村').str.strip('西多摩郡東京')
#published_df前処理4
rep ={'1低専':'第1種低層住居専用地域', '2低専':'第2種低層住居専用地域', '1中専':'第1種中高層住居専用地域', '2中専':'第2種中高層住居専用地域', '1住居':'第1種住居地域',
'2住居':'第2種住居地域', '準住居':'準住居地域', '商業':'商業地域', '近商':'近隣商業地域', '工業':'工業地域', '工専':'工業専用地域', '準工':'準工業地域', '田園住':'田園住居地域'}
for key, value in rep.items():
published_df2.loc[:, '都市計画'] = published_df2.loc[:, '都市計画'].str.replace(key,value)
#published_df前処理5
published_df2['logy'] = np.log1p(published_df2['y'])
published_df2 = published_df2.rename(columns={'利用の現況': '用途'})
published_df2.columns
Index(['id', '経度', '緯度', '市区町村コード', '地域', '連番', '年次', '前年所在地コード', '前年用途', '前年連番', '市区町村名', '住居表示', '行政', '面積(㎡)', '用途', '利用状況表示', '建物構造', '施設', '土地の形状', '間口(比率)', '奥行(比率)', '階層(地上)', '階層(地下)', '前面道路:種類', '前面道路:方位', '前面道路:幅員(m)', '前面道路の駅前区分', '前面道路の舗装状況', '側道区分', '側道方位区分', '交通施設との近接区分', '周辺の土地の利用の現況', '最寄駅:名称', '駅距離', '都市計画', '防火区分', '都市計画区分', '森林区分', '公園区分', '建ぺい率(%)', '容積率(%)', 'y', '取引時点', '最寄駅:距離(分)', '間口', '種類', '建築年(西暦)', '建物の構造', '地区詳細', 'logy'], dtype='object')
'''
id 経度 緯度 ○所在地コード 年次 ○市区町村名 住居表示 ◎地積 ◎利用の現況&利用状況表示 ◎建物構造 ◎形状区分 ◎間口(比率) ◎奥行(比率)階層(地上 階層(地下)◎前面道路区分 ◎前面道路の方位区分
◎前面道路の幅員 ◎駅名 ◎駅距離 ◎用途区分 ◎建蔽率 ◎容積率 価格 ◎用途
連番 行政 施設 前面道路の駅前区分 前面道路の舗装状況 側道区分 側道方位区分 交通施設との近接区分 防火区分 森林区分 公園区分 共通地点区分 選定年次ビット 周辺の土地の利用の現況 都市計画区分
○種類 ◎地域 ○市区町村コード◎最寄駅:距離(分)◎面積(㎡)◎建ぺい率(%) ◎容積率(%)◎間口 取引時点◎前面道路:方位
◎前面道路:種類 ◎前面道路:幅員(m)◎建物の構造○市区町村名 地区名 ◎最寄駅:名称◎用途
id ◎土地の形状 延床面積(㎡) 建築年
今後の利用目的 ◎都市計画 ○改装 y
都道府県名 間取り 取引の事情等
'''
'\nid 経度 緯度 ○所在地コード 年次 ○市区町村名 住居表示 ◎地積 ◎利用の現況&利用状況表示 ◎建物構造 ◎形状区分 ◎間口(比率) ◎奥行(比率)階層(地上 階層(地下)◎前面道路区分 ◎前面道路の方位区分\n◎前面道路の幅員\u3000 ◎駅名 ◎駅距離 ◎用途区分 ◎建蔽率 ◎容積率 価格\u3000◎用途\n\n 連番 行政 施設 前面道路の駅前区分 前面道路の舗装状況 側道区分 側道方位区分 交通施設との近接区分 防火区分 森林区分 公園区分 共通地点区分 選定年次ビット 周辺の土地の利用の現況\u3000都市計画区分\n\n○種類 ◎地域 ○市区町村コード◎最寄駅:距離(分)◎面積(㎡)◎建ぺい率(%) ◎容積率(%)◎間口 取引時点◎前面道路:方位 \n◎前面道路:種類 ◎前面道路:幅員(m)◎建物の構造○市区町村名 地区名 ◎最寄駅:名称◎用途\n\nid ◎土地の形状 延床面積(㎡) 建築年 \n今後の利用目的 ◎都市計画 ○改装 y\n\n都道府県名\u3000間取り 取引の事情等\n\n'
# 使う列を指定
#
target_columns = ['地域', '種類', '市区町村コード', '面積(㎡)','建ぺい率(%)', '容積率(%)','最寄駅:距離(分)', '前面道路:方位', '地区詳細','土地の形状','市区町村名',
'前面道路:種類', '前面道路:幅員(m)', '間口', '建物の構造', '最寄駅:名称', '用途', '都市計画', '建築年(西暦)', 'y', 'logy']
#平均値化取得用
tika = published_df2[target_columns]
tika.head()
地域 | 種類 | 市区町村コード | 面積(㎡) | 建ぺい率(%) | 容積率(%) | 最寄駅:距離(分) | 前面道路:方位 | 地区詳細 | 土地の形状 | ... | 前面道路:種類 | 前面道路:幅員(m) | 間口 | 建物の構造 | 最寄駅:名称 | 用途 | 都市計画 | 建築年(西暦) | y | logy | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | NaN | 13364 | 224 | 70 | 200 | 9 | 南 | 神津島村 | _ | ... | 村道 | 22 | 13.662601 | NaN | キャンドゥ前 | 住宅 | _ | NaN | 0.076 | 0.073250 |
1 | 5 | NaN | 13364 | 203 | 70 | 200 | 11 | 西 | 神津島村 | _ | ... | 村道 | 35 | 17.449928 | NaN | キャンドゥ前 | 住宅、店舗 | _ | NaN | 0.095 | 0.090754 |
2 | 0 | NaN | 13364 | 239 | 70 | 200 | 26 | 南東 | 神津島村 | _ | ... | 村道 | 40 | 16.935171 | NaN | 神津島港 | 住宅 | _ | NaN | 0.065 | 0.062975 |
3 | 0 | NaN | 13228 | 309 | 40 | 80 | 56 | 北西 | あきる野市 | _ | ... | 市道 | 47 | 21.529050 | NaN | 武蔵五日市 | 住宅 | _ | NaN | 0.370 | 0.314811 |
4 | 0 | NaN | 13205 | 135 | 40 | 80 | 12 | 東 | 青梅市沢井 | _ | ... | 私道 | 45 | 9.486833 | NaN | 軍畑 | 住宅 | 第1種低層住居専用地域 | NaN | 0.440 | 0.364643 |
5 rows × 21 columns
#試しに見てみる
col ='最寄駅:名称'
print('only all_df', set(all_df[col].unique()) - set(published_df2[col].unique()))
print('only publish_df', set(published_df2[col].unique()) - set(all_df[col].unique()))
tdf = tika[[col, 'y']].groupby([col]).mean().sort_values('y', ascending=False)
tdf[tdf['y']>50]
only all_df {'', '鬼子母神前', '飛鳥山', '学習院下', '西ヶ原四丁目', '浅草(東武・都営・', '所沢', '品川シーサイド', '潮見', '尾久', '栗平', '東池袋四丁目', '国立競技場', '東所沢', '有明', '幡ヶ谷', '立川南', '山下', '新宿西口', '南鳩ヶ谷', '新木場', 'テレポート', '舞浜', '牛田', '飯能', '町屋二丁目', '御嶽山', '赤土小学校前', '竹芝', '高尾山口', '古里', '東あずま', '新庚申塚', '新座', '松が谷', '芝浦ふ頭', '荒川二丁目', '宮ノ前', '黒川', '滝野川一丁目', '面影橋', '万願寺', '府中本町', '代々木公園', '日の出', '遊園地西', '矢部', '荒川一中前', '小田急多摩センター', '荒川区役所前', '川口元郷', '桜ヶ丘', '南新宿', '戸越公園', '馬喰横山', '六郷土手', '鳩ノ巣', '荒川七丁目', '武蔵小杉', '高野', '沢井', '牛込柳町', '中央大学・明星大学', '相模原', '東向島', '国会議事堂前', '石神前', 'お台場海浜公園', '奥多摩', '浦安', '向原', '青海', '栄町', '白丸', '天空橋', '有明テニスの森', '亀戸水神', '曳舟', '京成金町', '新豊洲', '都庁前', '高松', '御嶽', '京成関屋', '多摩センター', '巣鴨新田', '立飛', '川井', '乃木坂', '長津田', '雑司ヶ谷', '京成上野', '町屋駅前', 'なし', '西武新宿', '馬喰町', '三ノ輪橋', '小田急永山', '庚申塚', '西日暮里', '上野御徒町', '昭和島'} only publish_df {'町役場前停', '都営豊島園', '都営市ヶ谷', '青灯台入口', '霞ヶ関', '三根出張所前停', '焼場停', '村役場前', '下地停', 'キャンドゥ前', '裁判所前停', '元町港', '神津島港', '東京', '新島港', 'つくばエクスプレス浅草', '小田急町田', '錆ヶ浜停', '都営水道橋', '中之郷出張所前停', '奥村', '錆ヶ浜港入口停'}
y | |
---|---|
最寄駅:名称 | |
銀座 | 376.500000 |
東京 | 263.800000 |
銀座一丁目 | 241.600000 |
明治神宮前 | 240.000000 |
大手町 | 198.100000 |
京橋 | 170.000000 |
日比谷 | 145.733333 |
原宿 | 136.000000 |
霞ヶ関 | 130.000000 |
有楽町 | 128.000000 |
新宿 | 110.063636 |
新宿三丁目 | 108.500000 |
日本橋 | 105.375000 |
内幸町 | 93.775000 |
新橋 | 80.900000 |
渋谷 | 74.270588 |
虎ノ門 | 72.975000 |
宝町 | 72.700000 |
竹橋 | 72.300000 |
汐留 | 69.000000 |
東銀座 | 59.800000 |
外苑前 | 56.400000 |
青山一丁目 | 55.066667 |
淡路町 | 54.900000 |
上野広小路 | 53.100000 |
赤坂見附 | 50.933333 |
# all_df を抽出
all_df_target = all_df[target_columns+['延床面積(㎡)', '改装', '間取り', '取引の事情等']]
all_df_target = all_df_target.reset_index(drop=True)
#部屋数などを取得
all_df_target['間取り数'] = pd.to_numeric(all_df_target['間取り'].str[0], errors='raise')
all_df_target['部屋数'] = all_df_target['間取り'].str[2:].str.len()//2+1+all_df_target['間取り数']
#published_df2の集計値を結合 面積と掛け算、最寄り駅距離で補正
cols = ['地域', '市区町村コード', '地区詳細', '建ぺい率(%)', '容積率(%)', '都市計画', '前面道路:方位', '前面道路:種類', '最寄駅:名称']
for col in cols:
print(col, all_df_target.shape)
all_df_target = pd.merge(all_df_target, tika[[col, 'y']].groupby(col).mean().rename(columns={'y':col+'y'}), on=col, how='left')
all_df_target.loc[all_df_target['地区詳細y'].isna(), '地区詳細y'] = all_df_target.loc[all_df_target['地区詳細y'].isna(), '市区町村コードy']
all_df_target.loc[all_df_target['最寄駅:名称y'].isna(), '最寄駅:名称y'] = all_df_target.loc[all_df_target['最寄駅:名称y'].isna(), '地区詳細y']
cols = ['市区町村コード', '地区詳細', '最寄駅:名称']
#cols = ['地域', '市区町村コード', '地区詳細', '建ぺい率(%)', '容積率(%)', '都市計画', '前面道路:方位', '前面道路:種類', '最寄駅:名称']
for col in cols:
all_df_target['m2x'+col] = all_df_target[col+'y'] * all_df_target['面積(㎡)']/100
#all_df_target['nm2x'+col] = all_df_target[col+'y'] * all_df_target['延床面積(㎡)']/100
all_df_target['m2m2x'+col] = all_df_target[col+'y'] * (all_df_target['面積(㎡)']+all_df_target['延床面積(㎡)'].fillna(0))/100
all_df_target['m2m2x'+col+'_sta'] = all_df_target['m2m2x'+col] * (1 - all_df_target['最寄駅:距離(分)'].clip(0, 10)*0.02)
print(all_df_target.shape)
地域 (391188, 27) 市区町村コード (391188, 28) 地区詳細 (391188, 29) 建ぺい率(%) (391188, 30) 容積率(%) (391188, 31) 都市計画 (391188, 32) 前面道路:方位 (391188, 33) 前面道路:種類 (391188, 34) 最寄駅:名称 (391188, 35) (391188, 45)
all_df_target
地域 | 種類 | 市区町村コード | 面積(㎡) | 建ぺい率(%) | 容積率(%) | 最寄駅:距離(分) | 前面道路:方位 | 地区詳細 | 土地の形状 | ... | 最寄駅:名称y | m2x市区町村コード | m2m2x市区町村コード | m2m2x市区町村コード_sta | m2x地区詳細 | m2m2x地区詳細 | m2m2x地区詳細_sta | m2x最寄駅:名称 | m2m2x最寄駅:名称 | m2m2x最寄駅:名称_sta | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | 中古マンション等 | 13101 | 55.0 | 80.0 | 600.0 | 1.0 | NaN | 千代田区飯 | NaN | ... | 23.325 | 34.818967 | 34.818967 | 34.122588 | 20.7350 | 20.7350 | 20.3203 | 12.82875 | 12.82875 | 12.572175 |
1 | NaN | 中古マンション等 | 13101 | 20.0 | 80.0 | 500.0 | 5.0 | NaN | 千代田区飯 | NaN | ... | 23.325 | 12.661443 | 12.661443 | 11.395298 | 7.5400 | 7.5400 | 6.7860 | 4.66500 | 4.66500 | 4.198500 |
2 | NaN | 中古マンション等 | 13101 | 45.0 | 80.0 | 500.0 | 3.0 | NaN | 千代田区飯 | NaN | ... | 23.325 | 28.488246 | 28.488246 | 26.778951 | 16.9650 | 16.9650 | 15.9471 | 10.49625 | 10.49625 | 9.866475 |
3 | NaN | 中古マンション等 | 13101 | 20.0 | 80.0 | 500.0 | 5.0 | NaN | 千代田区飯 | NaN | ... | 23.325 | 12.661443 | 12.661443 | 11.395298 | 7.5400 | 7.5400 | 6.7860 | 4.66500 | 4.66500 | 4.198500 |
4 | 5.0 | 宅地(土地と建物) | 13101 | 80.0 | 80.0 | 500.0 | 3.0 | 南西 | 千代田区飯 | ほぼ台形 | ... | 23.325 | 50.645770 | 259.559574 | 243.985999 | 30.1600 | 154.5700 | 145.2958 | 18.66000 | 95.63250 | 89.894550 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
391183 | 0.0 | 宅地(土地と建物) | 13401 | 840.0 | 60.0 | 200.0 | NaN | 北西 | 八丈町三根 | ほぼ台形 | ... | 0.311 | 1.380400 | 1.479000 | NaN | 2.6124 | 2.7990 | NaN | 2.61240 | 2.79900 | NaN |
391184 | 0.0 | 宅地(土地) | 13401 | 370.0 | 70.0 | 200.0 | NaN | 北 | 八丈町三根 | ほぼ長方形 | ... | 0.311 | 0.608033 | 0.608033 | NaN | 1.1507 | 1.1507 | NaN | 1.15070 | 1.15070 | NaN |
391185 | 0.0 | 宅地(土地) | 13401 | 520.0 | 70.0 | 200.0 | NaN | 北東 | 八丈町三根 | 不整形 | ... | 0.311 | 0.854533 | 0.854533 | NaN | 1.6172 | 1.6172 | NaN | 1.61720 | 1.61720 | NaN |
391186 | 0.0 | 宅地(土地) | 13421 | 380.0 | 40.0 | 200.0 | NaN | 南 | 小笠原村父 | ほぼ台形 | ... | 0.522 | 1.983600 | 1.983600 | NaN | 1.9836 | 1.9836 | NaN | 1.98360 | 1.98360 | NaN |
391187 | 0.0 | 宅地(土地) | 13421 | 350.0 | 70.0 | 200.0 | NaN | 北東 | 小笠原村母 | 不整形 | ... | 0.522 | 1.827000 | 1.827000 | NaN | 1.8270 | 1.8270 | NaN | 1.82700 | 1.82700 | NaN |
391188 rows × 45 columns
#、で区切られてるのをonehot化
all_df_target = all_df_target.join(all_df_target['建物の構造'].str.get_dummies(sep='、'))
all_df_target = all_df_target.join(all_df_target['用途'].str.get_dummies(sep='、'))
all_df_target = all_df_target.join(all_df_target['間取り'].str[2:].str.get_dummies(sep='、'))
# all_df_target = all_df_target.drop(columns=['建物の構造', '用途', '間取り'])
all_df_target['m2kai'] = all_df_target['延床面積(㎡)'] / all_df_target['面積(㎡)']
all_df_target['men_magu'] = all_df_target['面積(㎡)'] / all_df_target['間口']
all_df_target['men_toshi'] = all_df_target['面積(㎡)'] * all_df_target['都市計画y']
all_df_target['douro_haba_syu'] = all_df_target['前面道路:種類y'] * all_df_target['前面道路:幅員(m)']
all_df_target['toshi_tyoson'] = all_df_target['都市計画y'] * all_df_target['市区町村コードy']
all_df_target['syuru_magu'] = all_df_target['間口'] / all_df_target['前面道路:種類y']
all_df_target['haba_magu'] = all_df_target['間口'] / all_df_target['前面道路:幅員(m)']
all_df_target['heya_m'] = all_df_target['面積(㎡)'] / all_df_target['部屋数']
#確認
all_des = all_df_target.describe(include='all')
all_des.round(2)
地域 | 種類 | 市区町村コード | 面積(㎡) | 建ぺい率(%) | 容積率(%) | 最寄駅:距離(分) | 前面道路:方位 | 地区詳細 | 土地の形状 | ... | S | T | m2kai | men_magu | men_toshi | douro_haba_syu | toshi_tyoson | syuru_magu | haba_magu | heya_m | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 214339.00 | 391188 | 391188.00 | 391188.00 | 385417.00 | 385417.00 | 380898.00 | 213915 | 390942 | 213940 | ... | 391188.00 | 391188.00 | 131541.00 | 196158.00 | 386008.00 | 209169.00 | 386008.00 | 193302.00 | 193651.00 | 170427.00 |
unique | NaN | 5 | NaN | NaN | NaN | NaN | NaN | 9 | 1236 | 9 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
top | NaN | 中古マンション等 | NaN | NaN | NaN | NaN | NaN | 南 | 大田区大森 | ほぼ長方形 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
freq | NaN | 176330 | NaN | NaN | NaN | NaN | NaN | 33859 | 3345 | 74779 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
mean | 0.58 | NaN | 13139.98 | 116.96 | 62.08 | 264.86 | 10.72 | NaN | NaN | NaN | ... | 0.00 | 0.00 | 1.23 | 17.48 | 880.97 | 67.51 | 189.86 | 2.29 | 1.87 | 11.78 |
std | 1.67 | NaN | 46.23 | 200.10 | 13.13 | 159.58 | 9.77 | NaN | NaN | NaN | ... | 0.07 | 0.01 | 1.00 | 12.76 | 2132.03 | 164.01 | 500.68 | 4.82 | 1.46 | 14.83 |
min | 0.00 | NaN | 13101.00 | 10.00 | 30.00 | 50.00 | 0.00 | NaN | NaN | NaN | ... | 0.00 | 0.00 | 0.02 | 0.52 | 28.97 | 0.16 | 1.02 | 0.02 | 0.03 | 1.67 |
25% | 0.00 | NaN | 13110.00 | 50.00 | 60.00 | 150.00 | 5.00 | NaN | NaN | NaN | ... | 0.00 | 0.00 | 0.78 | 10.62 | 284.03 | 11.79 | 16.20 | 0.67 | 1.00 | 10.00 |
50% | 0.00 | NaN | 13117.00 | 70.00 | 60.00 | 200.00 | 8.00 | NaN | NaN | NaN | ... | 0.00 | 0.00 | 1.00 | 13.75 | 400.92 | 25.04 | 26.08 | 1.36 | 1.60 | 10.83 |
75% | 0.00 | NaN | 13201.00 | 115.00 | 80.00 | 300.00 | 13.00 | NaN | NaN | NaN | ... | 0.00 | 0.00 | 1.40 | 18.75 | 719.79 | 64.15 | 79.26 | 2.95 | 2.29 | 12.50 |
max | 9.00 | NaN | 13421.00 | 2500.00 | 80.00 | 1300.00 | 120.00 | NaN | NaN | NaN | ... | 1.00 | 1.00 | 66.00 | 625.00 | 89973.68 | 4082.99 | 2958.25 | 338.46 | 45.83 | 2500.00 |
11 rows × 76 columns
#ラベルエンコード
for col in all_df_target.columns:
if all_df_target[col].dtype == 'object':
print(col, all_df_target[col].dtype)
#temp = all_df_target[[col, 'logy']].groupby(col).mean()['logy']
#all_df_target[col] = all_df_target[col].map(temp)
labels, uniques = all_df_target[col].factorize(sort=True)
all_df_target[col] = labels
種類 object 前面道路:方位 object 地区詳細 object 土地の形状 object 市区町村名 object 前面道路:種類 object 建物の構造 object 最寄駅:名称 object 用途 object 都市計画 object 改装 object 間取り object 取引の事情等 object
all_df_target.columns
Index(['地域', '種類', '市区町村コード', '面積(㎡)', '建ぺい率(%)', '容積率(%)', '最寄駅:距離(分)', '前面道路:方位', '地区詳細', '土地の形状', '市区町村名', '前面道路:種類', '前面道路:幅員(m)', '間口', '建物の構造', '最寄駅:名称', '用途', '都市計画', '建築年(西暦)', 'y', 'logy', '延床面積(㎡)', '改装', '間取り', '取引の事情等', '間取り数', '部屋数', '地域y', '市区町村コードy', '地区詳細y', '建ぺい率(%)y', '容積率(%)y', '都市計画y', '前面道路:方位y', '前面道路:種類y', '最寄駅:名称y', 'm2x市区町村コード', 'm2m2x市区町村コード', 'm2m2x市区町村コード_sta', 'm2x地区詳細', 'm2m2x地区詳細', 'm2m2x地区詳細_sta', 'm2x最寄駅:名称', 'm2m2x最寄駅:名称', 'm2m2x最寄駅:名称_sta', 'ブロック造', '木造', '軽量鉄骨造', '鉄骨造', 'RC', 'SRC', 'その他', '事務所', '住宅', '作業場', '倉庫', '共同住宅', '工場', '店舗', '駐車場', 'D', 'K', 'L', 'M', 'O', 'R', 'S', 'T', 'm2kai', 'men_magu', 'men_toshi', 'douro_haba_syu', 'toshi_tyoson', 'syuru_magu', 'haba_magu', 'heya_m'], dtype='object')
#トレーニングデータ取り出し
x_train = all_df_target[all_df_target['y']>=0].drop(['y', 'logy'], axis=1).values
y_train = all_df_target[all_df_target['y']>=0].loc[:, 'y'].values
print(x_train.shape, y_train.shape)
(356344, 74) (356344,)
# テストデータ取り出し
x_test = all_df_target[all_df_target['y']<0].drop(['y', 'logy'], axis=1).values
y_test = -all_df_target[all_df_target['y']<0].loc[:, 'y'].values
print(x_test.shape, y_test.shape)
(34844, 74) (34844,)
#外れ値と予想
large_y_index = [1305, 1960, 8069]
#5foldでモデルを作成、評価
from sklearn.model_selection import KFold
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
kf = KFold(n_splits=5, shuffle=True, random_state=1)
s = list(kf.split(x_train, y_train))
#yに補正をかけて全体で推論
ymin = 0.1
ymax = 30000
n = 5
line = 7000
y_train2 = y_train.copy()
y_train2[y_train2>=line] = (y_train2[y_train2>=line]-line)/n+line
print(y_train2.max())
gbk = lgb.LGBMRegressor(n_estimators=500, max_depth=9, subsample=0.8, colsample_bytree=0.8, min_child_weight=1)
gbk.fit(x_train, np.clip(y_train2, ymin, ymax))
y_pred = np.clip(gbk.predict(x_test), 0, 100000)
y_val = y_test
acc_gbk = np.sqrt(mean_squared_error(y_val, np.where(y_val>10000, y_val, y_pred))).round(1)
acc_gbk2 = np.sqrt(mean_squared_error(y_val, np.where(y_val>5000, y_val, y_pred))).round(1)
print(n, line, 'rmse', acc_gbk, 'rmse-1000', acc_gbk2)
17800.0 5 7000 rmse 159.9 rmse-1000 159.9
#yに補正をかけて全体で推論
ymin = 0.1
ymax = 30000
n = 5
line = 7000
y_train2 = y_train.copy()
y_train2[y_train2>=line] = (y_train2[y_train2>=line]-line)/n+line
print(y_train2.max())
gbk = lgb.LGBMRegressor(n_estimators=300, max_depth=6, subsample=0.8, colsample_bytree=0.8, min_child_weight=1)
gbk.fit(x_train, np.clip(y_train2, ymin, ymax))
y_pred2 = np.clip(gbk.predict(x_test), 0, 100000)
y_val = y_test
acc_gbk = np.sqrt(mean_squared_error(y_val, np.where(y_val>10000, y_val, y_pred2))).round(1)
acc_gbk2 = np.sqrt(mean_squared_error(y_val, np.where(y_val>5000, y_val, y_pred2))).round(1)
print(n, line, 'rmse', acc_gbk, 'rmse-1000', acc_gbk2)
17800.0 5 7000 rmse 162.7 rmse-1000 162.7
#大きいもののみを使用して推論
gbk_l = lgb.LGBMRegressor(n_estimators=200, max_depth=4, subsample=0.8, colsample_bytree=0.8, min_child_weight=1)
gbk_l.fit(x_train[y_train>5000], y_train[y_train>5000])
y_pred_l = np.clip(gbk_l.predict(x_test), 0, 100000).round(1)
acc_gbk = np.sqrt(mean_squared_error(y_pred_l[large_y_index], y_test[large_y_index])).round(1)
#おみくじ
import itertools
a = [0.5, 1, 1.5, 2]
b = [0.5, 1, 1.5, 2]
c = [1, 2, 3]
for use in range(48):
kumi = list(itertools.product(a,b,c))
#use = 0
use_kumi =np.array(kumi[use])
use_kumi_str = '_'.join(list(map(str, kumi[use])))
print(use_kumi, use_kumi_str)
kesu=np.array([[0.25, 0.95]]).reshape(2,1)
preds = (np.array([y_pred, y_pred2])*kesu).sum(0)
preds[large_y_index] = y_pred_l[large_y_index]*use_kumi
test_df['y'] = preds.round(1)
test_df[['id', 'y']].head()
test_df[['id', 'y']].to_csv('20200418_last_{}_{}.csv'.format(use, use_kumi_str), index=False)
[0.5 0.5 1. ] 0.5_0.5_1
chun1182
https://prob.space/competitions/real_estate_2020/discussions/chun1182-Post3748b67697bb27cb59e8
にありますが、いちいち前のコンペのページに行くのも面倒だと思うのでこちらにも貼ります。
前回のコンペの解法です、tutorialとして使用して下さい。スコアは0.38176です。
kesuのところがどう考えても悪さしてるのと、yをlogにしてから学習をしてないのでそこを対応すればもうちょっと精度は出るかと思われます。