당신은 주제를 찾고 있습니까 “머신러닝 시계열 예측 – [이것이 데이터 분석이다 with 파이썬_11] 시계열 예측 분석“? 다음 카테고리의 웹사이트 https://ppa.charoenmotorcycles.com 에서 귀하의 모든 질문에 답변해 드립니다: https://ppa.charoenmotorcycles.com/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 한빛미디어 이(가) 작성한 기사에는 조회수 15,521회 및 좋아요 145개 개의 좋아요가 있습니다.
머신러닝 시계열 예측 주제에 대한 동영상 보기
여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!
d여기에서 [이것이 데이터 분석이다 with 파이썬_11] 시계열 예측 분석 – 머신러닝 시계열 예측 주제에 대한 세부정보를 참조하세요
※ 도서 해당 내용
Chapter 03. 미래를 예측하는 데이터 분석(p162~p180)
– 비트코인 시세 예측하기
– 시간 정보가 포함된 데이터 살펴보기
– 파이썬 라이브러리를 활용해 시세 예측하기
※ 추천합니다!
– 코드를 실행하다가 이론을 모르겠어서 지치는 분들
– 이론을 공부하다가 수학이 막혀서 지치는 분들
– 수학 공부하다가 코드를 잊어보는 분들
WHY,
‘왜’ 가 중요합니다.
왜 이런 코드를 실행하고 분석의 방법을 잡는지
왜 이런 알고리즘이나 분석 방법을 여기서 사용하는지
※ 이 동영상은 『이것이 데이터 분석이다 with 파이썬』 책 내용을 토대로 제작되었습니다.
▶ 도서 자세히 보기 : http://www.hanbit.co.kr/store/books/look.php?p_code=B2717499992
▶ 질문하기 : 영상에 댓글을 달아주세요.
머신러닝 시계열 예측 주제에 대한 자세한 내용은 여기를 참조하세요.
Time series(시계열) Forecasting 시리즈 – 머신러닝 접근법 101
단변량 시계열 데이터를 예측하는 방법으로는 머신러닝이나 딥러닝 방법보다는 전통적인 ARIMA, ETS 방법이 효과적입니다. 시계열 데이터에 대한 머신러닝 기법을 알아 …
Source: datacrew.tech
Date Published: 12/28/2021
View: 3515
11가지 머신러닝 시계열 예측 모델 방법론 Time Series …
시계열 대회가 급증하여 머신러닝 시계열 예측 모델 방법론을 소개 합니다. Autoregression (AR); Moving Average (MA); Autoregressive Moving Average (ARMA) …
Source: dacon.io
Date Published: 1/19/2021
View: 459
머신러닝을 이용한 시계열 예측(Part-1)
시계열 예측 모델의 평가. 일반적으로 supervised machine learning 모델은 데이터 셋을 학습 데이터와 테스트 데이터를 랜덤하게 나누어 평가가 …
Source: medium.com
Date Published: 9/24/2021
View: 9886
머신러닝 시계열 예측 – 호텔리시스
그리고 머신러닝은 다시 세상의 관심을 받게 됩니다. 통계 분석 기법. 인공지능이 시계열 데이터의 예측에 적극적으로 활용될 수 있게 된 것은 인터넷 …
Source: hotelysis.com
Date Published: 9/11/2021
View: 2430
[시계열] Time Series에 대한 머신러닝(ML) 접근 – 다이엔 스페이스
이번 포스팅에서는 타임시리즈 데이터를 분석하기위해 머신러닝 기법을 사용하고, … 이런 방식으로 우리는 함수가 100% 예측가능하진 않지만, …
Source: diane-space.tistory.com
Date Published: 6/14/2022
View: 8387
1. 시계열 예측이란? – 불굴의관돌로그
관측된 시계열 데이터를 분석하여 미래를 예측하는 문제가 바로 시계열 … 일반적으로 supervised machine learning 모델은 데이터 셋을 학습 데이터 …
Source: undeadkwandoll.tistory.com
Date Published: 1/13/2021
View: 6732
시계열 예측을 위한 AutoML 설정 – Azure Machine Learning
Azure Machine Learning Python SDK를 사용하여 시계열 예측 모델을 학습하도록 Azure Machine Learning 자동화된 ML을 설정합니다.
Source: docs.microsoft.com
Date Published: 5/21/2021
View: 2630
시계열 예측: LSTM 모델로 주가 예측하기 – 인사이트캠퍼스
시계열 & 예측모델. 전통적으로 대부분의 머신러닝(ML) 모델은 일부 관찰(샘플/예제)을 입력 피쳐로 사용하지만 데이터에 시간 차원 …
Source: insightcampus.co.kr
Date Published: 2/14/2022
View: 7834
시계열 예측을 위한 LSTM 기반 딥러닝: 기업 신용평점 예측 사례
점을 예측하는 학습 모델을 구현하고, 여러 가. 지 머신러닝 분류 예측과 시계열 예측 분석 기. 법을 적용하여 각각의 성능을 평가했다. 다음으.
Source: www.koreascience.or.kr
Date Published: 10/15/2022
View: 3905
[ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!
이미 월가를 비롯해 주식시장의 최전방에 위치해있는 기업들은 실제로 다양한 기술을 이용하여 주식 가격의 미래를 예측하여 이를 실제로 수익과 연결 …
Source: box-world.tistory.com
Date Published: 6/30/2021
View: 9457
주제와 관련된 이미지 머신러닝 시계열 예측
주제와 관련된 더 많은 사진을 참조하십시오 [이것이 데이터 분석이다 with 파이썬_11] 시계열 예측 분석. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.
주제에 대한 기사 평가 머신러닝 시계열 예측
- Author: 한빛미디어
- Views: 조회수 15,521회
- Likes: 좋아요 145개
- Date Published: 2020. 3. 1.
- Video Url link: https://www.youtube.com/watch?v=AuzoQ8eZXEw
Time series(시계열) Forecasting 시리즈 – 머신러닝 접근법 101
Time series(시계열)이란?
시계열이라는 단어를 들어보신적이 있으신가요?
통계학을 전공한 분이라면 분명 들어보셨을 것입니다. 하지만, 통계학을 전공하지 않으신 분들은 쉽게 들어보기 어려운 단어입니다.
그러나, 시계열에 관련된 데이터들은 주위에서 쉽게 볼 수 있습니다.
가장 대표적인 것이 시계열 데이터는 주식 데이터 입니다.
1년 코스피 지수 그래프는 365개의 코스피 지수가 모여서 만들어진 그래프 입니다.
1일 그래프는 1일 동안 5분 단위로 78개의 코스피 지수가 모여서 만들어진 그래프입니다. 즉, 코스피 시계열 데이터는 시간이라는 특성(feature)와 코스피 지수라는 특성이 모여서 하나의 데이터로 만들어집니다.
주식 데이터를 통해서 살펴본 시계열 데이터를 간결하게 설명하자면 ‘시계열은 일정 시간 간격으로 한 줄로 배열된 데이터를 의미’ 라고 할 수 있습니다.
일정 시간 간격으로 배열되어 있는 데이터인 시계열을 분석을 하기 전에 시계열을 구성하는 요소들을 알아보도록 하겠습니다.
시계열 데이터는 시간에 따라 전개되는 특성과 변동주기에 따라 변화하는 특성이 있습니다. 그래서 변동 주기에 따라 추세, 순환, 계절, 불규칙 변동요인으로 구성되어 있습니다.
시계열 구성요소(components)
시계열을 구성하는 4가지 요인은 아래와 같습니다.
추세 (Trend) : 추세는 장기간 데이터의 일반적인 경향을 보여줍니다. 추세는 부드럽고 일반적인 장기적인 경향입니다. 짧은 구간에서 다른 변동을 보일 수 있지만 전체 추세는 상향, 하향 또는 안정적이어야합니다. 인구, 농업 생산, 제조 품목, 출생 및 사망자 수, 산업 또는 공장 수, 학교 또는 대학 수는 일종의 운동 경향을 보여주는 예입니다.
(Trend) : 추세는 장기간 데이터의 일반적인 경향을 보여줍니다. 추세는 부드럽고 일반적인 장기적인 경향입니다. 짧은 구간에서 다른 변동을 보일 수 있지만 전체 추세는 상향, 하향 또는 안정적이어야합니다. 인구, 농업 생산, 제조 품목, 출생 및 사망자 수, 산업 또는 공장 수, 학교 또는 대학 수는 일종의 운동 경향을 보여주는 예입니다. 순환 (Cyclic Variations ) : 1 년 이상 지속되는 시계열의 변동을 순환이라고 합니다. 이 변동은 1 년 이상의 주기를 갖습니다. Business cycle이라고 불리기도 합니다.
(Cyclic Variations ) : 1 년 이상 지속되는 시계열의 변동을 순환이라고 합니다. 이 변동은 1 년 이상의 주기를 갖습니다. Business cycle이라고 불리기도 합니다. 계절성 (Seasonal Variations ) : 1 년 미만의 기간에 걸쳐 규칙적이고 주기적으로 나타나는 변동입니다. 이러한 변동은 자연의 힘이나 사람이 만든 관습으로 인해 시작됩니다. 다양한 계절 또는 기후 조건은 계절 변화에 중요한 역할을합니다. 농작물 생산량은 계절에 따라 달라지고, 여름에 선풍기와 에어컨의 판매량이 높아지고 겨울에 판매량이 낮아지는 특징을 보이는 것을 계절성이라고 합니다.
(Seasonal Variations ) : 1 년 미만의 기간에 걸쳐 규칙적이고 주기적으로 나타나는 변동입니다. 이러한 변동은 자연의 힘이나 사람이 만든 관습으로 인해 시작됩니다. 다양한 계절 또는 기후 조건은 계절 변화에 중요한 역할을합니다. 농작물 생산량은 계절에 따라 달라지고, 여름에 선풍기와 에어컨의 판매량이 높아지고 겨울에 판매량이 낮아지는 특징을 보이는 것을 계절성이라고 합니다. 불규칙 변동요인(Random or Irregular movements) : 이 변동은 예측할 수없고 제어 할 수없고 예측할 수 없으며 불규칙합니다.
시계열의 구성요소 예시
시계열 구성요소 간의 구성(composition)
시계열 데이터를 구성하는 4가지 구성요소는 단일로 시계열을 구성할 수도 있고 가법, 승법 또한 가능합니다.
가법 모형 (addictive model) : 구성요소 간 독립적이고 가정하여 각 구성요소를 더하는 모형
(addictive model) : 구성요소 간 독립적이고 가정하여 각 구성요소를 더하는 모형 승법 모형(multiplicative model) : 구성요소 간 독립적이지 않고 상호작용 한다고 가정하여 구성요소 간 곱해주는 모형
참고로 여러 구성요소가 하나의 시계열 모형으로 있는 것을 여러개로 나누는 것을 ‘시계열 분해(de-composition)’이라고 합니다.
시계열 분석
시계열 데이터는 머신러닝 분야에서 관심이 많은 데이터 영역 입니다. 실제 세상에서는 시간적 요소가 중요한 데이터들이 많은 케이스가 많기 때문입니다. 시계열 데이터는 시간 변수와 한 개 혹은 여러 개의 변수들로 구성되어 있습니다. 시간과 한 개의 변수로 데이터가 구성되어 있을 땐 분석이 비교적 쉽습니다. 하지만, 시간과 여러 개의 변수로 데이터가 구성되어 있으면 분석이 어렵습니다. 시계열 데이터가 아닌 데이터에 대한 다변수 분석과 비교했을 때도 다변수 시계열 데이터는 분석이 더 어렵습니다.
단변량 시계열 데이터를 예측하는 방법으로는 머신러닝이나 딥러닝 방법보다는 전통적인 ARIMA, ETS 방법이 효과적입니다.
시계열 데이터에 대한 머신러닝 기법을 알아보기 전에 전통적인 분석방법에 대한 간략한 소개를 하겠습니다.
시계열 데이터의 특성
시계열 데이터는 크게 ‘규칙성을 가지는 패턴’과 ‘불규칙한 패턴’ 2가지로 나눕니다. 지금까지 시계열 모형은 이 두가지로 나누어서 만들어졌는데, 규칙성을 가지는 패턴을 이전의 결과와 이후의 결과 사이에서 발생하는 ‘자기상관성(autocorrelativeness)’과 이전에 생긴 불규칙한 사건이 이후의 결과에 편향성을 초래하는 ‘이동평균(moving average) 현상’으로 나누어서 보고 있습니다. 불규칙한 패턴의 경우 일반적으로 White Noise라고 칭하며 평균이 0이며 일정한 분산을 가진 정규분포에서 추출된 임의의 수치라고 가정하고 있습니다.
시계열은 추세 및 계절성 성분을 가지고 있으며 시계열 분석시에는 이를 정상 과정 신호와 분리할 필요가 있다. 회귀 분석을 사용하여 이러한 성분을 분리하는 방법을 설명합니다.
정상 과정(stationary process)은 시간이 지나도 신호의 확률적 특성이 그대로 유지되는 확률 과정을 말합니다. 대부분의 시계열 분석은 정상 과정 분석 방법을 기반으로 한다. 정상 과정 모형 중 가장 대표적인 백색 잡음(white noise)과 ARMA(auto-regressive moving average) 모형에 대해 소개합니다.
비정상 과정(nonstationary process)은 시간에 지나면서 기댓값의 수준이나 분산이 커지는 등 시계열의 특성이 변화하는 확률 과정을 말합니다. 비정상 과정 모형 중 가장 대표적인 것은 ARMA 모형을 누적한 ARIMA(auto-regressive integrated moving average) 모형입니다. ARIMA 모형의 개념을 설명하고 ADF 검정 등의 단위근 검정(unit root test)를 사용하여 모형의 적분 차수(integration order)를 결정하는 법을 설명합니다.
불규칙성을 띄는 시계열 데이터에 규칙성을 부여하는 방법으로 AR,MA,ARMA,ARIMA 모델등을 이용하여 미래를 예측하는 방법이 일반적이었다. 이러한 방법들은 선형 통계적 방법들이었습니다.
시계열 데이터의 머신러닝 모델
머신러닝 방식과 전통적인 통계적 방법의 목표는 동일합니다. 둘 다 sum of squared error과 같은 손실 함수(loss function)를 최소화 함으로써 예측 정확도를 향상시키는 것이 목표입니다. 전통적인 통계적 방법은 선형 처리를 하는 반면 머신러닝 방법은 비선형 알고리즘을 사용하여 최소화를 시켜서 목표를 달성합니다. 최근에는 딥러닝을 이용하여 시계열 데이터의 연속성을 찾아내는 방법이 연구되고 있다. RNN 종류의 LSTM이 좋은 성능을 냅니다. 머신러닝 알고리즘과 세부적으로 딥러닝 알고리즘 목록은 아래와 같습니다.
머신러닝
Multi-Layer Perceptron (MLP)
Bayesian Neural Network (BNN)
Radial Basis Functions (RBF)
Generalized Regression Neural Networks (GRNN)
kernel regression K-Nearest Neighbor regression (KNN)
CART regression trees (CART)
Support Vector Regression (SVR)
Gaussian Processes (GP)
딥러닝
Recurrent Neural Network (RNN)
Long Short-Term Memory (LSTM)
다음 포스팅에서는 시계열 데이터에 대한 예측 모델에 대해서 이야기를 해보겠습니다.
Reference
– https://www.toppr.com/guides/business-mathematics-and-statistics/time-series-analysis/components-of-time-series/
– Hyndman, R. J., & Athanasopoulos, G. (2018). Forecasting: principles and practice. OTexts.
11가지 머신러닝 시계열 예측 모델 방법론 Time Series Forecasting
시계열 대회가 급증하여 머신러닝 시계열 예측 모델 방법론을 소개 합니다.
Autoregression (AR) Moving Average (MA) Autoregressive Moving Average (ARMA) Autoregressive Integrated Moving Average (ARIMA) Seasonal Autoregressive Integrated Moving-Average (SARIMA) Seasonal Autoregressive Integrated Moving-Average with Exogenous Regressors (SARIMAX) Vector Autoregression (VAR) Vector Autoregression Moving-Average (VARMA) Vector Autoregression Moving-Average with Exogenous Regressors (VARMAX) Simple Exponential Smoothing (SES) Holt Winter’s Exponential Smoothing (HWES)
출처 :
https://machinelearningmastery.com/time-series-forecasting-methods-in-python-cheat-sheet/
머신러닝 시계열 예측
최근의 미드 범죄 수사물을 보면, 얼굴 인식 기술을 활용해 CCTV에 잡힌 범죄자의 신원을 특정하는 것이 당연한 절차인 것처럼 느껴집니다. 알파고와 이세돌 9단의 대국을 보며 충격에 휩싸였던 것이 엊그제 같은데, 순식간에 인공지능은 우리 삶에 파고들어 있는 것 같습니다.
인공지능의 역사
1940년대 말부터 산발적으로 연구되던 인공지능의 가능성은 Marvin Minsky, John McCarthy, Claude Shannon, Nathan Rochester 같은 과학자들이 1956년 미국의 다트머스 대학에서 개최한 컨퍼런스를 통해 인공지능이라는 이름을 갖게 됩니다. 그러나 이들이 생각했던 인공지능의 개념은 상당히 추상적이고 포괄적인 측면이 있었는데, 인간의 지능과 유사한 특징을 지닌 복잡한 컴퓨터를 의미했습니다.
IBM의 엔지니어였던 Arthur Samuel은 체스 프로그램을 만들면서 메모리 사용을 최소화하기 위해, 말을 두는 자리에 따라 승률을 계산하여 승률이 가장 높은 자리를 선택하는 함수를 만들었습니다. 그 과정에서 생성된 모든 경우의 수들을 프로그램이 암기하도록 했는데, 1959년 여기에 머신러닝이라는 이름을 붙입니다.
1957년, 코넬 항공우주 연구소의 Frank Rosenblatt는 Arthur Samuel의 시도를 기반으로 초기 형태의 인공 신경망인 Perceptron을 개발했습니다. IBM 704라는 초기 컴퓨터에 탑재되어 이미지 인식 기능을 수행하도록 계획되었지만, 인식률이 저조했고 오류가 자주 발생하면서 기대했던 성능을 보이지 못했습니다. 결국 머신러닝에 대한 회의적 견해가 확산되면서 관련 연구들이 정체되는 계기를 제공하게 됩니다.
2013년, 구글은 토론토 대학의 Geoffrey Hinton 교수와 그 제자들이 2012년 설립한 DNNresearch라는 스타트업을 인수했습니다. DNNresearch는 뇌의 뉴런과 유사한 정보 입출력 계층을 활용해 데이터를 학습하는, 이른바 딥러닝 알고리즘을 개발하기 위해 설립된 회사입니다. 그는 새로운 학습 체계를 통해 과거 인공 신경망 기술의 한계였던 과적합(overfitting) 문제를 해결했고, 때마침 고성능 GPU가 출시되면서 연산에 소요되는 시간을 단축할 수 있게 되었습니다. 그리고 머신러닝은 다시 세상의 관심을 받게 됩니다.
통계 분석 기법
인공지능이 시계열 데이터의 예측에 적극적으로 활용될 수 있게 된 것은 인터넷 검색 엔진들, 모바일 통신사들, 신용카드 회사들이 축적한 빅데이터 덕분입니다. 빅데이터 분석에 필요한 엄청난 양의 연산은 인공지능이 해결해 주었습니다. 인공지능 시계열 데이터 예측 모델들은 전통적인 통계 분석 기법들에 기반을 두고 있는데, 이동평균, 지수평활, 회귀분석 기법이 가장 많이 활용되어 왔던 것 같습니다.
이동평균(moving average)은 수많은 시계열 데이터 값들 중 정해진 수의 직전 값들을 평균하여 시계열 패턴을 분석하는 기법입니다. 다른 변수의 영향을 고려하지 않고 과거 데이터 값들의 패턴만을 분석하는 것이기 때문에, 계산이 쉬운 반면 예측 모델로서의 성능이 높지는 않습니다. 평균을 구하는 데 있어 산술평균을 사용하는 경우를 단순이동평균(simple moving average)이라고 하고, 가중치를 적용하여 평균을 산출하는 경우를 가중이동평균(weighted moving average)이라고 합니다.
지수평활(exponential smoothing)은 가중이동평균과 유사하지만, 전체 시계열 데이터 값들을 사용하고, 최근 값에 ‘지수적으로’ 더 큰 가중치를 부여한다는 차이가 있습니다. 이동평균처럼 계산이 쉬우면서, 불규칙적인 시계열 패턴 예측에는 더 큰 강점이 있습니다. 데이터에 추세와 계절성이 없는 경우 단순지수평활(simple exponential smoothing), 추세가 있는 경우 이중지수평활(double exponential smoothing), 추세와 계절성이 모두 있는 경우 삼중지수평활(triple exponential smoothing)이 사용됩니다.
회귀분석(regression analysis)은 이동평균이나 지수평활과 달리, 독립변수의 종속변수에 대한 영향을 고려할 수 있는 기법입니다. 회귀는 옛날 상태로 돌아가는 것을 의미합니다. 19세기 후반, 부모와 자녀의 키 사이에 선형적인 관계가 있으며 전체 키 평균으로 돌아가려는 경향이 있다는 Francis Galton의 가설에서 출발한 이후, 실증을 거쳐 함수 관계가 도출되면서 수학적 이론으로 정립되었습니다. 독립변수가 하나인 경우를 단순회귀분석(simple regression), 여러 개일 경우를 다중회귀분석(multiple regression)이라고 합니다.
독립변수를 어느 정도 특정할 수 있을 때에는 회귀분석이 가장 우수한 예측 성능을 보였기 때문에 가장 폭넓게 활용되어 왔습니다. 그러나, 가정과 변수에 따라 다양한 변형들이 존재하여, 성능에 커다란 차이가 나타나기도 합니다. 따라서, 모델들의 성능을 평가할 필요가 생겼고, 여기에 모델로부터 예측된 값과 실제 값의 차이를 의미하는 잔차(residual)가 사용되었습니다. 잔차가 정규분포에 따라 고르게 분산되어 있는지를 테스트하여, 0과 1 사이 값을 갖는 P-value가 0.05보다 작고, 마찬가지로 0과 1 사이 값을 갖는 R²이 1에 가까울수록 모델의 성능이 우수한 것으로 판단합니다.
인공지능 예측 모델
인공지능 시계열 데이터 예측 모델은 여전히 빠른 속도로 발전해가고 있고, 그 대부분은 회귀분석에 기반을 두고 있습니다. 머신러닝을 통한 시계열 데이터 예측 작업은 크게 새로운 데이터 값이 속하는 카테고리를 결정하는 분류(classification), 데이터 값들을 유사한 특성의 집단으로 묶는 군집화(clustering), 미지의 새로운 데이터 값 자체를 도출해내는 회귀(regression), 연산 속도를 향상시키기 위한 차원축소(dimensionality reduction)로 나뉩니다. 즉, 예측의 결과 값이 카테고리인 작업이 있는 반면, 숫자인 작업이 있는 셈입니다. 그리고 이러한 작업을 수행하는 모델들은 크게 Legacy, Classic, Topical로 분류될 수 있습니다.
Legacy 모델들은 초기에 개발된 것들로, 여전히 후속 모델들의 근간이 되고 있기는 하지만, 연산에 많은 시간이 소모되는 문제 때문에 지금은 많이 사용되지 않는 것들입니다. 여기에는 Recurrent Neural Network (RNN), Long Short-Term Memory (LSTM) 같은 모델들이 포함됩니다.
Classic 모델들은 널리 사용되면서 성능에 대한 검증이 완료된 모델들로, 현재 가장 보편적으로 활용되는 모델들입니다. 분류와 회귀 작업 모두에 사용되는 경우가 많은데, 다음과 같은 모델들이 포함됩니다.
Topical 모델들은 비교적 최근에 개발된 모델들로, 다른 모델들과 함께 사용되면서 특수한 기능을 담당하는 경우가 많습니다. Convolutional Neural Network (CNN), Attention Mechanism, Transformer Neural Network, Light Gradient Boosting Machine (LightGBM), Decision Trees, XGBoost, AdaBoost 같은 모델들이 여기에 포함됩니다.
한편, 다양한 인공지능 시계열 데이터 예측 모델들이 존재하는 만큼, 이들에 대한 성능을 평가하는 방법 또한 다양합니다. 그중 특히 2개의 방법이 자주 활용되는 것 같습니다. 백분율 기반으로 오차율을 검증한다는 공통점이 있는데, 하나는 Mean Absolute Percentage Error (MAPE)로 실제 값과 예측 값의 차를 실제 값으로 나누어 오차율을 계산합니다. 다만, 실제 값이 0에 가까울 때, 오차율이 무한대에 가까워지는 문제가 있습니다. 이를 보완하기 위해 Symmetric Mean Absolute Percentage Error (sMAPE)로 실제 값의 절댓값과 예측 값의 절댓값 차를 이 둘의 평균으로 나누어 오차율을 계산합니다.
인공지능 데이터 예측 모델을 개발하여 활용하기 위한 인프라 구축에는 이미 상당한 진척이 있습니다. 우선, 개발에 있어 가장 보편적으로 사용되는 프로그래밍 언어는 단연 Python으로, 누구나 무료로 이용할 수 있습니다. 그리고 머신러닝 알고리즘을 Python 기반으로 개발하는 데 있어 참고할 수 있는 방대한 라이브러리도 준비되어 있습니다. 대표적으로, 역시 누구나 무료로 이용할 수 있는 Scikit Learn은 원하는 기능에 따라 라이브러리가 체계적으로 분류되어 있으며, 카테고리별로 API와 모듈들까지 제공하고 있습니다.
다만, 여전히 발목을 잡고 있는 부분은 중구난방인 실제 데이터들입니다. 인공지능 시계열 데이터 예측 모델들이 제대로 활용되기 위해서는 일관된 형식의 과거 데이터가 많아야 하기 때문에, 아직은 이른바 빅데이터를 축적한 분야와 기간에 국한되어 있는 것이 현실입니다. 물론, 지나간 역사를 다시 쓸 수 없는 것처럼, 다시 과거로 돌아가 데이터를 만들어 올 수 없는 일입니다. 그럼에도 불구하고, 사람의 경험과 인공지능 알고리즘이 적절히 결합된다면, 과거의 데이터를 역으로 예측해내는 것도 불가능해 보이지는 않습니다.
[시계열] Time Series에 대한 머신러닝(ML) 접근
원문
towardsdatascience.com/ml-approaches-for-time-series-4d44722e48fe
ML Approaches for Time Series
비-전통적인 모델로 타임시리즈를 모델링 해봅시다.
이번 포스팅에서는 타임시리즈 데이터를 분석하기위해 머신러닝 기법을 사용하고, 이 시나리오 하에서 잠재적인 사용을 분석할 것입니다.
첫번째 포스트에서는 오직 목차의 첫번째 부분만 발전 시키겠습니다. 나머지는 목차로 부터 분리된 포스트로 접근 가능할 것입니다.
Note : 이번 연구는 2017년 부터 시작되었습니다. 그래서 몇몇 라이브러리들이 업데이트 됬을 수도 있습니다.
목차
1 – 데이터 생성, 창(windows) 과 기초 모델(baseline model)
2 – 유전 프로그래밍 : 기호 회귀 분석(symbolic regression)
3 – 극단의 학습 머신
4 – 가우시안 프로세스
5 – 합성곱 신경망 (CNN)
1 – 데이터 생성, 창(windows) 과 기초 모델(baseline model)
1.1 – 데이터 생성
이번 연구에서는 비주기적 시계열 데이터에 대한 분석을 경험하게 될것입니다. 우리는 3개의 랜덤 변수인 $x_1 , x_2, x_3 $의 합성 데이터를 만들고, 이러한 변수들의 일부 시차들의 선형 조합에 약간의 노이즈를 추가한 반응 변수인 $y$를 결정할 것입니다.
이런 방식으로 우리는 함수가 100% 예측가능하진 않지만, 반응변수가 예측치에 의존한다는 것과, 반응 변수에 대해 이전의 예측치에 대한 시차 (lags)의 효과로 유발된 시간 의존성 (time dependency) 이 있다는 것을 확실히 할 수 있습니다.
이 파이썬 스크립트는 시계열 데이터를 고려하는 창(windows)를 만들 것입니다. 그 이유는 우리가 가능한 가장 완전한 정보를 모델들에게 제공할 수 있게 문제의 틀을 형성하기 위함입니다.
첫번째로 우리가 가진 데이터와 어떤 기술을 우리가 앞으로 적용해야하는지 일단 봅시다.
import numpy as np import pandas as pd import matplotlib.pyplot as plt import copy as cp
N = 600 t = np.arange(0, N, 1).reshape(-1,1) # 각 숫자에다가 랜덤 오차항을 더함 t = np.array([t[i] + np.random.rand(1)/4 for i in range(len(t)) ]) # 각 숫자에다가 랜덤 오차항을 뺌 t = np.array([t[i] – np.random.rand(1)/7 for i in range(len(t)) ]) t = np.array(np.round(t,2)) x1 = np.round((np.random.random(N) * 5).reshape(-1,1),2) x2 = np.round((np.random.random(N) * 5).reshape(-1,1),2) x3 = np.round((np.random.random(N) * 5).reshape(-1,1),2) n = np.round((np.random.random(N)*2).reshape(-1,1),2) y = np.array([((np.log(np.abs(2 + x1[t])) – x2[t-1]**2) + 0.02 * x3[t-3]*np.exp(x1[t-1])) for t in range(len(t))]) y = np.round(y+n ,2 )
fig, (ax1,ax2) = plt.subplots(nrows=2) fig.set_size_inches(30,14) ax1.plot(y, marker = “o”) # 600일간 데이터 ax2.plot(y[:100], marker = “o”) # 100일간 데이터
이제, 우리는 3개의 독립변수에 노이즈를 첨가한 반응변수 y 함수를 가지고 있습니다.
또한 반응 변수는 직접적으로 주어진 지점에서 그들의 값 뿐만 아니라 독립 변수의 시차에 연관 (correlated) 되어 있습니다. 이 방식대로 우리는 시간 의존성을 보장하고, 우리의 모델이 이런 행동들을 식별하도록 만들 것입니다.
또한, 타임스템프의 간격이 균일하지 않습니다. 이런 식으로, 우리는 우리의 모델들이 단지 관측 수 (행)로 시리즈를 다룰 수 없기 때문에 시간 의존성을 이해하기 원한다는 생각을 굳건히 합니다.
우리는 데이터에 높은 비 선형성을 유도할 목적으로 지수연산자와 로그연산자를 포함시켰습니다.
1.2 – 창(Windows) 형성하기
이번 연구에서 모든 모델들이 따르는 접근은 정확한 예측을 달성하기 위해 우리가 가지고 있는 정보를 과거로 부터 주어진 시점에서 가능한 가장 완전한 정보를 모델에 제공하는 고정된 창(windows) 으로 재구성하는 것입니다. 추가적으로, 우리는 반응 변수 자체의 이전 값을 독립 변수로 제공하는 것이 모형에 어떤 영향을 미치는지 확인할 것입니다.
어떻게 되는지 한번 봅시다.
이 그림은 오직 시간 축과 반응변수만을 보여줍니다. 우리의 경우, t 값에 대한 반응 변수들은 3개 의 변수들이 있다는 것을 기억하세요.
제일 위에있는 그림은 w 크기로 선택된 (그리고 고정된) 창을 볼 수 있습니다. 이 경우에는 창의 크기가 4 이구요. 이것은 모델이 t+1 지점에서의 예측을 통해 창에 포함된 정보를 매핑한다는 사실을 의미합니다. 반응의 크기는 r 이 있는데, 우리는 과거에 몇가지 타임 스텝을 예측할 수 있었기 때문입니다. 이는 many-to-many 관계를 가집니다. 단순하고 쉬운 시각화를 위해서, 우리는 r=1 로 두겠습니다.
우리는 이제 Sliding Window 의 효과를 확인할 수 있습니다. 모델이 매핑함수를 찾기위해 갖게되는 input과 output의 다음 짝은 window를 한 스텝 미래로 움직음으로써 얻어집니다. 그리고 이전의 스텝에서 했던 것 처럼 같은 동작을 이어나갑니다.
Ok. 그러면, 어떻게 우리가 현재 데이터 셋에 이것을 적용할 수 있을까요? 우리가 필요한 것을 한번 봅시다. 그리고 우리의 유용한 함수를 만들어봅시다.
하지만 첫번째로, 우리는 시간이 절대값이 되는 것을 원하지 않습니다. 관찰 사이의 경과시간이 어느것인지 아는 것이 더 흥미로운 점입니다. (데이터가 균일하지 않다는 것을 기억하세요!). 그래서, $\Delta t$를 만들고, 우리의 데이터에 적용해봅시다.
dataset = pd.DataFrame(np.concatenate((t,x1,x2,x3,y), axis=1), columns = [‘t’,’x1′,’x2′,’x30′,’y’]) dataset[:7]
deltaT = np.array([(dataset.t[i+1] – dataset.t[i]) for i in range(len(dataset)-1)]) deltaT = np.concatenate( (np.array([0]), deltaT)) deltaT[:7]
dataset.insert(1,’∆t’,deltaT) dataset.head(3)
이제 우리의 데이터셋이 어떻게 생겼는지 알게되었습니다. 우리의 helper 함수가 테이블의 구성으로 무엇을 하기 원하는지 재현해봅시다.
window사이즈가 4인 경우에 :
우리의 함수가 하는 것은 window 안에 포함되어있는 모든 정보를 압축 (flatten) 하는 것입니다. 이 정보는 W window 내의 모든 값이며, 예측을 원하는 시간의 타임스탬프를 뜻합니다.
이 방식으로, 우리는 시스템을 모델링 하기 위한 2가지 다른 등식을 가지고 있으며, 새로운 예측치로 반응변 수의 이전의 값을 포함하고 있는 지에 따라 의존합니다.
함수가 리턴해야하는 결과는 이렇게 생겼습니다 :
우리는 $ l = n – (w+r) +1 $개의 windows를 만들 수 있을 것입니다, 왜냐하면 $Y(0)$ 의 첫번째 값에 대한 이전 정보가 없기 때문에 첫번째 행이 손실되기 때문입니다.
우리가 언급해온 모든 시차들은 모델의 새로운 예측치로 행동합니다 ( 이 시각화에서 Y의 이전 값이 포함되지 않았지만, 같은 값을 $X_i$ 로 따르게될 것입니다. ) 그리고 나서, (경과한) 타임스탬프는 여기서 우리가 원하는 예측값이 ∆t(4)가 되길 원할 것이며, 그에 따르는 예측에 대한 값이 Y(4)가 되야합니다. 모든 첫번째 ∆t(0) 가 0으로 초기화된다는 점에 주목하세요. 모든 window를 같은 범위로 표준화 하기를 원하기 때문입니다.
여기에 이 과정을 달성할 수 있는 코드를 만들었습니다. WindowSlider 형태의 함수가 있고 , 이 함수로 부터 파라미터를 변화하면서 다른 windows를 구성하는 객체를 만들 수 있습니다.
class WindowSlider(object): def __init__(self, window_size = 5): “”” Window Slider object ==================== w: window_size – number of time steps to look back o: offset between last reading and temperature r: response_size – number of time steps to predict l: maximum length to slide – (#obeservation – w) p: final predictors – (# predictors *w) “”” self.w = window_size self.o = 0 self.r = 1 self.l = 0 self.p = 0 self.names = [] def re_init(self, arr): “”” Helper function to initializate to 0 a vector “”” arr = np.cumsum(arr) return arr – arr[0] def collect_windows(self, X, window_size = 5, offset = 0, previous_y = False): “”” Input: X is the input matrix, each column is a variable Returns : different mappings window-output “”” cols = len(list(X))-1 N = len(X) self.o = offset self.w = window_size self.l = N – (self.w + self.r) + 1 if not previous_y: self.p = cols * self.w if previous_y: self.p = (cols +1) * self.w # Create the names of the variables in the window # Check first if we need to create that for the response itself if previous_y: x = cp.deepcopy(X) if not previous_y: x = X.drop(X.columns[-1], axis=1) for j , col in enumerate(list(x)): for i in range(self.w): name = col + (“(%d)” % (i+1)) self.names.append(name) # Incorporate the timestampes where we want to predict for k in range(self.r): name = “∆t” + (“(%d)” % (self.w + k +1)) self.names.append(name) self.names.append(“Y”) df = pd.DataFrame(np.zeros(shape = (self.l, (self.p + self.r +1))), columns = self.names) # Populate by rows in the new dataframe for i in range(self.l): slices = np.array([]) # Flatten the lags of predictors for p in range(x.shape[1]): line = X.values[i:self.w+i,p] # Reinitialization at every window for ∆T if p == 0: line = self.re_init(line) # Concatenate the lines in one slice slices = np.concatenate((slices,line)) # Incorporate the timestamps where we want to predict line = np.array([self.re_init(X.values[i:i+self.w +self.r,0])[-1]]) y = np.array(X.values[self.w + i + self.r -1, -1]).reshape(1,) slices = np.concatenate((slices,line,y)) # Incorporate the slice to the cake (df) df.iloc[i,:] = slices return df
1.2 – 기본 모델 (Baseline Model)
“항상 단순한 것을 먼저해라. 필요한 경우에만 지능을 적용해라” – Thad Starner
Windows 생성
w = 5 train_constructor = WindowSlider() train_windows = train_constructor.collect_windows(trainset.iloc[:,1:], previous_y = False) test_constructor = WindowSlider() test_windows = test_constructor.collect_windows(testset.iloc[:,1:], previous_y = False) train_constructor_y_inc = WindowSlider() train_windows_y_inc = train_constructor_y_inc.collect_windows(trainset.iloc[:,1:], previous_y = True) test_constructor_y_inc = WindowSlider() test_windows_y_inc = test_constructor_y_inc.collect_windows(testset.iloc[:,1:], previous_y = True) train_windows.head(3)
이제 모든 예측치, 남은 변수들의 과거 타임 스텝의 기록(window_length) 과 ∆t 의 누적 합을 어떻게 windows가 가져오는지 볼 수 있습니다.
예측치(prediction) = 현재(current)
우선 다음 타임스탬프의 예측으로 마지막 값(각 예측 지점에서 현재 값)을 주는 간단한 모델부터 시작해보겠습니다.
# ________________ Y_pred = current Y ________________ bl_trainset = cp.deepcopy(trainset) bl_testset = cp.deepcopy(testset) bl_train_y = pd.DataFrame(bl_trainset[‘y’]) bl_train_y_pred = bl_train_y.shift(periods = 1) bl_y = pd.DataFrame(bl_testset[‘y’]) bl_y_pred = bl_y.shift(periods = 1) bl_residuals = bl_y_pred – bl_y bl_rmse = np.sqrt(np.sum(np.power(bl_residuals,2)) / len(bl_residuals)) print(“RMSE = %.2f” % bl_rmse) print(“Time to train = 0 secconds”) >>> RMSE = 9.78 Time to train = 0 secconds
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(bl_y, marker = “o” , label = “actual”) # 100일간 데이터 ax1.plot(bl_y_pred, marker = “o”, label = “predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론 우리는 이미 다가오는 결과를 비교할 가치가 있습니다.
우리는 주어진 현재 값을 예측 값으로 고려하는 단순한 룰을 적용해보았습니다. 시계열에서 반응 변수의 값이 더욱 안정적이라면(stable) (a.k.a stationary) , 이 방식은 때때로 ML 알고리즘보다 놀랍게도 더 나은 성능을 보여줄 것입니다. 이런 경우에 데이터의 지그재그(zig-zag)는 악명이 높아 예측력이 떨어지는 것으로 이어집니다.
다중 선형 회귀 (Multiple Linear Regression)
우리의 다음접근은 다중 선형회귀 모델을 구성하는 것입니다.
# ______________ MULTIPLE LINEAR REGRESSION ______________ # import sklearn from sklearn.linear_model import LinearRegression import time lr_model = LinearRegression() lr_model.fit(trainset.iloc[:,:-1], trainset.iloc[:,-1]) t0 = time.time() lr_y = testset[“y”].values lr_y_fit = lr_model.predict(trainset.iloc[:,:-1]) lr_y_pred = lr_model.predict(testset.iloc[:,:-1]) tF = time.time() lr_residuals = lr_y_pred – lr_y lr_rmse = np.sqrt(np.sum(np.power(lr_residuals,2))/len(lr_residuals)) print(“RMSE = %.2f” % lr_rmse) print(“Time to train = %.2f seconds” % (tF-t0)) >>> RMSE = 7.52 Time to train = 0.01 seconds
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(lr_y, marker = “o” , label = “actual”) # 100일간 데이터 ax1.plot(lr_y_pred, marker = “o”, label = “predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론 다중 선형 회귀 모형이 얼마나 반응 변수의 동작을 포착하지 못하는지 알 수 있습니다. 이는, 반응변수와 독립변수 간의 비- 선형 관계 때문인데요. 또한 주어진 시간에 반응변수에게 영향을 미치는 것은 변수들간의 시차입니다. 따라서 이 관계를 매핑할 수 없는 모형에 대해 서로 다른 행에 값(values)들이 있습니다.
나는(저자는) windows의 구조에 대해 설명할 때 우리가 만든 가정을 이제 어떻게 확인해야 할지 궁금해졌습니다. 우리는 모든 예측 지점에 대해 완전한 정보 셋을 구성하기 원한다고 말해보겠습니다. 그래서, windows를 구성한 후의 예측력이 올라갸아합니다… 한번 가보죠 !
Windows를 가진 다중 선형 회귀 ( MLR with the Windows)
# ___________ MULTIPLE LINEAR REGRESSION ON WINDOWS ___________ lr_model = LinearRegression() lr_model.fit(train_windows.iloc[:,:-1], train_windows.iloc[:,-1]) t0 = time.time() lr_y = test_windows[‘Y’].values lr_y_fit = lr_model.predict(train_windows.iloc[:,:-1]) lr_y_pred = lr_model.predict(test_windows.iloc[:,:-1]) tF = time.time() lr_residuals = lr_y_pred – lr_y lr_rmse = np.sqrt(np.sum(np.power(lr_residuals,2))/ len(lr_residuals)) print(“RMSE = %.2f” %lr_rmse) print(“Time to Train = %.2f seconds” % (tF-t0)) >>> RMSE = 2.51 Time to Train = 0.01 seconds
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(lr_y, marker = “o” , label = “actual”) # 100일간 데이터 ax1.plot(lr_y_pred, marker = “o” , label = “predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
Wow! 굉장한 향상을 보였습니다.
이제 우리는 물리칠 수 있는 매우 강력한 모델이 있습니다. 새로운 windows 로, 모델은 전체 window 정보와 반응변수간의 관계를 찾을 수 있을 것으로 보입니다.
2 — 기호 회귀분석 (Symbolic Regression)
기호 회귀분석은 주어진 데이터셋을 적합하는 최적의 모델을 찾기위한 수학적 표현의 공간을 찾는 회귀 분석의 한 유형입니다.
기호 회귀분석의 기본은 유전 프로그래밍인데요, 그래서 진화 알고리즘 (a.k.a. 유전 알고리즘 (Genetic Algorithm – GA)이라고 합니다.
어떻게 알고리즘이 작동하는지 몇마디로 요약하면, 첫번째로 위의 그림과 같이, 수학적 표현이 트리 구조로 표현된다는 것을 이해할 필요가 있습니다.
이런 방식으로 알고리즘은 1세대에서 많은 나무의 개체수를 가지고 시작할 것이며, 이는 적합 함수 (fitness fuction)에 따라 측정될 것입니다. 우리의 경우에는 RMSE이죠. 각 세대에 가장 우수한 개인들은 그들 사이를 가로지르고 탐험과 무작위성을 포함하기 위해 일부 돌연변이를 적용합니다. 이 반복적인 알고리즘은 정지 조건이 충족될 때 끝납니다.
이 비디오는 유전 프로그래밍에 대한 훌륭한 설명을 해주고 있습니다.
모델
####################### # CREATION OF THE MODEL ####################### # !pip instal gplearn import gplearn as gpl from gplearn.genetic import SymbolicRegressor # It is possible to create custom operations to be considered in the tree def _xexp(x): a = np.exp(x); a[np.abs(a) > 1e+9] = 1e+9 return a xexp = gpl.functions.make_function( function = _xexp , name = ‘xexp’, arity=1) #function_set = [‘add’, ‘sub’,’mul’,’div’,’sin’,’log’] # ,xexp] function_set = [‘add’, ‘sub’,’mul’,’div’] if ‘model’ in locals(): del model model = SymbolicRegressor(population_size = 3000, tournament_size = 5, generations = 25, stopping_criteria = 0.1, function_set = function_set, metric = ‘rmse’, p_crossover = 0.65, p_subtree_mutation = 0.15, p_hoist_mutation = 0.05, p_point_mutation = 0.1, verbose = 1, random_state = None, n_jobs = -1) ########################################################### # TRAIN THE NETWORK AND PREDICT – Without previous values y ########################################################### # Train t0 = time.time() model.fit(train_windows.values[:,:-1], train_windows.values[:,-1]) tF = time.time() # Predict sr_y_fit = model.predict(train_windows.values[:,:-1]).reshape(-1,1) sr_y_pred = model.predict(test_windows.values[:,:-1]).reshape(-1,1) # Calculating Errors sr_residuals = sr_y_pred – testset.iloc[5:,-1].values.reshape(-1,1) sr_rmse = np.sqrt(np.sum(np.power(sr_residuals,2))/ len(sr_residuals)) print(“RMSE = %f” % sr_rmse) print(“Time to train %.2f” % (tF-t0)) print(model._program)
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(testset.iloc[5:,-1].values, marker = “o”, label=”actual”) # 100일간 데이터 ax1.plot(sr_y_pred, marker = “o”, label=”predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론
우리는 상징적 회귀분석이 검증데이터에 거의 완벽한 적합과 함께 상당히 좋은 성능을 발휘한다는 것을 보고 있습니다.
놀랍게도, 나는 더 많은 훈련 시간의 단점을 가지고도 가장 단순한 네개의 operators (덧셈, 뺄셈, 곱셈, 나눗셈) 만 포함시킴으로써 최고의 정확도를 달성했습니다.
나는 당신이 모델의 다른 파라미터들을 시도해보고 결과를 향상시키기를 기대합니다!
3 — 극단의 학습 머신 (Extreme Learning Machines)
극단의 학습 머신은 중요하고 알려진 머신러닝 기법입니다. 이 기법의 주요 측면은 모델의 파라미터들을 계산하기위해 학습 과정을 필요로 하지 않는다는 점입니다.
본질적으로, 한 EML 은 단층 피드포워드 신경망(Single-Layer-Feed-Forward Neural Network) 입니다 (SLFN) ELM 이론은 히든 레이어의 가중치 값이 조정될 필요가 없으며, 따라서 트레이닝 데이터와 독립적일 필요가 있다는 것을 보여줍니다.
보편적인 근사이론 (universal approximation property) 은 EML이 모든 숨겨진 뉴런에 대한 파라미터를 학습하기에 충분한 데이터를 가지고 있다면, 원하는 정확도로 회귀 문제를 해결할 수 있다는 것을 의미합니다.
EML은 또한 모델 구조와 정규화(regularization)의 이점을 얻는데, 이는 무작위 초기화 및 오버피팅의 부정적인 효과를 감소시킨다는 것입니다.
N개의 트레이닝 샘플 (x, t) 를 고려해보면, L개의 히든 신경망 출력값을 가진 SLFN은 다음과 같습니다 :
네트워크의 target, inputs , outputs 의 관계는 다음과 같습니다 :
히든 신경망이 입력 데이터를 두단계에 걸쳐 다른 표현으로 변형시킵니다. 첫번째로, 데이터는 입력층의 가중치와 편향을 통해 히든 레이어에 투영된 다음, 비선형 활성화 함수의 결과에 적용됩니다.
실제로, ELMs은 행렬 형태로 공통 신경망으로 해결됩니다. 행렬 형태는 다음과 같이 표현됩니다. :
그리고 여기에 이 방법이 도출하는 중요한 부분이 있습니다. T가 우리가 도달하고자 하는 target임을 감안할 때, 최소 제곱 오차 항이 있는 시스템은 무어-펜로즈 일반화된 유사 역행렬 (Moore-Penrose generalized inverse) 을 사용한 독특한 솔루션을 사용할 수 있습니다. 따라서, 우리는 한번의 작업으로 target T를 예측할 수 있는 최소한의 오차를 가진 해결책이 되는 히든레이어의 가중치 값을 계산할 수 있습니다.
이 가짜역행렬(presudoinverse)은 단수값 분해(Singular Value Decomposition)를 사용하여 계산되었습니다.
이 글에서는 어떻게 EML이 작동하는지, 그리고 EML의 높은 성능의 Toolbox 패키지와 MATLAB과 Python의 실행에 대해 상세하게 잘 정리된 설명이 있습니다.
모델
class Network(object): def __init__(self, input_dim, hidden_dim = 10, output_dim = 1): “”” Neural Network object “”” self.N = input_dim self.M = hidden_dim self.O = output_dim self.W1 = np.matrix(np.random.rand(self.N, self.M)) self.W2 = np.matrix(np.random.rand(self.M, self.O)) self.U = 0 self.V = 0 self.S = 0 self.H = 0 self.alpha = 0 # for regularization # Helper function def sigmoid(self, x): return 1.0 / (1.0 + np.exp(-0.1 * x)) – 0.5 def predict(self,x): “”” Forward pass to calculate the output “”” x = np.matrix(x) y = self.sigmoid( x @ self.W1) @ self.W2 return y def train(self, x, y): “”” Compute W2 that lead to minimal LS “”” X = np.matrix(x) Y = np.matrix(y) self.H = np.matrix(self.sigmoid(X @ self.W1)) H = cp.deepcopy(self.H) self.svd(H) iH = np.matrix(self.V) @ np.matrix(np.diag(self.S)).I @ np.matrix(self.U).T self.W2 = iH * Y print(‘W2 values updated…’) return H @ self.W2 – Y def svd(self, h): “”” Compute the Singualr Value Decomposition of a matrix H “”” H = np.matrix(h) self.U , self.S , Vt = np.linalg.svd(H, full_matrices = False) self.V = np.matrix(Vt).T print(‘SVD computed.. calulating Pseudoinverse..’) return np.matrix(self.U), np.matrix(self.S), np.matrix(self.V)
y의 이전 값을 features로 고려하지 않겠습니다.
############################################################### # TRAIN THE NETWORK AND PREDICT – Without previous values of y ############################################################### in_dim = train_windows.shape[1] -1 NN = Network(input_dim = in_dim, hidden_dim = 20, output_dim = 1) t0 = time.time() eml_residuals = NN.train(x =train_windows.iloc[:,:-1], y = train_windows.iloc[:,-1].values.reshape(-1,1)) tF = time.time() fit = NN.predict(train_windows.iloc[:,:-1]) predictions = NN.predict(test_windows.iloc[:,:-1]) eml_fit = cp.deepcopy(fit) eml_pred = cp.deepcopy(predictions) eml_residuals = eml_pred – testset.iloc[w:,-1].values.reshape(-1,1) eml_rmse = np.sqrt(np.sum(np.power(eml_residuals,2)) / len(eml_residuals)) print(‘RMSE = %.2f’ % eml_rmse) print(“Time to train %.2f” % ( tF-t0)) >>> ############################################################### # TRAIN THE NETWORK AND PREDICT – Without previous values of y ############################################################### in_dim = train_windows.shape[1] -1 NN = Network(input_dim = in_dim, hidden_dim = 20, output_dim = 1) t0 = time.time() eml_residuals = NN.train(x =train_windows.iloc[:,:-1], y = train_windows.iloc[:,-1].values.reshape(-1,1)) tF = time.time() fit = NN.predict(train_windows.iloc[:,:-1]) predictions = NN.predict(test_windows.iloc[:,:-1]) eml_fit = cp.deepcopy(fit) eml_pred = cp.deepcopy(predictions) eml_residuals = eml_pred – testset.iloc[w:,-1].values.reshape(-1,1) eml_rmse = np.sqrt(np.sum(np.power(eml_residuals,2)) / len(eml_residuals)) print(‘RMSE = %.2f’ % eml_rmse) print(“Time to train %.2f” % ( tF-t0)) >>> SVD computed.. calulating Pseudoinverse.. W2 values updated… RMSE = 3.70 Time to train 0.03
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(testset.iloc[w:,-1].values, marker = “o”, label = “actual”) # 100일간 데이터 ax1.plot(eml_pred, marker = “o”, label=”predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론
우리는 어떻게 EMLs가 우리의 데이터에 굉장한 예측력을 가지는지 볼 수 있었습니다. 또한, 반응변수의 이전 값을 예측 변수로 포함시킨 결과도 훨씬 더 나빠졌습니다.
확실히, EMLs는 계속해서 탐구해야할 모델입니다. 이것은 빠르게 구현함으로써 이미 그들의 엄청난 힘을 보여주었고, 단순한 역행렬과 몇번의 조작으로 그 정확성(accuracy)을 계산할 수 있었습니다.
온라인 학습
EMLs의 절대적으로 큰 장점은 온라인 모델을 구현하기 위해 계산적으로 매우 저렴하다는 것입니다. 이 글에서는 업데이트 및 다운데이트 작업에 대한 자세한 정보를 볼 수 있습니다.
몇줄 안가서, 우리는 모델이 적응이되었다고 말할 수 있으며, 만약 예측 오차가 안정된 임계값을 초과하면, 이 특정한 데이터 지점이 SVD에 통합됩니다. 그래서 모델이 값비싼 완전한 재트레이닝을 요구하지 않습니다. 이런 방식으로 모델은 프로세스에서 일어날 수 있는 변화로 부터 적응하고 배울 수 있습니다.
4 — Gaussian Processes
가우시안 프로세스 (Gaussian Processes) 는 그러한 변수의 모든 유한한 집합이 다변량 정규 분포를 가지도록 하는 랜덤 변수의 집합이며, 이는 이들 변수의 가능한 모든 선형 조합이 정규 분포를 따른 다는 것을 의미합니다. (가우시안 프로세스는 다변량 정규 분포의 유한-차원의 일반화로 볼 수 있습니다)
GP의 분포는 모든 랜덤 변수들의 결합 분포입니다. 몇마디로 줄이자면, GPs는 보이지 않는 지점에 대한 값을 예측하는 점들 사이의 유사성을 결정하는 커널 함수를 사용합니다.
이 비디오는 CO2 수준을 예측하는 가우시안 프로세스에 대한 훌륭하고 짧은 인트로를 소개합니다.
이 책은 가우시안 프로세스에 대한 주요 가이드 입니다.
GP의 한가지 분명한 장점은 예측을 중심으로 신뢰 구간을 쉽게 형성하기에, 모든 예측치에서 표준 편차를 얻을 수 있다는 사실입니다.
모델
매우 간단한 CNN을 가져와 보겠습니다 :
####################### # CREATION OF THE MODEL ####################### from sklearn.gaussian_process import GaussianProcessRegressor as GP from sklearn.gaussian_process.kernels import ConstantKernel as C from sklearn.gaussian_process.kernels import RBF from sklearn.gaussian_process.kernels import ExpSineSquared as ES from sklearn.gaussian_process.kernels import DotProduct as DP from sklearn.gaussian_process.kernels import Matern from sklearn.gaussian_process.kernels import WhiteKernel as WK l = 2. kernels = {‘cnt’: C(constant_value=0.1), ‘rbf’: RBF(length_scale=1), ‘ex2’: ES(length_scale=1), ‘dot’: DP(sigma_0 = 0.1), ‘mat’: Matern(length_scale=1, nu=1.5), ‘whi’: WK(noise_level=0.01)} k = kernels[‘cnt’] + kernels[‘ex2’] + kernels[‘rbf’] if ‘gp’ in locals(): del gp gp = GP(kernel = k , n_restarts_optimizer = 9, normalize_y = True)
y의 이전값을 feature로 고려하지 않겠습니다.
##################################################### # TRAIN THE NETWORK AND PREDICT – Without previous y ##################################################### # Train tranX = train_windows.values[:,:-1] tranY = train_windows.values[:,-1] testX = test_windows.values[:,:-1] testY = test_windows.values[:,-1] t0 = time.time() gp.fit(train_windows.values[:,:-1], train_windows.values[:,-1]) tF = time.time() # Predict gp_y_fit = gp.predict(train_windows.values[:,:-1], return_std = False) gp_y_pred, gp_y_std = gp.predict(test_windows.iloc[:,:-1], return_std = True) gp_y_up = (gp_y_pred + 1.96 * gp_y_std).reshape(-1,) gp_y_lw = (gp_y_pred – 1.96 * gp_y_std).reshape(-1,) gp_y_pred = gp_y_pred.reshape(-1,1) # Calculating Errors gp_residuals = gp_y_pred – testset.iloc[5:,-1].values.reshape(-1,1) gp_rmse = np.sqrt(np.sum(np.power(gp_residuals,2))/ len(gp_residuals)) print(“RMSE = %f” % gp_rmse) print(“Time to train % .2f” %(tF-t0)) >>> RMSE = 1.429122 Time to train 22.79
fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(testset.iloc[5:,-1].values, marker = “o”, label = “actual”) # 100일간 데이터 ax1.plot(gp_y_pred, marker = “o”, label=”predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론
우리는 가우시안 프로세스가 또 다른 높은 예측력을 가진 얼마나 아름다운 접근인지 볼 수 있었습니다. 이 모델은 또한 반응 변수의 이전 값을 예측치로 가져왔을 때 결과가 더욱 나빠졌습니다.
요점은, 튜닝된 커널의 거의 무한한 조합을 가지고 놀 수 있다는 것입니다. 즉, 그들의 결합 분포가 우리의 모델에 더 잘 맞는 랜덤 변수의 조합을 찾을 수 있다는 것입니다. 나는 당신만의 커널을 시도해보고, 이 결과를 향상시키길 권합니다.
5 — Convolutional NN
아이디어는 주어진 시간에 프로세스의 상태를 이전의 값의 window가 pucture로 정의한다는 것입니다.
그래서, 우리는 “pictures”를 반응 변수에 매핑하는 패턴을 찾고자 하기 때문에 이미지 인식의 평행도 (parallelism)을 사용하고자 합니다. 우리는 우리의 timeseries.py에 새로운 함수인 WindowsToPictures()를 포함하였습니다.
이 함수는 우리가 inputs 값으로 사용하던 windows를 가져가고, 반응 변수의 각 값에 대해 모든 열의 window 길이에 대한 이전의 모든 값을 가지고 picture를 만듭니다.
만약 우리가 chatper 1에서 windows를 reshape했던 것을 기억한다면, 이번에는 windows를 평활화 시키지 않을 것입니다. 대신에, 3D 텐서의 3차원으로 쌓을 것입니다. 여기서 각각의 slice는 각각 독특한 반응 변수로 매핑될 것입니다. 여기에 설명 그림이 있습니다.
CNN에 학습될 데이터 재구조화
def WindowsToPictures( data, window_size): dataset = data w = window_size arr = np.empty((0,w,3) , int) for i in range(0,len(dataset)-w+1): chunk = dataset.iloc[i:i+w,2:5].values chunk = chunk.reshape((1,)+chunk.shape) arr = np.append(arr,chunk, axis=0) xdata = arr arr_y= np.empty((0,)) for i in range(w-1,len(dataset)): chunk = dataset.iloc[i,5] chunk = chunk.reshape((1,)+chunk.shape) arr_y = np.append(arr_y,chunk, axis=0) ydata = arr_y return xdata, ydata
xdata , ydata = WindowsToPictures(dataset,5) xdata.shape #(596.5.3) ydata.shape # (596,) xtrain = xdata[:500] ytrain = ydata[:500] xtest = xdata[500:] ytest = ydata[500:] xtrain.shape # (500,5,3) ytrain.shape # (500,) xtest.shape # (96,5,3) ytest.shape # (96,)
모델
# !pip install keras from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers.convolutional import Conv1D, MaxPooling1D, AveragePooling1D “”” KERAS IMPLEMENTATION “”” # Research on parameter : Dilation_Rate of the convolution if ‘model’ in locals(): del model if ‘history’ in locals(): del history model = Sequential() model.add(Conv1D(filters = 32, input_shape = (5,3), data_format = ‘channels_last’, kernel_size = 2, # strides = (1,1), activation = ‘relu’)) # model.add(MaxPooling1D(pool_size=2)) ?? # model.add(AveragePooling1D(pool_size=2)) ?? model.add(Dropout(0.2)) model.add(Conv1D(filters = 12, data_format = ‘channels_last’, kernel_size = 2, # strides = (1,1), activation = ‘relu’)) # model.add(MaxPooling1D(pool_size=2)) ?? # model.add(AveragePooling1D(pool_size=2)) ?? model.add(Dropout(0.1)) model.add(Flatten()) model.add(Dropout(0.2)) model.add(Dense(45, activation = ‘relu’)) model.add(Dense(1)) model.compile(optimizer=’adam’, loss=’mean_squared_error’) model.summary()
history = model.fit(xtrain, ytrain,epochs=500, verbose=0) plt.plot(history.history[‘loss’])
model.evaluate(xtest,ytest) >>> 3/3 [==============================] – 0s 1ms/step – loss: 7.5618 7.561756610870361
y_predict=model.predict(xtest) fig, ax1 = plt.subplots(nrows=1) fig.set_size_inches(40,10) ax1.plot(ytest, marker = “o”, label = “actual”) # 100일간 데이터 ax1.plot(y_predict, marker = “o”, label=”predict”) # 100일간 데이터 ax1.legend(prop={‘size’:30})
결론
프로세스의 이전 상태를 매 타임 스텝마다 프로세스의 picture로 보는 것은 다변량 시계열 예측을 위한 합리적인 접근방식 처럼 보입니다. 이 접근방식은 재무 시계열 예측, 온도/날씨 예측, 프로세스 변수 모니터링 등 문제의 최고 책임자에게 문제를 구조화할 수 있습니다.
나는 여전히 결과를 개선하기 위해 windows와 picture를 만드는 새로운 방법에 대해서 생각해보고 싶지만, 내가 보기엔, 우리가 다 해보고 나서 볼 수 있듯이, 결코 실제 값을 넘어서지 않는 견고한 모듈 처럼 보입니다.
나는 당신이 이를 개선하기 위해 무엇을 생각해냈는지 많이 알고싶네요!
CNN 부분은 코드가 있지않아 직접 작성해보았습니다.
여러 시계열 예측을 해본 결과 가우시안 프로세스가 가장 낮은 RMSE 값을 가져왔네요,
혹시 오역이나 문제가될 사항이 있다면 문의를 댓글로 남겨주세요!
1. 시계열 예측이란?
시계열 예측(Time-Series Forecasting)이란?
시계열(Time-Series) 데이터란 시간의 흐름에 따라 순차적으로(sequentially) 기록된 데이터를 가리킨다.
관측된 시계열 데이터를 분석하여 미래를 예측하는 문제가 바로 시계열 예측 문제이다.
시계열 예측 문제는 흔하게 접하는 문제로써 주로 경제 지표를 예측하거나, 어떤 상품의 수요를 예측하는 문제에 이르기까지 다양한 어플리케이션을 가지고 있다.
특히, 예측된 결과를 바탕으로 여러 정책이나 비즈니스 전략을 결정하는 과정에 활용되기에, 실제 비즈니스 영역에서는 시계열 예측 문제가 매우 중요하게 여겨지고 있다.
일례로 McKinsey Global Institute의 연구에 따르면, 시계열 데이터가 텍스트나 이미지 데이터 보다 더 큰 잠재적 가치를 가지고 있다고 보고있다.
데이터 유형에 따른 잠재적 인공지능 활용 가치(McKinsey Global Institute analysis)
시계열 예측 문제의 주요 챌린지
무엇보다 시계열 문제가 4가지 어려운 점이 있다.
1.예측값은 완벽할 수 없으며, 항상 변동의 가능성을 내포.
따라서 시계열 예측에 있어 불확실성(uncertainty)이 고려되어야 한다. 다시 말해 예측값에 대해 적합한 확률 분포 모델(probability distribution)이 고려되어야 한다. 단순히 어떤 에측 값을 제공한다기 보다는 그 예측값의 불확실성(또는 신뢰도)에 대해 정량적인 평가가 함께 고려되어야 예측 모델로써 더욱 가치가 있다.
2. 시계열 데이터에 숨겨진 여려 형태의 패턴을 찾아 학습하는 문제.
보통 trend,seasonality,cycle 등의 유형으로 패턴을 구분하곤 한다. 대게 시계열 데이터에는 이러한 패턴이 복잡하게 섞여있고 데이터의 길이가 불충분 하거나, 노이즈, 아웃라이어 데이터로 인해 손쉽게 패턴을 구분해 내어 찾기가 어렵다.
3. 다변량 시계열 데이터(multiple time-series)를 다뤄야 하는 경우가 많아지고 있다.
과거에는 주로 다변량의 시계열 데이터(unvariate time-series)의 분석과 예측 문제가 주로 다뤄졌지만 근래에는 다변량 시계열 데이터를 다뤄야 하는 경우가 많아지고 있다.
순차적으로 관찰된 수많은 변수들에 대해, 이 변수들간의 상관 관계를 학습할 수 있어야 한다. 가령, 어떤 상품의 수요가 다른 상품들의 수요 변화에 영향을 받거나, 어떤 지역의 택시 수요가 다른 지역의 택시 수요와 일정한 시간 차이를 두고 상관 관계를 보일 수 있다. 이 변수가 적게는 수백에서 많게는 수백만에 이를 수 있으므로, 이를 효율적으로 처리하고 학습할 수 있는 알고리즘이 매우 중요해 지고 있다.
4. 시계열 데이터에는 노이즈 데이터 또는 관찰되지 못한 기간이 종종 존재한다.
이는 측정하고 데이터를 기록하는 과정에서의 오류나 예측치 못한 상황으로 인해 발생할 수 있다. 예를 들어 상품의 품절로 인하여 장기간 판매량이 없는 경우, 해당 상품에 대한 실제 수요를 판매량으로 유추할 수 없는 경우이다.
시계열 예측 문제에 있어서는 이에 대한 적절한 전처리 과정이 매우 중요하다.
시계열 예측 모델의 평가
일반적으로 supervised machine learning 모델은 데이터 셋을 학습 데이터와 테스트 데이터로 랜덤하게 나누어 평가를 한다. 하지만 시계열 예측 문제는 평가와 학습 대상의 데이터를 특정 시간 기준으로 엄밀하게 분리시켜, data leak이 없이 평가가 이루어져야 한다.
가령 시계열 데이터의 중간 구간을 잘라내 테스트용으로, 그 이전과 이후를 학습용으로 사용하면 정확한 평가가 이루어질 수 없다. 학습 데이터는 반드시 테스트 데이터 보다 이전에 관찰된 것이어야 한다.
모델링 과정에서는 최적의 성능을 가지되, robust한 모델을 찾기 위해 cross-validation을 통해 성능을 평가한다. 제한된 데이터 셋으로부터 여러 쌍의 학습 및 테스트 데이터를 샘플링해서 모델의 성능이 기대치에 부합하며, 안정적인지를 확인하게 된다. 시계열 예측 모델에서는 앞서 언급한 chronological testing 기준을 지키며, cross-validation을 할 수 있는 방법으로 크게 두가지가 고려된다.
1. Sliding window
슬라이딩 윈도우(Sliding Window) 알고리즘은 배열이나 리스트의 요소의 일정 범위의 값을 비교할 때 사용하면 유용한 알고리즘이다.
예를 들어 정수로 이루어진 배열 [2,4,7,10,8,4,5,6,7,1] 에서 길이가 3인 서브배열의 합계가 가장 큰 서브배열은 무엇일까?
서브 배열 합계 체크
특정 길이의 하위 배열의 최대 합계값을 구하는 단순한 방식을 먼저 살펴보자.
단순하게 for 문으로 모든 배열 요소를 특정 길이만큼 순회하며 합계를 구해서 최대 값을 구하는 단순하고 비효율적인 방법이다.
import sys def max_sub_array(arr, k): maxsum = -sys.maxsize – 1 arraysize = len(arr) for i in range(arraysize – k + 1): current_sum = 0 for j in range(i, i + k): current_sum += arr[j] maxsum = max(maxsum, current_sum) return maxsum if __name__ == ‘__main__’: print(max_sub_array([2, 4, 7, 10, 8, 4, 5, 6, 7, 1], 3)) 25 (7 + 10 + 8)
설명이 크게 필요 없는 단순한 코드이다.
물론 위와 같이 작성해도 데이터가 방대하지 않다면 큰 차이는 없을 것이다.
그렇다면 좀 더 효율적인 코드를 작성할 방법을 찾아보자.
우선 기존 단순한 방식에서 서브 배열의 요소를 순회하다 보면 중복되는 요소들이 존재한다.
서브배열의 공통된 요소 예시
위 이미지 처럼 범위가 5인 서브배열을 탐색하는 경우 0~4 범위의 서브배열과 1~5 범위의 서브배열은 공통적으로 1~4 범위가 중복된다.
중복되는 요소(공통 요소)들을 재상용하는 방법이 슬라이딩 윈도우 알고리즘의 핵심이다.
def max_sub_array(arr, k): window_sum = 0 max_sum = 0 window_start = 0 for window_end in range(len(arr)): window_sum += arr[window_end] # 슬라이딩 인덱스 범위 요소 합산 # 슬라이딩 윈도우의 범위가 k 보다 커진 경우 if window_end >= (k – 1): max_sum = max(max_sum, window_sum) window_sum -= arr[window_start] # 슬라이드 윈도우 범위를 벗어난 요소를 합계에서 제거 window_start += 1 # 슬라이드 윈도우 시작 인덱스 증가 return max_sum if __name__ == ‘__main__’: print(max_sub_array([2, 4, 7, 10, 8, 4], 3)) 25 (7 + 10 + 8)
이해를 쉽게 하기 위해 기존 배열보다 길이가 짧은 배열로 변경했다. 각 루프마다 다음과 같은 식으로 진행된다.
슬라이딩 알고리즘1 슬라이딩 알고리즘2
우선 슬라이딩 윈도우를 관리하기 위한 변수들로 window_start, window_end, window_sum 등을 사용한다.
-window_start: 슬라이딩 윈도우 시작 인덱스
-window_end: 슬라이딩 윈도우 끝 인덱스
-window_sum: 슬라이딩 윈도우 합계
슬라이딩 윈도우는 하위 윈도우의 범위 k 와 동일하게 유지하며 범위 내의 요소는 모두 합산하고 범위 밖으로 벗어난 요소들은 빼준다. 다만 슬라이딩 윈도우의 범위가 k 보다 커질때까지 (window_end>=k-1)는 요소들을 합산하기만 하고 이후부터는 범위 밖의 요소들을 차감시켜준다.
이렇게 하면 기존처럼 매번 서브배열의 합계를 구할 필요 없이 모든 요소를 1번만 순회하면서 최대값을 구하게 되므로 빠르고 효율적으로 처리된다.
위 sliding window 알고리즘을 통해 고정된 사이즈 2개의 window를 움직여가며 학습,테스트 데이터를 추출하여 cross-validation을 하는 방법이다.
2. Expanding window
위 sliding window를 이해하였다면 이는 간단하게 이해할 수 있다. 데이터 길이가 충분치 않을때 데이터를 확장해 가며 학습,테스트 데이터를 추출하는 알고리즘이다.
Cross-validation for time-series forecasting model(Source: https://eng.uber.com/forecasting-introduction/)
시계열 예측 모델의 평가는 문제에 따라 다양한 지표가 활용될 수 있다. Root Mean Squared Error(RMSE) 또는 Mean Absolute Percentage Error(MAPE)가 많이 사용되는 지표이다. 일반적으로 baseline 예측 모델(e.g.최근 평균값으로 예측)과의 비교가 매우 유용하다. 머신러닝을 도입하기 이전의 다소 단순한 방식과의 비교를 통해 개발된 예측 모델의 도입 효과를 가늠해 보곤한다. 예측 모델의 평가는 특정 성능 지표 뿐만 아니라 residual error의 분포, 시간축에 따른 Error의 propagation 패턴을 분석하여 모델의 bias가 있는지 혹은 overfitting 여부 등에 대한 검토가 반드시 필요하다.
주요한 시계열 패턴
전통적으로 시계열 데이터를 분석할 때 보통 trend, seasonality,cycles 그리고 random noise의 패턴으로 분류하여 분석한다.
Trend 는 전체적으로 긴구간에 걸쳐 일정하게 증가 또는 감소하는 패턴을 가리킨다.
Seasonal component는 규칙적인 주기에 따라 반복되는 패턴을 나타내며, 주기가 규칙적이지 않지만 wave형태로 반복되는 패턴을 cyclical component로 분류하여 분석한다.
Trend,seasonality,cycles를 제외한 그외 불규칙한 fluctuation은 random component로 분류한다.
Decomposition of time-series data(Source: Forecasting: Principles and Practices)
일반적을 전통적인 시계열 분석 모델에서는 이 4가지 유형이 패턴이 linear한 조합으로 이루어진 모델(additive model)을 가정한다. 간혹 seasonal 또는 cyclic 패턴의 변동폭이 시계열 값의 크기에 따라서 함께 변하는 경우 multiplicative model을 가정하기도 한다. 분석 모델 안에서 패턴이 어떻게 구성되느냐에 따라 , 개별 component에 대한 수학적 모델 또한 매우 다양하다. 주어진 시계열 데이터에 맞는 모델을 찾아가는 과정이 예측 모델을 만들어 가는 과정이라고 볼 수 있다.
대표적인 전통 시계열 예측 모델: ARIMA
전통적으로 시계열 데이터에서 패턴을 추출하고 그 패턴을 이용하여 미래를 예측하는 모델로 Autoregressive integrated moving average(ARIMA)가 있다.
ARIMA모델은 크게 세가지 component로 조합되어 만들어진다. 먼저 Autoregressive는 예측 시점(t-0)이 과거 p 개의 데이터 포인트(t-1,t-2,…,t-p)와 연관이 있다는 의미이다. 일련의 과거 관측값을 이용하여 미래의 값을 예측하는 regression 모델인 것이다.
Moving average는 과거의 예측 에러를 예측 대상과 연관 시키는 component이다. 가령 autoregressive 모델로 미래를 예측함에 있어, 과거의 에러들을 고려하여 그 예측값을 보정하는 역할을 한다고 볼 수 있다. 마지막으로 integrated의 의미는 non-stationary time-series의 데이터를 differencing을 통해 시간에 따라 데이터의 통계적 특성(e.g. mean, std)이 변하지 않는 stationary time-series 데이터로 변환하는 모델을 의미한다. 적합한 ARIMA 예측 모델을 만들기 위해서는 differencing order을 조절하여 데이터로부터 non-stationary를 반드시 제거해야 한다.
ARIMA 모델은 추가적인 component를 고려함으로써 다양한 형태로 변형, 발전될 수 있다. 예를 들어 추가적인 seasonal component를 고려하는 SARIMA가 있으며, univariate time-series가 아닌 추가적인 covariates를 함께 고려하여 예측할 수 있는 ARIMAX 모델이 존재한다. 물론 이 두가지를 모두 혼합한 SARIMAX모델도 사용되곤 한다.
시계열 예측을 위한 AutoML 설정 – Azure Machine Learning
목차
Python으로 시계열 예측 모델을 학습시키도록 AutoML 설정
아티클
08/10/2022
읽는 데 34분 걸림
기여자 22명
이 문서의 내용
적용 대상: Python SDK azureml v1
이 문서에서는 Azure Machine Learning Python SDK에서 Azure Machine Learning 자동화 ML을 사용하여 시계열 예측 모델에 AutoML 학습을 설정하는 방법을 알아봅니다.
이렇게 하려면 다음을 수행합니다.
시계열 모델링에 대한 데이터를 준비합니다.
AutoMLConfig 개체에서 특정 시계열 매개 변수를 구성합니다.
개체에서 특정 시계열 매개 변수를 구성합니다. 시계열 데이터를 사용하여 예측을 실행합니다.
하위 코드 환경의 경우 Azure Machine Learning Studio에서 자동화된 ML을 사용하는 시계열 예측 예제를 알아보려면 자습서: 자동화된 Machine Learning으로 수요 예측을 참조하세요.
고전적인 시계열 방법과 달리, 자동화된 ML에서는 이전 시계열 값이 “피벗”되어 다른 예측 변수와 함께 회귀 변수의 추가 차원이 됩니다. 이 방법은 학습 중에 여러 컨텍스트 변수와 각 변수 간 관계를 통합합니다. 여러 요인이 예측에 영향을 줄 수 있으므로 이 방법은 실제 예측 시나리오에 적합합니다. 예를 들어 판매를 예측하는 경우 판매 결과에 과거 기록 추세의 상호 작용, 환율 및 가격이 모두 함께 영향을 미칩니다.
필수 구성 요소
이 문서의 내용을 진행하려면 다음 항목이 필요합니다.
학습 및 유효성 검사 데이터
자동화된 ML에서 예측 회귀 작업 유형과 회귀 작업 유형 간의 가장 중요한 차이점은 유효한 시계열을 나타내는 기능을 학습 데이터에 포함하는 것입니다. 정규 시계열에는 잘 정의되고 일관된 빈도가 있으며 연속 시간 범위의 모든 샘플 요소에 값이 있습니다.
중요 미래 가치를 예측하기 위해 모델을 학습하는 경우 학습에 사용된 모든 기능을 의도한 구간에 대해 예측을 실행할 때도 사용할 수 있는지 확인합니다.
예를 들어, 수요 예측을 만들 때 현재 주가에 대한 기능을 포함하면 학습 정확도가 크게 높아질 수 있습니다. 그러나 장기 구간을 사용하여 예측하려는 경우 미래 시계열 요소에 해당하는 선물 주가를 정확하게 예측할 수 없으며 모델 정확성이 떨어질 수 있습니다.
별도의 학습 데이터 및 유효성 검사 데이터를 AutoMLConfig 개체에서 직접 지정할 수 있습니다. AutoMLConfig에 대해 자세히 알아보세요.
시계열 예측의 경우 기본적으로 ROCV(이동 원본 교차 유효성 검사)만 유효성 검사에 사용됩니다. 학습 및 유효성 검사 데이터를 함께 전달하고 n_cross_validations 매개 변수를 사용한 교차 유효성 검사 접기 수를 AutoMLConfig 에서 설정합니다. ROCV는 원본 시간 요소를 사용하여 계열을 학습 및 유효성 검사 데이터로 나눕니다. 원본을 시간에 따라 슬라이딩하여 교차 유효성 검사 겹을 생성합니다. 이 전략은 시계열 데이터의 무결성을 유지하고 데이터 누출의 위험을 제거합니다.
자체 유효성 검사 데이터를 가져올 수 있으며 AutoML에서 데이터 분할 및 교차 유효성 검사 구성에서 자세히 알아볼 수 있습니다.
적용 대상: Python SDK azureml v1
automl_config = AutoMLConfig(task=’forecasting’, training_data= training_data, n_cross_validations=3, … **time_series_settings)
AutoML이 교차 유효성 검사를 적용하여 과잉 맞춤 모델을 방지하는 방법에 대해 자세히 알아봅니다.
실험 구성
AutoMLConfig 개체는 자동화된 기계 학습 태스크에 필요한 설정 및 데이터를 정의합니다. 예측 모델의 구성은 표준 회귀 모델의 설정과 유사하지만 특히 시계열 데이터에 대해서는 특정 모델, 구성 옵션 및 기능화 단계가 존재합니다.
지원되는 모델
자동화된 Machine Learning은 모델 생성 및 튜닝 프로세스의 일부로 다른 모델 및 알고리즘을 자동으로 시도합니다. 사용자는 알고리즘을 지정할 필요가 없습니다. 예측 실험의 경우 원시 시계열 및 딥 러닝 모델은 모두 권장 시스템의 일부입니다.
팁 기존 회귀 모델도 예측 실험을 위한 권장 시스템의 일부로 테스트됩니다. SDK 참조 설명서에서 지원되는 모델의 전체 목록을 참조하세요.
구성 설정
회귀 문제와 마찬가지로 태스크 유형, 반복 횟수, 학습 데이터 및 교차 유효성 검사 수와 같은 표준 학습 매개 변수를 정의합니다. 예측 작업에는 실험을 구성하기 위해 time_column_name 및 forecast_horizon 매개 변수가 필요합니다. 데이터에 여러 매장의 판매 데이터 또는 여러 상태의 에너지 데이터와 같은 여러 시계열이 포함된 경우 자동화된 ML에서 자동으로 이를 감지하고 time_series_id_column_names 매개 변수(미리 보기)를 설정합니다. 실행을 더 잘 구성하기 위해 추가 매개 변수를 포함할 수도 있습니다. 포함할 수 있는 항목에 대한 자세한 내용은 선택적 구성 섹션을 참조하세요.
중요 자동 시계열 식별은 현재 공개 미리 보기로 제공됩니다. 이 미리 보기 버전은 서비스 수준 계약 없이 제공됩니다. 특정 기능이 지원되지 않거나 기능이 제한될 수 있습니다. 자세한 내용은 Microsoft Azure Preview에 대한 추가 사용 약관을 참조하세요.
매개 변수 이름 Description time_column_name 시계열을 작성하고 해당 빈도를 유추하는 데 사용되는 날짜/시간 열을 입력 데이터에 지정하는 데 사용됩니다. forecast_horizon 앞으로 어느 정도의 기간에 대해 예측할 것인지 정의합니다. 구간은 시계열 빈도의 단위입니다. 단위는 예측자가 예측해야 하는 학습 데이터의 시간 간격(예: 매월, 매주)을 기준으로 합니다.
코드는 다음과 같습니다.
ForecastingParameters 클래스를 활용하여 실험 학습에 대한 예측 매개 변수를 정의합니다.
클래스를 활용하여 실험 학습에 대한 예측 매개 변수를 정의합니다. time_column_name 을 데이터 세트의 day_datetime 필드에 설정합니다.
을 데이터 세트의 필드에 설정합니다. 전체 테스트 세트를 예측하려면 forecast_horizon 을 50으로 설정합니다.
from azureml.automl.core.forecasting_parameters import ForecastingParameters forecasting_parameters = ForecastingParameters(time_column_name=’day_datetime’, forecast_horizon=50, freq=’W’)
다음으로 이들 forecasting_parameters 가 표준 AutoMLConfig 개체로 전달되고 forecasting 작업 유형, 기본 메트릭, 종료 조건 및 학습 데이터도 함께 전달됩니다.
from azureml.core.workspace import Workspace from azureml.core.experiment import Experiment from azureml.train.automl import AutoMLConfig import logging automl_config = AutoMLConfig(task=’forecasting’, primary_metric=’normalized_root_mean_squared_error’, experiment_timeout_minutes=15, enable_early_stopping=True, training_data=train_data, label_column_name=label, n_cross_validations=5, enable_ensembling=False, verbosity=logging.INFO, **forecasting_parameters)
자동화된 ML을 사용하여 예측 모델을 학습시키는 데 필요한 데이터 양은 AutoMLConfig 를 구성할 때 지정된 forecast_horizon , n_cross_validations 및 target_lags 또는 target_rolling_window_size 값의 영향을 받습니다.
다음 수식은 시계열 기능을 구성하는 데 필요한 기록 데이터의 양을 계산합니다.
필요한 최소 기록 데이터: (2x forecast_horizon ) + # n_cross_validations + max(max( target_lags ), target_rolling_window_size )
지정된 관련 설정에 필요한 기록 데이터 양을 충족하지 않는 데이터 세트의 계열에 대해서는 Error exception 이 발생합니다.
기능화 단계
모든 자동화된 Machine Learning 실험에서 자동 크기 조정 및 정규화 기술이 기본적으로 데이터에 적용됩니다. 이러한 기술은 기능화 유형으로서 다양한 규모에서의 기능에 민감한 특정 알고리즘을 지원합니다. AutoML의 기능화에서 기본 기능화 단계에 대해 자세히 알아봅니다.
그러나 다음 단계는 forecasting 작업 유형에 대해서만 수행됩니다.
시계열 샘플 빈도(예: 매시간, 매일, 매주)를 검색하고 없는 시간 요소의 새 레코드를 만들어 계열이 연속되도록 합니다.
누락된 값을 대상(전방 채우기를 통해) 및 기능 열(중앙값 열 값 사용)에 귀속
시계열 식별자를 기반으로 기능을 만들어 여러 계열에서 고정 효과를 사용할 수 있도록 설정
계절적 패턴을 학습하는 데 도움이 되는 시간 기반 기능 만들기
범주 변수를 숫자 수량으로 인코딩
시계열 데이터에서 생성된 가능한 엔지니어링된 기능의 전체 목록을 보려면 TimeIndexFeaturizer 클래스를 참조하세요.
참고 자동화된 Machine Learning 기능화 단계(기능 정규화, 누락된 데이터 처리, 텍스트를 숫자로 변환 등)는 기본 모델의 일부가 됩니다. 예측에 모델을 사용하는 경우 학습 중에 적용되는 동일한 기능화 단계가 입력 데이터에 자동으로 적용됩니다.
기능화 사용자 지정
또한 ML 모델을 학습시키는 데 사용되는 데이터와 기능이 관련 있는 예측 결과를 내도록 기능화 설정을 사용자 지정하는 옵션도 있습니다.
forecasting 작업에 대해 지원되는 사용자 지정은 다음과 같습니다.
사용자 지정 정의 열 용도 업데이트 지정된 열에 대해 자동 감지된 기능 유형을 재정의합니다. 변환기 매개 변수 업데이트 지정된 변환기의 매개 변수를 업데이트합니다. 현재 Imputer(fill_value 및 median)를 지원합니다. 삭제 열 기능화에서 삭제할 열을 지정합니다.
SDK를 사용하여 기능화를 사용자 지정하려면 “featurization”: FeaturizationConfig 를 AutoMLConfig 개체에 지정합니다. 사용자 지정 기능화에 대해 자세히 알아봅니다.
참고 열 삭제 기능은 SDK 버전 1.19부터 더 이상 사용되지 않습니다. 자동화된 ML 실험에서 사용하기 전에 데이터 정리의 일부로 데이터 세트에서 열을 삭제합니다.
featurization_config = FeaturizationConfig() # `logQuantity` is a leaky feature, so we remove it. featurization_config.drop_columns = [‘logQuantitity’] # Force the CPWVOL5 feature to be of numeric type. featurization_config.add_column_purpose(‘CPWVOL5’, ‘Numeric’) # Fill missing values in the target column, Quantity, with zeroes. featurization_config.add_transformer_params(‘Imputer’, [‘Quantity’], {“strategy”: “constant”, “fill_value”: 0}) # Fill mising values in the `INCOME` column with median value. featurization_config.add_transformer_params(‘Imputer’, [‘INCOME’], {“strategy”: “median”})
실험에 Azure Machine Learning 스튜디오를 사용하는 경우 스튜디오에서 기능화를 사용자 지정하는 방법을 참조하세요.
선택적 구성
딥 러닝을 사용하도록 설정하고 대상 이동 기간 집계를 지정하는 등의 예측 작업에 대한 추가적인 옵션 구성을 사용할 수 있습니다. 추가 매개 변수의 전체 목록은 ForecastingParameters SDK 참조 설명서에서 확인할 수 있습니다.
빈도 및 대상 데이터 집계
빈도를 나타내는 freq 매개 변수를 활용하여 불규칙한 데이터, 즉 시간별 또는 일별 데이터와 같이 정해진 주기를 따르지 않는 데이터로 인한 오류를 방지할 수 있습니다.
매우 불규칙한 데이터 또는 변화하는 비즈니스 요구에 대해 사용자는 원하는 예측 빈도인 freq 를 선택적으로 설정하고 target_aggregation_function 을 지정하여 시계열의 대상 열을 집계할 수 있습니다. AutoMLConfig 개체에서 이 두 가지 설정을 활용하면 데이터 준비 시간을 절약할 수 있습니다.
대상 열 값에 대해 지원되는 집계 작업은 다음과 같습니다.
함수 Description sum 대상 값의 합계 mean 대상 값의 평균 또는 산술평균 min 대상의 최솟값 max 대상의 최댓값
딥 러닝 사용
참고 자동화된 Machine Learning의 예측에 대한 DNN 지원은 미리 보기로 제공되며, 로컬 실행 또는 Databricks에서 시작된 실행에는 지원되지 않습니다.
심층 신경망, 즉 DNN을 사용한 딥 러닝을 적용하여 모델의 점수를 개선할 수도 있습니다. 자동화된 ML의 딥 러닝을 사용하여 단변량 및 다변량 시계열 데이터를 예측할 수 있습니다.
딥 러닝 모델에는 다음과 같은 세 가지 기능이 내장되어 있습니다.
입력에서 출력으로의 임의 매핑에서 학습할 수 있습니다. 여러 입력 및 출력을 지원합니다. 긴 시퀀스에 걸쳐 있는 입력 데이터의 패턴을 자동으로 추출할 수 있습니다.
딥 러닝을 사용하도록 설정하려면 AutoMLConfig 개체에서 enable_dnn=True 를 설정합니다.
automl_config = AutoMLConfig(task=’forecasting’, enable_dnn=True, … **forecasting_parameters)
경고 SDK로 만든 실험에 DNN을 사용하도록 설정하면 최상의 모델 설명이 사용하지 않도록 설정됩니다.
Azure Machine Learning 스튜디오에서 만든 AutoML 실험에 DNN을 사용하도록 설정하려면 스튜디오 UI에서 작업 유형 설정 방법을 참조하세요.
대상 이동 기간 집계
종종 예측자가 보유할 수 있는 최상의 정보는 대상의 최신 값입니다. 대상 이동 기간 집계를 사용하면 데이터 값의 이동 집계를 기능으로 추가할 수 있습니다. 이러한 기능을 추가적인 상황별 데이터로 생성하여 사용하면 학습 모델의 정확도에 도움이 됩니다.
예를 들어 에너지 수요를 예측하고자 한다고 가정해 봅니다. 가열된 공간의 열 변화를 설명하기 위해 이동 기간 기능에 3일을 추가하고자 할 수 있습니다. 이 예에서는 AutoMLConfig 생성자에서 target_rolling_window_size= 3 을 설정하여 이 기간을 만듭니다.
이 표는 기간 집계가 적용될 때 발생하는 기능 엔지니어링 결과를 보여 줍니다. 최소, 최대 및 합계 열은 정의된 설정을 기반으로 3개의 슬라이딩 윈도우에서 생성됩니다. 각 행에는 새로 계산된 기능이 있는데 2017년 9월 8일 오전 4시 타임스탬프의 경우 최대, 최소 및 합계 값은 2017년 9월 8일 오전 1시 – 오전 3시의 수요 값을 사용하여 계산됩니다. 이 3개의 기간은 함께 이동하면서 나머지 행의 데이터를 채웁니다.
대상 이동 기간 집계 기능을 적용하는 Python 코드 예제를 확인합니다.
짧은 계열 처리
자동화된 ML은 모델 개발의 학습 및 유효성 검사 단계를 수행하기에 충분한 데이터 요소가 없으면 시계열을 짧은 계열로 간주합니다. 데이터 포인트의 수는 각 실험마다 다르며, max_horizon, 교차 유효성 검사 분할 수, 시계열 기능을 생성하는 데 필요한 기록의 최댓값인 모델 Lookback의 길이에 따라 달라집니다.
자동화된 ML은 short_series_handling_configuration 매개 변수를 사용하여 ForecastingParameters 개체에서 기본적으로 짧은 계열 처리를 제공합니다.
짧은 계열 처리를 사용하도록 설정하려면 freq 매개 변수도 정의해야 합니다. 시간별 빈도를 정의하려면 freq=’H’ 를 설정합니다. pandas 시계열 페이지 DataOffset 개체 섹션을 방문하여 빈도 문자열 옵션을 봅니다. short_series_handling_configuration = ‘auto’ 인 기본 동작을 변경하려면 short_series_handling_configuration 매개 변수를 ForecastingParameter 개체에서 업데이트합니다.
from azureml.automl.core.forecasting_parameters import ForecastingParameters forecast_parameters = ForecastingParameters(time_column_name=’day_datetime’, forecast_horizon=50, short_series_handling_configuration=’auto’, freq = ‘H’, target_lags=’auto’)
다음 표에는 short_series_handling_config 에 사용할 수 있는 설정이 요약되어 있습니다.
설정 Description auto 다음은 짧은 계열 처리의 기본 동작입니다. 모든 계열이 짧은 경우 데이터를 패딩합니다.
모든 계열이 짧은 것은 아닌 경우 짧은 계열을 삭제합니다. pad short_series_handling_config = pad 인 경우 자동화된 ML은 찾아낸 각 짧은 계열에 임의 값을 추가합니다. 다음 목록에는 열 유형과 채워지는 항목이 나와 있습니다. NaN으로 채워지는 개체 열 0으로 채워지는 숫자 열 False로 채워지는 부울/논리 열 대상 열은 평균이 0이고 표준 편차가 1인 임의 값으로 채워집니다. drop short_series_handling_config = drop 인 경우 자동화된 ML이 짧은 계열을 삭제하여 학습 또는 예측에 사용되지 않습니다. 이러한 계열에 대한 예측은 NaN을 반환합니다. None 채워지거나 삭제된 계열이 없음
경고 채우기는 모델 결과의 정확도에 영향을 줄 수 있는데 이는 이전 학습을 오류 없이 가져오려고 인공 데이터를 도입하고 있기 때문입니다.
많은 계열이 짧은 경우 설명 가능성 결과에 어느 정도 영향이 있을 수 있습니다.
실험 실행
AutoMLConfig 개체가 준비되면 실험을 제출할 수 있습니다. 모델이 완료된 후 최상의 실행 반복을 검색합니다.
ws = Workspace.from_config() experiment = Experiment(ws, “Tutorial-automl-forecasting”) local_run = experiment.submit(automl_config, show_output=True) best_run, fitted_model = local_run.get_output()
최적 모델로 예측
최상의 모델 반복을 사용하여 모델 학습에 사용되지 않은 데이터의 값을 예측합니다.
forecast_quantiles() 함수는 일반적으로 분류 및 회귀 작업에 사용되는 predict() 메서드와 달리 예측이 시작되어야 하는 시기를 지정할 수 있습니다. 기본적으로 forecast_quantiles() 메서드는 요소 예측 또는 평균/중앙값 예측을 생성하며, 이 예측에서는 시간이 지나며 불확실성이 점차 감소하는 현상(Cone of Uncertainty)이 나타나지 않습니다. 학습 데이터 Notebook에서 벗어나는 예측에 대해 자세히 알아보세요.
다음 예제에서는 먼저 y_pred 의 모든 값을 NaN 으로 바꿉니다. 이 경우에는 예측 원점이 학습 데이터의 끝에 오게 됩니다. 그러나 y_pred 의 두 번째 절반을 NaN 으로 바꾸면 이 함수는 처음 절반의 숫자 값을 수정하지 않은 상태로 유지하지만 두 번째 절반의 NaN 값을 예측합니다. 이 함수는 예측된 값과 정렬된 기능을 모두 반환합니다.
forecast_quantiles() 함수에서 forecast_destination 매개 변수를 사용하여 지정된 날짜까지의 값을 예측할 수도 있습니다.
label_query = test_labels.copy().astype(np.float) label_query.fill(np.nan) label_fcst, data_trans = fitted_model.forecast_quantiles( test_dataset, label_query, forecast_destination=pd.Timestamp(2019, 1, 8))
종종 고객은 분포의 특정 분위수에서 예측을 이해하려고 합니다. 예를 들어 식료품 품목 또는 클라우드 서비스용 가상 머신과 같은 인벤토리를 제어하는 데 예측을 사용하는 경우가 있습니다. 이 경우 제어점은 일반적으로 “품목이 재고가 있고 99%가 소진되지 않기를 원합니다”와 같은 것입니다. 다음은 50번째 백분위수 또는 95번째 백분위수와 같이 예측을 위해 보고 싶은 분위수를 지정하는 방법을 보여 줍니다. 앞서 언급한 코드 예제와 같이 분위수를 지정하지 않으면 50번째 백분위수 예측만 생성됩니다.
# specify which quantiles you would like fitted_model.quantiles = [0.05,0.5, 0.9] fitted_model.forecast_quantiles( test_dataset, label_query, forecast_destination=pd.Timestamp(2019, 1, 8))
모델 성능을 예측하는 데 도움이 되는 RMSE(제곱 평균 오차) 또는 MAPE(절대 평균 백분율 오차)와 같은 모델 메트릭을 계산할 수 있습니다. 예제는 자전거 공유 수요 Notebook의 평가 섹션을 참조하세요.
전체적인 모델 정확도를 확인한 후에 가장 현실적인 다음 단계는 모델을 사용하여 알 수 없는 미래 가치를 예측하는 것입니다.
테스트 세트 test_dataset 와 형식은 같지만 날짜/시간이 미래인 데이터 세트를 제공하면 결과 예측 세트는 각 시계열 단계에 대해 예측된 값입니다. 데이터 세트의 마지막 시계열 레코드가 2018년 12월 31일에 대한 것이라고 가정합니다. 다음 날(또는 <= forecast_horizon 을 예측해야 하는 기간)의 수요를 예측하려면 2019년 1월 1일의 각 매장에 대한 단일 시계열 레코드를 만듭니다. day_datetime,store,week_of_year 01/01/2019,A,1 01/01/2019,A,1 필요한 단계를 반복하여 이 미래 데이터를 데이터 프레임에 로드하고 best_run.forecast_quantiles(test_dataset) 를 실행하여 미래 가치를 예측합니다. 참고 target_lags 및/또는 target_rolling_window_size 를 사용하도록 설정한 경우 자동화된 ML을 사용한 예측에서 샘플 내 예측은 지원되지 않습니다. 대규모 예측 단일 기계 학습 모델로는 충분하지 않아 여러 기계 학습 모델이 필요한 시나리오가 있습니다. 예를 들어 특정 브랜드의 각 개별 매장에서 판매를 예측하거나 개별 사용자에 맞게 경험을 조정하는 것입니다. 각 인스턴스에 대한 모델을 빌드하면 많은 기계 학습 문제에서 결과가 향상될 수 있습니다. 그룹화는 그룹별로 개별 모델을 학습하기 위해 결합할 수 있는 시계열 예측의 한 개념입니다. 이 방법은 그룹에 다른 엔터티의 기록 또는 추세를 활용할 수 있는 스무딩, 채우기 또는 엔터티가 필요한 시간 계열이 있는 경우에 특히 유용할 수 있습니다. 많은 모델 및 계층적 시계열 예측은 이러한 대규모 예측 시나리오에 대한 자동화된 기계 학습을 통해 구동되는 솔루션입니다. 많은 모델 자동화된 기계 학습이 포함된 Azure Machine Learning 많은 모델 솔루션을 통해 사용자는 수백만 개의 모델을 병렬로 학습하고 관리할 수 있습니다. 많은 모델 솔루션 가속기는 Azure Machine Learning 파이프라인을 활용하여 모델을 학습합니다. 특히 파이프라인 개체 및 ParalleRunStep이 사용되며 ParallelRunConfig를 통해 설정된 특정 구성 매개 변수가 필요합니다. 다음 다이어그램에서는 많은 모델 솔루션의 워크플로를 보여줍니다. 다음 코드에서는 사용자가 많은 모델 실행을 설정하는 데 필요한 주요 매개 변수를 보여줍니다. 많은 모델 예측 예제는 많은 모델 - 자동화된 ML Notebook을 참조하세요. from azureml.train.automl.runtime._many_models.many_models_parameters import ManyModelsTrainParameters partition_column_names = ['Store', 'Brand'] automl_settings = {"task" : 'forecasting', "primary_metric" : 'normalized_root_mean_squared_error', "iteration_timeout_minutes" : 10, #This needs to be changed based on the dataset. Explore how long training is taking before setting this value "iterations" : 15, "experiment_timeout_hours" : 1, "label_column_name" : 'Quantity', "n_cross_validations" : 3, "time_column_name": 'WeekStarting', "max_horizon" : 6, "track_child_runs": False, "pipeline_fetch_max_batch_size": 15,} mm_paramters = ManyModelsTrainParameters(automl_settings=automl_settings, partition_column_names=partition_column_names) 계층적 시계열 예측 대부분의 애플리케이션에서 고객은 서로 다른 지리적 위치에서 제품 판매를 예측하는지 또는 회사의 여러 조직에 대한 예상 인력 수요를 이해하는지 여부와 같이 비즈니스의 매크로 및 마이크로 수준에서 예측을 이해해야 합니다. 계층 데이터에서 지능적으로 예측하도록 기계 학습 모델을 학습시키는 기능은 필수적입니다. 계층적 시계열은 각 고유 계열이 지리 또는 제품 유형과 같은 차원 기반 계층 구조로 정렬되는 구조입니다. 다음 예제에서는 계층 구조를 형성하는 고유한 특성이 있는 데이터를 보여줍니다. 여기서 계층 구조는 헤드폰 또는 태블릿과 같은 제품 유형, 제품 유형을 액세서리 및 디바이스로 구분하는 제품 범주, 제품이 판매되는 지역으로 정의됩니다. 이를 추가로 시각화하기 위해 계층의 리프 수준에는 특성 값이 고유하게 조합된 모든 시계열이 포함됩니다. 계층 구조의 각 상위 수준은 시계열을 정의하기 위해 더 작은 차원 하나를 고려하고 하위 수준의 각 자식 노드 집합을 부모 노드로 집계합니다. 계층적 시계열 솔루션은 다대다 모델 솔루션을 기반으로 하며 비슷한 구성 설정을 공유합니다. 다음 코드에서는 계층적 시계열 예측 실행을 설정하기 위한 주요 매개 변수를 보여줍니다. 엔드투엔드 예제는 계층적 시계열 - 자동화된 ML Notebook을 참조하세요. from azureml.train.automl.runtime._hts.hts_parameters import HTSTrainParameters model_explainability = True engineered_explanations = False # Define your hierarchy. Adjust the settings below based on your dataset. hierarchy = ["state", "store_id", "product_category", "SKU"] training_level = "SKU"# Set your forecast parameters. Adjust the settings below based on your dataset. time_column_name = "date" label_column_name = "quantity" forecast_horizon = 7 automl_settings = {"task" : "forecasting", "primary_metric" : "normalized_root_mean_squared_error", "label_column_name": label_column_name, "time_column_name": time_column_name, "forecast_horizon": forecast_horizon, "hierarchy_column_names": hierarchy, "hierarchy_training_level": training_level, "track_child_runs": False, "pipeline_fetch_max_batch_size": 15, "model_explainability": model_explainability,# The following settings are specific to this sample and should be adjusted according to your own needs. "iteration_timeout_minutes" : 10, "iterations" : 10, "n_cross_validations": 2} hts_parameters = HTSTrainParameters( automl_settings=automl_settings, hierarchy_column_names=hierarchy, training_level=training_level, enable_engineered_explanations=engineered_explanations ) 노트북 예제 다음을 포함하는 고급 예측 구성의 자세한 코드 예제는 예측 샘플 Notebook을 참조하세요. 다음 단계
시계열 예측: LSTM 모델로 주가 예측하기 – 인사이트캠퍼스
* 이 글은 towardsdatascience에 작성된 Serafeim Loukas의 글을 번역하였습니다.
해당 포스팅에서는 LSTM 예측 모델을 사용하여 주가를 예측하는 방법을 제시한다.
1. 도입
1.1. 시계열 & 예측모델
전통적으로 대부분의 머신러닝(ML) 모델은 일부 관찰(샘플/예제)을 입력 피쳐로 사용하지만 데이터에 시간 차원은 없다.
시계열 예측 모형은 이전에 관측된 값을 기반으로 미래의 값을 예측할 수 있는 모형이다.
시계열 예측은 비정형 데이터에서 널리 사용된다. 평균 및 표준 편차와 같은 통계적 특성이 시간이 지남에 따라 일정하지 않은 데이터를 비정형 데이터라고 한다.
이러한 비정형 입력 데이터(해당 모델에 대한 입력으로 사용)를 일반적으로 시계열이라고 한다. 시계열의 예로는 시간 경과에 따른 온도, 주가, 주택 가격 등이 있다. 따라서 입력은 시간에 따라 연속적으로 나타나는 신호(시계열)이다.
시계열은 시간에 따라 순차적으로 취하는 일련의 관측치이다.
관측: 시계열 데이터는 개별 시간 척도로 기록된다.
주의: 시계열 분석 알고리즘을 사용하여 주가를 예측하려는 시도가 있었지만, 실제 시장에서 베팅을 하기는 힘들다. 이 포스팅은 단지 사람들에게 주식을 사도록 “지시”하려는 의도가 전혀 없는 튜토리얼일 뿐이다.
2. LSTM 모델
LSTM은 딥러닝 분야에 사용되는 순환신경망(RNN) 아키텍처이다. 표준 피드포워드 신경망과 달리 LSTM은 피드백 연결이 있다. 단일 데이터 포인트(예: 이미지)뿐만 아니라 전체 데이터 시퀀스(예: 음성 또는 비디오 입력)도 처리할 수 있다.
LSTM 모델은 일정 기간 동안 정보를 저장할 수 있다.
한마디로 기억력을 가지고 있다는 것이다. LSTM은 장기 메모리 모델을 의미한다.
이 특성은 시계열 또는 시퀀스 데이터를 처리할 때 매우 유용하다. LSTM 모델을 사용할 때 우리는 어떤 정보를 저장하고 어떤 정보를 버릴지 결정할 수 있다. 우리는 “게이트”를 사용한다. LSTM에 대한 깊은 이해는 이 포스팅의 범위 밖이지만, 더 많은 것을 알고 싶다면 이 게시물 끝에 있는 참고 자료를 살펴보자.
3. 주가 기록 데이터 가져오기
야후 파이낸스 덕분에 우리는 무료로 데이터를 얻을 수 있다. 다음 링크를 사용하여 테슬라의 주가 기록을 확인해보자.
https://finance.yahoo.com/quote/TSLA/history?period1=1436486400&period2=1594339200&interval=1d&filter=history&frequency=1d
다음 사항을 확인해야 한다:
다운로드를 클릭하고 .csv 파일을 컴퓨터에 로컬로 저장한다.
데이터는 2015년부터 현재까지(2020년)이다!
4. 파이썬 작업 예제
필요한 모듈: Keras, Tensorflow, Pandas, Scikit-Learn & Numpy
우리는 이 예에서 테슬라 주가를 예측하기 위해 다층 LSTM 순환 신경망을 구축할 것이다.
데이터를 로드하고 검사해 보자.
import math
import matplotlib.pyplot as plt
import keras
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from keras.layers import *
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from keras.callbacks import EarlyStopping
df=pd.read_csv(“TSLA.csv”)
print(‘Number of rows and columns:’, df.shape)
df.head(5)
Output of the above code
다음 단계는 데이터를 훈련 세트와 테스트 세트로 분할하여 과적합을 피하고 모델의 일반화 능력을 조사할 수 있도록 하는 것이다. 과적합에 대해 자세히 알아보려면 이 포스팅을 참고하자.
https://towardsdatascience.com/is-your-model-overfitting-or-maybe-underfitting-an-example-using-a-neural-network-in-python-4faf155398d2
예측될 목표값은 주가에 ‘가까운’ 값이 될 것이다.
training_set = df.iloc[:800, 1:2].values
test_set = df.iloc[800:, 1:2].values
모델 적합 전에 데이터를 정규화하는 것이 좋다. 이렇게 하면 성능이 향상된다. Min-Max Scaler에 대한 자세한 내용은 여기에서 확인할 수 있다.
https://towardsdatascience.com/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79
시차가 1일(lag 1)인 입력 피쳐를 구축해 보자.
# Feature Scaling
sc = MinMaxScaler(feature_range = (0, 1))
training_set_scaled = sc.fit_transform(training_set)
# Creating a data structure with 60 time-steps and 1 output
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-60:i, 0])
y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
#(740, 60, 1)
다음, 데이터를 다음과 같은 형식(#값, #타임스텝, #1차원 출력)으로 재배열한다.
자, 이제 모델을 만들 시간이다. 우리는 50개의 뉴런과 4개의 숨겨진 층으로 LSTM을 만들 것이다. 마지막으로, 우리는 정규화된 주가를 예측하기 위해 출력층에 1개의 뉴런을 할당할 것이다. MSE 손실 함수와 Adam stochastic gradient decent optimizer를 사용할 것이다.
참고: 다음은 어느정도 시간이 소요된다(~5분).
model = Sequential()
#Adding the first LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))
model.add(Dropout(0.2))
# Adding a second LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))
# Adding a third LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))
# Adding a fourth LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50))
model.add(Dropout(0.2))
# Adding the output layer
model.add(Dense(units = 1))
# Compiling the RNN
model.compile(optimizer = ‘adam’, loss = ‘mean_squared_error’)
# Fitting the RNN to the Training set
model.fit(X_train, y_train, epochs = 100, batch_size = 32)
피팅이 완료되면 다음과 같은 내용을 볼 수 있다.
테스트 데이터 준비(재배열):
# Getting the predicted stock price of 2017
dataset_train = df.iloc[:800, 1:2]
dataset_test = df.iloc[800:, 1:2]
dataset_total = pd.concat((dataset_train, dataset_test), axis = 0)
inputs = dataset_total[len(dataset_total) – len(dataset_test) – 60:].values
inputs = inputs.reshape(-1,1)
inputs = sc.transform(inputs)
X_test = []
for i in range(60, 519):
X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
print(X_test.shape)
# (459, 60, 1)
테스트 세트를 사용하여 예측하기
predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
이제 결과를 시각화해 보자:
# Visualising the results
plt.plot(df.loc[800:, ‘Date’],dataset_test.values, color = ‘red’, label = ‘Real TESLA Stock Price’)
plt.plot(df.loc[800:, ‘Date’],predicted_stock_price, color = ‘blue’, label = ‘Predicted TESLA Stock Price’)
plt.xticks(np.arange(0,459,50))
plt.title(‘TESLA Stock Price Prediction’)
plt.xlabel(‘Time’)
plt.ylabel(‘TESLA Stock Price’)
plt.legend()
plt.show()
5. 결과
1의 시차 (하루):
관측: COVID-19 봉쇄로 인한 2020년 3월 큰 하락!
우리는 우리의 모델이 매우 잘 수행되었다는 것을 분명히 알 수 있다.그러나 가장 최근의 날짜 스탬프에 대해서는 모델이 주가의 실제 가치에 비해 낮은 값을 예상(예측)했음을 알 수 있다.
lag에 대한 참고 사항
이 포스팅에서 처음 선택한 lag는 1일, 즉 1일의 단계를 사용한 것이다. 이는 3D 입력을 작성하는 코드를 변경하여 쉽게 변경할 수 있다.
예: One can change the following 2 blocks of code:
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-60:i, 0])
y_train.append(training_set_scaled[i, 0])
그리고
X_test = []
y_test = []
for i in range(60, 519):
X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
다음과 같은 새 코드를 사용한다.
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-50:i, 0])
y_train.append(training_set_scaled[i, 0])
그리고
X_test = []
y_test = []
for i in range(60, 519):
X_test.append(inputs[i-50:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
이 경우 결과는 다음과 같다.
이상이다! 이번 포스팅이 마음에 들었길 바라!
아래는 구글 주가를 예측하기 위해 사용했던 페이스북 Prophet 모델을 다룬 포스팅이다.
https://towardsdatascience.com/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5
ARIMA 모델을 사용하여 최근에 작성한 포스팅도 확인해보자.
https://towardsdatascience.com/time-series-forecasting-predicting-stock-prices-using-an-arima-model-2e3b3080bd70
레퍼런스
[1] https://colah.github.io/posts/2015-08-Understanding-LSTMs/ [2] https://en.wikipedia.org/wiki/Long_short-term_memory번역 – 핀인사이트 인턴연구원 강지윤([email protected])
원문 보러가기>
https://towardsdatascience.com/lstm-time-series-forecasting-predicting-stock-prices-using-an-lstm-model-6223e9644a2f
[ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!
반응형
사는 데 더 나은 방법을 찾아라
– 엘빈 토플러 –
코로나로 인해 가장 크게 떠오른 분야가 무엇이냐고 한다면, 저는 주식만한게 없다고 생각합니다. 우린 결국 돈을 벌고 싶고, 미래를 예측하여 주식 가격을 예측할 수 있다면 더할 나위가 없겠죠^^
이미 월가를 비롯해 주식시장의 최전방에 위치해있는 기업들은 실제로 다양한 기술을 이용하여 주식 가격의 미래를 예측하여 이를 실제로 수익과 연결시킵니다. 이번 포스팅에서는 순환 신경망 RNN(Recurrent Neural Network)에 대해 알아보겠습니다.
이 RNN은 우리가 그동안 봐왔던 대부분의 네트워크처럼 고정된 길이의 Input이 아닌 임의의 길이를 가진 시퀀스를 다룰 수 있습니다. 시퀀스의 예로는 문장, 문서, 오디오 샘플 등 가변적인 길이가 가진 것들을 예시로 들 수 있고, 이것은 자동 번역, Speech to Text 같은 자연어 처리(NLP)에 매우 유용합니다.
Recurrent Neuron and Recureent Layer
지금까지 우리가 봐온 네트워크들에서 Input이라 하면, 출력층을 향해서 한 방향으로만 흘러가는 Feed-Forward Network였습니다. 그러나 지금부터 우리가 볼 RNN은 출력으로 나온 Output이 다시 입력으로 순환하여 들어가는 연결이 있다는 점에서 기존과 차이점을 보입니다.
위 그림의 가장 왼쪽에 있는 것은 입력 $x$를 받아서 출력 $y$를 내보내고 이것을 다시 자기 자신에게 입력으로 보내는 가장 간단한 RNN입니다. 이것은 각 타임 스텝 $t$(하나의 단위 데이터가 들어올 때마다)마다 $x_{(t)}$와 이전 타임 스텝의 출력인 $y_{(t-1)}$을 입력으로 받습니다. 이때 가장 첫번째 타임 스텝에서는 이전 출력이 없기 때문에 $y_{(t-1)}$를 0으로 잡습니다.
왼쪽의 가장 간단한 RNN이 매 타임스텝마다 $x$와 $y_{(t-1)}$를 받아 $y_{(t)}$를 내보내는 과정을 시간을 축으로 하여 위 그림의 오른쪽처럼 표현할 수 있습니다. 이를 시간에 따라 네트워크를 펼쳤다라고 말합니다.(즉 동일 뉴런을 타임 스텝마다 하나로 표현한 것입니다.)
이러한 하나의 순환 뉴런 여러개가 모여 구성된 층(Layer)는 쉽게 만들 수 있습니다.
뉴런이 여러개라는 건 입력이 여러 개라는 것이기 때문에 이제 입력은 스칼라가 아닌 벡터 $x_(t)$가 되고, 이전 타임 스텝의 출력 $y_{(t)}$ 또한 벡터가 됩니다. (하나의 뉴런의 출력은 스칼라입니다)
각 순환 뉴런은 두 개의 가중치 벡터를 가집니다. 하나는 입력 벡터 $x_(t)$, 다른 하나는 이전 타임 스텝의 출력 $y_{(t)}$을 위한 것입니다. 이것들을 각각 $W_x$, $W_y$라고 하겠습니다. 그렇다면 순환 뉴런의 출력 $y_{(t)}$는 다음 식으로 계산될 수 있습니다.
$∅$는 Relu와 같은 활성화 함수입니다. 보통 RNN에서는 Relu보단 tanh 함수를 선호합니다.
여기에 더 나아가서 이번엔 입력이 벡터 단위가 아니라, 미니 배치로써 여러 벡터가 들어온다고 하면 이를 행렬 $X_{(t)}$로 만들어 출력을 한번에 계산할 수 있습니다.
$Y_{(t)}$는 $X_{(t)}$와 $Y_{(t-1)}$을 입력으로 받는 함수이고, $Y_{(t-1)}$는 $X_{(t-1)}$와 $Y_{(t-2)}$을 입력으로 받고, 다시 $Y_{(t-2)}$는 $X_{(t-2)}$와 $Y_{(t-3)}$을 입력으로 받게됩니다. 여기서 알 수 있는 점은 $Y_{(t)}$는 맨 처음 $t=0$에서부터 모든 입력을 받은 뉴런의 출력값이라는 점입니다.
Memory Cell
타임 스텝 $t$에서 뉴런의 출력은 이전 타임 스텝의 모든 입력에 대한 함수이므로 이를 일종의 메모리 형태라고 할 수 있습니다. 그래서 타임 스텝에 걸쳐 형성된 어떤 상태를 보존하는 RNN의 구성 요소를 메모리 셀 간단하게 셀이라고 부릅니다. –
하나의 순환 뉴런 Layer는 일반적으로 10 타임 스텝 내외를 학습할 수 있는 기본적인 셀이지만, 뒤에서 더욱 긴 패턴을 학습할 수 있는 강력한 셀에 대해 공부하게 됩니다.
일반적으로 타임 스텝 $t$에서의 셀의 상태 $h_{(t)}$는 $t$에서의 Input과 이전 타임 스텝의 셀 $h_{(t-1)}$에 대한 함수입니다. 타임 스텝 $t$에서의 출력 $y_{(t)}$도 이전 $h$와 현재 Input에 대한 함수이므로, 기본적인 셀의 경우 출력 $y_{(t)}$와 $h_{(t)}$는 같다고 할 수 있습니다. 하지만 모든 종류의 셀에서 그런 것은 아닙니다.
Input Sequence and Output Sequence
RNN에는 다양한 네트워크 구조가 있습니다. 크게 <(입력)-투-(출력) 네트워크>에서 입출력의 형태가 시퀀스냐, 벡터냐에 따라 구조의 이름이 결정됩니다. 시퀀스와 벡터를 나누는 기준은 간단합니다. 벡터가 여러개가 들어가거나 여러개가 나가면 시퀀스, 하나의 벡터만 들어가거나 나오면 벡터입니다.
– 시퀀스-투-시퀀스 네트워크(좌측 상단) ex) 주식가격 같은 시계열 데이터를 예측하는데 유용합니다. 최근 $0~N$ 일치의 주식 가격을 주입하면 네트워크는 하루 앞선 가격 즉 $1~N+1$일치 주식 가격을 출력해야 합니다.
– 시퀀스-투-벡터 네트워크(우측 상단) : 마지막 출력($Y_{(3)}$)을 제외한 나머지 출력을 모두 무시하는 네트워크 입니다. ex) 한 문장의 영화 리뷰가 있다고 할때, 문장을 구성하는 단어를 하나의 입력 벡터라고 생각할 수 있습니다. 이때 이 리뷰의 평점을 계산한다 할때, 각 단어(입력 벡터)가 들어갈 때마다 평점이 계산되어 나오는 것이 아니라, 모든 단어(시퀀스)가 들어간 후에 최종적인 한번의 평점(벡터)이 출력되는 것입니다.
– 벡터-투-시퀀스 네트워크 ex) 하나의 이미지(입력 벡터)를 넣어주면 이미지에 대한 설명문(문장은 단어로 구성된 시퀀스이다)으로 출력할 수 있습니다.
– (우측 하단) : 마지막은 인코더라 부르는 시퀀스-투-벡터 네트워크 뒤에 디코더라 부르는 벡터-투-시퀀스 네트워크를 연결한 구조입니다. ex) 한국말을 영어로 번역하는데 사용될 수 있습니다. 즉 한국어 문장으 주입하면 인코더는 이를 하나의 벡터 표현으로 변환하고 디코더가 이 벡터를 영어 문장으로 디코딩합니다.
이러한 인코더-디코더 모델은 시퀀스-투-시퀀스 RNN을 사용하여 한 단어씩 번역하는 것보다 훨씬 더 잘 작동합니다. 왜냐하면 RNN의 경우엔 문장의 마지막 단어가 번역의 첫번째 단어에 영향을 줄 수 있기 때문입니다. 따라서 하나의 단어가 들어올때 마다 번역해서 단어를 뽑아내는 것(RNN의 방식)이 아닌 전체 문장이 주입될 때까지 기다렸다 번역해야 더 좋은 성능을 낼 수 있습니다.(인코더-디코더 모델)
RNN 훈련하기
RNN 훈련 방식으로 타임 스텝으로 네트워크를 펼치고, 보통의 역전파(Back Propagation)을 사용하는 것인데 이를 BPTT(Backpropagation through time)이라고 합니다. 본격적으로 훈련 방식을 차례대로 살펴보겠습니다.
위 그림을 살펴보면서 이해해보겠습니다. 우선 회색 점선 화살표 방향으로 네트워크를 통과하면서 비용 함수 $C(Y_{(0)}, Y_{(1)} … Y_{(T)})$(T는 최대 타임 스텝)을 사용하여 출력 시퀀스를 평가됩니다. 이때 비용 함수는 Y_{(0)}, Y_{(1)}과 같은 일부 출력을 무시할 수 있습니다.
그 다음 비용함수의 Gradient는 짙은 회색선의 방향으로 전파되면서 모델 파라미터는 업데이트 됩니다. 이때 Gradient는 마지막 출력 $Y_{(4)}$에만 전달되어 노란색 박스 간의 수평방향으로 전달되는 것이 아니라, 비용 함수에 사용된 Y_{(2)}, Y_{(3)}, Y_{(4)}에 모두 각각 전달됩니다. 또한 각 타임 스텝마다 같은 매개변수 $W$와 $b$가 사용되기 때문에 역전파가 진행되면 모든 타임 스텝에 걸쳐 합산될 것입니다.
Time-Series Forecasting
어떤 웹사이트에서 1) 시간당 접속 사용자의 수, 2) 도시의 날짜별 온도, 3) 여러 feature를 사용하여 기업의 분기별 재정 안정성 등을 연구한다고 가정해보겠습니다. 이 경우 들어오는 Input Data는 타임 스텝마다 하나 이상의 값을 가지는 시퀀스이며 이를 Time-Series Data라고 부릅니다.
[1) 시간당 접속 사용자의 수, 2) 도시의 날짜별 온도]는 타임 스텝마다 하나의 feature를 가지므로 단변량 시계열 (univariate time series)이고, 3)기업의 분기별 재정 안정성은 회사의 수입, 부채 등의 여러 feature를 이용하므로 다변량 시계열(multiivariate time series)입니다.이런 Time-Series Data를 가지고 할 수 있는 몇가지 Task가 있는데 첫번째가 미래 예측(Forecasting)입니다. 또 하나는 기존 데이터에서 비어 있는 값을 채우는 Imputation입니다.
다음은 앞서 예시로 든 데이터와 별개의 3개의 단변량 시계열입니다. 각 타임 스텝은 50개이며, 목표는 51번째 타임 스텝의 값을 예측 하는 것입니다.
다음 코드에서 간단하게 $sin$ 곡선과 약간의 잡음으로 이뤄진 시계열 데이터를 생성해보겠습니다.
def generate_time_series(batch_size, n_steps): freq1, freq2, offsets1, offsets2 = np.random.rand(4, batch_size, 1) time = np.linspace(0, 1, n_steps) series = 0.5 * np.sin((time – offsets1) * (freq1 * 10 + 10)) # wave 1 series += 0.2 * np.sin((time – offsets2) * (freq2 * 20 + 20)) # + wave 2 series += 0.1 * (np.random.rand(batch_size, n_steps) – 0.5) # + noise return series[…, np.newaxis].astype(np.float32)
이 함수는 n_steps 길이의 시계열을 batch_size만큼 만들어냅니다. 각 시계열의 타임 스텝에는 하나의 값이 존재 즉 단변량이며 [배치 크기, 타임 스텝 수, 1]크기의 넘파이 배열을 반환합니다. 이러한 리턴 타입은 일반적으로 임의 길이의 time-series 데이터를 다룰 때 사용하며, 단변량은 dimensionallity가 1이고, 다변량은 1이상입니다.
이제 이 함수를 사용해 데이터를 train, validation, test set으로 나누겠습니다.
np.random.seed(42) n_steps = 50 series = generate_time_series(10000, n_steps + 1) X_train, y_train = series[:7000, :n_steps], series[:7000, -1] X_valid, y_valid = series[7000:9000, :n_steps], series[7000:9000, -1] X_test, y_test = series[9000:, :n_steps], series[9000:, -1]
기준 성능
본격적으로 RNN을 구현하기 전, 우리가 구현할 RNN이 잘 작동하는지 판단하기 위해서는 기준이 되는 무언가가 필요합니다. 가장 간단한건 각 시계열의 마지막 값을 그대로 예측하는 것입니다. 이를 naive forecasting이라고 부르는데 이 성능을 뛰어넘는 것이 매우 어렵스빈다. 이 경우 MSE가 0.020이 나오네요
y_pred = X_valid[:, -1] np.mean(keras.losses.mean_squared_error(y_valid, y_pred)) >> 0.020211367
또 다른 방법은 Fully Connected Network를 사용하는 것입니다. 이 네트워크는 입력마다 1차원 feature 배열을 기대하므로 Flatten Layer를 추가해줘야 합니다.
model = keras.models.Sequential([ keras.layers.Flatten(input_shape=[50, 1]), keras.layers.Dense(1) ]) model.compile(loss=”mse”, optimizer=”adam”) history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid)) model.evaluate(X_valid, y_valid) >>0.004168086685240269
0.004의 MSE의 값을 얻었는데 naive한 forecasting보다 훨씬 낫습니다.
간단한 RNN 구현하기
이제 간단한 RNN을 사용해 방금 구현한 네트워크들을 앞설 수 있는지 확인해보겠습니다.
model = keras.models.Sequential([ keras.layers.SimpleRNN(1, input_shape=[None, 1]) ]) optimizer = keras.optimizers.Adam(lr=0.005) model.compile(loss=”mse”, optimizer=optimizer) history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid))
위 코드가 가장 간단하게 만들 수 있는 RNN으로 하나의 뉴런을 가지는 하나의 layer로 이루어져 있습니다. 코드에서 input_shape에 None이 들어있는 이유는 RNN은 어떤 길이의 타임 스텝도 처리할 수 있기 때문에 길이를 지정해 줄 필요가 없습니다.
기본적으로 SimepleRNN Layers는 tanh를 activation function으로 사용합니다. 작동방식은 앞서 이론에서 살펴보았던 것과 완전히 동일합니다.
model.evaluate(X_valid, y_valid) >> 0.010881561785936356
우리가 구현한 RNN을 통해 얻은 0.014의 MSE는 naive forecasting보단 낫지만, 간단한 FC Layer 기반 선형 모델을 앞지르지 못합니다. 이는 선형 모델에서는 전체 타임스텝이 50개라 했을 때, 50개의 뉴런이 준비되어 각 입력을 받고 하나의 입력마다 하나의 파라미터를 가지고 편향까지 존재합니다. 최종적으로 51개의 파라미터가 있는 셈이죠.
반면 기본 RNN의 순환 뉴런은 Input과 셀 h의 차원마다 하나의 파라미터를 가지고 편향이 있습니다. 그러니 3개의 파라미터가 있는 셈인데, 선형 모델보다 파라미터 갯수가 월등히 적기 때문에 성능도 그만큼 덜 나오는 것입니다.
트렌드와 계절성
가중 이동 평균(weighted moving average)이나 자동 회귀 누적 이동 평균(ARIMA)같이 Time-Series Data를 forecasting하는 방법은 많습니다. 그런데 올바른 forecasting을 위해서 일부는 트렌드(Trend)나 계절성(Seasonality)를 제거해야 합니다. 트렌드라 하면 전체적인 데이터가 상승하거나 내려가거나 하는 추세를 의미합니다. 예를 들어 매달 10% 성장하는 추세의 웹사이트의 접속 사용자 수를 조사한다면, 시계열에서 트렌드를 삭제하고 예측한 후 최종 결과에 다시 이 트렌드를 더해야합니다.
비슷하게 매달 선크림 판매량 예측 시 여름에 특히 더 잘 팔리는 계절성을 관찰할 수 있습니다. 따라서 마찬가지로 최종 예측 후 이러한 계절성을 더해줘야합니다.
하지만 RNN을 사용하면 이런 작업이 필요 없습니다. 그만큼 RNN은 좋은 성능을 내기에 단순합니다. 더 많은 Layer를 추가하면 됩니다!
심층 RNN
RNN은 셀을 여러 층으로 쌓는 것이 일반적입니다. 이렇게 만든 것을 심층 RNN (Deep RNN)이라 부릅니다.
구현은 그저 SimpleRNN을 쌓아주면 됩니다.
model = keras.models.Sequential([ keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]), keras.layers.SimpleRNN(20, return_sequences=True), keras.layers.SimpleRNN(1) ])
이 모델의 MSE는 0.003으로 드디어 선형 모델을 이기게 되었습니다! 그러나 마지막 층을 좀 더 손볼 필요가 있어 보입니다. 단변량 시계열을 예측한다는 건 하나의 유닛이 필요하고 이는 타임 스텝마다 하나의 출력을 만들어야 한다는 뜻입니다. 하나의 유닛을 가진다는 건 h가 스칼라 값이라는 것입니다.
그런데 마지막 Layer의 h는 그리 필요하지 않습니다. 게다가 SimpleRNN Layer는 tanh 함수를 사용하여 forecasting 값이 -1과 1 사이의 범위에 놓입니다. 따라서 보통은 이런 이유로 출력층을 Dense 층으로 바꾸는데, 이를 통해 빠르면서 정확도는 거의 비슷합니다. 다만 이렇게 바꾸려면 두 번째 순환 층에 return_sequences=True를 제거해줘야합니다.
model = keras.models.Sequential([ keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]), keras.layers.SimpleRNN(20), keras.layers.Dense(10) ])
여러 타임 스텝 앞을 예측하기
지금까지는 다음 타임 스텝의 값만 예측했지만, 1스텝 앞이 아니라, 10스텝 앞의 값으로 타깃을 바꾸어 10 스텝 앞을 예측하는 것도 그리 어려운 일이 아닙니다. 하지만 1개의 값이 아니라 한번에 10개를 예측하고 싶다면 어떻게 해야할까요?
첫 번째 방법은 pre-trained model을 사용하여 다음 스텝의 값을 예측한 후 이 값을 다시 입력으로 추가해나가며 10개를 예측하는 것입니다. 코드는 다음과 같습니다.
series = generate_time_series(1, n_steps + 10) X_new, Y_new = series[:, :n_steps], series[:, n_steps:] X = X_new for step_ahead in range(10): y_pred_one = model.predict(X[:, step_ahead:])[:, np.newaxis, :] X = np.concatenate([X, y_pred_one], axis=1) Y_pred = X[:, n_steps:]
당연하지만 다음 스텝에 대한 예측이 훨씬 더 미래의 예측보다 정확합니다. 훨씬 더 미래의 예측은 오차가 누적될 수 있기 때문입니다. 어쨌든 위 방식을 적용하면 약 0.029의 MSE를 얻습니다. 성능은 비슷할지라도 task가 훨씬 어렵기 때문에 단순 비교는 어렵습니다.
두 번째 방법은 RNN을 훈련하여 다음 값 10개를 한번에 예측하는 것입니다. 시퀀스-투-벡터 모델을 사용하지만, 1개가 아닌 값 10개를 출력합니다.
series = generate_time_series(10000, n_steps + 10) X_train, Y_train = series[:7000, :n_steps], series[:7000, -10:, 0] X_valid, Y_valid = series[7000:9000, :n_steps], series[7000:9000, -10:, 0] X_test, Y_test = series[9000:, :n_steps], series[9000:, -10:, 0] model = keras.models.Sequential([ keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]), keras.layers.SimpleRNN(20), keras.layers.Dense(10) ])
이 모델의 다음 10개 스텝에 대한 MSE는 약 0.008로 선형 모델보다 훨씬 좋습니다. 다만 개선할 여지가 있는데, 마지막 타임스텝에서만 10개를 예측하도록 훈련하는게 아니라, 모든 타임 스텝에서 다음 10개를 예측하도록 모델을 훈련할 수 있습니다. 즉 시퀀스-투-벡터에서 시퀀스-투-시퀀스로 바꿀 수 있는 것입니다.(타임 스텝 0에서는 타임 스텝 1~10까지 예측을 담은 벡터를, 타임 스텝 1에서는 2~11까지의 예측을 담는 벡터를 출력합니다.)
이것의 장점은 모든 타임 스텝에서 forecasting을 진행하며 이것들에 대한 출력이 loss에 포함되면서 더 많은 오차 그레디언트가 모델로 흐르게 되고 결과적으로 안정적인 훈련과 함께 훈련 속도를 높이게 됩니다. 다음은 구현 코드입니다.
model = keras.models.Sequential([ keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]), keras.layers.SimpleRNN(20, return_sequences=True), keras.layers.TimeDistributed(keras.layers.Dense(10)) ])
시퀀스-투-시퀀스 모델로 바꾸려면 우선 모든 SimpleRNN 층의 return_sequences=True로 지정합니다. 그 다음 모든 타임 스텝 층에 Dense 층을 적용해야하는데 이를 위해 바로 TimeDistributed Layer를 사용합니다.
TimeDistributed Layer는 각 타임 스텝을 별개의 샘플처럼 다루도록 입력의 크기를 바꿉니다. ([배치 크기, 타임 스텝 수, 입력 차원] -> [배치 크기 x 타임 스텝 수, 입력 차원]) 그 다음 Dense Layer에 적용하고 마지막으로 출력 크기를 시퀀스로 되돌립니다. ([배치 크기 x 타임 스텝 수, 입력 차원] -> [배치 크기, 타임 스텝 수, 입력 차원])
def last_time_step_mse(Y_true, Y_pred): return keras.metrics.mean_squared_error(Y_true[:, -1], Y_pred[:, -1]) model.compile(loss=”mse”, optimizer=keras.optimizers.Adam(lr=0.01), metrics=[last_time_step_mse]) history = model.fit(X_train, Y_train, epochs=20, validation_data=(X_valid, Y_valid))
검증 MSE로 0.006을 얻었는데, 이는 이전 모델보다 25%나 향상된 것입니다.
다음 시간에는 좀 더 긴 시퀀스의 예측 시 사용하는 LSTM과 경량화된 모델인 GRU에 대해 공부해보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 🙂
반응형
키워드에 대한 정보 머신러닝 시계열 예측
다음은 Bing에서 머신러닝 시계열 예측 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.
이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!
사람들이 주제에 대해 자주 검색하는 키워드 [이것이 데이터 분석이다 with 파이썬_11] 시계열 예측 분석
- 데이터 분석
- 데이터 과학
- 데이터
- 데이터과학자
- 데이터분석가
- 파이썬
- python
- datascientist
- datascience
- data
- 데이터분석 배우기
- 데이터분석 책
- 데이터 과학 책
- 데이터 분석 책 추천
- 데이터 분석 기초
- 데이터 분석 강의
- 데이터 분석 강좌
- 데이터 분석 입문
- 데이터 분석 무료 강의
- 윤기태
- ARIMA
YouTube에서 머신러닝 시계열 예측 주제의 다른 동영상 보기
주제에 대한 기사를 시청해 주셔서 감사합니다 [이것이 데이터 분석이다 with 파이썬_11] 시계열 예측 분석 | 머신러닝 시계열 예측, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.