标签:
从以往的时间序列值,进行指数平滑,做两次预测出下一个时间的估计值。
目录结构如下:
Python代码如下:
forecast.py
# -*-coding:utf-8 -*- # Time:2015.11.25 sangjin __author__ = ‘hunterhug‘ import matplotlib #matplotlib.use("Agg") #matplotlib.use("TkAgg") #matplotlib.use("gtk") import matplotlib.pyplot as plt from matplotlib.pyplot import savefig from matplotlib.font_manager import FontProperties from operator import itemgetter #读取execel使用(支持07) from openpyxl import Workbook #写入excel使用(支持07) from openpyxl import load_workbook import os def judgefile(): path = input("请输入该目录下的excel文件名:") # file path if os.path.isfile(path): return path.lower() else: print("文件不存在") return judgefile() def writeexcel07(path, content, name=‘Sheet1‘, sheetnum=0): wb=Workbook() #sheet=wb.add_sheet("xlwt3数据测试表") sheet=wb.create_sheet(sheetnum,name) # values = [["名称", "hadoop编程实战", "hbase编程实战", "lucene编程实战"], ["价格", "52.3", "45", "36"], ["出版社", "机械工业出版社", "人民邮电出版社", "华夏人民出版社"], ["中文版式", "中", "英", "英"]] for i in range(0,len(content)): for j in range(0,len(content[i])): sheet.cell(row = i+1,column= j+1).value = content[i][j] # sheet.cell(row = 1,column= 2).value="温度" wb.save(path) print("写入数据成功!") def read07excel(path): excelcontent = [] wb2=load_workbook(path) sheetnames = wb2.get_sheet_names() ws=wb2.get_sheet_by_name(sheetnames[0]) row=ws.get_highest_row() col=ws.get_highest_column() # print("列数: ",ws.get_highest_column()) # print("行数: ",ws.get_highest_row()) for i in range(0,row): rowcontent = [] for j in range(0,col): if ws.rows[i][j].value: rowcontent.append(ws.rows[i][j].value) excelcontent.append(rowcontent) print("读取数据成功!") return excelcontent def calvalue(excel, a): date = [] # x label date data = [] # y label data for i in range(2,len(excel)-1): data.append(float(excel[i][1])) date.append(excel[i][0]) e1 = [data[0]] # one time forecast for i in range(0,len(data)): next = data[i] * a + e1[i] * (1 - a) e1.append(next) e1e = [] # one time absoultion error for i in range(0,len(data)): e1e.append(abs(data[i]-e1[i])) e1e2 = sum(e1e) e2 = [data[0]] # second time forecast for i in range(0,len(data)): next = e1[i] * a + e2[i] * (1 - a) e2.append(next) e2e = [] # second time absoultion error for i in range(0,len(data)): e2e.append(abs(data[i]-e2[i])) e2e2 = sum(e2e) e1y = e1[len(e1)-1] # one time forecast value e2y = e2[len(e2)-1] # two time forecast value return [a, e1y, e2y, e1e2, e2e2] def calvaluetop5(excel, step = 0.01): initvalue = 1.0 all = [] top5 =[] while initvalue <= 1.0 and initvalue >= 0: all.append(calvalue(excel, initvalue)) initvalue = initvalue -step d = {} for i in range(0, len(all)): d.setdefault(i, all[i][3]) d1 = sorted(d.items(), key=itemgetter(1)) #print(d1) topnum = len(d1) if topnum>=5: topnum = 5 else: pass for i in range(0,topnum): pos = d1[i][0] top5.append(all[pos]) return top5 def judgestep(): try: a = float(input("请选择系数变化步长(范围0~1):")) # change var except: print("请输入数字好么...") return judgestep() while a > 1 or a < 0: print(‘输入的步长范围在0-1之间‘) return judgestep() return a def judge(): try: a = float(input("请输入变化系数a:")) # change var except: print("请输入数字好么...") return judge() while a > 1 or a < 0: print(‘输入的变化系数范围在0-1之间‘) return judge() return a def single(a,path): excel = read07excel(path) title1 = excel[0][0] title2 = excel[1] # print(excel) title = ‘:‘.join(excel[0]) date = [] # x label date data = [] # y label data for i in range(2,len(excel)-1): data.append(float(excel[i][1])) date.append(excel[i][0]) # print(‘/n‘,data) # print(title,data,date) e1 = [data[0]] # one time forecast for i in range(0,len(data)): next = data[i] * a + e1[i] * (1 - a) e1.append(next) # print(‘/n‘,e1) e1e = [] # one time absoultion error for i in range(0,len(data)): e1e.append(abs(data[i]-e1[i])) # print(‘/n‘,e1e) ele2 = sum(e1e) # print(ele2) e2 = [data[0]] # second time forecast for i in range(0,len(data)): next = e1[i] * a + e2[i] * (1 - a) e2.append(next) # print(‘/n‘,e2) e2e = [] # second time absoultion error for i in range(0,len(data)): e2e.append(abs(data[i]-e2[i])) # print(‘/n‘,e2e) e2e2 = sum(e2e) # print(e2e2) e1y = e1[len(e1)-1] # one time forecast value e2y = e2[len(e2)-1] # two time forecast value content = [[title1,‘可变系数a=‘,a]] content.append([title2[0],title2[1],‘一次指数平滑预测值‘,‘绝对误差‘,‘二次指数平滑‘,‘绝对误差‘]) datas = [date, data, e1[:len(e1)-1], e1e, e2[:len(e2)-1], e2e] datast = [[r[col] for r in datas] for col in range(len(datas[0]))] content[len(content):] = datast yu1 = [‘‘, e2y, e1y, ele2, e2y, e2e2] yu2 = [‘‘, ‘最终预测值‘, ‘一次指数平滑预测值‘, ‘一次指数平滑绝对误差累加‘, ‘二次指数平滑预测值‘, ‘一次指数平滑绝对误差累加‘] content.append(yu1) content.append(yu2) content.append([‘说明:请手动插入走势图。此文件为自动计算生成‘]) # print(content) path1 =path.replace(‘.xlsx‘, ‘(结果生成).xlsx‘) writeexcel07(path1, content, ‘生成表‘) print("请打开所在目录生成的excel文件(结果生成)") plt.close(‘all‘) font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14) plt.figure(figsize=(10,7)) num = range(0,len(date)) plt.plot(num, data, ‘b-*‘, label=‘原始数据‘) plt.plot(num, e1[:len(e1)-1], ‘r*-‘, label=‘一次指数预测‘) plt.plot(num, e2[:len(e2)-1], ‘g*-‘, label=‘二次指数预测‘) bottomtitle1 = ‘\n一次预测值:‘+str(e1y)+"\t误差和:"+str(ele2) bottomtitle = bottomtitle1 + ‘\n二次预测值:‘+str(e2y)+"\t误差和:"+str(e2e2) plt.title(‘指数平滑法预测走势图(时间序列)变化系数a={0:3f}‘.format(a)+bottomtitle, fontproperties=font) # simfang.ttf # plt.text(0, 0, bottomtitle, fontproperties=font) plt.xlabel(‘时间间隔‘, fontproperties=font) plt.ylabel(‘成交额‘, fontproperties=font) legend = plt.legend(loc=‘upper right‘, prop=font) # legend = plt.legend(loc=‘upper right‘, shadow=True, prop=font) legend.get_frame().set_facecolor(‘white‘) plt.grid(True) # Tweak spacing to prevent clipping of ylabel plt.subplots_adjust(left=0.15) plt.show() savefig(‘Fig.png‘) def begin(): sangjin = ‘‘‘ ----------------------------------------- | 欢迎使用二次指数平滑法预测未来值 | | | | 使用方法: | | 1.根据提示进行操作 | | 2.输出为预测走势图,以及处理后的excel | ----------------------------------------- | 青木公司花名:桑槿 | | 新浪微博:一只尼玛 | | 微信/QQ:569929309 | ----------------------------------------- ‘‘‘ print(sangjin) def loop(path): choice1 = input("自动计算变化系数请选择y,手动请选择n\n") if choice1 == ‘y‘: step = judgestep() p5 = calvaluetop5(read07excel(path), step) print(‘总误差最小的前五个是‘) for i in p5: print(‘变化系数:{0:3f}\t预测值:{1:3f}\t总误差值:{2:3f}‘.format(i[0],i[2],i[4])) single(p5[0][0],path) else: a = judge() single(a,path) def loop3(path): choice2 = input("如果想操作其他文件请选择y,退出选择n,其他操作按任意键\n") if choice2 == ‘y‘: loop1() elif choice2 == ‘n‘: print("正在退出中...\n"*6) print("正在退出中...谢谢") exit(1) else: loop(path) loop3(path) def loop1(): path = judgefile() loop(path) loop3(path) begin() loop1()
输入excel格式如下:
输出结果:
代码参考:
标签:
原文地址:http://www.cnblogs.com/nima/p/5001727.html