精华内容
下载资源
问答
  • 周期性时间序列的预测

    万次阅读 2018-08-17 18:00:00
    最近在研究时间序列的时候,发现很多序列具有很强的周期性,那如何对此类序列进行预测呢? 1 数据处理 挑选一个如下图的具有周期性时间序列。该序列是取得是过去7天的数据,每小时一个点,一共7*24个点。   2 ...
        

    女主宣言

    AIOps 从立项到现在已经半年有余,从最开始的 LVS 异常检测,到如今的实时关联分析,智能运维已经渗透到我们日常运维中的许多场景,之后我们会将积累的经验分享出来,供大家学习参考,本文最先发布于 OpsDev,转载已获取作者授权。

    PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

    640?wx_fmt=jpeg

    At Tranquility Base, 1969

    by NASA IOTD

    最近在研究时间序列的时候,发现很多序列具有很强的周期性,那如何对此类序列进行预测呢?


    1

    数据处理

    挑选一个如下图的具有周期性的时间序列。该序列是取得是过去7天的数据,每小时一个点,一共7*24个点。

    640?wx_fmt=png 

    2

    划分数据集

    我们取前六天的数据做训练,第七天做测试集。


    3

    平滑处理

    时间序列经常会出现毛刺的点,需要做平滑处理才能分析,类似上图中的数据。消除数据的毛刺,可以用移动平均法,但是移动平均有时候处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充:

    640?wx_fmt=jpeg

    经过处理以后,上图的时间序列得到了平滑处理,效果如下图。

    640?wx_fmt=png 

    4

    周期性分解

    具有周期性特征的序列需要将周期性特征提取出来。python里面的statsmodels工具包里面有针对周期性分解的函数seasonal_decompose,我们可以将序列进行分解。seasonal_decompose这个函数里面有个two_sided的参数,默认是True。Trend处理的时候用到移动平均的方法,熟悉此方法的读者就会发现,经过该方法处理以后,序列收尾两段有一部分数据缺失了,但是如果该参数为FALSE,则只有开始的时候有一段缺失值。

    640?wx_fmt=jpeg
    640?wx_fmt=png

    图3中的第一张图是observed,体现的原始数据;第二张是trend,体现的是分解出来的趋势部分;第三张是seasonal,体现的是周期部分;最后是residual,体现的是残差部分。


    本文采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?后面会有介绍。


    5

    预测

    我们对trend部分进行预测,最后再加上seasonal部分。对trend的预测,我们采用ARIMA模型。熟悉该模型的都知道,需要确定三个参数p,q和d,可以使用aic和bic的方法进行定阶,可以查阅相关的文献。

    640?wx_fmt=jpeg


    得到模型以后,就可以进行预测。

    640?wx_fmt=jpeg


    下面是预测的结果,从图中可以看到预测的结果将周期性的特征完美地体现出来了。

    640?wx_fmt=png
     

    6

    评估

    对第七天作出预测,评估的指标为均方根误差rmse,本序列的rmse小于5,效果还是不错的。


    7

    总结

    本文介绍了周期性序列的预测方法,你可能会问并不是所有的序列都具有周期性,事实确实如此,接下来几篇博客,我会重点介绍周期性检测的一些方法。希望此博客对您研究时间序列有所帮助。

    HULK一线技术杂谈

    由360云平台团队打造的技术分享公众号,内容涉及云计算数据库大数据监控泛前端自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

    640?wx_fmt=gif
    展开全文
  • 把坑填上,用前后值的均值把缺失值补上,再看一眼: 填充好缺失值的序列.png 发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到: 1、这是一个周期性时间序列,数值有规律的以天为周期上下波动...

    1、背景

    公司平台上有不同的api,供内部或外部调用,这些api承担着不同的功能,如查询账号、发版、抢红包等等。日志会记录下每分钟某api被访问了多少次,即一个api每天会有1440条记录(1440分钟),将每天的数据连起来观察,有点类似于股票走势的意思。我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,触发报警。

    2、数据探索

    我放了一份样例数据在data文件夹下,

    看一下数据大小和结构

    data.png

    数据大小:

    共10080条记录,即10080分钟,七天的数据。

    字段含义:

    date:时间,单位分钟

    count:该分钟该api被访问的次数

    画图看一下序列的走势:(一些画图等探索类的方法放在了test_stationarity.py 文件中,包含时间序列图,移动平均图,有兴趣的可以自己尝试下)。

    序列.png

    看这糟心的图,那些骤降为0的点这就是我遇到的第一个坑,我当初一拿到这份数据就开始做了。后来折腾了好久才发现,那些骤降为0的点是由于数据缺失,ETL的同学自动补零造成的,沟通晚了(TДT)。

    把坑填上,用前后值的均值把缺失值补上,再看一眼:

    填充好缺失值的序列.png

    发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到:

    1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动,图中这个api,在每天下午和晚上访问较为活跃,在早上和凌晨较为稀少。在建模之前需要做分解。

    2、我的第二个坑:数据本身并不平滑,骤突骤降较多,而这样是不利于预测的,毕竟模型需要学习好正常的序列才能对未知数据给出客观判断,否则会出现频繁的误报,令气氛变得十分尴尬( ´Д`),所以必须进行平滑处理。

    3、这只是一个api的序列图,而不同的api的形态差距是很大的,毕竟承担的功能不同,如何使模型适应不同形态的api也是需要考虑的问题。

    3、预处理

    3.1 划分训练测试集

    前六天的数据做训练,第七天做测试集。

    3.2 对训练数据进行平滑处理

    消除数据的毛刺,可以用移动平均法,我这里没有采用,因为我试过发现对于我的数据来说,移动平均处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充,注意可能会连续出现变化较大的点:

    平滑后的训练数据:

    平滑后的训练序列.png

    3.3 将训练数据进行周期性分解

    采用statsmodels工具包:

    分解图.png

    第一行observed:原始数据;第二行trend:分解出来的趋势部分;第三行seasonal:周期部分;最后residual:残差部分。

    我采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?当然是再做加法,后面会详细写。

    4、模型

    4.1 训练

    对分解出来的趋势部分单独用arima模型做训练:

    4.2 预测

    预测出趋势数据后,加上周期数据即作为最终的预测结果,但更重要的是,我们要得到的不是具体的值,而是一个合理区间,当真实数据超过了这个区间,则触发报警,误差高低区间的设定来自刚刚分解出来的残差residual数据:

    预测并完成最后的加法处理,得到第七天的预测值即高低置信区间:

    4.3 评估:

    对第七天作出预测,评估的指标为均方根误差rmse,画图对比和真实值的差距:

    预测结果.png

    可以看到,均方根误差462.8,相对于原始数据几千的量级,还是可以的。测试数据中的两个突变的点,也超过了置信区间,能准确报出来。

    展开全文
  •  但是都属于典型的周期性时间序列,它的核心思想很简单:做好分解,做好预测结果的还原,和置信区间的设置,具体操作可根据具体业务逻辑做调整,祝大家建模愉快。 - END - 原文链接:...

    e37eabf760c7a8741c3544d833750253.png

    公司平台上有不同的api,供内部或外部调用,这些api承担着不同的功能,如查询账号、发版、抢红包等等。

    日志会记录下每分钟某api被访问了多少次,即一个api每天会有1440条记录(1440分钟),将每天的数据连起来观察,有点类似于股票走势的意思。

    我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,触发报警。

    数据探索

    我放了一份样例数据在data文件夹下,看一下数据大小和结构。

    data = pd.read_csv(filename)print('size: ',data.shape)print(data.head())
    19645bbd264d6862274cf4782f9b8c48.png
    数据大小:
    共10080条记录,即10080分钟,七天的数据。
    字段含义:
    date:时间,单位分钟
    count:该分钟该api被访问的次数
    画图看一下序列的走势:(一些画图等探索类的方法放在了test_stationarity.py 文件中,包含时间序列图,移动平均图,有兴趣的可以自己尝试下)。
    def draw_ts(timeseries):    timeseries.plot()    plt.show()data = pd.read_csv(path)data = data.set_index('date')data.index = pd.to_datetime(data.index)ts = data['count']draw_ts(ts)
    f4aa2638ae19644d4de188c7b9afe7be.png序列看这糟心的图,那些骤降为0的点这就是我遇到的第一个坑,我当初一拿到这份数据就开始做了。后来折腾了好久才发现,那些骤降为0的点是由于数据缺失,ETL的同学自动补零造成的,沟通晚了(TДT)。把坑填上,用前后值的均值把缺失值补上,再看一眼:00f497c1d7b7eb286cc619115bd81340.png填充好缺失值的序列发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到:1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动,图中这个api,在每天下午和晚上访问较为活跃,在早上和凌晨较为稀少。在建模之前需要做分解。2、我的第二个坑:数据本身并不平滑,骤突骤降较多,而这样是不利于预测的,毕竟模型需要学习好正常的序列才能对未知数据给出客观判断,否则会出现频繁的误报,令气氛变得十分尴尬( ´Д`),所以必须进行平滑处理。3、这只是一个api的序列图,而不同的api的形态差距是很大的,毕竟承担的功能不同,如何使模型适应不同形态的api也是需要考虑的问题。预处理

    1、划分训练测试集

    前六天的数据做训练,第七天做测试集。
    class ModelDecomp(object):    def __init__(self, file, test_size=1440):        self.ts = self.read_data(file)        self.test_size = test_size        self.train_size = len(self.ts) - self.test_size        self.train = self.ts[:len(self.ts)-test_size]        self.test = self.ts[-test_size:]
    2、对训练数据进行平滑处理消除数据的毛刺,可以用移动平均法,我这里没有采用,因为我试过发现对于我的数据来说,移动平均处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充,注意可能会连续出现变化较大的点。
    def _diff_smooth(self, ts):    dif = ts.diff().dropna() # 差分序列    td = dif.describe() # 描述性统计得到:min,25%,50%,75%,max值    high = td['75%'] + 1.5 * (td['75%'] - td['25%']) # 定义高点阈值,1.5倍四分位距之外    low = td['25%'] - 1.5 * (td['75%'] - td['25%']) # 定义低点阈值,同上    # 变化幅度超过阈值的点的索引    forbid_index = dif[(dif > high) | (dif < low)].index     i = 0    while i < len(forbid_index) - 1:        n = 1 # 发现连续多少个点变化幅度过大,大部分只有单个点        start = forbid_index[i] # 异常点的起始索引        while forbid_index[i+n] == start + timedelta(minutes=n):            n += 1        i += n - 1        end = forbid_index[i] # 异常点的结束索引        # 用前后值的中间值均匀填充        value = np.linspace(ts[start - timedelta(minutes=1)], ts[end + timedelta(minutes=1)], n)        ts[start: end] = value        i += 1self.train = self._diff_smooth(self.train)draw_ts(self.train)
    平滑后的训练数据:37e710df558c0c63159383e7152ab091.png

    3、将训练数据进行周期性分解

    采用statsmodels工具包:
    from statsmodels.tsa.seasonal import seasonal_decomposedecomposition = seasonal_decompose(self.ts, freq=freq, two_sided=False)# self.ts:时间序列,series类型; # freq:周期,这里为1440分钟,即一天; # two_sided:观察下图2、4行图,左边空了一段,如果设为True,则会出现左右两边都空出来的情况,False保证序列在最后的时间也有数据,方便预测。self.trend = decomposition.trendself.seasonal = decomposition.seasonalself.residual = decomposition.residdecomposition.plot()plt.show()
    95d2d0ed857923ce5d1a5a3cdc6c2f74.png分解图第一行observed:原始数据;第二行trend:分解出来的趋势部分;第三行seasonal:周期部分;最后residual:残差部分。我采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?当然是再做加法,后面会详细写。模型

    1、训练

    对分解出来的趋势部分单独用arima模型做训练:
    def trend_model(self, order):    self.trend.dropna(inplace=True)    train = self.trend[:len(self.trend)-self.test_size]    #arima的训练参数order =(p,d,q),具体意义查看官方文档,调参过程略。    self.trend_model = ARIMA(train, order).fit(disp=-1, method='css')
    2、预测预测出趋势数据后,加上周期数据即作为最终的预测结果,但更重要的是,我们要得到的不是具体的值,而是一个合理区间,当真实数据超过了这个区间,则触发报警,误差高低区间的设定来自刚刚分解出来的残差residual数据:
    d = self.residual.describe()delta = d['75%'] - d['25%']self.low_error, self.high_error = (d['25%'] - 1 * delta, d['75%'] + 1 * delta)
    预测并完成最后的加法处理,得到第七天的预测值即高低置信区间:
        def predict_new(self):        '''        预测新数据        '''        #续接train,生成长度为n的时间索引,赋给预测序列        n = self.test_size        self.pred_time_index= pd.date_range(start=self.train.index[-1], periods=n+1, freq='1min')[1:]        self.trend_pred= self.trend_model.forecast(n)[0]        self.add_season()    def add_season(self):        '''        为预测出的趋势数据添加周期数据和残差数据        '''        self.train_season = self.seasonal[:self.train_size]        values = []        low_conf_values = []        high_conf_values = []        for i, t in enumerate(self.pred_time_index):            trend_part = self.trend_pred[i]            # 相同时间点的周期数据均值            season_part = self.train_season[                self.train_season.index.time == t.time()                ].mean()            # 趋势 + 周期 + 误差界限            predict = trend_part + season_part            low_bound = trend_part + season_part + self.low_error            high_bound = trend_part + season_part + self.high_error            values.append(predict)            low_conf_values.append(low_bound)            high_conf_values.append(high_bound)        # 得到预测值,误差上界和下界        self.final_pred = pd.Series(values, index=self.pred_time_index, name='predict')        self.low_conf = pd.Series(low_conf_values, index=self.pred_time_index, name='low_conf')        self.high_conf = pd.Series(high_conf_values, index=self.pred_time_index, name='high_conf')
    3、评估:对第七天作出预测,评估的指标为均方根误差rmse,画图对比和真实值的差距:
        md = ModelDecomp(file=filename, test_size=1440)    md.decomp(freq=1440)    md.trend_model(order=(1, 1, 3)) # arima模型的参数order    md.predict_new()     pred = md.final_pred    test = md.test    plt.subplot(211)    plt.plot(md.ts) # 平滑过的训练数据加未做处理的测试数据    plt.title(filename.split('.')[0])    plt.subplot(212)    pred.plot(color='blue', label='Predict') # 预测值    test.plot(color='red', label='Original') # 真实值    md.low_conf.plot(color='grey', label='low') # 低置信区间    md.high_conf.plot(color='grey', label='high') # 高置信区间    plt.legend(loc='best')    plt.title('RMSE: %.4f' % np.sqrt(sum((pred.values - test.values) ** 2) / test.size))    plt.tight_layout()    plt.show()
    预测结果可以看到,均方根误差462.8,相对于原始数据几千的量级,还是可以的。测试数据中的两个突变的点,也超过了置信区间,能准确报出来。

    结语

    前文提到不同的api形态差异巨大,本文只展示了一个。我在该项目中还接触了其他形态的序列,有的有明显的上升或下降趋势;有的开始比较平缓,后面开始增长... ... 但是都属于典型的周期性时间序列,它的核心思想很简单:做好分解,做好预测结果的还原,和置信区间的设置,具体操作可根据具体业务逻辑做调整,祝大家建模愉快。

    - END -

    原文链接:

    https://www.jianshu.com/p/09e5218f58b4

    文源网络,仅供学习之用。如有侵权,联系删除。

    往期精彩

    5dc1c7a13223436d5e9f4a33c2efb8ec.png

    ◆  50款开源工具你都用过吗?

    ◆  python+C、C++混合编程的应用

    ◆  python网络爬虫的基本原理详解

    ◆  Python自动操控excel,一小时解决你一天的工作

    ◆  如何用Python增强Excel,减少处理复杂数据的痛苦?

    434f9236d628681c4c5d3f46bbe40813.png

    展开全文
  • 但是都属于典型的周期性时间序列,它的核心思想很简单:做好分解,做好预测结果的还原,和置信区间的设置,具体操作可根据具体业务逻辑做调整,祝大家建模愉快。 文源网络,仅供学习之用,侵删。 在学习Python的...

    公司平台上有不同的api,供内部或外部调用,这些api承担着不同的功能,如查询账号、发版、抢红包等等。

    日志会记录下每分钟某api被访问了多少次,即一个api每天会有1440条记录(1440分钟),将每天的数据连起来观察,有点类似于股票走势的意思。

    我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,触发报警。

    数据探索

    我放了一份样例数据在data文件夹下,看一下数据大小和结构。

    data = pd.read_csv(filename)

    print('size: ',data.shape)

    print(data.head())

    数据大小:

    共10080条记录,即10080分钟,七天的数据。

    字段含义:

    date:时间,单位分钟

    count:该分钟该api被访问的次数

    画图看一下序列的走势:(一些画图等探索类的方法放在了test_stationarity.py 文件中,包含时间序列图,移动平均图,有兴趣的可以自己尝试下)。

    def draw_ts(timeseries):

    timeseries.plot()

    plt.show()

    data = pd.read_csv(path)

    data = data.set_index('date')

    data.index = pd.to_datetime(data.index)

    ts = data['count']

    draw_ts(ts)

    序列

    看这糟心的图,那些骤降为0的点这就是我遇到的第一个坑,我当初一拿到这份数据就开始做了。后来折腾了好久才发现,那些骤降为0的点是由于数据缺失,ETL的同学自动补零造成的,沟通晚了(TДT)。

    把坑填上,用前后值的均值把缺失值补上,再看一眼:

    填充好缺失值的序列

    发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到:

    1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动,图中这个api,在每天下午和晚上访问较为活跃,在早上和凌晨较为稀少。在建模之前需要做分解。

    2、我的第二个坑:数据本身并不平滑,骤突骤降较多,而这样是不利于预测的,毕竟模型需要学习好正常的序列才能对未知数据给出客观判断,否则会出现频繁的误报,令气氛变得十分尴尬( ´Д`),所以必须进行平滑处理。

    3、这只是一个api的序列图,而不同的api的形态差距是很大的,毕竟承担的功能不同,如何使模型适应不同形态的api也是需要考虑的问题。

    预处理

    1、划分训练测试集

    前六天的数据做训练,第七天做测试集。

    class ModelDecomp(object):

    def __init__(self, file, test_size=1440):

    self.ts = self.read_data(file)

    self.test_size = test_size

    self.train_size = len(self.ts) - self.test_size

    self.train = self.ts[:len(self.ts)-test_size]

    self.test = self.ts[-test_size:]

    2、对训练数据进行平滑处理

    消除数据的毛刺,可以用移动平均法,我这里没有采用,因为我试过发现对于我的数据来说,移动平均处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:

    把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充,注意可能会连续出现变化较大的点。

    def _diff_smooth(self, ts):

    dif = ts.diff().dropna() # 差分序列

    td = dif.describe() # 描述性统计得到:min,25%,50%,75%,max值

    high = td['75%'] + 1.5 * (td['75%'] - td['25%']) # 定义高点阈值,1.5倍四分位距之外

    low = td['25%'] - 1.5 * (td['75%'] - td['25%']) # 定义低点阈值,同上

    # 变化幅度超过阈值的点的索引

    forbid_index = dif[(dif > high) | (dif < low)].index

    i = 0

    while i < len(forbid_index) - 1:

    n = 1 # 发现连续多少个点变化幅度过大,大部分只有单个点

    start = forbid_index[i] # 异常点的起始索引

    while forbid_index[i+n] == start + timedelta(minutes=n):

    n += 1

    i += n - 1

    end = forbid_index[i] # 异常点的结束索引

    # 用前后值的中间值均匀填充

    value = np.linspace(ts[start - timedelta(minutes=1)], ts[end + timedelta(minutes=1)], n)

    ts[start: end] = value

    i += 1

    self.train = self._diff_smooth(self.train)

    draw_ts(self.train)

    平滑后的训练数据:

    3、将训练数据进行周期性分解

    采用statsmodels工具包:

    from statsmodels.tsa.seasonal import seasonal_decompose

    decomposition = seasonal_decompose(self.ts, freq=freq, two_sided=False)

    # self.ts:时间序列,series类型;

    # freq:周期,这里为1440分钟,即一天;

    # two_sided:观察下图2、4行图,左边空了一段,如果设为True,则会出现左右两边都空出来的情况,False保证序列在最后的时间也有数据,方便预测。

    self.trend = decomposition.trend

    self.seasonal = decomposition.seasonal

    self.residual = decomposition.resid

    decomposition.plot()

    plt.show()

    分解图

    第一行observed:原始数据;第二行trend:分解出来的趋势部分;第三行seasonal:周期部分;最后residual:残差部分。

    我采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。

    在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?当然是再做加法,后面会详细写。

    模型

    1、训练

    对分解出来的趋势部分单独用arima模型做训练:

    def trend_model(self, order):

    self.trend.dropna(inplace=True)

    train = self.trend[:len(self.trend)-self.test_size]

    #arima的训练参数order =(p,d,q),具体意义查看官方文档,调参过程略。

    self.trend_model = ARIMA(train, order).fit(disp=-1, method='css')

    2、预测

    预测出趋势数据后,加上周期数据即作为最终的预测结果,但更重要的是,我们要得到的不是具体的值,而是一个合理区间,当真实数据超过了这个区间,则触发报警,误差高低区间的设定来自刚刚分解出来的残差residual数据:

    d = self.residual.describe()

    delta = d['75%'] - d['25%']

    self.low_error, self.high_error = (d['25%'] - 1 * delta, d['75%'] + 1 * delta)

    预测并完成最后的加法处理,得到第七天的预测值即高低置信区间:

    def predict_new(self):

    '''

    预测新数据

    '''

    #续接train,生成长度为n的时间索引,赋给预测序列

    n = self.test_size

    self.pred_time_index= pd.date_range(start=self.train.index[-1], periods=n+1, freq='1min')[1:]

    self.trend_pred= self.trend_model.forecast(n)[0]

    self.add_season()

    def add_season(self):

    '''

    为预测出的趋势数据添加周期数据和残差数据

    '''

    self.train_season = self.seasonal[:self.train_size]

    values = []

    low_conf_values = []

    high_conf_values = []

    for i, t in enumerate(self.pred_time_index):

    trend_part = self.trend_pred[i]

    # 相同时间点的周期数据均值

    season_part = self.train_season[

    self.train_season.index.time == t.time()

    ].mean()

    # 趋势 + 周期 + 误差界限

    predict = trend_part + season_part

    low_bound = trend_part + season_part + self.low_error

    high_bound = trend_part + season_part + self.high_error

    values.append(predict)

    low_conf_values.append(low_bound)

    high_conf_values.append(high_bound)

    # 得到预测值,误差上界和下界

    self.final_pred = pd.Series(values, index=self.pred_time_index, name='predict')

    self.low_conf = pd.Series(low_conf_values, index=self.pred_time_index, name='low_conf')

    self.high_conf = pd.Series(high_conf_values, index=self.pred_time_index, name='high_conf')

    3、评估:

    对第七天作出预测,评估的指标为均方根误差rmse,画图对比和真实值的差距:

    md = ModelDecomp(file=filename, test_size=1440)

    md.decomp(freq=1440)

    md.trend_model(order=(1, 1, 3)) # arima模型的参数order

    md.predict_new()

    pred = md.final_pred

    test = md.test

    plt.subplot(211)

    plt.plot(md.ts) # 平滑过的训练数据加未做处理的测试数据

    plt.title(filename.split('.')[0])

    plt.subplot(212)

    pred.plot(color='blue', label='Predict') # 预测值

    test.plot(color='red', label='Original') # 真实值

    md.low_conf.plot(color='grey', label='low') # 低置信区间

    md.high_conf.plot(color='grey', label='high') # 高置信区间

    plt.legend(loc='best')

    plt.title('RMSE: %.4f' % np.sqrt(sum((pred.values - test.values) ** 2) / test.size))

    plt.tight_layout()

    plt.show()

    预测结果

    可以看到,均方根误差462.8,相对于原始数据几千的量级,还是可以的。测试数据中的两个突变的点,也超过了置信区间,能准确报出来。

    结语

    前文提到不同的api形态差异巨大,本文只展示了一个。

    我在该项目中还接触了其他形态的序列,有的有明显的上升或下降趋势;有的开始比较平缓,后面开始增长... ...

    但是都属于典型的周期性时间序列,它的核心思想很简单:做好分解,做好预测结果的还原,和置信区间的设置,具体操作可根据具体业务逻辑做调整,祝大家建模愉快。

    文源网络,仅供学习之用,侵删。

    在学习Python的道路上肯定会遇见困难,别慌,我这里有一套学习资料,包含40+本电子书,800+个教学视频,涉及Python基础、爬虫、框架、数据分析、机器学习等,不怕你学不会!

    https://shimo.im/docs/JWCghr8prjCVCxxK/ 《Python学习资料》

    关注公众号【Python圈子】,优质文章每日送达。

    展开全文
  • 有的开始比较平缓,后面开始增长… … 但是都属于典型的周期性时间序列,它的核心思想很简单:做好分解,做好预测结果的还原,和置信区间的设置,具体操作可根据具体业务逻辑做调整,祝大家建模愉快。 原文链接: ...
  • 这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的...
  • 这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的...
  • 这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的...
  • 作者:黄天元,复旦大学博士在读,热爱数据科学与开源工具(R),致力于利用数据科学迅速积累行业经验优势和科学知识发现,涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识...时间序列有...
  • 时间序列如何更好地分析周期性

    千次阅读 2020-06-18 11:09:43
    事实上,时间序列周期性可分为三种: 第一种是符号周期性,它表示只有一个符号是周期性的,比如序列T = fbcnfkgbfops,只有f有周期性,它的周期是p= 4,可以用CONV方法检测; 第二种是部分周期性,它表示有一个以上...
  • 时间序列分析 电子工业出版社 提 纲 1.时间序列分析概述 2.时间序列数据的预处理 3....分析时间序列图,可以从运动的角度认识事物的本质,如几个时间序列之间的差别、一个较长时间序列周期性,...
  • 很多数据都具有周期性,比如客流量、支付 需要确定周期长短, 比如一周,一个月,结合STL分解 观察周期变化 2、缺点 没有考虑到节假日、突发事件情况 3、STL分解介绍 将时序图拆解为Trend+Sensoinnal+Residual...
  • 我们考虑一些时间序列,例如道路上的交通流量, > plot(T,X,type="l") > reg=lm(X~T) > abline(reg,col="red") 如果存在趋势,我们应该将其删除,然后处理残差 > Y=residuals(reg) > acf(Y...
  • R-时间序列-分解季节性时间序列

    千次阅读 2018-10-16 17:06:08
    1.季节性时间序列 包含:长期趋势Trend,季节趋势Seasonal,周期循环Circle,随机项Random 这里分解为相加模型X=T+S+C+R   在对时间序列进行分解之前,应该对序列进行检验:(下次写) 2.decompose()函数 将...
  • 文章目录读写特点写读基于Hash和Sorted Set实现(单键和范围查询)...场景:如何周期性地统计近万台设备的实时状态,包含设备ID、压力、温度、湿度、时间戳 时间序列:与发生时间相关的一组数据,没有严格的关系模型,
  • 对商业周期的分析需要提取时间序列周期性成分,该时间序列通常也受到诸如潜在趋势或噪声等其他因素的影响。本文介绍了一些在最近的文献中用于从给定系列中提取商业周期的方法。它基于Stock and Watson(1999)在...
  • 时间序列分析是一种动态数据处理的统计方法。...季节变动(S):是时间序列在一年内重复出现的周期性波动。循环波动©:是时间序列呈现出得非固定长度的周期性变动。随机因素(I):是时间序列中除去长期趋势、...
  • 1、现有一个时间序列,具有明显的周期性,如何计算这个具体的周期值呢? 二、基于python现有方法的思路 1、基于python中SARIMAX()方法,先给出限定性的seasonal_order参数,然后使用按照aic最小的标准寻找...
  • 我的同僚经济学家的“错误信念”,我们称之为轰动效应的“神话”,被显示出来:有关商业周期时间序列和预测的“神话”。 尽管从长远来看,我们都死了,但经济历史……记住。 “贸易周期”理论最终成为“商业周期...
  • 根据作者提出的能量关联度理论,探讨了多维时间序列周期分析问题,互能量关联度的计算及频率域上主要影响因素的提取,结合实例验证了理论和方法的可行
  • 经济时间序列的分析通常需要提取其周期性成分。这篇文章介绍了一些方法,可用于将时间序列分解为它们的不同部分。它基于《宏观经济学手册》中Stock和Watson(1999)关于商业周期的章节,但也介绍了一些较新的方法,...
  • facebook开源的prophet时间序列预测工具---识别多种周期性、趋势性(线性,logistic)、节假日效应,以及部分异常值
  • 时间序列分析 - ARMA, ARIMA, SARIMA

    千次阅读 2019-03-06 17:19:26
    ARIMA: 针对非平稳非周期性时间序列分析 SARIMA: 针对非平稳周期性时间序列分析。 【自协方差与自相关系数】 时间序列在t时刻记作Xt,在s时刻记作Xs,那么这两个时刻对应的时间序列的自协方差的计算公式为: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 555
精华内容 222
关键字:

周期性时间序列