딥러닝(LSTM)으로 아파트 지수 예측하기 – 1) 훈련 데이터 생성

이번 포스팅에서는 LSTM으로 아파트 지수 예측하기 실험을 하겠습니다.

LSTM은 RNN(Recurrent Neural Network) 알고리즘의 특별한 한 종류입니다. RNN은 글, 유전자, 손글씨, 음성 신호, 주가 등 배열(sequence 또는 시계열 데이터)의 형태를 갖는 데이터에서 패턴을 인식하는 인공 신경망입니다. LSTM은 기존 RNN을 개선한 모델로 긴 의존 기간(long-term dependency)을 필요로 하는 데이터를 학습하는데 효과적인 모델입니다. RNN과 LSTM에 대한 알고리즘에 대한 설명은 개별 포스팅을 작성해서 추후에 링크 걸어놓도록 하겠습니다.

이번 포스팅에서는 실험을 먼저 진행해 보겠습니다. LSTM 실험에는 시계열 데이터가 필요하기 때문에 연속된 부동산 매매 데이터가 필요합니다. 부동산 개별 실거래가는 매달에 맞춰 거래가 일어나지 않기 때문에 일단 한국감정원에서 배포하는 전국주택가격지수 중에서 강남구의 아파트 거래가격 지수를 사용하겠습니다. 부동산 개별 실거래가를 사용한 실험이나 다른 경제 지표와 같이 수행하는 실험은 이어서 포스팅하겠습니다.

실험에 사용한 전체 코드와 데이터는 여기서 다운로드 받을 수 있습니다. 실험은 google colab (설명)에서 진행했습니다.

실험 데이터 업로드 하기

패키지 import & 실험 데이터 파일 올리기

실험에 사용할 패키지들을 import합니다. 구글 colab에서 데이터 업로드를 하기 위해 google.colab 패키지의 upload 함수를 사용합니다. 아래와 같이 데이터 업로드가 정상적으로 완료되었습니다.

데이터 파일은 아래와 같이 날짜와 그 달의 강남구 아파트 매매 지수가 있는 간단한 형식으로 되어있습니다.

date,trade_price_idx_value
2006-01-01,74.200000000000003
2006-02-01,75.799999999999997
2006-03-01,78.099999999999994
2006-04-01,81.400000000000006
2006-05-01,83.599999999999994
2006-06-01,83.799999999999997
2006-07-01,83.599999999999994
2006-08-01,83.5

데이터 기본 format

df.info()로 데이터를 살펴봅니다. 기간은 2006년도에서 2019년도로 되어있지만 매달 한 건의 강남구 아파트 매매지수만 있다보니 데이터 개수는 생각보다 적습니다. 총 165개의 데이터가 있습니다.

훈련 데이터와 테스트 데이터 분리하기

plot으로 데이터 흐름을 살펴봅니다. 2014년도가 강남구 아파트 매매지수의 저점이였고 그 후 가파르게 상승하고 있습니다. 이제 데이터를 훈련 데이터, 테스트 데이터로 분리합니다. 2017년 1월 1일까지의 데이터를 훈련 데이터, 그 이후의 데이터를 테스트 데이터로 분리합니다.

그래프에서 train set과 test set을 색으로 표시하면 아래와 같습니다.


plot으로 표시된 train, test 데이터 셋

데이터 스케일링(Scaling)

마지막으로 MinMaxScaler 클래스를 사용하여 데이터를 스케일링 합니다. MinMaxScalar(X)는 데이터의 최대값이 1, 최소값이 0이 되도록 변환합니다. 이렇게 데이터의 scale을 맞추면 weight의 scale도 일관성 있게 나올 수 있습니다.

사용방법은 다음과 같습니다.

(1) 훈련 데이터의 분포 추정 : 훈련 데이터를 입력으로 하여 fit 메서드를 실행하여 분포 모수를 객체내에 저장
(2) 훈련 데이터의 변환 : 훈련 데이터를 입력으로 하여 transform 메서드를 실행하면 훈련 데이터를 변환
(3) 테스트 데이터의 변환: 테스트 데이터를 입력으로 하여 transform 메서드를 실행하여 테스트 데이터를 변환.

훈련 데이터는 (1)번과 (2)번 과정을 합쳐서 fit_transform 메서드를 사용하고 테스트 데이터는 transform 메서드를 사용하여 스케일링을 진행합니다.

