ข้อมูลอนุกรมเวลา(Time Series data) คือชุดของข้อมูลที่เก็บรวบรวมตามระยะเวลาเป็นช่วง ๆ การคาดการณ์อนุกรมเวลามีความสำคัญเชิงธุรกิจอย่างมาก ข้อมูลที่ธุรกิจเก็บและต้องการพยากรณ์มักมาในรูปแบบอนุกรมเวลา เช่นอุปสงค์และยอดขายจำนวนผู้เข้าชมเว็บไซต์ราคาหุ้น ฯลฯ เป็นข้อมูลอนุกรมเวลา
การวิเคราะห์อนุกรมเวลาเกี่ยวข้องกับการทำความเข้าใจกับแง่มุมต่าง ๆ เกี่ยวกับการเปลี่ยนแปลงตามธรรมชาติของข้อมูล เพื่อให้สามารถพยากรณ์ข้อมูลในอนาคตได้เเม่นยำขึ้น
ตัวอย่างข้อมูลอนุกรมเวลา (Time Series data)
from dateutil.parser import parseimport matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd# Import as Dataframe
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'])
df.head()
panel data
คือ ข้อมูลที่เก็บจากหน่วยตัวอย่าง i ในช่วงเวลาต่างๆ ทำให้ข้อมูลแต่ละช่วงเวลา ไม่เป็นอิสระต่อกัน ความแตกต่างคือนอกเหนือจากอนุกรมเวลายังมีตัวแปรที่เกี่ยวข้องอย่างน้อยหนึ่งตัวที่วัดในช่วงเวลาเดียวกัน โดยทั่วไปคอลัมน์ที่อยู่ในข้อมูลพาเนลจะมีตัวแปรอธิบายซึ่งมีประโยชน์ในการทำนาย Y โดยที่คอลัมน์เหล่านั้นจะพร้อมใช้งานในช่วงการคาดการณ์ในอนาคต
ตัวอย่างข้อมูล panel
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()การแสดงข้อมูลอนุกรมเวลา
มาใช้ matplotlib เพื่อแสดงข้อมูลอนุกรมเวลา
# Time series data source: fpp pacakge in R.import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')
เนื่องจากค่าทั้งหมดเป็นค่าบวก เราสามารถแสดงสิ่งนี้บนทั้งสองด้านของแกน Y เพื่อเน้นการเติบโต
# Import datadf = pd.read_csv('datasets/AirPassengers.csv', parse_dates=['date'])
x = df['date'].values
y1 = df['value'].values
# Plot
fig, ax = plt.subplots(1, 1, figsize=(16,5), dpi= 120)
plt.fill_between(x, y1=y1, y2=-y1, alpha=0.5, linewidth=2, color='seagreen')
plt.ylim(-800, 800)
plt.title('Air Passengers (Two Side View)', fontsize=16)
plt.hlines(y=0, xmin=np.min(df.date), xmax=np.max(df.date), linewidth=.5)
plt.show()
การเปรียบเทียบรายปีบ้างครั้งเนื่องจากข้อมูลเป็นฤดูกาลเราอาจต้องเปลี่ยบเทียบในช่วงเดือนเดี่ยวกัน
# Import Datadf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')df.reset_index(inplace=True)# Prepare datadf['year'] = [d.year for d in df.date]df['month'] = [d.strftime('%b') for d in df.date]years = df['year'].unique()# Prep Colorsnp.random.seed(100)mycolors = np.random.choice(list(mpl.colors.XKCD_COLORS.keys()), len(years), replace=False)# Draw Plotplt.figure(figsize=(16,12), dpi= 80)for i, y in enumerate(years):if i > 0:plt.plot('month', 'value', data=df.loc[df.year==y, :], color=mycolors[i], label=y)plt.text(df.loc[df.year==y, :].shape[0]-.9, df.loc[df.year==y, 'value'][-1:].values[0], y, fontsize=12, color=mycolors[i])# Decorationplt.gca().set(xlim=(-0.3, 11), ylim=(2, 30), ylabel='$Drug Sales$', xlabel='$Month$')plt.yticks(fontsize=12, alpha=.7)plt.title("Seasonal Plot of Drug Sales Time Series", fontsize=20)plt.show()Boxplot ของการกระจายแบบ Month-wise (Seasonal) และ Year-wise (trend)
เราสามารถจัดกลุ่มข้อมูลตามช่วงเวลาตามฤดูกาลและดูว่ามีการกระจายค่าภายในปีหรือเดือนที่กำหนดอย่างไรและเปรียบเทียบได้อย่างไรเมื่อเวลาผ่านไป
# Import Datadf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/mast er/a10.csv', parse_dates=['date'], index_col='date')
df.reset_index(inplace=True)
# Prepare data
df['year'] = [d.year for d in df.date]
df['month'] = [d.strftime('%b') for d in df.date]
years = df['year'].unique()
# Draw Plot
fig, axes = plt.subplots(1, 2, figsize=(20,7), dpi= 80)
sns.boxplot(x='year', y='value', data=df, ax=axes[0])
sns.boxplot(x='month', y='value', data=df.loc[~df.year.isin([1991, 2008]), :])
# Set Title
axes[0].set_title('Year-wise Box Plot\n(The Trend)', fontsize=18);
axes[1].set_title('Month-wise Box Plot\n(The Seasonality)', fontsize=18)
plt.show()
บ็อกซ์พล็อตทำให้การกระจายรายปีและรายเดือนชัดเจน นอกจากนี้ในบ็อกซ์พล็อตแบบเดือนต่อเดือนของเดือนธันวาคมและมกราคมมีการขายยาที่สูงขึ้นอย่างชัดเจนซึ่งสามารถนำมาประกอบกับฤดูส่วนลดวันหยุด
การหา PATTERN ของข้อมูลอนุกรมเวลาการหารูปแบบการเคลื่อนไหวของข้อมูลอนุกรมเวลาอย่างๆ ง่ายทำได้โดยการหาแนวโน้ม
การคาดการณ์เส้นแนวโน้มจากสมการต่างๆ โดยปกติมักใช้สมการดังต่อไปนี้
สมการเชิงเส้นตรง
Y = aX +b
สมการ Polynominal
Y =aX**n + aX**(n-1) …..aX +b
สมการ Logistic
Y = aIn(X) + b
สมการ exponential
Y = a* *x + b
#import libery!pip install -q requests
import requeste
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit#import Dataset
dataurl = "//covid19.th-stat.com/"
htmlsource = requests.get(dataurl).content
odat = pd.read_html(htmlsource)[0]#chang colum name
daycount = odat['หมายเลข'].values
daycount = [int(d.split('-')[-1].strip()) for d in daycount]
odat['daycount'] = daycount
dat = odat[['วันที่ยืนยัน','daycount']]
dat = dat.groupby('วันที่ยืนยัน').max()
dat = dat.sort_values(by='daycount')
dat['date'] = list(dat.index.values)
dat['date'] = dat['date'].astype('datetime64[ns]')
dat.index = range(len(dat))import pylab as py
xdata = list(dat.index.values)
ydata = list(dat['daycount'].values)
py.plot(xdata,ydata)
ขั้นตอนต่อมาคือประกาศฟังชั่นที่จะใช้ในการพยากรณ์ ในที่นี้จะใช้ สมการ exponential และสมการ Polynominal กำลัง2,3
import matplotlib.pyplot as pltimport numpy as np
from scipy.optimize import curve_fitdef expofunc(x, a, b, c):
return a * np.exp(b * x) + cdef polyfunc(x,a,b,c):
return a*x**2+b*x+cdef polyfunc2(x,a,b,c,d):
return a*x**3+b*x**2+c*x+dexpoparam, _ = curve_fit(expofunc, xdata, ydata)
polyparam, _ = curve_fit(polyfunc, xdata, ydata)
polyparam2, _ = curve_fit(polyfunc2, xdata, ydata)
a,b,c=polyparam
predictfrompoly = []
daylist = list(range(0,xrange))
for xi in daylist:
predictfrompoly.append(polyfunc(xi,a,b,c))
xrange = 100
predictfromexpo = []
daylist = list(range(0,xrange))
for xi in daylist:
predictfromexpo.append(expofunc(xi,a,b,c))a,b,c=polyparam
predictfrompoly = []
daylist = list(range(0,xrange))
for xi in daylist:
predictfrompoly.append(polyfunc(xi,a,b,c))a,b,c,d=polyparam2predictfrompoly2 = []
daylist = list(range(0,xrange))
for xi in daylist:
predictfrompoly2.append(polyfunc2(xi,a,b,c,d))def funcplot. (xlim,predictfrompoly,predictfromexpo,daylist,xdata,ydata):py.plot(daylist[0:xlim],predictfrompoly[0:xlim],label='Predicted Polyfit')
py.plot(daylist[0:xlim],predictfromexpo[0:xlim],label='Predicted Expofit')
py.plot(xdata,ydata,label='Actual')
py.legend()
py.grid()
เปรียบเทียบแต่ละสมการที่เราทำนายได้
nextday = 0xlim = 39 + nextdaypy.plot(daylist[0:xlim],predictfrompoly[0:xlim],label='Predicted Polyfit')py.plot(daylist[0:xlim],predictfrompoly2[0:xlim],label='Predicted Polyfit#2')py.plot(daylist[0:xlim],predictfromexpo[0:xlim],label='Predicted Expofit')py.plot(xdata,ydata,label='Actual')py.legend()
py.grid()
จะสังเกตเห็นได้ว่าจำนวนผู้ติดเชื่อมีความใกล้เคียงกับ Polynominal กำลัง3 มากที่สุด
ต่อมาเราก็มาพยากรณ์จำนวนผู้ติดเชื่อในอีก 30 วันข้างหน้า
nextday = 30xlim = 40 + nextdaypy.plot(daylist[0:xlim],predictfrompoly[0:xlim],label='Predicted Polyfit')py.plot(daylist[0:xlim],predictfrompoly2[0:xlim],label='Predicted Polyfit#2')py.plot(daylist[0:xlim],predictfromexpo[0:xlim],label='Predicted Expofit')py.plot(xdata,ydata,label='Actual')py.legend()
py.grid()
ข้อมูลอนุกรมเวลาประกอบไปด้วย: ค่าพื้นฐาน+ แนวโน้ม + ฤดูกาล + ข้อผิดพลาด
มีการสังเกตแนวโน้มเมื่อมีการเพิ่มหรือลดความชันที่สังเกตได้ในอนุกรมเวลา ในขณะที่ฤดูกาลมีการสังเกตเมื่อมีรูปแบบการทำซ้ำที่ชัดเจนสังเกตได้ระหว่างช่วงเวลาปกติเนื่องจากปัจจัยตามฤดูกาล อาจเป็นเพราะเดือนของปี, วันที่ของเดือน, วันธรรมดาหรือแม้แต่เวลาของวัน
อย่างไรก็ตามไม่ได้บังคับว่าอนุกรมเวลาทั้งหมดจะต้องมีแนวโน้มและ / หรือฤดูกาล อนุกรมเวลาอาจไม่มีแนวโน้มที่ชัดเจน แต่มีฤดูกาล ตรงกันข้ามอาจมีแต่แนวโน้มไม่มีฤดูกาลก็ได้
ดังนั้นอนุกรมเวลาอาจถูกจินตนาการว่าเป็นการรวมกันของแนวโน้มฤดูกาลและข้อผิดพลาด
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()0
อีกแง่มุมที่ควรพิจารณาก็คือพฤติกรรมแบบวนรอบ ที่เกิดขึ้นเมื่อรูปแบบการขึ้นและลงในซีรีส์ไม่ได้เกิดขึ้นในช่วงเวลาที่กำหนดตามปฏิทิน ควรใช้ความระมัดระวังเพื่อไม่ให้เกิดความสับสน ‘เอฟเฟกต์’ กับเอฟเฟกต์ “ซีซัน”
ดังนั้นจะแยกความแตกต่างระหว่างรูปแบบ “วงจร” กับ “ฤดูกาล” อย่างไรหากรูปแบบไม่ใช่ความถี่ตามปฏิทินที่แน่นอนก็เป็นวงจร เพราะต่างจากฤดูกาลฤดูกาลผลกระทบตามวงจรมักจะได้รับอิทธิพลจากธุรกิจและปัจจัยทางเศรษฐกิจและสังคมอื่น ๆ
อนุกรมเวลาแบบเพิ่มและแบบคูณขึ้นอยู่กับลักษณะของแนวโน้มและฤดูกาลอนุกรมเวลาสามารถสร้างแบบจำลองเป็นAdditiveหรือแบบMultiplicativeซึ่งการสังเกตแต่ละครั้งในชุดสามารถแสดงได้ทั้งผลรวมหรือผลคูณของส่วนประกอบ:
Additive time series:
Value = Base Level + Trend + Seasonality + Error
Multiplicative Time Series:
Value = Base Level x Trend x Seasonality x Error
เราสามารถสามารถแยกอนุกรมเวลาโดยพิจารณาว่าอนุกรมเป็นการรวมกันของBase Levelแนวโน้มดัชนีตามฤดูกาลและError โดยใช้ # Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')0 ใน# Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')1
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()1
หากต้องการเอาผลลัพธ์มาแยกใน datafram ก็ทำได้ดังนี้
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()2
ผลรวมของ # Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')2, # Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')3 and # Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')4 จะเท่ากับ # Time series data source: fpp pacakge in R.
import matplotlib.pyplot as plt
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
# Draw Plot
def plot_df(df, x, y, title="", xlabel='Date', ylabel='Value', dpi=100):
plt.figure(figsize=(16,5), dpi=dpi)
plt.plot(x, y, color='tab:red')
plt.gca().set(title=title, xlabel=xlabel, ylabel=ylabel)
plt.show()
plot_df(df, x=df.index, y=df.value, title='Monthly anti-diabetic drug sales in Australia from 1992 to 2008.')5.
Stationarity เป็นคุณสมบัติของอนุกรมเวลา อนุกรมที่อยู่กับที่นั้นเป็นค่าที่ค่าของอนุกรมไม่ใช่ฟังก์ชันของเวลา
นั่นคือคุณสมบัติทางสถิติของข้อมูลเช่นค่าเฉลี่ยความแปรปรวนและความสัมพันธ์อัตโนมัติมีค่าคงที่เมื่อเวลาผ่านไป Autocorrelation ของซีรี่ย์นั้นไม่มีอะไรนอกจากความสัมพันธ์ของซีรี่ย์กับค่าก่อนหน้านี้
ดังนั้นวิธีการระบุว่าชุดอยู่กับที่หรือไม่? ลองพล็อตตัวอย่างเพื่อทำให้ชัดเจน
วิธีการพยากรณ์ทางสถิติส่วนใหญ่ออกแบบมาเพื่อทำงานกับอนุกรมเวลาแบบ non-stationary ขั้นตอนแรกในกระบวนการคาดการณ์คือโดยทั่วไปแล้วจะทำการแปลงบางอย่างเพื่อแปลงข้อมูลให้เป็น stationary
วิธีสร้างข้อมูลอนุกรมเวลาแบบ stationary?เราสามารถสร้าง stationary โดย:
- ความแตกต่างของซีรี่ส์ (หนึ่งครั้งหรือมากกว่า)Differencing the Series (once or more)
- ใส่ Logarithm ในข้อมูล
- ใส่รากที่ n ให้ข้อมูล
วิธีที่นิยมใช้ในการแปลงข้อมูลอนุกรมเวลาให้เป็น time series โดย การดําเนินการหาผลต่างระหว่างช่วงเวลา ของข้อมูลอย่างน้อยหนึ่งครั้งจนกว่าจะกลายเป็นประมาณนิ่ง
ถ้า 𝑦𝑡 เป็นตัวแปรที่เราสนใจแล้ว first differencing ของ 𝑦𝑡 จะเท่ากับ 𝑦𝑡 − 𝑦𝑡−1 = 𝑦𝑡 − 𝐿𝑦𝑡 = (1 − 𝐿)𝑦𝑡
ตัวอย่างให้ข้อมูล: [1, 5, 2, 12, 20]
เราสามารถแปลงขั้นที่ 1: [5–1, 2–5, 12–2, 20–12] = [4, -3, 10, 8]
Seเราสามารถแปลงขั้นที่ 2: [-3–4, -10–3, 8–10] = [-7, -13, -2]
ทำใมต้องทำข้อมูลให้เป็น non-stationary series stationary ก่อนพยากรณ์?การถดถอยเชิงเส้นจะเเม่นยำที่สุดเมื่อตัวแปร X ไม่สัมพันธ์กับตัวแปรเป้าหมาย ดังนั้นการแก้ปัญหาให้กับ stationary จะช่วยแก้ปัญหานี้ได้เนื่องจากจะลบความสัมพันธ์โดยธรรมชาติใดๆออกไป ทำให้ตัวแปรในการทำนายในแบบจำลองการพยากรณ์เป็นอิสระ
วิธีการทดสอบ stationaryวิธีทดสอบ stationary อาจทำง่ายๆด้วยการพล็อตกราฟ
อีกวิธีหนึ่งคือการแบ่งชุดข้อมูลออกเป็น 2 ส่วนหรือมากกว่านั้นและคำนวณสถิติสรุปเช่นค่าเฉลี่ยความแปรปรวนและค่าความสัมพันธ์อัตโนมัติ หากสถิติแตกต่างกันมากแสดงว่าซีรีส์ไม่น่าจะstationary
อย่างไรก็ตามคุณจำเป็นต้องมีวิธีในการพิจารณาเชิงปริมาณว่าชุดข้อมูล stationary หรือไม่ ซึ่งสามารถทำได้โดยใช้การทดสอบทางสถิติที่เรียกว่า ‘Unit Root Tests’ มีหลายรูปแบบของสิ่งนี้ซึ่งการทดสอบตรวจสอบว่าอนุกรมเวลาแบบ non-stationary และมี unit root
มีการทำสอบ Unit Root หลายวิธีเช่น
- Augmented Dickey Fuller test (ADH Test)
- Kwiatkowski-Phillips-Schmidt-Shin — KPSS test (trend stationary)
- Philips Perron test (PP Test)
ที่ใช้กันมากที่สุดคือการทดสอบ ADF Test ที่สร้างสมมติฐาน null hypothesis ว่าข้อมูลเป็น non-stationary ดังนั้นถ้าค่าระดับนัยสำคัญ (0.05) เราจะปฏิเสธ null hypothesis
การทดสอบ KPSS นั้นใช้สำหรับทดสอบแนวโน้มstationary สมมติฐาน null hypothesis และการตีความค่า P เป็นค่าที่ตรงกันข้ามกับการทดสอบ ADH โค้ดด้านล่างใช้การทดสอบสองรายการนี้โดยใช้แพคเกจ statsmodels ด้วย Python
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()3การขจัดแนวโน้มออกจากชุดข้อมูลอนุกรณ์เวลา
การขจัดแนวโน้มออกจากชุดข้อมูลอนุกรณ์เวลา มีหลายวิธี
- ลบเส้นแนวโน้มที่เหมาะสมที่สุดออกจากข้อมูลอนุกรมเวลา เส้นแนวโน้มที่เหมาะสมที่สุดหาได้จากแบบจำลองการถดถอยเชิงเส้นพร้อม
- ลบด้วยค่าเฉลี่ย
- ใช้วิธีการทางสถิติอื่นเช่น Baxter-King (statsmodels.tsa.filters.bkfilter) Hodrick-Prescott (statsmodels.tsa.filters.hpfilter) เพื่อลบเส้นค่าเฉลี่ยเคลื่อนที่หรือองค์ประกอบวัฏจักร
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()4วิธีขจัดฤดูกาลออกจากข้อมูลอนุกรมเวลา
มีหลายวิธีในการขจัดฤดูกาลออกจากข้อมูลอนุกรมเวลา
- ใช้ค่าเฉลี่ยเคลื่อนที่
- ลบด้วยค่าของฤดูกาลก่อนหน้า
- แบ่งชุดข้อมูลด้วยดัชนีตามฤดูกาลที่ได้จากการแยก STL
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()5วิธีทดสอบฤดูกาลตามในข้อมูลอนุกรมเวลา
หากคเราต้องการการตรวจสอบฤดูกาลที่ชัดเจนยิ่งขึ้นให้ใช้พล็อต Autocorrelation Function (ACF) เพิ่มเติมเกี่ยวกับ ACF ในส่วนที่จะเกิดขึ้น แต่เมื่อมีรูปแบบตามฤดูกาลที่แข็งแกร่งพล็อต ACF มักจะแสดงให้เห็นถึงหนามแหลมที่ซ้ำแล้วซ้ำอีกที่ทวีคูณของหน้าต่างตามฤดูกาล
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()6
วิธีการจัดการกับค่าที่หายไปในอนุกรมเวลา?
ในบ้างครั้งข้อมูลที่เราได้มาอาจมีข้อมูลที่ขาดหายไป เรามีทางเลือกมากมายในการเติบค่าที่หายไปอาทิเช่น
- Backward Fill
- Linear Interpolation
- Quadratic interpolation
- Mean of nearest neighbors
- Mean of seasonal couterparts
เราจะเลือกวิธีใหนนั้นขึ้นอยู่กัว่าเราต้องการความเชื่อมั่นในค่านั้นขนาดใหน
- หากเรามีตัวแปรอธิบายให้ใช้แบบจำลองการทำนาย เช่นฟอเรสต์แบบสุ่มหรือเพื่อนบ้าน k- ที่ใกล้ที่สุดเพื่อทำนาย
- หากการสังเกตการณ์ในอดีตเพียงพอให้คาดการณ์ค่าที่หายไป
- หากมีข้อสังเกตในอนาคตมากพอให้ย้อนกลับค่าที่หายไป
การคาดการณ์ของคู่จากรอบก่อนหน้า
Autocorrelation เป็นความสัมพันธ์ของชุดข้อมูลที่เกิดจากตัวข้อมูลเอง หากชุดข้อมูลมีความสัมพันธ์กันอย่างมีนัยสำคัญ นั่นหมายความว่าค่าก่อนหน้าของชุดข้อมูล อาจมีประโยชน์ในการทำนายค่าปัจจุบัน
การประเมินการพยากรณ์ยิ่งมีรูปแบบเวลาปกติและทำซ้ำได้มากเท่าไหร่ก็ยิ่งง่ายต่อการคาดการณ์เท่านั้น ‘Entropimate Entropy’ สามารถใช้ในการกำหนดปริมาณความสม่ำเสมอและความไม่แน่นอนของความผันผวนในอนุกรมเวลา
ยิ่งค่าเอนโทรปีโดยประมาณสูงเท่าไหร่ก็ยากที่จะคาดการณ์ได้
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()7การปรับค่าอนุกรมเวลาให้ราบเรียบ
การทำให้เรียบของอนุกรมเวลาอาจมีประโยชน์ใน: การลดเอฟเฟกต์ของการรบกวนในในการประมาณค่าวิธีการทำในการปรับค่าข้อมูลให้ราบเรียบ มีวิธีการต่อไปนี้:
- ค่าเฉลี่ยเคลื่อนที่ ค่าเฉลี่ยเคลื่อนที่คือ ค่าเฉลี่ยของชุดข้อมูเป็นช่วงๆเช่น: 12 มักมีประโยชน์ในการเปรียบเทียบข้อมูลที่มีทั้งแนวโน้มและฤดูกา
- Localized Regression LOESS ย่อมาจาก ‘regression LOcalized’ เหมาะกับการถดถอยหลายจุดในพื้นที่ใกล้เคียงของแต่ละจุด. ถูกนำมาใช้ในแพคเกจ statsmodels ซึ่งสามารถควบคุมระดับของการปรับให้เรียบโดยใช้อาร์กิวเมนต์ frac ซึ่งระบุเปอร์เซ็นต์ของจุดข้อมูลในบริเวณใกล้เคียงที่ควรได้รับการพิจารณาว่าเหมาะสมกับแบบจำลองการถดถอย
- Locally Weighted Regression
df = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()8การทดสอบความเป็นเหตุเป็นผลของ Granger
การทดสอบความเป็นเหตุเป็นผลของ Granger ใช้เพื่อพิจารณาว่าอนุกรมเวลาหนึ่งจะมีประโยชน์ในการคาดการณ์แบบอื่น
โดยมีแนวคิดที่ว่าถ้า X ทำให้ Y ดังนั้นการคาดการณ์ของ Y ตามค่าก่อนหน้าของ Y และค่าก่อนหน้าของ X ความเชื่อมั่นควรสูงกว่าการคาดการณ์ของ Y ตามค่าก่อนหน้าของ Y เพียงอย่างเดียว
ดังนั้นเข้าใจว่า Granger causality ไม่ควรใช้เพื่อทดสอบว่าความล่าช้าของ Y เป็นสาเหตุของ Y หรือไม่โดยทั่วไปจะใช้กับตัวแปรภายนอก (ไม่ใช่ Y lag) เท่านั้น
สมมติฐาน Null คือ: ซีรีส์ในคอลัมน์ที่สองไม่เกรนเจอร์ทำให้เกิดซีรีส์ในครั้งแรก หากค่า P-Value มีค่าน้อยกว่าระดับนัยสำคัญ (0.05) คุณก็จะปฏิเสธสมมติฐานว่างแล้วสรุปได้ว่าความล่าช้าของ X นั้นมีประโยชน์จริง ๆ
อาร์กิวเมนต์ที่สอง maxlag บอกว่าจนถึงจำนวน lags ของ Y ที่ควรรวมในการทดสอบ
# dataset source: //github.com/rouseguydf = pd.read_csv('//raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv')
df = df.loc[df.market=='MUMBAI', :]
df.head()9
ในกรณีข้างต้นค่า P เป็นศูนย์สำหรับการทดสอบทั้งหมด ดังนั้น ‘เดือน’ จึงสามารถใช้ในการคาดการณ์ผู้โดยสารได้