홍동이의 성장일기
[👩💻TIL 22일차 ] 유데미 스타터스 취업 부트캠프 4기 본문
목차
[섹션7] Statsmodels를 이용한 시계열 자료 분석
[섹션6] Pandas를 사용한 시계열
DateTime 인덱스 - Part 1 & 2
➡️ 대부분의 데이터에는 데이터 시간 인덱스가 있을 것이므로, 이러한 종류의 데이터를 다루는 방법을 배워보았다.
- Python Datetime Review
- from datetime import datetime
- 원하는 날짜/시간 개체의 모든 부분을 가져올 수 있다.
- Numpy Datetime 배열
: Numpy는 Python의 datetime 형식보다 날짜를 더 효율적으로 처리한다. Numpy 데이터 유형은 파이썬의 데이터 시간과 구별하기 위해 datetime64라고 부른다.- dtype = datetime64[ ] 원하는 측정값을 넣을 수 있다.
- Numpy 날짜 범위
: np.range(start, stop, step)을 사용하여 균등한 간격의 정수 배열을 생성할 수 있는 것처럼, dtype 인수를 전달하여 날짜 배열을 얻을 수 있다. 중지 날짜는 배타적이다.- np.arange(start, stop, step, dtype = 'datetime64[]')
step값을 생략하면 정밀도에 기초한 모든 값을 얻을 수 있다.
- np.arange(start, stop, step, dtype = 'datetime64[]')
- Pandas Datetime Index
- pd.date_range(date, periods, freq)
- 들어오는 텍스트 변환하기: format = '%_'
- datetime 객체의 리스트나 배열을 pd.DatetimeIndex()로 전달하기
- 기존 열을 인덱스로 설정하려면 .set_index() 사용
df.set_index('Date', inplace=True)
- Pandas Datetime 분석
: df.index.(arg)max/(arg)min
시간 리샘플링
- 데이터 불러오기
- parse_dates = True: Pandas가 자동으로 날짜라고 인식한다.
- resample
: 시계열 데이터의 일반적인 작업은 시계열 인덱스를 기반으로 다시 샘플링하는 것이다.- .resample()을 호출할 때는 먼저 규칙 매개 변수를 전달한 다음 집계 함수를 호출해야 한다. 규칙 매개 변수는 집계 함수를 적용할 빈도(일, 월, 연도별 등)를 설정한다. 오프셋 별칭을 사용하여 전달된다.
- 사용자 지정 리샘플링 기능
- 플로팅
: Pandas는 각각의 표본을 자신의 흔적으로 취급하고 기본적으로 각각 다른 색을 할당한다. 원하는 경우 색상 인수를 전달하여 고유한 색상 집합을 할당하거나 균일한 색상을 설정할 수 있다.
시간 이동
➡️ 시계열 인덱스를 따라 모든 데이터를 위 또는 아래로 이동해야할 수 있다.
- .shift() forward
: 이 메서드는 기간에 관계없이 지정된 행 수만큼 전체 날짜 인덱스를 이동한다. 원본 df의 수정된 복사본을 반환한다. - .shift() backwards
: 음수로 행 입력 - 시계열 빈도 코드를 기반으로 한 이동
: 빈도 인수를 전달하여 데이터를 재정렬하지 않고 인덱스 값을 위 또는 아래로 이동하도록 선택할 수 있다. 이 방법은 빈도 코드를 기반으로 날짜를 다음 기간으로 이동한다. 일반적인 코드는 월말 = 'M', 연말 = 'A'이다.
Rolling과 Expanding
➡️ 시계열의 일반적인 공정은 롤링 평균을 기반으로 데이터를 생성하는 것이다. 데이터를 시간의 "windows"으로 나눈 다음 각 windows에 대한 집계 함수를 계산한다. 이러한 방식으로 단순한 이동 평균을 얻을 수 있다.
- Rolling
- 움직이는 windows가 있고 그 windows는 이동하면서 원하는 크기의 windows만큼 평균을 취한다
- 행 항목을 제공하며 모든 항목이 windows를 나타낸다. (window -1)값이 반영된다.
- 범례 추가: 롤링값을 새 열로 만들기
- Expanding
- windows가 계속 이동하면서 맨 처음부터 타임스탬프까지 확장한다. 그러면 본질적으로 전체 열의 평균으로 수렴하게 된다.
- 시계열 시작부터 각 시점까지의 모든 것을 고려하기
시계열 데이터 시각화 - Part 1 & 2
플롯 형식 지정
- 제목 및 축 레이블 추가
: .plot() 함수에 제목을 전달할 수는 있지만 x/y축 레이블은 전달할 수 없다. 그러나 .plot()이 matplotlib.axes.AxesSubplot을 반환하므로 레이블을 설정할 수있다. - X Limits
: 특정 시간 범위를 x축 한계로 설정하는 방법- 데이터 세트의 슬라이스를 플롯
[장점]
- pandas가 그에 따라 y한계를 자동으로 조정한다.
- 상한/하한을 제한으로 포함하는 것이 더 쉽다. - x-limit 값을 인수로 df.plot()에 전달할 수 있다.
[장점]
- pandas가 자동으로 x축을 조여준다.
- y제한을 설정하는 경우 가독성을 향상시킬 수 있다.
- 데이터 세트의 슬라이스를 플롯
[섹션7] Statsmodels를 이용한 시계열 자료 분석
Statsmodels 라이브러리 입문
statsmodels는 다양한 통계 모형의 추정과 통계 검정, 통계적 데이터 탐색 등을 다루는 클래스와 함수를 제공하는 파이썬 모듈이다.
➡️ statsmodels 라이브러리에서 함수를 호출해 통계 검정을 하는 방법
📍 시계열 데이터의 특징
1️⃣ 추세(=경향성)
- upward
- horizontal / stationary
- downward
2️⃣ 계절성: 반복적 추세 O
3️⃣ 순환 요소: 반복적 추세 X
📍 Hodrick-Prescott 필터 (hpfilter)
데이터의 추세 요소와 순환 요소를 찾아 분해한다.
from statsmodels.tsa.filters.hp_filter import hpfilter
# Tuple unpacking
gdp_cycle, gdp_trend = hpfilter(df['realgdp'], lamb=1600)
- tsa = Time Series Analysis 모듈
- 람다는 사용할 데이터의 주기에 따라 정해진다.
연간 데이터: 6.25, 분기: 1600, 월별 데이터: 129600
_ETS 분해
ETS = Error(오차)-Trend(추세)-Seasonality(계절성)
➡️ 데이터 평활화
- statsmodels의 ETS 분해를 실행하면 datetime을 x축으로 그린 4개의 플롯들을 리턴한다.
= 원본 데이터, 추세, 계절성, 잔차(오차)
- ETS 모델 종류
- 덧셈 모델: 추세가 선형에 더 가깝고 계절성이 거의 일정해 보일 때 적용
- 곱셈 모델: 지수적 증감하는 경우와 같이 비선형적으로 증가, 감소하는 경우에 적합
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(airline['Thousands of Passengers'], model='multiplicative')
※ 덧셈 모델일 때는 addtive 사용
EWMA(지수 가중 이동 평균) 이론
📍 단순 이동 평균(simple moving average: SMA)의 문제점
- 전체 모델이 같은 이동 평균 기간으로 제한된다.
- 짧은 이동 평균 기간를 이용하면 신호보다 잡음이 커질 수 있다 → 이동 평균 기간이 짧아질수록 시계열 데이터를 더 잘 설명할 수 있지만 그만큼 잡음도 커지기 떄문에 적절한 이동 평균 기간을 찾는 것은 매우 어렵다.
- 이동 평균 기간만큼 시차가 발생한다 → 평균을 함으로써 원래 데이터의 극대/극소값에 못 미치는 값을 보인다.
- 미래 변동에 대한 정보가 없다. 단순히 현재 데이터의 일반적 추세만을 보여준다.
- 극단적으로 크거나 작은 값은 단순 이동 평균 왜곡시킬 수 있다.
➡️ EWMA을 사용해 해결이 가능하다.
: 최근의 값들에 가중치를 적용함으로써 SMA에서의 시차 효과를 감소시킬 수 있다. (지수적으로 가중된다) 가중치는 매개변수에 의해 결정되며 이동 평균 기간에 따라서도 변화한다.
EWMA (Exponentially weighted moving average, 지수 가중 이동 평균)
- 하나의 평활 인자, 알파를 이용해 지수 평활을 하는 방법
→ 계절성이나 전반적 추세를 제대로 고려하지 못함 (하나의 매개변수만 사용하기 때문에) - parse_dates=True는 값이 누락되어있으면 동작하지 않는다.
airline['EWMA12'] = airline['Thousands of Passengers'].ewm(span=12,adjust=False).mean()
airline[['Thousands of Passengers','EWMA12']].plot();
➡️ 오래된 자료보다 최신의 자료에 더 큰 가중치를 주었기 때문에 계절성 추세가 끝부분으로 갈수록 더 잘 보인다.
- 지수 가중 함수를 제공하는 ewm메소드
- com: span과 역관계를 가진다
- span: N일 이동 평균
- halflife (=반감기): 지수적 가중치가 반으로 줄어드는데 걸리는 기간
홀트-윈터스 계절성 기법
= 이중/삼중 지수 평활법
- l_t → 알파: 특정 시간 t에서의 수준을 나타냄
- b_t → 베타: 전반적 추세로부터 정의됨 => 직선으로 예측
- c_t → 감마: 계절성 요소
- L = 주기당 데이터 포인트의 수
- 계절성 요소를 다루기 위한 방법
- 덧셈 기법: 계절성 요소가 전체 데이터에서 일정한 폭으로 나타날 때 이용
- 곱셈 기법: 계절적 변동폭이 데이터의 수준에 비례해 나타날 때 사용
단일 지수 평활법 = 지수 가중 이동 평균법(EWMA)
홀트-윈터스 계절성 기법을 이용한 코드 짜보기 - Part 1 & 2
단일 지수 평활법
- pandas의 datetime 인덱스를 살펴보면 빈도를 뜻하는 freq 속성값을 찾을 수 있다.
대부분의 경우에는 기본값으로 빈도값을 제공하지 않아서 freq = None으로 표시된다.
statsmodels는 freq값을 자동으로 읽어들이기 때문에 수동으로 설정해주어야 한다.
df.index.freq = 'MS' # 월의 첫째날
# 단일 지수 평활법 임포트
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
span = 12
alpha = 2/(span+1)
df['EWMA12'] = df['Thousands of Passengers'].ewm(alpha=alpha,adjust=False).mean()
df['SES12']=SimpleExpSmoothing(df['Thousands of Passengers']).fit(smoothing_level=alpha,optimized=False).fittedvalues.shift(-1)
※ optimzed: 설정되지 않은 값들을 자동으로 최적화할지 묻는 것
이중 지수 평활법
- 지수적 증가: 증가율이 시간이 지남에 따라 커지는 것
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 거의 선형적으로 증가하다가 마지막 부분에서야 지수적 증가가 보인다 -> 선형적 = 덧셈 모델
df['DESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='add').fit().fittedvalues.shift(-1)
df[['Thousands of Passengers','EWMA12','DESadd12']].iloc[:24].plot(figsize=(12,5));
# iloc를 통해 24개월(=2년)의 자료만 그림
➡️ 이중 지수 평활법이 단일 지수 평활법보다 원래 데이터(Thousands of Passengers)와 잘 맞는다.
📍 덧셈 모형 vs 곱셈 모형
df['DESmul12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='mul').fit().fittedvalues.shift(-1)
df[['Thousands of Passengers','EWMA12','DESadd12','DESmul12']].iloc[:24].plot(figsize=(12,6)).autoscale(axis='x',tight=True);
➡️ 곱셈 모형이 덧셈 모형이 비해 더 잘 맞는다.
: 데이터 증가율이 시간의 지남에 따라 증가하는 데이터에서는 가장 최근의 데이터와 가장 오래된 데이터 모두를 잘 피팅하기 때문에 곱셈 모형을 사용해야 한다.
삼중 지수 평활법
df['TESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'],trend='mul',seasonal='add',seasonal_periods=12).fit().fittedvalues
# shift가 필요하지 않다.
df['TESmul12'] = ExponentialSmoothing(df['Thousands of Passengers'],trend='mul',seasonal='mul',seasonal_periods=12).fit().fittedvalues
# 이중, 삼중 곱셈 비교
df[['Thousands of Passengers','DESmul12','TESmul12']].iloc[:24].plot(figsize=(12,6)).autoscale(axis='x',tight=True);
➡️ 더 복잡하고 고차원적인 삼중 지수 평활법이 이중 지수 평활법보다 좋은 결과를 내지 못한다고 결론지을 수 있다.
df[['Thousands of Passengers','DESmul12','TESmul12']].iloc[-24:].plot(figsize=(12,6)).autoscale(axis='x',tight=True);
➡️ 최근 데이터로 갈수록 삼중 지수 평활법의 결과값이 실제 데이터에 근접해져간다. 따라서 예측에 있어서는 계절적 변동을 예측할 수 있는 삼중 지수 평활법이 더 적합할 것으로 보인다.
⭐ 최종정리
1️⃣ statsmodels를 이용해 모형을 만들고 안에 datetime 인덱스를 가진 변수를 넣어준다.
→ 이것을 가능하게 하려면 그 전에 인덱스의 freq 요소를 우리가 가진 데이터셋에 맞게 정해주어야 한다.
2️⃣ 모형 피팅, 다양한 매개변수 입력
3️⃣ fittedvalues로 값 가져오기 (+ 어떤 모형을 사용했는지에 따라 shift()를 이용해 한칸씩 이동해야 할 수 있다.)
4️⃣ 주어진 타임스탬프에 대한 미래값 예측
✍️ 마무리하며
지난번에 배웠던 파이썬에 대해 다시 한 번 정리도 해볼 수 있었고, 새롭게 코드짜는 방법들도 배울 수 있어 유익한 시간이었다. 오늘 배웠던 시계열 데이터 다루는 법이 4월에 진행될 프로젝트에서 유용하게 사용될 것 같다.
* 유데미 큐레이션 바로가기 : https://bit.ly/3HRWeVL
* STARTERS 취업 부트캠프 공식 블로그 : https://blog.naver.com/udemy-wjtb
📌 본 후기는 유데미-웅진씽크빅 취업 부트캠프 4기 데이터분석/시각화 학습 일지 리뷰로 작성되었습니다.
'교육 > 유데미 스타터스 4기' 카테고리의 다른 글
[👩💻TIL 24일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.03.12 |
---|---|
[👩💻TIL 23일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.03.12 |
[👩💻TIL 21일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.03.08 |
[👩💻TIL 20일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.03.06 |
[오류 해결] 태블로 오류 코드:6EA18A9E (0) | 2023.03.06 |