Tableau/R을 활용한 Prophet Model 구현

1. Intro

안녕하세요 명완식 입니다. 여러분들은 태블로에서 R을 활용하여 예측 모델을 만들어 볼 수 있다는 것을 알고 있으셨나요? 태블로를 자주 활용하셨다면, 예전부터 태블로에서 Rserve()를 활용하여 통계 모델을 그대로 사용할 수 있다고 알고 있으신분들이 있으실 텐데요. 하지만, 국내에 많은 사례가 없어 사용하기 주저 하셨던 분들을 위해 오늘 제가 Prophet 모델 사용 케이스 하나를 포스트로 남기게 되었습니다. 주제는 바로 많은 분들이 실무에서 수행하고 계시는 “수요 예측” 입니다.

이번에는 한국여신전문금융협회 국내 카드 사용량 데이터를 기반으로 예측모델을 만들어 보았습니다. 만들게 된 계기는 제가 예전에 분석했던 산업별 카드사용량(아래 대시보드)을 이번에 “예측 모델링을 통해 수요 예측을 해보면 어떨까?” 하는 생각으로 만들게 되었습니다.

1.1 데이터 다운로드

데이터는 여기를 클릭하여 다운로드하여 주세요. 해당 데이터는 통계청에서 다운로드 받았습니다.

1.2 대시보드 다운로드

대시보드는 여기를 클릭하여 다운로드하여 주세요.

2. 모델 설명

Prophet 모델은 메타(구 페이스북)에서 만든 모델로써, 비선형적인 트랜드가 매주, 매월에 나타나고 휴일 등의 효과를 가산하는 모델 입니다. 특히 Prophet 모델은 날짜 변수와 측정값만 있으면 만들 수 있는 모델이기 때문에 매우 만들기 쉽고 연산 속도도 빠르다는 장점이 있습니다.

Prophet 모델은 따라서, 트렌드, 계절성, 휴일 3가지를 중점으로 예측합니다. 이번 포스트 예시에서는 데이터가 월단위로 말아져 있기 때문에 휴일 효과보다는 트렌드와 계절성 중심으로 예측 모델이 설계되어 있습니다.

Y(t)= g(t)+s(t)+h(t)+ϵi

Y(t) = 카드 사용량

g(t) = 트랜드 (선형)

s(t) = 계절성 (월/년 등)

h(t) = 휴일 (주말 등)

ϵi = 설명되지 않은 에러

t = 초기 날짜부터(t0) 순차적인 날짜

 

선형 모델은 누구나 보았을 때 직관적이고 트렌드 라인을 1차 함수로 명확하게 보여주기 때문에 해석하기 매우 쉽습니다. 따라서 추세가 증가세인지 혹은 감소세인지 유추하기 쉽습니다. 가장 기본적으로 수행할 수 있는 모델입니다.

Linear 모델은 시간(여기서는 1개월 단위)의 증가로 인해 선형 기울기에 따라 카드 사용량이 얼마나 되는지 측정합니다.

Y(t)= B0+B1(t)+ϵi

Y(t) = 카드 사용량

B0 = 절편

B1(t) = 카드 사용량 기울기

ϵi = 설명되지 않은 에러

t = 초기 날짜부터(t0) 순차적인 날짜

3. 대시보드 살펴보기

그럼 어떻게 대시보드를 만들었는지는 뒤로하고, 만든 대시보드가 어떠한 정보를 제공하며 예측을 잘 수행하고 있는지 알아보도록 하겠습니다. 국내 카드 사용량 데이터는 (1)교육서비스업, (2)도매 및 소매업, 보건업 및 사회복지 서비스업, (3)사업시설관리 및 사업지원 서비스업, (4)숙박 및 음식점업, (5)예술 스프츠 및 여가관련 서비스업, (6)운수업, (7)협회 및 단체 수리 및 기타 개인 서비스업으로 분류되어 있습니다.

