과정:
1. 데이터 준비
2. 데이터 전처리
3. 모델 학습
4. 모델 평가
1. 데이터 준비:
- 실거래가 공개시스템에서 다운로드 (http://rtdown.molit.go.kr/)
- 다세대(연립)
- 2022년도
- 2023년도 1월~6월
- 2023년도 7월, 8월 (26일까지)
2. 데이터 전처리:
- train: 2022년도, 2023년도 1월~6월
- validate: 2023년도 7월, 8월 (26일까지)
- train 데이터 합치기
- 데이터 중 전세 제거
- 보증금 column 에서 comma 제거
- 시군구 column 데이터는 labelencoder 로 값 부여
- drop nan data
- 월세 column 에서 str 골라내서 comma 제거 및 int로 type 변경
3. 모델 학습:
- model: RandomForestRegressor
4. 모델 평가:
- error: mean_absolute_error
- result: 13.58378536758879
5. 결론:
- 현재 모델로 월세 계산시 약 13만원 차이가 위 또는 아래로 발생함
In [1]:
import os
import pandas as pd
os.chdir('./data/서울')
In [2]:
전월세_2023_train = pd.read_csv('연립다세대(전월세)_실거래가_2023년1월~6월.csv', encoding='cp949')
/tmp/ipykernel_42800/77199815.py:1: DtypeWarning: Columns (10,18) have mixed types. Specify dtype option on import or set low_memory=False. 전월세_2023_train = pd.read_csv('연립다세대(전월세)_실거래가_2023년1월~6월.csv', encoding='cp949')
In [3]:
len(전월세_2023_train)
Out[3]:
66751
In [4]:
전월세_2023_train.head()
Out[4]:
시군구 | 번지 | 본번 | 부번 | 건물명 | 전월세구분 | 전용면적(㎡) | 계약년월 | 계약일 | 보증금(만원) | 월세(만원) | 층 | 건축년도 | 도로명 | 계약기간 | 계약구분 | 갱신요구권 사용 | 종전계약 보증금 (만원) | 종전계약 월세 (만원) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 서울특별시 강남구 개포동 | 1163-4 | 1163 | 4 | (1163-4) | 전세 | 21.88 | 202301 | 20 | 16,000 | 0 | 3 | 2013.0 | 논현로 10 | 202302~202502 | 신규 | - | 0 | 0.0 |
1 | 서울특별시 강남구 개포동 | 1163-4 | 1163 | 4 | (1163-4) | 월세 | 13.56 | 202301 | 28 | 1,000 | 50 | 2 | 2013.0 | 논현로 10 | 202302~202501 | 신규 | - | 0 | 0.0 |
2 | 서울특별시 강남구 개포동 | 1163-4 | 1163 | 4 | (1163-4) | 월세 | 13.56 | 202303 | 9 | 2,500 | 45 | 4 | 2013.0 | 논현로 10 | 202304~202503 | 신규 | - | 0 | 0.0 |
3 | 서울특별시 강남구 개포동 | 1172-2 | 1172 | 2 | (1172-2) | 월세 | 42.15 | 202303 | 14 | 1,500 | 110 | 2 | 2012.0 | 논현로6길 22-6 | 202305~202505 | 갱신 | 사용 | 1,500 | 105.0 |
4 | 서울특별시 강남구 개포동 | 1181-8 | 1181 | 8 | (1181-8) | 월세 | 44.45 | 202303 | 11 | 3,000 | 80 | 2 | 2020.0 | 논현로8길 62-3 | 202305~202505 | 신규 | - | 0 | 0.0 |
In [5]:
전월세_validate = pd.read_csv('연립다세대(전월세)_실거래가_2023년7월8월.csv', encoding='cp949')
In [6]:
len(전월세_validate)
Out[6]:
14564
In [7]:
전월세_validate.head()
Out[7]:
시군구 | 번지 | 본번 | 부번 | 건물명 | 전월세구분 | 전용면적(㎡) | 계약년월 | 계약일 | 보증금(만원) | 월세(만원) | 층 | 건축년도 | 도로명 | 계약기간 | 계약구분 | 갱신요구권 사용 | 종전계약 보증금 (만원) | 종전계약 월세 (만원) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 서울특별시 강남구 개포동 | 1163-4 | 1163 | 4 | (1163-4) | 전세 | 21.88 | 202307 | 22 | 17,000 | 0 | 5 | 2013.0 | 논현로 10 | - | - | - | NaN | NaN |
1 | 서울특별시 강남구 개포동 | 1218-19 | 1218 | 19 | (1218-19) | 월세 | 59.04 | 202308 | 10 | 35,000 | 10 | 3 | 2013.0 | 개포로22길 29 | 202309~202509 | 갱신 | - | 0 | 10.0 |
2 | 서울특별시 강남구 개포동 | 1233-22 | 1233 | 22 | (1233-22) | 월세 | 26.90 | 202307 | 18 | 12,000 | 80 | 4 | 2015.0 | 논현로18길 18-5 | 202308~202508 | 갱신 | 사용 | 12,000 | 85.0 |
3 | 서울특별시 강남구 개포동 | 171-13 | 171 | 13 | (171-13) | 월세 | 45.14 | 202308 | 14 | 500 | 60 | -1 | 1988.0 | 선릉로14길 11 | 202308~202312 | 신규 | - | 0 | 0.0 |
4 | 서울특별시 강남구 개포동 | 1186 | 1186 | 0 | 1186HOUSE | 월세 | 47.05 | 202307 | 12 | 10,000 | 120 | 2 | 2020.0 | 논현로8길 24 | 202308~202508 | 신규 | - | 0 | 0.0 |
In [8]:
전월세_2022_train = pd.read_csv('연립다세대(전월세)_실거래가_2022년1월~12월.csv', encoding='cp949')
/tmp/ipykernel_42800/3982910938.py:1: DtypeWarning: Columns (10,18) have mixed types. Specify dtype option on import or set low_memory=False. 전월세_2022_train = pd.read_csv('연립다세대(전월세)_실거래가_2022년1월~12월.csv', encoding='cp949')
In [9]:
전월세_train = pd.concat([전월세_2022_train, 전월세_2023_train], ignore_index=True)
len(전월세_train)
Out[9]:
210550
In [10]:
전월세_train.columns
Out[10]:
Index(['시군구', '번지', '본번', '부번', '건물명', '전월세구분', '전용면적(㎡)', '계약년월', '계약일', '보증금(만원)', '월세(만원)', '층', '건축년도', '도로명', '계약기간', '계약구분', '갱신요구권 사용', '종전계약 보증금 (만원)', '종전계약 월세 (만원)'], dtype='object')
In [11]:
전월세_train = 전월세_train[전월세_train['전월세구분'] == '월세']
In [12]:
전월세_train.head()
Out[12]:
시군구 | 번지 | 본번 | 부번 | 건물명 | 전월세구분 | 전용면적(㎡) | 계약년월 | 계약일 | 보증금(만원) | 월세(만원) | 층 | 건축년도 | 도로명 | 계약기간 | 계약구분 | 갱신요구권 사용 | 종전계약 보증금 (만원) | 종전계약 월세 (만원) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 서울특별시 강남구 개포동 | 1163-4 | 1163 | 4 | (1163-4) | 월세 | 13.56 | 202207 | 14 | 1,000 | 90 | 2 | 2013.0 | 논현로 10 | 202207~202407 | 신규 | - | 0 | 0.0 |
12 | 서울특별시 강남구 개포동 | 1196-11 | 1196 | 11 | (1196-11) | 월세 | 55.28 | 202204 | 7 | 3,000 | 120 | 4 | 2014.0 | 논현로12길 9-10 | 202205~202405 | 신규 | - | 0 | 0.0 |
13 | 서울특별시 강남구 개포동 | 1196-11 | 1196 | 11 | (1196-11) | 월세 | 57.66 | 202205 | 20 | 10,000 | 120 | 2 | 2014.0 | 논현로12길 9-10 | 202205~202405 | 신규 | - | 0 | 0.0 |
14 | 서울특별시 강남구 개포동 | 1201-7 | 1201 | 7 | (1201-7) | 월세 | 22.24 | 202206 | 14 | 1,000 | 90 | 3 | 2021.0 | 개포로22길 49-5 | 202207~202407 | 신규 | - | 0 | 0.0 |
15 | 서울특별시 강남구 개포동 | 1201-7 | 1201 | 7 | (1201-7) | 월세 | 22.95 | 202208 | 18 | 2,000 | 150 | 4 | 2021.0 | 개포로22길 49-5 | 202209~202409 | 신규 | - | 0 | 0.0 |
In [13]:
전월세_train['보증금(만원)'] = 전월세_train['보증금(만원)'].str.replace(',', '')
In [14]:
전월세_train['보증금(만원)']
Out[14]:
2 1000 12 3000 13 10000 14 1000 15 2000 ... 210539 5700 210540 3420 210543 13000 210544 15000 210546 414 Name: 보증금(만원), Length: 87728, dtype: object
In [15]:
전월세_validate = 전월세_validate[전월세_validate['전월세구분'] == '월세']
In [16]:
전월세_validate['보증금(만원)'] = 전월세_validate['보증금(만원)'].str.replace(',', '')
In [17]:
from sklearn.preprocessing import LabelEncoder
In [18]:
label_encoder = LabelEncoder()
전월세_train['시군구'] = label_encoder.fit_transform(전월세_train['시군구'])
In [19]:
전월세_validate['시군구'] = label_encoder.transform(전월세_validate['시군구'])
In [20]:
len(전월세_train)
Out[20]:
87728
In [21]:
전월세_train = 전월세_train.dropna()
In [22]:
len(전월세_train)
Out[22]:
69840
In [23]:
전월세_validate = 전월세_validate.dropna()
In [24]:
전월세_train.columns
Out[24]:
Index(['시군구', '번지', '본번', '부번', '건물명', '전월세구분', '전용면적(㎡)', '계약년월', '계약일', '보증금(만원)', '월세(만원)', '층', '건축년도', '도로명', '계약기간', '계약구분', '갱신요구권 사용', '종전계약 보증금 (만원)', '종전계약 월세 (만원)'], dtype='object')
In [25]:
전월세_train_features = ['시군구','전용면적(㎡)', '계약년월', '보증금(만원)', '층', '건축년도']
In [26]:
train_y = 전월세_train['월세(만원)']
In [27]:
len(train_y)
Out[27]:
69840
In [28]:
train_X = 전월세_train[전월세_train_features]
In [29]:
len(train_X)
Out[29]:
69840
In [30]:
val_y = 전월세_validate['월세(만원)']
In [31]:
val_X = 전월세_validate[전월세_train_features]
In [32]:
for idx, val in enumerate(train_y.values):
if type(val) == str:
print(train_y.values[idx])
train_y.values[idx] = int(val.replace(',', ''))
print(train_y.values[idx])
In [33]:
for idx, val in enumerate(val_y.values):
if type(val) == str:
val = val.replace(',', '')
val_y.values[idx] = int(val)
In [34]:
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
model = RandomForestRegressor(random_state=1)
model.fit(train_X, train_y)
Out[34]:
RandomForestRegressor(random_state=1)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomForestRegressor(random_state=1)
In [35]:
predicted = model.predict(val_X)
print(mean_absolute_error(val_y, predicted))
13.58378536758879