정규화가 완료된 데이터들은 다시 pandas dataframe 데이터 타입으로 변환합니다. dataframe으로 타입을 변경하는 이유는 pandas는 시계열 자료에 대한 다양한 기능을 제공하여 LSTM에서 사용하는 window를 만들기 유용하기 때문입니다.

sliding window 구성하기

window는 LSTM을 훈련하기 위한 단위로 고정된 사이즈를 가집니다. window가 12개라면 과거 시간 데이터 12개를 사용해서 다음 시간 단위의 값을 예측하게 됩니다. 현재 실험 데이터의 경우 과거의 시간 단위 12개 부동산 지수들이 훈련 속성들이 되고 현재 시간의 부동산 지수가 target이 됩니다.

dataframe의 shift 연산을 사용하면 인덱스는 그대로 두고 데이터만 시간 단위로 이동할 수 있어 sliding window 타입의 데이터를 구성하기에 용이합니다. 예를 들어 shift(1)을 하면 바로 다음 시간 인덱스로 데이터가 이동하며 shift(-1)을 하면 바로 이전 시간 인덱스로 데이터가 이동합니다. 아래 예시를 보면서 자세히 설명해보겠습니다.

shift 사용하여 window 구성

shift(1)을 사용한 칼럼은 데이터 값이 다음 시간 인덱스로 한칸씩 이동한 것을 확인할 수 있습니다. 이렇게 구성된 데이터에서 dropna로 NaN값을 포함한 데이터를 제거하고 드디어 본격적인 실험에 들어갑니다. 생각보다 포스팅이 길어져서 여기서 한번 자르고 다음 포스팅으로 이어 쓰겠습니다.

참고:

LSTM 실험 (Keras) :
https://3months.tistory.com/168

minmax:
https://datascienceschool.net/view-notebook/f43be7d6515b48c0beb909826993c856/

scikit-learn을 사용하여 부동산 가격 예측하기 – 4) linear regression 사용법

scikit-learn을 사용하여 부동산 가격 예측하기 실험 시리즈 네번째 포스팅입니다.이제 본격적인 실험에 들어갑니다. 

기계학습을 할 경우 실험 과제의 특성(분류화, 클러스터링 등)와 데이터의 속성 및 복잡도, 사이즈에 따라 적합한 학습방법을 선택해야 합니다. 이 실험에서는 데이터 개수와 속성 개수가 적으면서 실제 예측값이 나와야 하므로 싸이킷런에서 제공하는 가장 간단한 알고리즘인 선형 회귀(linear regression) 알고리즘을 사용해 보겠습니다. 나중에 개별 매물 평가 실험에서는 부동산 실거래가 데이터를 사용하여 신경망을 사용한 더 복잡한 기계학습을 사용해보려고 합니다.

이전 포스팅 내용 요약

이전 포스팅에서 속성 소개, 데이터 분석에 대해서 완료했습니다. 그 중 데이터를 읽어와서 pandas dataframe으로 저장한 이후에 이어서 실험을 하겠습니다.

dropna 함수로 속성에 빈 값이 있는 데이터는 실험에서 제거하였습니다.

실험 데이터는 2017년도 이전의 데이터는 훈련 데이터 셋으로, 2017년 이상의 데이터는 테스터 데이터셋으로 구성을 했습니다. 일반적인 fold validation으로 실험데이터를 구성하지 않은 이유는 예측 실험에서는 과거 데이터로 최근의 데이터를 예측하는 것이 중요하다고 생각하였기 때문입니다. 나중에 소개드릴 로보리포트 시계열 예측 서비스에서는 다양한 방식으로 실험 데이터를 구성하도록 지원하고 있습니다.

X_train.shape : (6356, 16) 
X_test.shape : (196, 16)

속성 소개하기

전체 16개의 속성이며 훈련 셋 크기는 6356개, 테스트 셋 크기는 196개 입니다. 참고로 실험 속성은 지역코드, 년도, 월, 빌딩 타입(아파트, 빌라 등), 매매가격 지수, 금리, 환율, 미분양 데이터 등입니다. 자세한 내용은 아래 표를 참조해 주세요.
그리고 target 속성은 다음달 주택 매매가격지수(tradeprice_sido_n1)를 설정했습니다.

region_cd 지역코드(시도)
year 연도
month
building_type 부동산타입
tradeprice_sido 매매가격지수(시도)
construction_realized_amount 건설기성액(백만원)
cd
cd(91일물)

spirit_deposit_rate

정기예금금리
exchange_rate 환율
composite_stock_price_index 종합주가지수
economy_growth 경제성장률
exchequer_bond_three 채3년
household_loan_all 가계대출액(전국)
mortgage_all 주택대출액(전국)
numberofnosells 미분양 가구수(시도)
unsalenum_c 공사완료후 미분양(민간,시도)

실험을 하기 위해 우선 Linear Regression 패키지를 import 합니다. 선형 회귀 알고리즘(linear regression)은 주어진 데이터 집합에 대해 종속 변수 Y 와 설명 변수 X와의 선형 관계를 모델링합니다. 쉽게 이야기해서 아래와 같이 실험 데이터에 가장 근사하게 매치하는 직선을 그린다고 생각하면 됩니다. y절편은 이 직선이 y축과 만나는 점을 의미하며 LinearRegression 클래스의 intercept_ 속성에 그 값이 저장됩니다.

표현식은 아래와 같습니다. 이중에서 베타는 weight, 상관계수 라고도 불리며 각 속성의 영향도를 의미합니다. 실험이 끝나면 훈련이 끝난 모델의 coef_ 속성에 값이 저장됩니다. intercept_ 속성은 항상 실수 값 하나지만, coef_ 속성은 각 입력 특성에 하나씩 대응되는 Numpy 배열입니다. 16개의 속성이므로 coef_ 속성 배열 사이즈도 16이 될 것 입니다.

선형회귀 실험

LinearRegression 함수 인자의 문는 아래를 참고하세요.

fit_intercept는 y 절편을 계산할지에 대한 설정입니다. 데이터를 표현하는 식이 원점을 지나가는 선이 최적화된 선이 아니라면 기본적으로 사용하는 것이 좋습니다. normalize는 regressors X를 정규화 시킬 것인지에 대한 옵션입니다. n_jobs 는 모델 계산에 사용될 작업 개수를 의미합니다. 데이터 개수가 작아 None으로 설정했습니다.

Linear Regression test file accuracy:0.904775830424
Out[12]:
array([ 2.41360754e-06, -1.43348218e-01, -6.30260362e-03, -9.82386414e-03, 9.78713133e-01, -9.70551425e-09, 2.54192891e-01, -1.51807329e-01, 1.58985085e-05, 5.78284319e-04, 1.10692957e-01, -6.18784363e-02, -5.71178866e-06, 1.41955024e-05, -1.97553459e-05, -4.99848193e-06])

sklearn은 기본적으로 fit 함수를 사용하여 훈련 데이터 셋에서 모델을 생성합니다. 그리고 score 함수를 사용해서 생성된 모델의 성능을 확인하고 predict 함수로 테스트 셋의 예측값을 생성합니다. 이 세가지 함수는 알고리즘의 종류와 관계 없이 대부분의 알고리즘에 존재합니다.

Score 함수에서 리턴하는 값은 R2 이며 결정계수, R-Square,
coefficient of determination 로도 불립니다. 결정계수는 모델의 전반적인 성능을 0~1까지의 숫자로 알려줍니다. 종속 변수와 독립 변수와의 상관도가 높을 수록 값은 1에 가까워 집니다. 실험에서 나온 결정계수의 스코어는 0.90으로 그럭저럭 높은 예측값을 보여줍니다. 그리고 coef_ 변수에는 각 속성들의 상관계수 값이 들어있습니다. 상관계수는 -1 에서 1까의 값을 가지며 -는 음의 영향력, +는 양의 영향력을 의미합니다. 부호와 상관없이 숫자의 절대값은 영향력의 크기를 의미합니다.

위 코드에서 속성의 순서에 따라 결정계수의 값이 배열로 들어있긴 하지만 속성과 연관해서 확인하기는 힘들어서 한글 속성 이름으로 변경하고 절대값이 큰 순서로 정렬해서 pandas dataframe으로 다시 확인해 보았습니다.

당연한 결과이지만 해당 월의 매매가격 지수가 0.9로 매우 강한 양의 상관관계를 보이고 그외 단기 금리인 cd와 0.25의 약한 양의 상관관계, 정기예금금리와는 -0.15의 약한 음의 관계, 연도와는 -, 경제성장률은 +의 매우 약한 상관 관계를 보여주고 있습니다. 그 외 나머지는 0.1 이하의 값으로 크게 상관관계가 없어보입니다. 미분양 데이터가 상관관계가 적어보이는 것은 약간 의아하지만 바로 다음달의 매매가격지수를 예측했기에 그럴 수도 있을 것 같습니다. 어느정도 시차를 두고 영향을 끼치는 속성들은 3개월후, 6개월후, 1년후 등으로 예측 시기를 변경해서 실험을 해보는 것도 의미가 있을 것 같습니다.

실험 결과 해석하기

다음은 테스트셋의 실제 값을 x축으로 예측 값을 y축으로 그래프를 그려보겠습니다. 원칙적으로 모든 예측 값이 실제 값과 일치하면 직선이 나올 것이고 모델의 성능이 좋지 않을 수록 흩어진 점들을 볼 수 있을 것입니다. 해당 실험은 아래와 같이 어느정도 직선에 가까운 모습을 보입니다.

mse = sklearn.metrics.mean_squared_error(Y_test, Y_pred)
print(mse)


0.100838171768

그리고 실제 값과 예측 값의 mean squared error를 구해보았습니다. mean squared error는 오차의 제곱의 평균값을 계산한 값으로 숫자가 적을 수록 예측값과 실제 값의 차이가 적은 것을 의미합니다. 0.1의 값이 나왔습니다.

그럼 지금까지 부동산 가격에 영향이 있을 것 같은 속성들을 일부 골라서 선형 회귀로 다음달의 부동산 지수를 예측하는 실험을 해 보았습니다. 처음 작성하는 실험 포스팅이라 최대한 자세하고 쉽게 적으려고 노력을 해보았습니다. 다음 포스팅에서는 각 알고리즘에 대한 설명 및 실험 관련 속성들에 대해서 간략하게 적어보도록 하겠습니다. 포스팅 연재를 읽어주셔서 감사합니다.

참고로 해당 포스팅의 실험 결과는 로보리포트 사이트에 지속적으로 업데이트 될 예정입니다. 관심 있으신 분은 방문 부탁드립니다 +_+

https://land.roboreport.co.kr

읽을만한 글들

linear regression : https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html

https://medium.com/@haydar_ai/learning-data-science-day-9-linear-regression-on-boston-housing-dataset-cd62a80775ef

scikit-learn을 사용하여 부동산 가격 예측하기 – 3) 실험 데이터 분석하기

scikit-learn을 사용하여 부동산 가격 예측하기

3) 실험 데이터 분석하기

본격적으로 실험을 하기전에 pandas의 resample 함수를 사용해서 데이터의 분포를 확인해 보려고 합니다.  pandas의 resample 함수에서는 시계열 데이터의 시간 간격을 재조정할 수 있습니다. 이 함수를 사용하기 위해서는 dataframe이 시간 관련 index(datetimeIndex, PeriodIndex, TimedeltaIndex 등)를 가져야 합니다. 이전 포스트에서 데이터를 읽어올 때부터 아래와 같이 date 칼럼을 index로 설정하여 바로 사용이 가능합니다. 

df = pd.read_csv(“economy.csv”, parse_dates =[“date”], index_col =”date”)


함수의 사용방법은 아래와 같습니다.

DataFrame.resample(rule, how=None, axis=0, fill_method=None, closed=None, label=None, convention=’start’, kind=None, loffset=None, limit=None, base=0, on=None, level=None)

rule에는 resample을 실행할 시간 단위를 적어둡니다. (아래 표 참조)
이 때 시간 구간이 작아지면 데이터 양이 증가한다고 해서 업-샘플링(up-sampling)이라 하고 시간 구간이 커지면 데이터 양이 감소한다고 해서 다운-샘플링(down-sampling)이라 부릅니다.



좀 더 보기좋게 시간 단위의 alias만 정리된 표는 아래와 같습니다.

시간 단위 alias

그리고 아래와 같은 기본적인 aggregation 함수들을 dispatching이라는 방법으로 간단하게 호출하여 resample 함수와 같이 사용할 수 있습니다.