첫번째 라인 그래프는 실제 카드 사용량(회색선), Prophet 예측(파란색선), 선형 회귀(점선) 3가지를 표현하고 있습니다. 파란선과 회색선이 일치하는 모습일 수록 예측 모델이 잘 예측하고 있음을 보여줍니다.

두번째 아래 막대 그래프는 오차를 보여주고 있습니다. 오차가 낮을 수록 파란색, 높을 수록 붉은색입니다.

모든 카드 사용량을 다 해석해서 보여 드리는 것은 너무 글이 길어질 것 같아, 대표성이 있는 4개 분야만 해석하도록 하겠습니다.

3.1 국내 카드 사용 전체(총합) 사용량, 오차 적음

먼저, 한국여신전문금융협회에서 제공하는 데이터를 모두 총합했을 때의 모습입니다. 카드 사용량이 꾸준히 올라가는 모습을 보여주고 있으며, 파란 예측선이 카드 사용량을 잘 예측하는 모습을 보여주고 있습니다. 밑에 막대차트를 참고하여 보시면, 오차율이 10% 미만으로 꽤나 높은 예측을 보여주고 있습니다. 코로나가 시작되던 2020년 3월과 오미크론의 여파가 크던 2022년 2월과 3월에 오차가 크게 발생한것이 인상적입니다. 이는 코로나 영향에 따라 이전 카드 사용량과는 데이터가 다른 패턴으로 움직였기 때문에 Prophet 모델이 정확히 예측하지 못한 것으로 보입니다.

 

평균 오차는 1조 6백억원 수준이며, 오차율은 전체 카드사용량에 1.88%로 꽤나 낮은 오차를 보여주고 있습니다. Prophet 모델의 에러율은 Linear 모델보다 무려 약 2.2% 낮으며, 평균오차도 매달 1조 2천억원이나 낮습니다. 오차로만 보면 Prophet 모델이 시계열 패턴을 아주 잘 읽었습니다.

3.2 국내 카드 사용 교육서비스업 사용량, 오차 적음

교육 서비스업은 코로나 여파가 매우 컸나 봅니다. Prophet 모델이 예측이 가끔 10% 이상의 오차를 보여주다가 코로나 여파가 있었던 2020년 3월에 오차율이 무려 40% 이상을 기록합니다. 그리고 이후 다시 오차율이 10% 아래로 떨어지는 모습을 볼 수 있습니다. 반면 오미크론이 발생했던 2022년 초반에는 그렇게 큰 타격을 주지 못한 것도 그래프를 통해 확인할 수 있습니다.

2022년 6월 예측은 오차율 4.97%로 5% 미만의 낮은 오차를 보여줍니다. 그래프를 보면 꽤나 일치하는 트렌드로 올라가는 것을 볼 수 있습니다.

Prophet 모델의 평균 오차율은 6.32%이며, 선형 모델 7.84% 보다 1.5%나 평균적으로 오차율이 낮습니다. 매달 평균적으로 1.6 백억원 더 오차가 낮습니다.

마지막 2022년 5월 ~ 6월에 Prophet 예측치를 보면 실사용량보다 약간 낮게 예측한 것을 볼수 있습니다. 제가 수치를 낸다면 7월의 예측은 Prophet 상위 예측지와 예측치 사이인 1조 38백억원 ~ 1조 5천억 사이로 수요를 예측할 것 같습니다.

3.3 국내 카드 사용 도매 및 소매업 사용량, 오차 매우 적음

도매 및 소매업의 경우 코로나 여파가 가장 미미했던 것 같습니다. 모델이 전체적으로 10% 아래의 오차율을 보여주고 있으며, 평소에는 2% 아래로 낮은 오차율을 보여주고 있습니다. 특히, 마지막 오차율 0.09%로 거의 예측값과 실제 값이 일치하는 높은 정확도를 보여주고 있습니다.

Prophet 모델의 평균 오차율 1.30% 입니다. 선형 모델보다 오차율이 약 3.2%나 높은 것으로 매달 약 1조 1천억 높게 예측하고 있습니다. Prophet 모델이 시계열 패턴을 아주 잘 읽어서 좋은 예측을 꾸준히 보여줄 것으로 예상됩니다.

