대선

2017년 대선 지지율 예측 (2)

이전 포스팅에서는 시계열 분석을 이용해서 대선 후보들의 지지율 추세를 예측했었다. 대략적인 추세는 파악할 수 있었지만 각 후보의 지지율 시계열이 서로 독립이라는 둥, 외인변수를 고려하지 않는 둥 몇 가지 현실과는 다소 동떨어지는 가정을 해야했었다. 또한 이렇게 얻어낸 예측치는 너무나도 당연한 것이어서(…) 직관적인 예상을 수치적으로 뒷받침 해주는 – 현재 시점의 지지율 값이 과대평가 되었는지, 과소평가 되었는지 – 정도의 의미만을 가졌다.

이번에는 외인변수를 이용해 회귀분석으로 주요 세 후보의 지지율을 예측해보면서 2017 대선 관련 분석을 마무리하고자 한다. 몇 가지 외적인 변수와 지지율간의 관계를 함수(회귀모형)로 세우고 이 함수로 알려지지 않은 시점의 지지율을 예측하는 방식이다. 예상치 못한 사건으로 인한 변동을 반영하지 못하고 시간이 흐를수록 예측값이 단순히 앙상블 기댓값으로 수렴했던 시계열 분석의 단점을 보완할 수 있을 것이다.

자세한 회귀모형 검정 결과와 코드는 이 노트북에서 확인할 수 있다. 작은 사진은 클릭하면 커진다.

 

회귀모형 설정

외인 변수로 사용하려고 다음의 두세 가지 값을 읽어왔다.

  1. 각 후보 관련주 2개의 전 날 종가
  2. 검색어를 각 후보의 이름으로 넣었을 때, 전 날 구글 트렌드 트래픽
    • pytrends를 이용해서 긁어왔다.

변수들간의 관계 및 분포를 대략 파악하기 위해 스캐터 플롯 매트릭스를 그려보았다 (클릭하면 커짐).

