(图片来自百度)

数据

分析数据第一步还是套路------画图

数据看上去比较平整,但是由于数据太对看不出具体情况,于是将只取前300个数据再此画图

这数据看上去很不错,感觉有隐藏周期的意思

代码

#coding:utf-8
import csv
import matplotlib.pyplot as plt def read_csv_data(aim_list_1, aim_list_2, file_name):
i = 0
csv_file = csv.reader(open(file_name,'r'))
for data in csv_file:
if (i == 0):
i += 1
continue
aim_list_1.append(float(data[1]))
aim_list_2.append(data[3])
return
def plot_picture(x, y):
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x, y)
plt.show()
return
if __name__ == '__main__':
temp = []
tim = []
file_name = 'C:/Users/lichaoxing/Desktop/testdata.csv'
read_csv_data(temp, tim, file_name)
plot_picture(tim[:300], temp[:300])

使用ARIMA模型(ARMA)

第一步观察数据是否是平稳序列,通过上图可以看出是平稳的

如果不平稳,则需要进行预处理,方法有   对数变换    差分

对于平稳的时间序列可以直接使用ARMA(p, q)模型进行拟合

ARMA (p, q) :  AR(p) + MA(q)

此时参数p和q的确定可以通过观察ACF和PACF图来确定

通过观察PACF图可以看出,阶数为9也就是p=9,这里ACF图看出自相关呈现震荡下降收敛,但是怎么决定出q,我没太明白,这里姑且拍脑袋才一个吧就q=3

但是这里我遇到了一个问题,没有搞懂,就是平稳的序列,如果我进行一阶差分后应该仍然是平稳的序列,但是这个时候我又画了一个ACF与PACF图,竟然是下图这样,lag的范围是-0.04到0.04(不懂)


lag的范围是-0.04到0.04的问题原因(修改于再次使用此模型)

原因:

当时,我使用的是一阶差分,也就是让数据的后一个值减去前一个值得到新的值,这样就会导致第一个值变为缺失值(下面的数据是再此使用此模型时的数据,与原博客数据无关)

就是因为此处的值为缺失值,导致绘制ACF与PACF时数据有问题而无法成功显示

解决办法,在绘制上述图形前,将第一个数据去除:

dta= dta.diff(1)
dta = dta.truncate(before= ym[1])#删除第一个缺失值

其实还有就是使用ADF检验,得到的结果如图,这个p值很小===》平稳

画图代码

