3

用fbprophet预测北京未来一个月的气温

 3 years ago
source link: https://zxs.io/article/1428
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
用fbprophet预测北京未来一个月的气温 | XINDOO

  fbprophet是facebook开源的时序数据预测包,提供了简洁的python和R api,可以对时序数据做一些预测,也提供了有些简单的趋势分析。更多细节可以看下官方文档。官方doc中给了一个数据集作为prophet的入门,这里我也只是按照官方的入门文档编写了的代码,很简单,只是把数据集换成了北京这8年来的每日温度数据,温度数我从网上爬取的,爬虫源码和数据可以从我github上找到。

# -*- coding: utf-8 -*-
# 首先导入我们需要的包,fbprophet没多少包依赖,pandas是为了读入数据的,pyplot是用来绘图的,fbprophet也支持直接绘图
import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet

  因为爬虫爬到的数据是无序的,所以要重新排序,其实不排序也没关系,并不影响prophet的预测。倒是异常点对预测影响挺多的,异常点太多或者值太大对结果的准确率影响也非常大,如果数据中有异常数据点,可以直接删除掉,prophet有对缺失数据补齐的能力。

data = pd.read_csv('bjweather.csv')
data = data.sort_values(by=['date'])
data = data.reset_index()
# 对数据做格式转化,prophet所需要的只有两列,分别是ds和y,这里我分别预测未来一个月的最小值和最大值。
dfmin = pd.DataFrame()
dfmin['ds'] = data['date']
dfmin['y'] = data['minT']
dfmax = pd.DataFrame()
dfmax['ds'] = data['date']
dfmax['y'] = data['maxT']
dfmax.head(10)

ds y 0 2011-01-01 0 1 2011-01-02 -2 2 2011-01-03 1 3 2011-01-04 -1 4 2011-01-05 -1 5 2011-01-06 0 6 2011-01-07 1 7 2011-01-08 1 8 2011-01-09 -1 9 2011-01-10 -1

  因为我需要分别预测未来一个月的最低温度和最高温度,所以需要分别训练两个模型,分别是minModel和maxModel。prophet的api也特别简单,只需要把历史数据传给fit函数即可。

minModel = Prophet()
minModel.fit(dfmin)
maxModel = Prophet()
maxModel.fit(dfmax)

  预测的时候需要传入需要预测的日期,以及预测所用的历史数据日期,prophet提供了一个make_future_dataframe的方法,可以生成所需要的日期数据。periods默认是天,也可以加freq='H',更改为其他时间粒度,我试了下,貌似最细时间粒度只能到小时。

futuremin = minModel.make_future_dataframe(periods=30)
futuremax = maxModel.make_future_dataframe(periods=30)
futuremin.tail()

ds 2948 2019-01-25 2949 2019-01-26 2950 2019-01-27 2951 2019-01-28 2952 2019-01-29

  用predict方法就可以做出预测了,预测结果里包含'ds', 'trend', 'yhat_lower', 'yhat_upper', 'trend_lower', 'trend_upper',
'additive_terms', 'additive_terms_lower', 'additive_terms_upper','weekly', 'weekly_lower', 'weekly_upper', 'yearly', 'yearly_lower','yearly_upper', 'multiplicative_terms', 'multiplicative_terms_lower','multiplicative_terms_upper', 'yhat',这些数据,具体某个数据的含义大家可以参考下prophet的官方文档,我这里只简单提下部分数据。

fcmin = minModel.predict(futuremin)
fcmax = maxModel.predict(futuremax)
fcmin[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
# 这几个数据分别是预测日期,预测结果值,预测结果上下界。

ds yhat yhat_lower yhat_upper 2948 2019-01-25 -7.446095 -10.686345 -4.430015 2949 2019-01-26 -7.410766 -10.581734 -4.291753 2950 2019-01-27 -7.505449 -10.612294 -4.659177 2951 2019-01-28 -7.434773 -10.413356 -4.334310 2952 2019-01-29 -7.435442 -10.549608 -4.453615

fig0 = minModel.plot(fcmin)

在这里插入图片描述

  除了预测结果和预测的上下界之外,prophet也可以提供一些趋势分析,包括年度趋势,月度趋势,和周趋势。从下面几张图里可以看出,北京在进8年里7-8月最热,1月最冷,大家肯定都知道。但8年里13年最冷,17年最暖和,周三平均温度最高,周一温差最大,周二最冷,这些估计没多少人知道了吧。

fig3 = minModel.plot_components(fcmin)

在这里插入图片描述

fig1 = maxModel.plot(fcmax)

在这里插入图片描述

fig2 = maxModel.plot_components(fcmin)

在这里插入图片描述

plt.plot(fcmin['ds'].tail(30), fcmin['yhat'].tail(30))
plt.plot(fcmax['ds'].tail(30), fcmax['yhat'].tail(30))

在这里插入图片描述
  最后我把预测出的1月份最高温和最低温放在一个图里展示出来,大家看看就好,不必当真。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK