대메뉴 바로가기 본문 바로가기

데이터 기술 자료

데이터 기술 자료 상세보기
제목 기계 학습의 A to Z : 인구 변화 시각화와 예측
등록일 조회수 6382
첨부파일  

기계 학습의 A to Z

인구 변화 시각화와 예측



영화 ‘설국열차’의 절대권력자 월포드는 열차의 인구 숫자를 항상 걱정한다. 사람이 너무 많으면 혁명(반란)을 인위적으로 만들거나 용인해 조절한다. 작고 통제된 사회에서 가능한 일이다. 과학 기술의 발전에 따라 한 사람의 결정권이 큰 역할을 할 수 있지만 실제로는 여러 이익 집단이나 이해 관계가 인구 변화를 이끈다. 지난 1798년 출판된 토머스 맬서스의 ‘인구론’은 인구와 사회 관계를 조명하고 인구 관리를 역설한다. 이후, 많은 현대 국가는 인구를 기록, 예측하여 사회 제도에 적극 반영하고 있다. 특히, 인구와 재화의 재분배는 우리 사회에 뜨거운 감자다. 우리나라도 매월 통계청에서 인구 조사 결과를 발표한다.



인류 역사를 한 걸음 떨어져 바라보면 사회 변화와 혁명은 인구 변화와 아주 밀접한 관계가 있음을 알 수 있다. 자원이 늘어나면 자연히 인구가 증가했지만 자원이 줄어들면 전쟁이나 사회적 충돌로 인구도 자연스레 줄어들었다. 현대 사회로 접어들면서 인구의 증가, 감소, 이동을 기록, 통제하는 이유도 마찬가지일 것이다. 정부에서 제공하는 인구 데이터를 파이썬 라이브러리인 ‘Pandas’ ‘statsmodels’ ‘Scipy’를 활용해 시각화하며, 회귀 모형과 마코프 체인을 바탕으로 인구 변화를 예측한다.



데이터 구하기

2013년 미국 오바마 정부는 ‘공공데이터(Open Data) 정책’을 발표했다. 공공데이터의 취지는 미국 기술 산업 발전의 디딤돌을 제공하여 혁신과 일자리 창출, 정부 효율성을 높이는데 있다. 이와 더불어 세계의 여러 정부들이 공공 데이터가 국민의 재산이라는 인식을 가지고 확대, 개방하고 있다. 우리 정부도 다양하게 데이터를 제공하고 있다. KOSIS에서 다양한 정보를 제공하는데, 그중 시도별 인구, 출생, 사망, 이동에 관한 데이터를 내려 받았다.





내려 받은 파일을 처리하기 편리하게 편집한다. 다음은 시도별 인구 조사이다. 시도는 세종시를 포함해 서울, 부산, 대구, 경기도등 총 17개다. 기간은 2010년부터 2014년까지이다. <그림 2>에서 알 수 있듯이, 서울은 계속적으로 인구가 줄어, 2014년에는 천만명 아래로 떨어졌다. 이에 반해, 제주도는 꾸준히 인구가 증가하고 있다. 다음은 시도별 인구 전출/입수이다. 다음 표는 2014년 서울과 각 시도별간 이동한 인구를 나타낸다. 이를테면, 첫 번째 행으로, 각각 부산에서 1만7365명, 대구에서 11,481명, 인천에서 2만5332명이 서울로 전입한 인구이다.



이 데이터로 인구 이동을 알 수 있으며, 장기 도시 계획의 바탕을 삼을 수 있다.



데이터 시각화

Pandas로 간단하게 시각화를 한다. 우선, 데이터는 연별 평균 자료이기 때문에 소수점 자리로 되어 있다. 큰 소수점 자리는 필요하지 하지 않기 때문에 소수점 한 자리까지만 사용하도록 하겠다. Pandas를 임포트하고 옵션을 설정한다.



<리스트 1> Pandas, Numpy 임포트와 옵션 조절 import pandas as pd import numpy as np import statsmodels.api as sm %matplotlib inline pd.set_option('precision', 1) pd.options.display.float_format = '{:,.1f}'.format



각 데이터를 Pandas로 로드해 보자. raw-data.xlsx의 각 시트에서 해당 데이터를 얻는다.



<리스트 2> 데이터 로드 trans2014 = pd.read_excel('raw-data.xlsx', '2014', index_col='in/out', na_values=['NA']) population = pd.read_excel('raw-data.xlsx', 'population', index_col='local/year') birth = pd.read_excel('raw-data.xlsx', 'birth', index_col='local/year') death = pd.read_excel('raw-data.xlsx', 'death', parse_dates='local/year', index_col='local/year')



시도별 2014년 인구 이동, 시도별 인구, 시도별 출생, 시도별 사망에 대한 데이터를 로드한다. 일부 데이터를 시각화해 보자. Pandas는 다양한 시각화 도구를 제공한다. 아주 세밀하거나 대화형 시각화는 일부 부족한 면이 있지만 데이터의 경향이나 분포를 파악하는데 부가 작업이 필요 없이 사용할 수 있다는 장점이 있다. 다음은 시도별 출산에 대한 시각화이다.



2012년 이후, 서울, 경기도, 경상남도등에서 출생 명수가 줄어드는 것이 확연하게 보인다. 다음은 시도별 인구를 시각화하자. 2014년 서울 인구는 감소하고 인천과 경기도는 인구가 증가한다. 이외 다른 시도는 큰 변경이 없다(<그림 5> 참조). 대략적으로 보면, 서울에서 경기나 인천으로 이동했을 것으로 추정할 수 있으나, 증가분과 감소분이 차이가 있어 보인다. 2014년 인구에서 2013년 인구를 빼면, 변화를 알 수 있다.





<리스트 3> 2014년 인구수와 2013년 인구수의 차 print(population2014 - population2013) ## 결과 Seoul -41,719.0 Busan -7,819.0 Daegu -5,222.0 Incheon 30,465.5 ... Gyeonggi-do 134,969.5 Gangwon-do 3,234.5 ... Jeju-do 12,050.0



서울은 4만1719명인 줄어든 반면, 인천, 경기도는 각각 3만465.5명, 13만4969.5명이 늘었다. 2014년 출생자 수에서 사망자 수를 합하면, 순수 증감수를 알 수 있다.



<리스트 4> 2014년 출생자수와 2014년 사망자수의 합 print(birth2014 - death2014) ## 결과 Seoul 41,300 Busan 6,000 Daegu 6,700 Incheon 12,400 ... Gyeonggi-do 60,600 Gangwon-do -300 ... Jeju-do 2,200



2014년 서울에서 출생, 사망으로 증가한 인구수는 4만1300명 증가했지만, 결과적으로 2013년보다 4만1719명이 줄어들었다. 경기도는 출생, 사망으로 6만600명이 증가했고, 결과적으로 134,969.5명이 증가했다. 시도 기준인 통계이기 때문에 통계에 속하지 않은 부분을 고려해야 한다. 다른 특별한 점으로, 강원도는 300명 출생수보다 사망자수가 더 많아 인구가 줄어들 수 있는 지역임을 알 수 있다. 마지막으로, 2014년 시도별 인구 비율을 시각화한다.



<리스트 5> 2014년 시도별 인구 비율 population2014_pie = population2014.astype(float) / population2014.sum() * 100 population2014_pie.plot(kind="pie", autopct='%.2f', figsize=(8, 8), title='2014 Population')



전체 인구로 각 시도 인구를 나누면 각 지역에 백분율 비율을 구할 수 있다. Pandas의 dataframe 메서드 plot에서 kind="pie"를 선택한다.



서울, 경기도, 인천의 합이 약 50%이다. 같은 방법으로 2010년 시도별 인구 비율 구하면, 2010년과 2014년에서 가장 변화가 큰 시도를 구할 수 있다.



<리스트 6> 2014년 지역별 인구 분포 population2014_pie - population2010_pie ## 결과 Seoul -0.8 Busan -0.2 Daegu -0.1 Incheon 0.2 ... Sejong 0.3 Gyeonggi-do 0.8 Gangwon-do -0.0 ... Gyeongsangnam-do 0.0 Jeju-do 0.0



인구 비율로, 서울은 가장 감소가 큰 지역이며, 경기도는 가장 증가가 큰 지역이다. 서울을 중심으로 한 지역 편중은 사라지지 않고 있으며, 서울을 중심으로 경기도 지역으로 인구 이동이 있다는 점을 유추할 수 있다.



인구 변화 예측