def acf_pacf(temp, tim):
x = tim
y = temp
dta = pd.Series(y, index = pd.to_datetime(x))
fig = plt.figure(figsize=(9,6))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(dta,lags=50,ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(dta,lags=50,ax=ax2)
show()

ADF检验代码

def test_stationarity(timeseries):
dftest = adfuller(timeseries, autolag='AIC')
return dftest[1]

这里先使用ARMA(9,3)来实验测试一下效果,取前300个数据中的前250个作为train,后面的作为test

效果

可以说这个模型是真的强大,预测的还是十分准确的

代码

def test_300(temp, tim):

    x = tim[0:300]
y = temp[0:300]
dta = pd.Series(y[0:249], index = pd.to_datetime(x[0:249])) fig = plt.figure(figsize=(9,6))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(dta,lags=30,ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(dta,lags=30,ax=ax2) arma_mod = sm.tsa.ARMA(dta, (9, 3)).fit(disp = 0) predict_sunspots = arma_mod.predict(x[200], x[299], dynamic=True) fig, ax = plt.subplots(figsize=(9, 6))
ax = dta.ix[x[0]:].plot(ax=ax)
predict_sunspots.plot(ax=ax) show()

其实,可以通过代码来自动的选择p和q的值,依据BIC准则,目标就是bic越小越好

代码

def proper_model(timeseries, maxLag):
init_bic = 100000000
init_properModel = None
for p in np.arange(maxLag):
for q in np.arange(maxLag):
model = ARMA(timeseries, order=(p, q))
try:
results_ARMA = model.fit(disp = 0, method='css')
except:
continue
bic = results_ARMA.bic
if bic < init_bic:
init_properModel = results_ARMA
init_bic = bic
return init_properModel

遇到的问题,预测时predict函数没怎么使用明白

当写于某些预测区间的时候,会报 “start”或“end”的相关错误,还有一个函数forcast,这个函数使用就是forcast(N):预测后面N个值

返回的是预测值(array型)标准误差(array型)置信区间(array型)

还有:

对于构造时间序列,时间可以是时间格式:如 “2018-01-01”  或者就是个时间戳,在用时间戳的时候,其实在序列里它会自动识别时间戳,并加上起始时间1970-01-01 00:00:01

形式

附录(代码)

预测一序列中某一点的值

#coding:utf-8
import csv
import time
import pandas as pd
import numpy as np
from statsmodels.tsa.arima_model import ARMA
import argparse
import warnings warnings.filterwarnings('ignore')
def timestamp_datatime(value):
value = time.localtime(value)
dt = time.strftime('%Y-%m-%d %H:%M',value)
return dt def time_timestamp(my_date):
my_date_array = time.strptime(my_date,'%Y-%m-%d %H:%M')
my_date_stamp = time.mktime(my_date_array)
return my_date_stamp def read_csv_data(aim_list_1, aim_list_2, file_name):
i = 0
csv_file = csv.reader(open(file_name,'r'))
for data in csv_file:
if (i == 0):
i += 1
continue
aim_list_1.append(float(data[1])) #1:温度 2:湿度
dt = int(data[3])
aim_list_2.append(dt)
return def proper_model(timeseries, maxLag):
init_bic = 100000000
init_properModel = None
for p in np.arange(maxLag):
for q in np.arange(maxLag):
model = ARMA(timeseries, order=(p, q)) #bug
try:
results_ARMA = model.fit(disp = 0, method='css')
except:
continue
bic = results_ARMA.bic
if bic < init_bic:
init_properModel = results_ARMA
init_bic = bic
return init_properModel def test_300(temp, tim, time_in): x = []
y = []
end_index = len(tim)
for i in range(0, len(tim)):
if (time_in - (tim[i]) < 300):
end_index = i
break
if (end_index < 100):
x = tim[0: end_index]
y = temp[0: end_index]
else:
x = tim[end_index - 100: end_index]
y = temp[end_index - 100: end_index] tidx = pd.DatetimeIndex(x, freq='infer')
dta = pd.Series(y, index = tidx)
print(dta)
arma_mod = proper_model(dta, 9) predict_sunspots = arma_mod.forecast(1)
return predict_sunspots[0]
def predict_temperature(file_name, time_in): temp = []
tim = []
read_csv_data(temp, tim, file_name) result_temp = test_300(temp, tim, time_in) return result_temp
if __name__ == '__main__': parser = argparse.ArgumentParser()
parser.add_argument('-f', action='store', dest='file_name')
parser.add_argument('-t', action='store', type = int, dest='time_') args = parser.parse_args()
file_name = args.file_name
time_in = args.time_ result_temp = predict_temperature(file_name, time_in) print ('the temperature is %f ' % result_temp)

在上面的代码中,预测某一点的值我采用序列中此点的前100个点作为训练集

如果给出待预测的多个点,由于每次都要计算模型的p和q以及拟合模型,时间会很慢,于是考虑将给定的待预测时间点序列切割成小段,使每一段中最大与最小的时间间隔在某一范围内

在使用forcast(n)函数一次预测多点,然后在预测值中找到与待预测的时间值相近的值,速度大大提升,思路如图

代码

#coding:utf-8
import csv
#import time
import pandas as pd
import numpy as np
from statsmodels.tsa.arima_model import ARMA
import warnings warnings.filterwarnings('ignore') def proper_model(timeseries, maxLag):
init_bic = 1000000000
init_p = 1
init_q = 1
for p in np.arange(maxLag):
for q in np.arange(maxLag):
model = ARMA(timeseries, order=(p, q))
try:
results_ARMA = model.fit(disp = 0, method='css')
except:
continue
bic = results_ARMA.bic
if bic < init_bic:
init_p = p
init_q = q
init_bic = bic
return init_p, init_q def read_csv_data(file_name, clss = 1):
i = 0
aim_list_1 = [] #temperature(1) or humidity(2)
aim_list_2 = [] #time
csv_file = csv.reader(open(file_name,'r'))
for data in csv_file:
if (i == 0):
i += 1
continue
aim_list_1.append(float(data[clss]))
dt = int(data[3])
aim_list_2.append(dt) tidx = pd.DatetimeIndex(aim_list_2, freq = None)
dta = pd.Series(aim_list_1, index = tidx)
init_p, init_q = proper_model(dta[:aim_list_2[100]], 9)
return init_p, init_q, aim_list_2, dta def for_kernel(p, q, tim, dta, tmp_time_list, result_dict):
interval = 20
end_index = len(tim) - 1
for i in range(0, len(tim)):
if (tmp_time_list[0]["time"] - tim[i] < tim[1] - tim[0]):
end_index = i
break if (end_index < 100):
dta = dta.truncate(after = tim[end_index])
else:
dta = dta.truncate(before= tim[end_index - 101], after = tim[end_index]) arma_mod = ARMA(dta, order=(p, q)).fit(disp = 0, method='css')
#为未来interval天进行预测, 返回预测结果, 标准误差, 和置信区间
predict_sunspots = arma_mod.forecast(interval)
####################################
for tim_i in tmp_time_list:
for tim_ in tim:
if tim_i["time"] - tim_ >= 0 and tim_i["time"] - tim_ < tim[1] - tim[0]:
result_dict[tim_i["time"]] = predict_sunspots[0][tim.index(tim_) - end_index]
return def kernel(p, q, tim, dta, time_in_list):
interval = 20
time_first = time_in_list[0]
det_time = tim[1] - tim[0]
result_dict = {}
tmp_time_list = []
for time_ in time_in_list:
if time_first["time"] + det_time * interval > time_["time"]:
tmp_time_list.append(time_)
continue time_first = time_
for_kernel(p, q, tim, dta, tmp_time_list, result_dict)
tmp_time_list = []
tmp_time_list.append(time_first) for_kernel(p, q, tim, dta, tmp_time_list, result_dict) return result_dict def predict_temperature(file_name, time_in_list, clss = 1):
p, q, tim, dta = read_csv_data(file_name, clss) result_temp_dict = kernel(p, q, tim, dta, time_in_list) return result_temp_dict def predict_humidity(file_name, time_in_list, clss = 2):
p, q, tim, dta = read_csv_data(file_name, clss)
result_humi_dict = kernel(p, q, tim, dta, time_in_list) return result_humi_dict if __name__ == '__main__': file_name = "testdata.csv"
time_in = [{"time":1530419271,"temp":"","humi":""},{"time":1530600187,"temp":"","humi":""},{"time":1530825809,"temp":"","humi":""}] #time_in = [{"time":1530600187,"temp":"","humi":""},]
result_temp = predict_temperature(file_name, time_in)
print(result_temp)

由于后续又改动了需求,需要预测温度以及湿度,完成了项目在github

https://github.com/xinglicha0/armamodel


ARIMA模型---时间序列分析---温度预测的更多相关文章

  1. 【机器学习笔记之五】用ARIMA模型做需求预测用ARIMA模型做需求预测

    本文结构: 时间序列分析? 什么是ARIMA? ARIMA数学模型? input,output 是什么? 怎么用?-代码实例 常见问题? 时间序列分析? 时间序列,就是按时间顺序排列的,随时间变化的数 ...

  2. 时间序列分析工具箱—— h2o + timetk

    目录 时间序列分析工具箱-- h2o + timetk h2o 的用途 加载包 安装 h2o 加载包 数据 教程:h2o + timetk,时间序列机器学习 时间序列机器学习 最终的胜利者是... 翻 ...

  3. ARIMA模型——本质上是error和t-?时刻数据差分的线性模型!!!如果数据序列是非平稳的,并存在一定的增长或下降趋势,则需要对数据进行差分处理!ARIMA(p,d,q)称为差分自回归移动平均模型,AR是自回归, p为自回归项; MA为移动平均,q为移动平均项数,d为时间序列成为平稳时所做的差分次数

    https://www.cnblogs.com/bradleon/p/6827109.html 文章里写得非常好,需详细看.尤其是arima的举例! 可以看到:ARIMA本质上是error和t-?时刻 ...

  4. 时间序列分析工具箱——timetk

    目录 时间序列分析工具箱--timetk timetk 的主要用途 加载包 数据 timetk 教程: PART 1:时间序列机器学习 PART 2:转换 翻译自<Demo Week: Time ...

  5. 【R实践】时间序列分析之ARIMA模型预测___R篇

    时间序列分析之ARIMA模型预测__R篇 之前一直用SAS做ARIMA模型预测,今天尝试用了一下R,发现灵活度更高,结果输出也更直观.现在记录一下如何用R分析ARIMA模型. 1. 处理数据 1.1. ...

  6. 用R做时间序列分析之ARIMA模型预测

    昨天刚刚把导入数据弄好,今天迫不及待试试怎么做预测,网上找的帖子跟着弄的. 第一步.对原始数据进行分析 一.ARIMA预测时间序列 指数平滑法对于预测来说是非常有帮助的,而且它对时间序列上面连续的值之 ...

  7. 时间序列模式——ARIMA模型

    ARIMA模型全称为自回归积分滑动平均模型(Autoregressive Integrated Moving Average Model,简记ARIMA),是由博克思(Box)和詹金斯(Jenkins ...

  8. [python] 时间序列分析之ARIMA

    1 时间序列与时间序列分析 在生产和科学研究中,对某一个或者一组变量  进行观察测量,将在一系列时刻  所得到的离散数字组成的序列集合,称之为时间序列. 时间序列分析是根据系统观察得到的时间序列数据, ...

  9. 时间序列预测之--ARIMA模型

    什么是 ARIMA模型 ARIMA模型的全称叫做自回归移动平均模型,全称是(ARIMA, Autoregressive Integrated Moving Average Model).也记作ARIM ...

随机推荐

  1. OOM之类、对象、实例、实体之辨析

    一.场景再现         有一个重要的概念你需要弄明白,那就是“类(class)”和“对象(object)”的区别.我用禅语来解释一下吧:         鱼和三文鱼有什么区别?         ...

  2. d 属性: 赋予字段执行动作的能力

    1.对只读属性误解 property AppSetting: ISuperobject read fAppSetting;当看到 AppInfo.AppSetting.D['lastLat'] := ...

  3. SRS服务器搭建,ffmpeg 本地推流,srs从本地拉流

    参考: https://github.com/ossrs/srs/wiki/v2_CN_SampleFFMPEG git clone https://github.com/ossrs/srs cd s ...

  4. 不断更新的 ToDo-List

    有些事情要明着写出来才会去干. 这里是一个不断更新的 ToDo-List,大致按照重要度和列出时间排序,已经完成的会画上删除线. 主要着眼短期计划,其中的大部分事务应该在一周内解决,争取不做一只鸽子. ...

  5. LOJ 3043: 洛谷 P5280: 「ZJOI2019」线段树

    题目传送门:LOJ #3043. 题意简述: 你需要模拟线段树的懒标记过程. 初始时有一棵什么标记都没有的 \(n\) 阶线段树. 每次修改会把当前所有的线段树复制一份,然后对于这些线段树实行一次区间 ...

  6. Python算法:推导、递归和规约

    Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心 ...

  7. awk对列/行进行统计求和【转】

    场景]--类似于excel中的sum函数对列/行进行统计求和 A01 A02 A03 A09 [要求1]--对列进行统计求和 A01 A02 A03 A09 TOTAL [要求2]--对行进行统计求和 ...

  8. HTML学习笔记06-连接

    HTML超链接 HTML使用标签<a>来设置文本超链接. 超链接可以是文字,也可以是图片,点击这些内容跳转到新的文档或当前文档的某个部分 代码类似这样: <a href=" ...

  9. 『转载』hadoop 1.X到2.X的变化

    表1新旧hadoop脚本/变量/位置变化表 改变项 原框架中 新框架中(Yarn) 备注 配置文件位置 ${hadoop_home_dir}/conf ${hadoop_home_dir}/etc/h ...

  10. ajax post 传参数加引号和不加引号的区别

    1.前言 用ajax技术,type:post,data:参数列表.参数列表就是一个JSON数据,但key可以加引号,也可以不加引号,那总有区别的. 2.区别 var d2 = "two&qu ...