이제 실제 데이터 분포를 확인해보겠습니다. 예전 포스팅에서 부동산 지수 예측을 위해 저장했던 dataframe을 사용하겠습니다. 기존 데이터를 년말 기준으로 resample을 해서 각 칼럼당 개별 년도의 mean 값을 확인해보겠습니다.

df.resample(rule=’A’).mean()

데이터가 2010년부터 2018년도 까지 있다는 것을 확인할 수 있습니다. 그리고 각각의 속성(칼럼)의 mean 값을 확인할 수 있습니다. 얼핏 봐도 cd 금리(cd)와 국가채(spirit_deposit_rate) 시간이 지날 수록 연도별 평균값이 점점 낮아지고 있는 것을 확인할 수 있습니다.

그럼 실제로 cd 금리로 시계열 그래프를 그려보도록 하겠습니다. jupyter notebook을 사용할 경우 %matplotlib inline 을 명시하면 노트북 내부에서 그래프가 표시됩니다. 월말 기준으로(rule=’M’) 바 그래프(‘bar’)를 plot함수를 사용하여 아래와 같이 그려보겠습니다.

%matplotlib inline
df[‘cd’].resample(rule=’M’).mean().plot(‘bar’)



cd 금리 그래프

간단하게 그래프가 그려졌습니다. 그렇지만 월별 데이터로 그리니 넘 촘촘하게 그려지고 있습니다.

년도 단위로 데이터가 얼마나 있나 확인하고 싶어 count 함수를 rule=’A’ 옵션과 같이 사용해서 그래프를 다시 그려봅니다.

2018년도 데이터가 다른 년도 데이터보다 더 적은 것을 확인 할 수 있습니다.

이런식으로 시계열 데이터를 간단히 그래프를 그릴 수 있습니다.
그럼 이제 본격적인 실험으로 들어가보도록 하겠습니다 : )

scikit-learn을 사용하여 부동산 가격 예측하기 : 2) 실험 데이터 설정하기

scikit-learn을 사용하여 부동산 가격 예측하기

2) 실험 데이터 설정하기

실험 데이터는 pandas dataframe을 사용하여 설정하였습니다.

pandas는 데이터 처리와 분석을 위한 파이썬 라이브러리로

pandas의 dataframe은 엑셀의 스프레드시트와 비슷한 테이블 형태를 지원합니다.

전체 배열의 원소가 동일해야 하는 numpy와는 달리

pandas는 각 열의 타입이 달라도  사용이 가능합니다.

SQL, 엑셀 파일, csv 파일 등 다양한 파일과 데이터베이스에서 데이터를 읽어와서

dataframe으로 간단히 사용을 할 수 있어

python을 사용하는 기계 학습에서 자주 사용되고 있습니다.

이번 실험에 사용할 데이터를 pandas의 read_csv 함수를 사용하여

아래와 같이 pandas 데이터프레임으로 저장 하였습니다.

read_csv 함수에서 parse_dates 인자로날짜 타입인 열 이름( date)을 전달하고

index_col 인자로 date 열을 인덱스로 설정했습니다.

날짜 타입을 인덱스로 설정한 이유는 나중에 시계열 그래프를 그리기 위해서입니다.

dropna 함수를 사용하여 하나의 속성이라도 비어있는 열들은

실험에서 제외 하였습니다.

head 함수를 사용하여 상단의 데이터 값을 확인해 보겠습니다.

각 필드의 간략 설명은 다음과 같습니다.

경제 지표 관련 속성들이 부동산지수에 어떻게 영향을 미치는지 테스트 하기 위해서

금리, 환율 등의 경제지표 속성들을 실험에 포함했습니다.

예측 타겟은 한달 후의 한국감정원의 주택가격지수 중  주택매매지수 (‘tradeprice_sido_n1)입니다.

내가 이번달의 주택매매지수와 다른 경제 지표들을 알고 있을때

다음달의 주택매매지수를 예측할 수 있는지가 이번 실험의 타겟입니다.

시도단위의 매매지수이며 속성에서도 시도값이 따로 있을경우

속성 설명에 (시도)를 따로 적어두었습니다.

속성에 대한 개별적인 포스팅이 추가되면

해당 포스팅의 속성 설명로 링크로 계속 업데이트 하겠습니다.