3.4 국내 카드 사용 숙박 및 음식점업, 오차 높음

숙박 및 음식점업은 매우 인상적인 패턴을 보여주어 공유드릴까 합니다. Prophet 예측 모델이 패턴을 잘 인식하고 10% 정도 수준의 오차율을 보여주다가 2020년 12월과 2021년 1월에 매우 높은 오차율을 보여주고 있습니다. 연말 특수를 통해 음식점과 숙박업소가 높은 매출을 기록할 것이라고 Prophet 모델이 예측하였으나, 코로나로 인해 그에 기대하지는 못하는 추세를 실사용액에서 보여준것으로 파악됩니다.

이는 2019년 카드 사용액보다 훨씬 떨어진 카드 사용액 현상을 보여주고 있습니다. 지난 2020년 3월 쯤부터 코로나 여파가 시작된 것을 보면, 2020년 12월 2021년 1월 카드 사용액의 오차가 높은 것은 어느정도 이해가 되는 현상입니다.

4.0 Rserve()를 통한 R과 Tableau 연결

그럼 지금부터 차근 차근 어떻게 R과 태블로를 연결하고 Prophet 모델을 만들었는지 설명 드리겠습니다. 

4.1 R과 태블로 연결

태블로에 도움말 → 설정 및 성능 → 분석 확장 프로그램 연결관리로 들어가면 R과 통합할 수 있습니다. 저는 로컬 환경의 R을 사용하여 위와 같이 정보를 입력하여 주었습니다.

호스트이름: localhost

포트: 6311

4.2 Rserve() 실행

실행하는 방법은 매우 간단합니다. R 코드 실행창에서 library: Rserve()를 다운받아 불러와 주시고 이후 위처럼 코드를 입력하시면 되십니다. 

				
					# install.packages(Rserve) -- 라이브러리 다운로드
library(Rserve) # Rserve() 라이브러리 실행 
Rserve(args = '--no-save') # Rserve 실행
				
			

그러면 아래와 같은 메세지가 나타나며, 시스템 활성 상태(맥북기준)에 Rserve가 백그라운드로 돌아가고 있는 것을 확인할 수 있습니다. 

5.0 Prophet 모델 만들기

그럼 본격적으로 어떻게 모델이 만들어졌는지 배워 봅시다. 

5.1 카드 사용량 데이터 로드

카드 사용량은 날짜 데이터가 월단위로 한국표준산업분류 별로 저장되어 있습니다. 이에따라, 각 월과 산업분류별로 카드 사용액이 백억원 단위로 저장되어 있습니다.

5.2 매개변수 만들기 (예측하고 싶은 기간 설정)

먼저, 예측하고 싶은 기간을 위한 매개변수를 위와 같이 만듭니다. 저는 12개월 1년치를 예측하고 싶어 현재 값을 12로 넣어주었습니다.

이름: Period to Forecast

데이터 유형: 정수

허용가능한 값: 전체

5.3 Prophet Model: yhat

				
					SCRIPT_REAL(
"library(prophet)
library(tidyverse)
period = .arg3[1]
df = as_tibble(data.frame('ds' = .arg1, 'y' = .arg2))

m = prophet(df)
future = make_future_dataframe(m, periods = period, freq = 'month')
forecast = predict(m , future, freq= 'month')

forecast[,'yhat']",

ATTR([Date]), SUM([백억원]),[Period to Forecast])
				
			

위와 같이 Prophet 모델 스크립트를 넣어줍니다. 현재 월단위로 예측하는 것이기 떄문에 freq = ‘month’가 예측 형식에 들어가 있는 것을 볼 수 있습니다. 저희가 예측 치만 뽑아낼 예정이기 ‘yhat’의 데이터만 뽑아냅니다.