이전에 회귀(Regression)분석으로 값을 예측하는 것을 다뤘다. 회귀분석은 주어진 속성(입력 변수)와 목적 변수가 긴밀하게 관계돼 있을 때, 사용할 수 있는 방법으로 관찰된 현상과 그 현상에 영향을 미치는 변수들간의 통계 모델을 만들고, 모델로 새로운 입력 변수에 따른 목적 변수를 예측하는 분석법이다. 회귀 분석으로 2015년, 2016년 인구를 예측해 보자. 먼저, 회귀분석으로 예측하기 위해 statsmodels 라이브러리를 사용하겠다. statsmodels 라이브러리는 일반최소제곱(Ordinary Least Squares) 기법을 제공한다. 다음은 Pandas의 dataframe의 각 행에 대해 예측값을 구하는 함수다.



<리스트 7> OLS로 예측하는 함수 def predict(df, year): X = np.array(range(2010, 2015)) X = sm.add_constant(X) n, m = df.shape l = [] for i in range(0, n): y = df.ix[i, :].values est = sm.OLS(y, X).fit() l.append(float(est.predict(np.array([1, year])))) return pd.Series(l, index=df.index)



2015년 시도별 인구를 예측해 보자. 2010년부터 2014년까지 회귀분석을 기반으로 2015년, 2016년의 시도별 예측해 보면 다음과 같다.



<리스트 8> 2014년 시도별 인구 분포 population_predict = population.copy() population_predict['2015'] = predict(population, 2015) population_predict['2016'] = predict(population, 2016) print(population_predict.sum())



시각화 해보면 다음 그림과 같다. 인구 변화 경향(trend)을 그대로 담고 있다. 즉, 인구가 증가하거나 감소하는 경향을 그대로 반영하고 그 증감소만 차이가 있다.



마찬가지로, 시도별 출생에 적용하면, 유사한 경향을 찾을 수 있다. 전체 출생자수를 보면, 전체적으로 감소하는 경향이 있다.



<리스트 9> 2014년 시도별 출생 예측 birth_predict = birth.copy() birth_predict['2015'] = predict(birth, 2015) birth_predict['2016'] = predict(birth, 2016) print(birth_predict.sum()) ## 결과 2010 470,171.0 2011 471,265.0 2012 484,550.0 2013 436,455.0 2014 435,300.0 2015 428,182.6 2016 417,727.4





2016년 총 출생자 수는 41만7727.4명으로, 2010년보다 약 5만 명이상 감소할 것으로 예측할 수 있다.

이번에는 시도별 인구 이동을 기반으로 시도별 인구 분포를 예측한다. 여기서 마코프 체인을 활용해 보자. 마코프 체인은 단위 시간에 따른 상태 변화를 나타낸다. 매 단위 시간마다 상태가 변이되거나 유지되며, 상태 변이를 전이라 한다. 전이는 상태전이확률(state transition probability) 행렬로 나타내며, 이를 바탕으로 변화된다.

즉, 현재 상태에서 다음 상태로 전이될 때 이 상태전이확률로 확률적으로 전이된다. <그림 3>에서 보듯, 2014년 각 시도의 이동 인구는 상태전이확률로 나타낼 수 있다. 즉, 2014년 서울에서 이동하여 다른 시도로 이동할 확률은 서울에서 떠난 전인구로 각 시도로 이동한 인구를 나누면, 상태전이확률이 된다. 각 시도도 마찬가지로 시도에서 전출한 총인구를 각 다른 시도로 전입한 인구를 나누면 된다.



<리스트 10> 2014년 지역별 인구 분포 trans2014_percent = trans2014.copy() for i in range(0, 17): trans2014_percent.iloc[:, i] = trans2014.iloc[:, i].astype(float)/trans2014.iloc[:, i].sum()



다음은 일부 2014년 시도별 이동인구를 상태전이확률로 나타낸 그림이다.



서울에서 서울로 전이 확률은 0.611, 서울에서 부산으로 전이 확률은 0.014, 서울에서 대구로 전이 확률은 0.008이다. 이 상태전이확률을 이용하여 다음 상태를 구할 수 있다. 즉, X1 = T * X0로, 내년 인구 X1는 상태전이확률 T와 현재 인구 X0의 내적으로 구할 수 있다.



