iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 29
3

前言

今天是鐵人的第29天,要來使用Prophet來預測股票。
Prophet:為Facebook提供的套件,用來預測系統,主要用時間序來做分析。
架構如下
https://ithelp.ithome.com.tw/upload/images/20181107/20111390lwYBwCpKAp.png
(圖片來源Url)

Modeling:建立時間序列的模型。這邊使用股票來做模型。
Forecast Evaluation:模型評估。
Surface Problems:呈現問題。
Visually Inspect Forecasts:以視覺化的方式呈現預測結果。


前置作業

打開Anaconda Prompt看是否有安裝Prophet(使用「conda list」指令),沒有就執行

conda install -c conda-forge fbprophet 

預先載入套件

介紹底下的圖表之前先預先載入需要的套件

# basic
import numpy as np
import pandas as pd

# get data
import pandas_datareader as pdr

# visual
import matplotlib.pyplot as plt
%matplotlib inline

#time
import datetime as datetime

#Prophet
from fbprophet import Prophet


from sklearn import metrics

讀取股票

我們讀取以下股票
2492:華新科

start = datetime.datetime(2015,1,5)
df_2492 = pdr.DataReader('2492.TW', 'yahoo', start=start)

收盤價

如果只是用單純的收盤價繪製圖表,之前也介紹過了,範例如下:

plt.style.use('ggplot')
df_2492['Adj Close'].plot(figsize=(12, 8))

https://ithelp.ithome.com.tw/upload/images/20181107/2011139039zPt9RRVX.png

使用Prophet來預測股票

new_df_df_2492['y'] = np.log(new_df_df_2492['y'])
# 定義模型
model = Prophet()

# 訓練模型
model.fit(new_df_df_2492)

# 建構預測集
future = model.make_future_dataframe(periods=365) #forecasting for 1 year from now.

# 進行預測
forecast = model.predict(future)

figure=model.plot(forecast)

https://ithelp.ithome.com.tw/upload/images/20181108/20111390JjJIfN0MWw.png
其中黑色代表實際的值,請注意黑色只到今天這個日期,藍線代表的是預測值,而淡藍色的陰影區表示不確定性,未來時間距離越遠,不確定區域就會越來越大。

如果不考慮未來的不確定性,只有看預測和實際數據的最後800筆(一年252筆),只想看實際和預測之間的視覺差距。

df_2492_close = pd.DataFrame(df_2492['Adj Close'])
two_years = forecast.set_index('ds').join(df_2492_close)
two_years = two_years[['Adj Close', 'yhat', 'yhat_upper', 'yhat_lower' ]].dropna().tail(800)
two_years['yhat']=np.exp(two_years.yhat)
two_years['yhat_upper']=np.exp(two_years.yhat_upper)
two_years['yhat_lower']=np.exp(two_years.yhat_lower)
two_years[['Adj Close', 'yhat']].plot(figsize=(8, 6));

https://ithelp.ithome.com.tw/upload/images/20181108/20111390koTe8eA7Ov.png

橘色是實際的股價,藍色是預測的股價,從圖來看可以知道實際的股價和預測的股價非常相近。

計算誤差

現在來計算實際的股價和預測股價的誤差

two_years_AE = (two_years.yhat - two_years['Adj Close'])
two_years_AE.describe()
# 輸出結果
count    800.000000
mean      -1.451949
std       14.302471
min      -88.053614
25%       -2.389504
50%        0.129703
75%        2.074819
max       64.853188
dtype: float64

平均誤差了-1.451949,最大差別了64.853188,最小-88.053614

  • MSE:均方誤差
print ("MSE:",metrics.mean_squared_error(two_years.yhat, two_years['Adj Close']))
# 輸出結果
MSE: 206.41313426786152

MSE越接近0越好

  • MAE:平均絕對誤差
print ("MAE:",metrics.mean_absolute_error(two_years.yhat, two_years['Adj Close']))
# 輸出結果
MAE: 7.052998896728383

看了一下誤差數,Prophet預測這個股票是算準確的,但參考文章的內容卻是說用來預測股票是不適合的XDD。

  • 加上預測的上下限
fig, ax1 = plt.subplots(figsize=(10, 8))
ax1.plot(two_years['Adj Close'])
ax1.plot(two_years.yhat)
ax1.plot(two_years.yhat_upper, color='black',  linestyle=':', alpha=0.5)
ax1.plot(two_years.yhat_lower, color='black',  linestyle=':', alpha=0.5)

ax1.set_title('華新科技實際和預測的誤差')
ax1.set_ylabel('Price')
ax1.set_xlabel('Date')

https://ithelp.ithome.com.tw/upload/images/20181108/20111390CSpbi3dAH1.png
橘色是實際的價格,藍色是是預測的,上下限用灰色。除了2018年7月的時候波動性太大造成的預測比較不準外,其他其實都蠻相近的。

從這幾個分析來看Prophet比較一個月內的預測,時間拉得越長預測會越不準。

參考資料

Prophet

之前的章節


上一篇
[Day28]投資組合的風險評估 - 對數收益率
下一篇
[Day30]心得分享
系列文
python 入門到分析股市30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
draguitar
iT邦新手 4 級 ‧ 2019-08-19 15:16:06

使用Prophet來預測股票
new_df_df_2492['y'] = np.log(new_df_df_2492['y'])
NameError: name 'new_df_df_2492' is not defined
這裡會報錯,想請問版大該怎麼改呢~謝謝你<(._.)>

Summer iT邦新手 5 級 ‧ 2019-08-19 15:20:23 檢舉

https://github.com/lastsummer/learn_python_data_analysis/blob/master/06.stock/day29.ipynb 這裡有完整程式,在文章中沒有加上定義的程式碼。所以會出現not defined

draguitar iT邦新手 4 級 ‧ 2019-08-20 16:48:39 檢舉

謝謝回覆~

我要留言

立即登入留言