5.4 Prophet Model: yhat_upper

				
					SCRIPT_REAL(
"library(prophet)
library(tidyverse)
period = .arg3[1]
df = as_tibble(data.frame('ds' = .arg1, 'y' = .arg2))

m = prophet(df)
future = make_future_dataframe(m, periods = period, freq = 'month')
forecast = predict(m , future, freq= 'month')

forecast[,'yhat_upper']",

ATTR([Date]), SUM([백억원]),[Period to Forecast])
				
			

5.3 yhat과 다른것은 forecast에서 yhat_upper를 사용한 것 입니다. 80% interval이 기본값이고 예측을 긍정적으로 바라 봤을때 예측 값입니다. (yhat_upper와 yhat_lower를 사이 값을 80% 신뢰구간으로 예측합니다.)

5.5 Prophet Model: yhat_lower

				
					SCRIPT_REAL(
"library(prophet)
library(tidyverse)
period = .arg3[1]
df = as_tibble(data.frame('ds' = .arg1, 'y' = .arg2))

m = prophet(df)
future = make_future_dataframe(m, periods = period, freq = 'month')
forecast = predict(m , future, freq= 'month')

forecast[,'yhat_lower']",

ATTR([Date]), SUM([백억원]),[Period to Forecast])
				
			

5.3 yhat과 다른것은 forecast에서 yhat_lower를 사용한 것 입니다. 80% interval이 기본값이고 예측을 부정적으로 바라 봤을때 예측 값입니다. (yhat_upper와 yhat_lower를 사이 값을 80% 신뢰구간으로 예측합니다.)

5.6 Regression 모델

선형회귀는 이전에 제가 작성했던 포스트를 참고 부탁드립니다. 

6.0 Prophet 모델 구현하기

Prophet 모델을 시계열로 구현하는데 필수 절차가 필요합니다. 천천히 아래를 따라해주시면 누구나 성공적으로 모델을 만들 수 있습니다

6.1 누락된 값 표시 실행

먼저 연속형 ‘월’을 클릭하여 주시고 누락된 값 표시를 선택해 주세요. 위처럼 누락된 값을 표기하시면 예측하고 싶은 12개월 예측 값을 R과 연동하여 누락없이 표현할 수 있습니다. 

6.2 카드 사용액과 예측치 표현하기

행 선반에 카드사용액(백억원)과 Prophet Forecast 필드를 배치합니다. 위 그래프를 보면, 카드 사용액 마지막 값 하나가 점으로 나타나 라인으로 이어지지 않은 것을 볼 수 있습니다. 해당 값을 제거해주도록 하겠습니다. 

6.3 Last 함수를 통한 마지막 카드 사용액 제거하기

위처럼 라스트 함수를 활용하여 특정 마지막 값만 제거해줄 수 있습니다. 해당 필드를 만든 후 필터 선반에 위치 시킵니다. 

이후 위 워크시트처럼 필터값을 설정하여, 마지막 값만 제거해 주면 됩니다. 이후 이중 축과 축 동기화 기능을 사용하여 두 라인 차트를 겹쳐주시면 예측선과 실제 사용액을 겹쳐 표현할 수 있습니다. 

7.0 결론

지금까지 R과 Tableau를 활용하여 Prophet 모델을 중심으로 대시보드를 만들어 보았습니다. 예측 모델을 이해하고 대시보드를 보니, 예측 모델을 한껏 더 이해할 수 있었습니다. 또한, 코로나라는 요소가 얼마나 우리 소비 생활에 영향을 끼쳤는지도 볼 수 있었습니다.

만약 제가 이 모델을 한번 더 발전 시킨다면 코로나 변수도 추가해서 볼 것 같습니다. 포스트에서 설명하지 않은 다른 기능들은 대시보드를 다운로드하여 확인해 주시기 바라며, 다음 시간에도 즐거운 통계 분석 주제로 찾아 뵙겠습니다. 감사합니다.

독자님들에게

