ysyblog.tistory.com/179?category=1186605
해당 포스팅은 위 포스팅에 이어 진행됩니다.
Import Package and Dataset
# Ignore the warnings
import warnings
# warnings.filterwarnings('always') #항상 warning가 뜨게함
warnings.filterwarnings('ignore')
# System related and data input controls
import os #시스템 관련 핸들링
# Data manipulation and visualization
import pandas as pd
pd.options.display.float_format = '{:,.2f}'.format
pd.options.display.max_rows = 10 # 보여지는 행개수
pd.options.display.max_columns = 20 # 보여지는 열개수
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Modeling algorithms
# General
import statsmodels.api as sm
from scipy import stats
# Model selection
from sklearn.model_selection import train_test_split
# Evaluation metrics
# for regression
from sklearn.metrics import mean_squared_log_error, mean_squared_error, r2_score, mean_absolute_error
DataSET
location = "https://raw.githubusercontent.com/cheonbi/TimeSeriesAnalysis/master/Data/BikeSharingDemand/Bike_Sharing_Demand_Full.csv"
raw_all = pd.read_csv(location) #train data와 test data를 합친것
raw_all
Feature Engineering: 데이터에서 시계열패턴 추출하기
# string to datetime
raw_all['datetime'] = pd.to_datetime(raw_all['datetime'])
# set index as datetime column
raw_all.set_index('DateTime', inplace=True)
데이터를 시간단위로 만들기
raw_all.asfreq('H').index #시간단위로 되어있다.
# raw_all.asfreq('D') #일별데이터로 바꿔줌
# raw_all.asfreq('W')
raw_all.asfreq('H').isnull().sum() # 하지만 165개가 빠져있다.
raw_all.asfreq('H')[raw_all.asfreq('H').isnull().sum(axis=1) > 0] #아래 시간대가 빠져있는 것이다.
# setting frequency of time series data
raw_all = raw_all.asfreq('H', method='ffill') #앞에 있는 데이터로 뒤에 있는 값을 채운다. 3시가 비이었으면 2시의 데이터로 가져다가 채운다.
Target 변수 시각화 및 시계열 분해
- 타겟변수인 count와 count와 관련이 있는 'registered','casual'을 비교하면 다음과 같다.
raw_all[['count','registered','casual']].plot(kind='line', figsize=(20,6), linewidth=3, fontsize=20, xlim=('2012-01-01', '2012-06-01'), ylim=(0,1000)) plt.title('Time Series of Target', fontsize=20) plt.xlabel('Index', fontsize=15) plt.ylabel('Demand', fontsize=15) plt.show()
# line plot of Y
raw_all[['count']].plot(kind='line', figsize=(20,6), linewidth=3, fontsize=20,
xlim=('2012-01-01', '2012-03-01'), ylim=(0,1000))
plt.title('Time Series of Target', fontsize=20)
plt.xlabel('Index', fontsize=15)
plt.ylabel('Demand', fontsize=15)
plt.show()
시계열분해
# split data as trend + seasonal + residual
plt.rcParams['figure.figsize'] = (14, 9)
sm.tsa.seasonal_decompose(raw_all['count'], model='additive').plot()
plt.show()
- sm.tsa.seasonal_decompose는 계절성을 없애는 함수이며, model = additive는 trend, seasonal, residual가 더히기(+)로 이루어져 있을 것이다라는 것이다.
# 수치로도 볼 수 있다.
result = sm.tsa.seasonal_decompose(raw_all['count'], model='additive')
result.observed
result.trend
- trend에 nan이 있는데 실제로는 그게 아님, trend를 만드려면 여러개가 있어야 하는데 초반과 끝부분은 그게 없어서 그렇기 때문,
- 해당 데이터는 12개를 트렌드를 추론하는데 사용
# split data as trend * seasonal * residual
sm.tsa.seasonal_decompose(raw_all['count'], model='multiplicative').plot()
plt.show()
- model = multiplicative은 trend, seasonal, residual가 곱하기(*)로 이루어져 있을 것이다라는 것이다.
- 따라서 도메인의 특성에 따라 additive, multiplicative를 선택해야 한다.
# fill nan as some values of data
result = sm.tsa.seasonal_decompose(raw_all['count'], model='additive')
Y_trend = pd.DataFrame(result.trend)
Y_trend.fillna(method='ffill', inplace=True) #trend의 nan값 채우기(뒤에 있는 nam값들 앞 값드로 채우기)
Y_trend.fillna(method='bfill', inplace=True) #trend의 nan값 채우기(앞에 있는 nam값들 뒤 값들로 채우기)
Y_trend.columns = ['count_trend']
Y_seasonal = pd.DataFrame(result.seasonal)
Y_seasonal.fillna(method='ffill', inplace=True) #seasonal의 nan값 채우기(뒤에 있는 nam값들 앞 값드로 채우기)
Y_seasonal.fillna(method='bfill', inplace=True) #seasonal의 nan값 채우기(앞에 있는 nam값들 뒤 값들로 채우기)
Y_seasonal.columns = ['count_seasonal']
# merging several columns
raw_all = pd.concat([raw_all, Y_trend, Y_seasonal], axis=1)
해당 포스팅은 패스트캠퍼스의 <파이썬을 활용한 시계열 데이터 분석 A-Z 올인원 패키지> 강의를 듣고 정리한 내용입니다
728x90
반응형