-
周期性时间序列的预测
2018-08-17 18:00:00最近在研究时间序列的时候,发现很多序列具有很强的周期性,那如何对此类序列进行预测呢? 1 数据处理 挑选一个如下图的具有周期性的时间序列。该序列是取得是过去7天的数据,每小时一个点,一共7*24个点。 2 ...女主宣言
AIOps 从立项到现在已经半年有余,从最开始的 LVS 异常检测,到如今的实时关联分析,智能运维已经渗透到我们日常运维中的许多场景,之后我们会将积累的经验分享出来,供大家学习参考,本文最先发布于 OpsDev,转载已获取作者授权。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
At Tranquility Base, 1969
by NASA IOTD
最近在研究时间序列的时候,发现很多序列具有很强的周期性,那如何对此类序列进行预测呢?
1
数据处理
挑选一个如下图的具有周期性的时间序列。该序列是取得是过去7天的数据,每小时一个点,一共7*24个点。
2
划分数据集
我们取前六天的数据做训练,第七天做测试集。
3
平滑处理
时间序列经常会出现毛刺的点,需要做平滑处理才能分析,类似上图中的数据。消除数据的毛刺,可以用移动平均法,但是移动平均有时候处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充:
经过处理以后,上图的时间序列得到了平滑处理,效果如下图。
4
周期性分解
具有周期性特征的序列需要将周期性特征提取出来。python里面的statsmodels工具包里面有针对周期性分解的函数seasonal_decompose,我们可以将序列进行分解。seasonal_decompose这个函数里面有个two_sided的参数,默认是True。Trend处理的时候用到移动平均的方法,熟悉此方法的读者就会发现,经过该方法处理以后,序列收尾两段有一部分数据缺失了,但是如果该参数为FALSE,则只有开始的时候有一段缺失值。
图3中的第一张图是observed,体现的原始数据;第二张是trend,体现的是分解出来的趋势部分;第三张是seasonal,体现的是周期部分;最后是residual,体现的是残差部分。
本文采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?后面会有介绍。
5
预测
我们对trend部分进行预测,最后再加上seasonal部分。对trend的预测,我们采用ARIMA模型。熟悉该模型的都知道,需要确定三个参数p,q和d,可以使用aic和bic的方法进行定阶,可以查阅相关的文献。
得到模型以后,就可以进行预测。
下面是预测的结果,从图中可以看到预测的结果将周期性的特征完美地体现出来了。
6
评估
对第七天作出预测,评估的指标为均方根误差rmse,本序列的rmse小于5,效果还是不错的。
7
总结
本文介绍了周期性序列的预测方法,你可能会问并不是所有的序列都具有周期性,事实确实如此,接下来几篇博客,我会重点介绍周期性检测的一些方法。希望此博客对您研究时间序列有所帮助。
HULK一线技术杂谈
由360云平台团队打造的技术分享公众号,内容涉及云计算、数据库、大数据、监控、泛前端、自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享
-
CNN做时间序列预测_Python建模:预测周期性时间序列的正确姿势
2020-11-21 18:13:23日志会记录下每分钟某api被访问了多少次,即一个api每天会有...我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有...公司平台上有不同的api,供内部或外部调用,这些api承担着不同的功能,如查询账号、发版、抢红包等等。
日志会记录下每分钟某api被访问了多少次,即一个api每天会有1440条记录(1440分钟),将每天的数据连起来观察,有点类似于股票走势的意思。
我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,触发报警。
数据探索我放了一份样例数据在data文件夹下,看一下数据大小和结构。
data = pd.read_csv(filename)print('size: ',data.shape)print(data.head())
数据大小:
画图看一下序列的走势:(一些画图等探索类的方法放在了test_stationarity.py 文件中,包含时间序列图,移动平均图,有兴趣的可以自己尝试下)。
共10080条记录,即10080分钟,七天的数据。
字段含义:
date:时间,单位分钟
count:该分钟该api被访问的次数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、划分训练测试集
前六天的数据做训练,第七天做测试集。
2、对训练数据进行平滑处理消除数据的毛刺,可以用移动平均法,我这里没有采用,因为我试过发现对于我的数据来说,移动平均处理完后并不能使数据平滑,我这里采用的方法很简单,但效果还不错:把每个点与上一点的变化值作为一个新的序列,对这里边的异常值,也就是变化比较离谱的值剃掉,用前后数据的均值填充,注意可能会连续出现变化较大的点。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:]
平滑后的训练数据: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)
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()
分解图第一行observed:原始数据;第二行trend:分解出来的趋势部分;第三行seasonal:周期部分;最后residual:残差部分。我采用的是seasonal_decompose的加法模型进行的分解,即 observed = trend + seasonal + residual,另还有乘法模型。在建模的时候,只针对trend部分学习和预测,如何将trend的预测结果加工成合理的最终结果?当然是再做加法,后面会详细写。模型
1、训练
对分解出来的趋势部分单独用arima模型做训练:
2、预测预测出趋势数据后,加上周期数据即作为最终的预测结果,但更重要的是,我们要得到的不是具体的值,而是一个合理区间,当真实数据超过了这个区间,则触发报警,误差高低区间的设定来自刚刚分解出来的残差residual数据: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')
预测并完成最后的加法处理,得到第七天的预测值即高低置信区间:d = self.residual.describe()delta = d['75%'] - d['25%']self.low_error, self.high_error = (d['25%'] - 1 * delta, d['75%'] + 1 * delta)
3、评估:对第七天作出预测,评估的指标为均方根误差rmse,画图对比和真实值的差距: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')
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文源网络,仅供学习之用。如有侵权,联系删除。
往期精彩◆ 50款开源工具你都用过吗?
◆ python+C、C++混合编程的应用
◆ python网络爬虫的基本原理详解
◆ Python自动操控excel,一小时解决你一天的工作
◆ 如何用Python增强Excel,减少处理复杂数据的痛苦?
-
python时间序列预测不连续怎么办_Python建模:预测周期性时间序列的正确姿势
2020-12-03 18:25:54日志会记录下每分钟某api被访问了多少次,即一个...我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,...公司平台上有不同的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圈子】,优质文章每日送达。
-
python时间和周期_Python 预测[周期性时间序列]
2020-12-24 06:48:021、背景公司平台上有不同的api,供内部或外部调用,这些api...我想通过前N天的历史数据预测出第N+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,相对于原始数据几千的量级,还是可以的。测试数据中的两个突变的点,也超过了置信区间,能准确报出来。
-
基于周期因子的时间序列预测
2021-01-29 17:16:11一、基于周期因子的时间序列预测 1、场景 很多数据都具有周期性,比如客流量、支付 需要确定周期长短, 比如一周,一个月,结合STL分解 观察周期变化 2、缺点 没有考虑到节假日、突发事件情况 3、STL分解介绍... -
python 预测调用_用Python预测「周期性时间序列」的正确姿势
2020-12-11 11:31:08这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的... -
Python建模:预测周期性时间序列的正确姿势
2020-05-21 13:23:43我想通过前N天的历史数据预测出第N+1天的流量访问情况,预测值即作为合理参考,供新一天与真实值做实时对比。当真实流量跟预测值有较大出入,则认为有异常访问,触发报警。 数据探索 我放了一份样例数据在data文件夹... -
python短期预测图_用Python预测「周期性时间序列」的正确姿势
2020-12-16 19:10:38这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的... -
用Python预测「周期性时间序列」的正确姿势
2018-03-30 09:55:31这是当初刚进公司时,leader给的一个独立练手小项目,关于时间序列预测,情景比较简单,整个过程实现下来代码也仅100多行,但完成过程中踩了很多坑,觉的有必要分(tu)享(cao)一下。完整代码和样例数据放到了我的... -
时间序列预测算法总结
2018-10-18 10:30:48time series data mining 主要包括decompose(分析数据的各个成分,例如趋势,周期性),prediction(预测未来的值),classification(对有序数据序列的feature提取与分类),clustering(相似数列聚类)等。... -
天池 - 资金流入流出预测-基于周期因子的时间序列预测
2020-08-22 20:35:05之前接触的时间序列,一般是使用ARMA模型进行预测,基于周期因子的方法,是第一次接触到,经过两天的简单沉淀下学习心得: 1.使用前提:数据可以有周期性,但总体趋势需要相对平稳(时间从14年3月开始使用的原因) 2... -
时间序列预测_时间序列预测(EXCEL版)
2020-12-17 13:08:29葛大娘分享数分小技能人生路上持续成长■ 基本概念■(一)时间序列同一现象在不同时期的观察值排列而成的序列,如经济序列、人口序列,通过观测发展趋势、变化方向及速度等,建立预测模型。(二)乘法模型Yt为t时间内的... -
python有趋势的时间序列预测_用python做时间序列预测三:时间序列分解
2020-12-10 13:12:25在初始概念篇中,我们简单提到了时间序列由趋势、周期性、季节性、误差构成,本文将介绍如何将时间序列的这些成分分解出来。分解的使用场景有很多,比如当我们需要计算该时间序列是否具有季节性,或者我们要去除该... -
季节性ARIMA:时间序列预测
2019-02-17 15:22:36SARIMAX (seasonal autoregressive integrated moving average with exogenous regressor)是一种常见的时间序列预测方法,可以分为趋势部分和周期性部分;每个部分又可以分为自回归、差分和平滑部分。 趋势稳定性... -
facebook开源的prophet时间序列预测工具---识别多种周期性、趋势性(线性,logistic)、节假日效应,以及...
2020-10-09 10:06:32facebook开源的prophet时间序列预测工具---识别多种周期性、趋势性(线性,logistic)、节假日效应,以及部分异常值 -
时间序列预测方法总结
2020-10-18 15:14:52这本来是我回答的一个问题:有什么好的模型可以做高精度的时间序列预测呢? - BINGO Hong的回答 - 知乎 https://www.zhihu.com/question/21229371/answer/533770345 但觉得在那个答案下一直更新好麻烦,干脆就移到... -
统计学——时间序列预测
2019-02-15 10:43:12第13章 时间序列分析和预测 时间序列是同一现象在不同时间上的相继观测值排列而成的序列。本书中用t表示所观察的时间,Y表示观察值,则Yi( i =1, 2, …, n)为时间ti上的观察值。 时间序列可以分为平稳序列和非平稳... -
R语言ARIMA,SARIMA预测道路交通流量时间序列:季节性、周期性
2021-02-23 11:16:27我们考虑一些时间序列,例如道路上的交通流量, > plot(T,X,type="l") > reg=lm(X~T) > abline(reg,col="red") 如果存在趋势,我们应该将其删除,然后处理残差 > Y=residuals(reg) > acf(Y... -
用python做时间序列预测三:时间序列分解
2020-06-02 16:37:00在初始概念篇中,我们简单提到了时间序列由趋势、周期性、季节性、误差构成,本文将介绍如何将时间序列的这些成分分解出来。分解的使用场景有很多,比如当我们需要计算该时间序列是否具有季节性,或者我们要去除该... -
[python]时间序列预测
2019-02-22 19:25:21周期时间序列的预测 (有python代码) 具有周期性特征的序列需要将周期性特征提取出来。python里面的statsmodels工具包里面有针对周期性分解的函数seasonal_decompose,我们可以将序列进行分解。seasonal_... -
利用炮掘工作面瓦斯涌出时间序列预测工作面突出危险性
2020-04-23 23:12:05炮掘工作面瓦斯涌出是一个极为复杂的非线性时间序列,...发现不同突出危险区域,掘进工作面瓦斯涌出时间序列趋势项、周期项以及噪声项之间存在显著的差异,并利用这些差异成功地对考察巷道突出危险性进行了准确的预测。 -
论文研究 - 关于预测,商业周期和时间序列的神话使经济学家无法预测:在航运业中的应用
2020-05-31 12:55:10我的同僚经济学家的“错误信念”,我们称之为轰动效应的“神话”,被显示出来:有关商业周期,时间序列和预测的“神话”。 尽管从长远来看,我们都死了,但经济历史……记住。 “贸易周期”理论最终成为“商业周期... -
时间序列预测-传统统计学模型ARIMA
2021-02-03 23:53:36ARIMA单变量预测股价DEMO时间序列介绍:统计学模型-ARIMA介绍ARIMA 参数选择说明源...平稳时间序列是标准的严平稳时间序列,表示有着明显的周期性的序列数据,在整个序列中不存在“噪声”等,而现实的世界中大都是非平 -
acf看序列是否平稳_时间序列可预测性度量
2021-01-03 01:05:21关于时间序列是否可预测性的问题,之前零碎的思考过,现结合过往的项目经验,整理如下,抛砖引玉。先从简单易理解的入手。前言是否容易预测,不是能否预测的问题,而是是否可以精确预测。精确一词,用业界最常用的... -
论文研究-基于趋势点状态模型的时间序列预测算法.pdf
2019-07-22 22:30:07针对传统的时间序列线性预测算法对时间序列的线性程度要求高,而非线性方法一般建模复杂且计算量大,提出了一种基于趋势点状态模型...通过模拟实验,结果表明该算法性能良好,尤其对具有周期性的时间序列预测精度很高。 -
时间序列预测之Prophet
2021-01-21 20:28:35一、ARIMA进行预测的缺点 1、ARMA 要求时序数据是稳定的,显示数据很难符合 2、ARIMA 模型为线性模型,无法处理非线性的... 2、对yearly、weakly和daily的周期性使用非线性拟合,可以很好的对节日(比如十一、... -
论文研究-基于构造性神经网络的时间序列混合预测模型.pdf
2019-07-22 23:23:08针对传统时间序列预测模型不适应非线性预测而适应非线性预测的 BP算法存在收敛速度慢 ,且容易陷入局部极小等问题 ,提出一种基于构造性神经网络的时间序列混合预测模型。采用构造性神经网络模型 (覆盖算法 )得出的... -
【季节性预测法 - 时间序列分解法】利用excel进行复合型时间序列的分解预测
2019-05-27 17:47:17希望我整理的内容对路过的你有所...从上图可以明显看出,啤酒销售量具有明显季节成分,而且后面年份销量比前面年份高,因此其中含有趋势成分,但其周期性难以判断。可以认定啤酒销售量序列是一个含有季节性成分和趋...