태블로를 통한 데이터 분석 사례 혹은 태블로 활용 사례가 있으시다면 누구나 태블로 위키의 객원작가로써 글을 남길 수 있습니다. 간단하게 홈 페이지의 객원 작가 신청을 누르시고 남기고 싶으신 글 기획을 보내 주시면 되십니다. 대한민국 즐거운 데이터 분석 문화를 위해, 여러분들의 소중한 창의력과 아이디어 기다리고 있겠습니다.

3 thoughts on “Tableau/R을 활용한 Prophet Model 구현

  1. 안녕하세요!!
    태블로 대시보드 관련해 질문 드리려고 합니다
    (게시물과는 크게 상관없는 질문이지만 최신글에 질문을 하고자 하는 이기심…문제가 되면 삭제하겠습니다)

    데이터 원본 순서대로 항목이 나열되지 않고 있습니다….
    다시 말해, 엑셀에 corn-born-concern-arm 이렇게 배치를 했는데도 불구하고
    태블로로 가져오면 알파벳 순서대로 arm-born-concern-corn 이렇게 배치됩니다

    그럼 다시 수동으로 재배치를 해 놓으면
    데이터 원본을 바꿀 때 마다 다시 알파벳 순(가나다순)으로 돌아가버려서 매번 수동으로 조정을 하고 있습니다.

    ‘데이터 원본 순서’의 기준이 무엇인지 의구심이 듭니다…
    또 한 가지 의문점은 ‘정렬’에 들어가서 ‘데이터 원본 순서’를 누르면 왜…오름차순과 내림차순만 있는 걸까요.
    애초에 데이터 정렬을 원본 순서대로 할 수 없는 게 아닌가하는 생각이 드는 옵션입니다ㅠㅠ

    엑셀에 정렬한 대로 태블로에도 적용 시킬 수 있는 방법이 무엇인지 알고 싶습니다!
    또한 대시보드에서 데이터 원본 바꾸기를 해도 기존에 설정한 사항들이 변하지 않게 하는 방법도 알고 싶습니다!

    게시글 너무 잘 보고 있고 도움 많이 받고 있습니다.
    감사합니다!

    1. 안녕하세요 Sarah님,
      태블로를 통한 정렬 기준이 궁금하시군요.
      엑셀은 데이터를 직접입력하여 입력 기준으로 리포팅을 하는 툴이기 때문에 형식 그대로 유지할 수 있습니다.
      반면 태블로와 같은 BI 툴이나 데이터 베이스 툴들은 SQL 기반이기 때문에 불러오신 차원값을 Group by 형식으로 집계 인식하여 데이터를 집계합니다.
      해당 경우 데이터를 재 정렬 해줘야 하기때문에 오름차순 혹은 내림차순 기반으로 알파벳 혹은 수치 중심으로 집계 정렬을 수행하게 됩니다.
      따라서 엑셀 형식의 원본 기반의 정렬은 활용할 수 없습니다. 정말 해당 정렬이 필요하시면 데이터 앞에 수치를 입력하시는 것도 방법입니다. (1.corn 2.born 3.concern 4.arm)

      또한 원본을 바꾸게 되면 사용하신 데이터와 원본은 명확히 다른 데이터이기 때문에 계산식이 아닌 세부적인 정렬 혹은 색상은 다시 설정하여 주셔야합니다.
      원본교체를 통한 불필요한 재 설정을 원하지 않으실 경우에는, 데이터 원본 교체보다는 데이터에 날짜와 숫자같은 인덱스를 넣으시는 데이터 업데이트 방식 혹은 원본 자체에 데이터를 업데이트 하는 방안을 고려해보시기 바랍니다.

      감사합니다.

      1. 와….정말 두 번째 질문이긴 하지만 항상 친절하고 구체적이고 쉽게 이해할 수 있도록 답변 달아주셔서 너무너무 감사합니다. 명완식 마스터님(?) 덕분에 타블로가 더 재밌어졌어요ㅎㅎ 감사합니다! 좋은 하루 되시길 바랍니다~

댓글 남기기

태블로위키만의 새로운 소식, 놓칠 수 없겠죠?