使用facebook的fbprophet模型預測湖北新冠肺炎確診人數(包含源碼和具體分析過程)

就在最近,一次偶然的機會學習了以下fbprophet時序預測模型,就決定使用這個框架來進行未來20天人數的預測。但是傳染病模型通常比較複雜,此次使用此模型來預測,僅僅是用來練習,結果僅供參考。

fbprophet模型簡介

  • 這個模型(算法)是由facebook公司在2017年正式開源的,主要用於對時間序列進行預測。
  • 這個模型上手非常容易,即便是很一般的數據分析師也能夠做一個比較精準的預測。
  • 該模型只需要設置基本配置,並傳入指定格式的數據,就可以完成數據的預測。
  • 整體框架分爲Modeling、Forecast Evaluation、Surface Problems以及Visually Inspect Forecasts這四個部分。
  • 模型有三部分組成,增長趨勢,季節趨勢,節假日影響。

更多關於這個模型的介紹,騰訊技術寫過一篇我見過最詳細的介紹,我就不做重複工作了,大家自行查看把
騰訊技術工程 | 基於Prophet的時間序列預測

python實戰

一、包的安裝

首先強調一下安裝fbprophet我遇到的坑:

  • 需要首先安裝pystan,這個包使用pip安裝很難成功,建議使用anaconda安裝。
  • 成功安裝pystan後,使用pip安裝fbprophet。怪吧,因爲我使用anaconda安裝不上fbprophet。
二、使用的數據

我所使用的數據是湖北省從2019年12月1日到2020年2月29日的確診人數數據【數據下載】(提取碼:vmnv):
在這裏插入圖片描述
根據官網的描述,只要用 csv 文件存儲兩列即可,第一列的名字是 ‘ds’, 第二列的名稱是 ‘y’。第一列表示時間序列的時間戳,第二列表示時間序列的取值。所以這裏我們可以手動在文件中更改列名,也可以在程序中改。這裏我們使用後者方法。

三、處理數據
import pandas as pd
import pystan
from fbprophet import Prophet
import matplotlib.pyplot as plt

pdata = pd.read_csv("data/20200301-nCoV-hb.csv")
pdata.rename(columns={'date':'ds','confirmed':'y'},inplace=True)
pdata['ds'] = pd.to_datetime(pdata['ds'],format='%Y%m%d')

首先我們將列名修改成了官方要求的’ds’和’y’,其次我們將’ds‘的格式修改成了datatime時間格式。

四、初步預測
	#創建一個模型
 	m = Prophet()
    # pdata['cap']=69000
    m.fit(pdata)#傳入模型需要預測的數據
    #創建一個包含預測時間的dataframe,這裏period時預測時,單位默認是天
    future = m.make_future_dataframe(periods=20)
    # future['cap']=69000
    #進行預測,返回預測值及其其他相關值,格式是dataframe。
    forecast = m.predict(future)
    #繪畫出圖形
    m.plot(forecast)
    plt.show()#顯示圖片
    test = forecast[['ds','yhat']].tail(20)#輸出預測的20天的值
    print(forecast[-20:])

結果圖:
在這裏插入圖片描述
圖中,黑色的點是我們文件中的數據,也就是確診人數,中間深藍色的線就是我們預測的曲線,曲線輪廓的上下邊界有淺藍色區域,它表示模型預測值的上、下邊界。

這個結果肯定不能讓我們滿意,好了,我們來調整一下模型。

五、調整模型

模型可以調整的參數(prophet()中的參數):

  • prophet()有兩種模式,第一種是線性’linear‘,第二種是邏輯迴歸(非線性)‘logistic’。默認是線性的。注意 若使用後者,需要添加cap 進行容量值設置。
  • changepoints( prophet()模型中的):改變點。使用者可以自主填寫已知時刻的標示着增長率發生改變的”改變點。默認是0.05
  • changepoint_prior_scale( prophet()模型中的):增長趨勢模型的靈活度。值越大,曲線擬合就越靈活,過大也會出現過擬合的情況
  • holidays 節假日定義,holidays_prior_scale節假日對模型的影響,值越大,影響程度越大,默認值是10。holidays格式第一個參數是節假日名字,這個一般都自己寫; 第二個是你指定哪些日子爲假期;第三個lower_window 是前面你設定的節假期前幾天;第四個upper_window是節假日後幾天。下圖中我設置的是2月20日爲一個節日,這個節日時長爲之後的14天。
  • seasonality_prior_scale 調節季節的影響程度默認值是10
    在這裏插入圖片描述

好了,我們首先將模式改爲邏輯迴歸(非線性),注意容量值的設置。

    m = Prophet(growth='logistic')
    pdata['cap']=69000#容量值設置
    m.fit(pdata)
    #創建一個包含預測時間的dataframe
    future = m.make_future_dataframe(periods=20)
    future['cap']=69000#容量值設置

看一下這次的結果吧
在這裏插入圖片描述
這次比上次好了很多,已經非常擬合了,接下來咱們再修改一下增長趨勢擬合度,這個值默認是0.05,咱們修改爲2

m = Prophet(growth='logistic',changepoint_prior_scale=2)

在這裏插入圖片描述
對比起來沒有什麼變化,我們得去找找問題。

看上面咱們說得調整模型參數,changepoints,會不會是因爲我們沒有設置固定得改變點,使得圖片擬合沒有發生什麼變化,試一試。

    m = Prophet(growth='logistic',changepoint_prior_scale=2,changepoints=['2020-01-24','2020-02-14','2020-02-20'])

在這裏插入圖片描述

好了,這個模型趨勢看起來已經相當擬合,但是這裏需要注意,changepoint_prior_scale值過大會出現過擬合的情況,所以需要你多去嘗試,尋找合適的值。

咱們把最終調整完模型預測的值寫一下,看看未來幾天跟我們的預測有多大差距,想想還是很激動的:

在這裏插入圖片描述
源碼:

import numpy as np
import pandas as pd
import pystan
from fbprophet import Prophet
import matplotlib.pyplot as plt

pdata = pd.read_csv("data/20200301-nCoV-hb.csv")
pdata.rename(columns={'date':'ds','confirmed':'y'},inplace=True)
pdata['ds'] = pd.to_datetime(pdata['ds'],format='%Y%m%d')
m = Prophet(growth='logistic',changepoint_prior_scale=2,changepoints=['2020-01-24','2020-02-14','2020-02-20'])
pdata['cap']=69000
m.fit(pdata)
#創建一個包含預測時間的dataframe
future = m.make_future_dataframe(periods=20)
future['cap']=69000
forecast = m.predict(future)
m.plot(forecast)
plt.show()
test = forecast[['ds','yhat']].tail(20)
print(test[-20:])
不足與思考:
  • 新型冠狀病毒傳染模型比較複雜,涉及到多種模型,這裏只是使用這個模型做一下簡單的預測。目的是學習此模型。
  • 上文我只是添加了幾個改變點,大家在地下嘗試的時候可以添加假期和假期影響程度。
  • 這裏我只是輸出了forecast[[‘ds’,‘yhat’]] 一個是時間信息,一個是與測試,forecast還包含yhat_lower,yhat_upper。分別是預測值的下限,預測值的上限。
  • 以後有機會學習到傳染病傳播相關模型,會於此模型進行結合。

參考文章:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章