독립변수(외인변수) 간 선형관계가 존재하면 독립변수의 제곱합 행렬(X'X)의 역행렬이 존재하지 않게 되어 회귀모형을 설정할 수 없게 된다. 따라서 독립변수 간 선형관계가 없도록 관련주 중 회귀모형에서의 유의성이 더 높은 것의 값만을 사용했다.

진단 상 문제가 없도록 이리저리 모형을 바꿔가며 설정한 결과 다음과 같이 각 후보의 회귀모형이 결정되었다. 기존에 있는 어떤 이론을 바탕으로 한 것이 아니고 그저 유효한 회귀모형을 만들겠다는 생각으로만 설정된 모형이기에 수식이 엉망이다. 수식에서 y는 지지율, t는 구글 트렌드, s_{1(or 2)}는 관련주1(혹은 2)의 종가이다. m은 문재인, a는 안철수, h는 홍준표를 의미한다.

  • 문재인: y_m = \hat{\beta_1}\cdot{\log{t_m}}, \hat{\beta_1} = 9.9620
  • 안철수: \log{y_{a}} = \hat{\beta_2}\cdot{\log{s_{a2}}} +\hat{\beta_3}\cdot{t_{a}} +\hat{\beta_4}\cdot{\sqrt{t_{a}}}, \hat{\beta_2} = 0.1704, \hat{\beta_3} = -0.0178, \hat{\beta_4} = 0.3904
  • 홍준표: y_h =\hat{\beta_5}\cdot{s_{h1}} +\hat{\beta_6}\cdot{t_h},\hat{\beta_5} = 0.0014, \hat{\beta_6} = 0.1603

Intercept를 포함했을 때 condition number1가 미친듯이 치솟는 현상이 나타나서 세 모형 모두 intercept를 포함시키지 않았다. 실제로도 관련주 종가, 구글 트렌드가 0 일 때 (즉, 해당 후보에 대한 사람들의 관심이 없다시피 할 때) 지지율이 0에 가까운 값을 가질 것으로 생각되므로 intercept를 포함시키지 않는 것이 타당해 보인다. 문재인 후보 회귀식의 경우 관련주 종가가 지지율 값에 유의한 영향을 미친다고 보기 어려워 구글 트렌드만으로 예측을 했다.

이렇게 설정한 회귀모형에서의 지지율과 실제 지지율의 값을 비교해보았다. 시계열 예측과는 달리 지지율의 업 앤 다운도 어느정도 적합값에 나타나는 것을 볼 수 있다..

아래 부분의 그래프는 실제 값과 모형 예측값의 차이다. 자기상관성이 크게 나타나는 점에서 좋은 모형이라고 하기는 어려워 보인다. 다만 예측하려는 값, 즉 여론조사로 집계한 지지율 자체에 관측오차가 있기에 회귀모형에서 얻은 지지율 값에도 오차가 있을 것이다.

 

지지율 예측

output_46_1

지지율 회귀분석 결과

위의 회귀모형으로 5월 4일의 관련주 종가, 구글 트렌드로 5월 5일의 지지율을 예측해보았다(•).

 

그 외..

  • 최근 며칠간의 실제값-모형값 차를 보았을 때 모형의 5월 5일 예측값이 안철수 후보에서는 과대추정, 홍준표 후보에서는 과소추정이 된 것이 아닌지 의심스럽다. 다른 외인변수를 더 찾아 넣으면 더 정확하게 개선할 수도 있을 듯한데.
  • 시계열분석의 단점을 보완할 수 있을 것이란 예상과는 달리, 자기상관성이 크게 나타나는 문제가 생긴다. 추가적인 보정을 통해 보완할 필요가 있다.
  • 문재인 후보, 홍준표 후보의 경우 관련주 종가가 지지율과 강한 음의 상관관계(\rho_m = -0.79, \rho_{h1} = -0.68)를 보이는 기괴한 모습을 보인다. 안철수 후보의 관련주 종가에서도 높았던 주가가 지지율 하락의 순간에 뒤따라 하락하는 모습을 보인다. 이게 바로 테마주의 허망함인가..하는 생각을 하게 만든다.

 


  1. 다중공선성(multicolinearity)을 감지하는 데에 사용되는 값이다. 독립변수가 아주 작은 값 변화했을 때 모형 함수값이 얼마나 크게 변하는지를 나타내는 민감도 척도이다. 

2017년 대선 지지율 예측

네이버에서 여론조사 데이터를 긁어오는 스크립트를 짜면서  ‘당선 가능성’이라는 것이 여론조사에 항목에 있다는 걸 알게 되었다. 여론조사가 말하는 ‘당선 가능성’은 그저 “어느 후보가 가장 당선 가능성이 높다고 생각하십니까?”라는 질문에 대한 시민들의 응답을 기록한 것이었다.

가장 잘 생긴 사람을 뽑는 대회와 다른 사람들이 가장 잘 생겼을 것이라고 생각할 사람을 뽑는 대회는 사뭇 다르다. 여론조사의 ‘당선 가능성’을 후자에 빗댄다면 통계적 예측을 통한 확률로서의 당선 가능성을 전자라 할 수 있을 것이다.

진짜 확률로서의 당선가능성을 뽑아낼 방법이 없을까 하는 물음에서 2017 대선후보 중 주요 후보 다섯 명(기호 순 문재인, 홍준표, 안철수, 유승민, 심상정)의 지지율 추세를 시계열(time series)로 보고 시계열 분석을 시작해봤다. 대중에게 여론조사가 공표될 수 없는 내일 이후 6일간의 기간동안 지지율 추세의 대략적인 지표가 될 수도 있으리라 본다.

분석에 사용한 데이터와 가정은 다음과 같다:

  1. 각 후보의 지지율 추세는 (독립적인) 확률과정이다.
    1. 실제 지지율과는 매우 동떨어진 가정이다. 한 후보의 지지율은 결국 비율이기 때문에 내재적으로 다른 후보의 지지율에 의존할 수밖에 없다.
  2. 외인 변수는 고려하지 않는다. 즉, 여기서 예측하는 지지율은 앞으로 큰 변동/사건이 일어나지 않는다고 할 때 가능한 지지율 추세이다.
  3. 지지율 시계열은 0차 이상의 차분을 통해 stationary process로 표현할 수 있다.
  4. 다섯 후보 모두의 지지율이 계속해서 집계되기 시작한 3월 28일자부터 5월 3일까지 공표된 여론조사 데이터를 사용했다. (5월 3일 새로 공표된 여론조사 반영하여 수정함)

 

ARIMA 모형 차수 설정

분석 과정에서 문제가 있지는 않았나 싶어 과정을 공개하고자 한다. 무시하고 바로 결과로 건너뛰어도 된다.

stationary process 검정 (Dickey-Füller test) 등 보다 자세한 과정 및 수정 내역은 이 노트북에서 확인할 수 있다. RNN을 이용하려했던 흔적도 찾을 수 있다.

output_6_0

지지율 시계열

output_11_0

1차 차분한 시계열

output_14_0

2차 차분한 시계열

Dikey-fuller 검정 결과 stationary process를 만족하는 최소 차분수 시계열을 바탕으로 각각 ARIMA 모형을 피팅했다. AR, MA 모형 차수를 설정하기 위해 아래와 같이 ACF(autocorrelation function)와 PACF(partial autocorrelation function)를 확인했다.

output_16_0

문재인 시계열 – 차분 안 함 – ACF, PACF

문재인 후보 시계열의 모형으로 ARMA(1,2)를 선택했다.

output_17_0

심상정, 유승민, 홍준표 시계열 – 1차 차분 – ACF, PACF

심상정, 유승민, 홍준표 후보 모형으로 ARIMA(1,1,1)을 선택했다.

output_18_0

안철수 시계열 – 2차 차분

안철수 후보 시계열의 모형으로 ARIMA(1,2,2)를 선택했다.

 

지지율 예측 결과

미래 시점의 예상 지지율 기댓값을 실선과 원으로 (-o-의 모양새), 95% 신뢰구간을 그림자로 나타냈다. 시계열만으로 예측하는 것이기에 95% 신뢰구간이 크게 나타나는 것에 유의. 시계열 분석은 미래를 확정적으로 예측하는 마법같은 도구가 아니다.

쉽게 표현하자면 실선으로 표시된 부분은 그나마 가장 가능성이 높아뵈는 시나리오 정도로 받아들이면 된다. 실제로는 어디에든 지지율 포인트가 찍힐 수 있다. 빈도주의 관점에서 본다면 평행우주(?)에서 100번 대선을 실시하면 95번 정도는 그림자 안에 지지율이 찍힐게다. 달리 말하자면 신뢰구간의 폭이 넓을수록 예측이 어렵다는 이야기가 된다.

output_24_0

대선 지지율 추세 예측

실제로 일어날 법한 지지율 추세가 나온다. 특히 안철수 후보의 지지율의 경우 넓은 지지율 변동폭을 반영해 높은 예측 불가능성(매우 넓은 신뢰구간)을 보여준다. 이 외에도 현재의 지지율 값이 과대평가된 값인지, 혹은 과소평가된 값인지를 시계열 기댓값 예측값으로 판단할 수 있다.

 


시계열 분석은 미래를 확정적으로 예측하는 방법이 아니다. 데이터에 대한 여러 가정을 세우고 그 모든 가정을 충족시킨다 할 때 현재까지의 추세를 바탕으로 가장 그럴듯한 예측치를 보여주는 것 뿐이다.

가정이 하나라도 크게 어긋난다면 그리 좋은 예측이 되지 못한다. 가정이 모두 충족되더라도 하나의 확실한 예측값을 보여주지는 못한다. 데이터 자체의 속성과 미래를 예측하고자 하는 데에 따르는 (때로는 거대한) 불확실성을 항상 염두에 두어야 한다는 이야기이다.

그러나 그리 세밀한 예측치가 아니더라도 충분할 때가 있다. 여론조사 공표가 금지되는 다음 일주일, 더 나아가 각 후보의 당선 가능성을 가늠하는 데에 지금까지의 추세를 반영한 시계열 예측이 한 번 참고해 볼 수준은 될 수 있을 게다.