<리스트 11> 2014년 지역별 인구 분포 pd.Series(np.dot(trans2014_percent, population2014), index=trans2014.index) #결과 Seoul 10,092,922.116 Busan 3,352,765.245 Daegu 2,342,050.227 Incheon 2,894,262.745 ... Gyeonggi-do 12,184,951.910 Gangwon-do 1,567,610.963 Chungcheongbuk-do 1,554,853.272 ... Gyeongsangbuk-do 2,592,971.551 Gyeongsangnam-do 3,261,545.733 Jeju-do 656,033.285 # 예측 결과 - 2014년 인구 Seoul 121,929.616 (만큼 증가) Busan -132,628.755 (만큼 감소) Daegu -135,772.273 Incheon 30,592.745 ... Gyeonggi-do -11,236.590 Gangwon-do 37,844.963 Chungcheongbuk-do -10,726.728 ... Gyeongsangbuk-do -89,431.449 Gyeongsangnam-do -59,488.767 Jeju-do 59,905.785



전혀 생각하지 못한 결과를 얻었다. 예측 결과와 2014년 인구의 차를 구하면, 2014년보다 서울, 인천, 제주도는 증가하고, 부산, 대구, 경기도는 감소한다. 이전에 시도별 인구 예측과 다른 결과를 얻었다. 이러한 결과는 아마도 2014년 시도별 인구 이동 통계가 정확한 통계를 반영하지 못한 이유일 듯하다. 다시 말해, 인구 이동이 시도별로 제한되어 있지 않고 해외로 이동 할 수도 있고 군, 면으로 이동했을 수도 있기 때문이 아닐까 한다. 좀 더 정확한 통계 데이터가 있었다면, 좀 더 정확한 인구 이동을 예측할 수 있다. 이러한 오차를 감안하고, 좀 더 진행해 보자. 2년 후 인구 상태인 X2 = T * X1이며, 이는 다시 X2 = T * T * X1으로 나타낼 수 있다. 마찬가지로 3년 후인 3 = T * T * T * X1이다. 일반화하면, Xn = * X1이 된다.



<리스트 12> n년 후 지역별 인구 분포 population_trans_10 = pd.Series(np.dot(np.linalg.matrix_power(trans2014_percent, 10), population2014), index=trans2014.index) # 10년 후 Seoul 10,368,312.894 Busan 3,009,841.354 Daegu 2,002,425.750 Incheon 2,997,727.722 ... Gyeonggi-do 12,458,837.601 Gangwon-do 1,641,059.317 Chungcheongbuk-do 1,623,880.375 ... Gyeongsangbuk-do 2,323,398.934 Gyeongsangnam-do 2,984,296.768 Jeju-do 776,791.243 population_trans_40 = pd.Series(np.dot(np.linalg.matrix_power(trans2014_percent, 40), population2014), index=trans2014.index) # 40년 후 Seoul 10,402,791.840 Busan 2,964,402.087 Daegu 1,970,722.896 Incheon 3,013,844.062 ... Gyeonggi-do 12,513,037.743 Gangwon-do 1,647,521.936 Chungcheongbuk-do 1,631,350.328 ... Gyeongsangbuk-do 2,295,078.217 Gyeongsangnam-do 2,939,411.191 Jeju-do 781,245.940



이러한 마코프 체인은 일정 시간이 지나면 평형 상태(steady-state)에 도달할 수 있다. 즉, 40년 이후 상태나 60년 이후 상태의 변화가 거의 없다. 일정한 값에 수렴하기 때문이다. 이러한 상태 변화를 잘 이용하면, 거시적인 관점에서 국가 기반 시설을 만드는데 도움이 될 수 있다.



결론

지금까지 인구 데이터를 가지고 시각화를 하고, 회귀분석으로 인구 변화를 예측해 보았다. 인구 이동 데이터와 마코프 체인으로 인구 변화도 살펴보았다. 일부 통계가 부족하여 예상과 다른 결과를 얻었지만, 관련 기법을 충분히 활용할 수 있었다. 더불어 국가 정책으로 인구는 곧잘 변경될 수 있으니, 다른 변수나 변경되는 통계를 잘 활용할 필요가 있다. 코드는 다음 http://nbviewer.ipython.org/github/brenden17/markov-chains-population/blob/master/Population.ipynb에서 확인할 수 있다.



출처 : 마이크로소프트웨어 4월호

제공 : 데이터전문가 지식포털 DBguide.net