전반적인 실험 과정을 전달하기 위해서 최대한 기본적인 내용만 실험에 포함해서 진행해보겠습니다.

여기서 더 다양한 속성들과 다른 실험 방식을 사용하는 예시는

추후 다른 포스팅에서 이어서 전달하려고 합니다.

‘region_cd’: ‘지역코드(시도)’,

‘year’: ‘연도’,

‘month’:’월’,

‘building_type’: ‘부동산타입’,
‘tradeprice_sido’ : ‘매매가격지수(시도)’,

‘construction_realized_amount’ : ‘건설기성액(백만원)’,

“cd”: “cd(91일물)“,
‘spirit_deposit_rate’: ‘정기예금금리’,

‘exchange_rate’: ‘환율’,

‘composite_stock_price_index’: ‘종합주가지수’,
‘economy_growth’: ‘경제성장률’,

‘exchequer_bond_three’ : ‘국고채3년‘,

‘household_loan_all’: ‘가계대출액(전국)’,
‘mortgage_all’ : ‘주택대출액(전국)’,

‘numberofnosells’:’미분양 가구수(시도)’,

‘unsalenum_c’:’공사완료후 미분양(민간,시도)’

데이터프레임의 info 함수를 사용해서 index 정보와 컬럼수, 전체 데이터 개수, 각 열의 타입을 확인합니다.

describe 함수를 사용하면 각 필드별로 평균값, 분포, 최소값 등을 간단히 확인할 수 있습니다.

범주형 속성도 있긴 하지만 일단은 별도 처리 없이 진행합니다.

 다음 포스팅에서는 본격적으로 실험을 시작하기 전에 matplotlib 을 사용하여

각 데이터의 분포를 확인해보겠습니다.

 이전 부동산 가격 실험 관련 포스팅

scikit-learn을 사용하여 부동산 가격 예측하기 : 1) target 설정 : 전국주택가격 지수

cd 금리와 부동산 가격 상관 관계 알아보기 (1)

참조: https://www.geeksforgeeks.org/python-pandas-dataframe-resample/

scikit-learn을 사용하여 부동산 가격 예측하기 : 1) target 설정 : 전국주택가격 지수

 

scikit-learn을 사용하여 부동산 가격 예측하기

1 ) target 설정 : 전국주택가격 지수

 

scikit-learn을 사용하여 부동산 가격 예측하기 실험을 연재해보겠습니다.

scikit-learn은 파이썬으로 구현된 기계학습 오픈소스 라이브러리로

보통 싸이킷 런이라 발음합니다.

다양한 기계 학습 알고리즘 동일한 함수로 사용할 수 있어서

알고리즘을 바꿔가면서 간단히 실험하기에 좋습니다.

scikit-learn에 대한 자세한 사용법은 다음 포스팅에 이어서 하겠습니다.

무엇보다 기계학습 실험을 하기 위해서는 실험 대상이 있어야 합니다.

향후 다양한 실험을 하면서 개별 매물 가격 등의 다양한 타겟들을 실험해보겠지만

이번 실험에서는 한국감정원의 전국주택가격 지수를 사용하려고 합니다.

 

전국주택가격지수는 한국감정원에서 매주 또는 월간으로

전국 아파트, 단독, 연립주택을 표본 조사해서 만든 하나의 수치로

주택 시장의 평균적인 가격변화를 측정하는 지표로 사용합니다.

자세한 내용은 아래 한국 감정원에서의

전국주택가격 지수 설명 링크를 참조할 수 있습니다.

 

한국 감정원 전국주택가격 지수 설명 링크

 

다른 주택가격지수들도 있지만 전국주택가격지수 데이터를 타겟으로 설정했던 이유는

시군구 단위의 가격지수를 제공한다는 점,

그리고 월간 데이터긴 하지만 아파트, 단독, 연립주택 지수를 주기 때문입니다.

 

 

 

전국주택가격지수 데이터는 공공데이터 포털에서 수집였고

아래 링크를 따라 가면 데이터 수집에 대한 자세한 설명을 확인할 수 있습니다.

 

데이터 제공 API: https://www.data.go.kr/dataset/15002287/openapi.do

 

그럼 다음 포스팅에서는 실험에 사용해볼 속성들에 대한 소개들을 해보겠습니다.