前言
时间序列预测第一次尝试,效果很差劲hhhh,但总算是迈出了第一步。
思路
- 原excel的样子:
时间(单位:月) | 密度(只/笼) |
---|
2016/1/1 | 0.54 |
2016/2/1 | 0.21 |
…… | …… |
2016/12/1 | 0.1 |
2017/1/1 | 0.2 |
…… | …… |
2020/11/1 | 0.1 |
- 从excel中提取这两列表格,并转换为以年份为行,月份为列的表格:
以2020年的数据作为真实值(truth)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|
2016 | | | | | | | | | | | | |
2017 | | | | | | | | | | | | |
…… | | | | | | | | | | | | |
2019 | | | | | | | | | | | | |
- 根据周期因子的方法求年均值,并在表格右侧新建一列
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | year_avg |
---|
2016 | | | | | | | | | | | | | |
2017 | | | | | | | | | | | | | |
…… | | | | | | | | | | | | | |
2019 | | | | | | | | | | | | | |
- 将所有数据除以年均值
- 求每列(不同年份相同月份)的中位数,添加在最后一行,以年均值的中位数作为base
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | year_avg |
---|
2016 | | | | | | | | | | | | | |
2017 | | | | | | | | | | | | | |
…… | | | | | | | | | | | | | |
2019 | | | | | | | | | | | | | |
中位数 | | | | | | | | | | | | | |
- base*每一个月的中位数得到预测值(predict)添加在最后一行,并加入2020的数据
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | year_avg |
---|
2016 | | | | | | | | | | | | | |
2017 | | | | | | | | | | | | | |
…… | | | | | | | | | | | | | |
2019 | | | | | | | | | | | | | |
中位数 | | | | | | | | | | | | | |
predict | | | | | | | | | | | | | |
2020 | | | | | | | | | | | | | |
- 用matplotlib画图一下
结果如下:(差距很大。。)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210106091240519.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NreXd1dXU=,size_16,color_FFFFFF,t_70)
分析
我认为是数据体量太小(仅有三年数据)且每年的变化过大,周期性不明显所导致无法很准确的预测值。进一步来说,在数据小的情况下,又想要预测完整的数据,就更显得吃力,所以应该要通过已有的数据,预测未来一两个月的值,不要贪多。
- 本人小白一个,如果大家有更好的见解或本人有什么失误之处,欢迎在评论区指出!
代码
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd
import xlrd
matplotlib.rc("font",family='FangSong')
def readData(file_name,sheet_name,col_names):
work_book = xlrd.open_workbook(file_name)
sheet = work_book.sheet_by_name(sheet_name)
df = pd.DataFrame([], columns=sheet.row_values(col_names))
for i in range(col_names + 1, sheet.nrows):
p = sheet.row_values(i)[1]
df.loc[i,'时间(单位:月)'] = xlrd.xldate.xldate_as_datetime(sheet.row_values(i)[0],0)
if p != '':
df.loc[i,'密度(只/笼)'] = sheet.row_values(i)[1]
else:
df.loc[i, '密度(只/笼)'] = np.nan
return df
def rearrange(df):
new_df = pd.DataFrame([])
j = 0
k = 1
for i in range(df.shape[0]):
if k % 13 == 0:
k = 1
j += 1
new_df.loc[k,2016+j] = df.loc[i+1,'密度(只/笼)']
k+=1
return new_df
def getYearAvg(df):
for i in range(df.shape[0]):
df.loc[2016+i,'year_avg'] = np.sum(df.loc[2016+i])/12
return df
def getColumnMid(df):
df.loc['中位数'] = df.median().T
return df
def plot(df):
plt.title('苍蝇预测')
plt.xlabel('月份')
plt.ylabel('密度(只/笼)')
plt.plot(df.columns,df.loc['predict'],label='预测值')
plt.plot(df.columns,df.loc['truth'],label='2020(真实值)')
plt.legend(loc='upper right')
plt.show()
if __name__ == '__main__':
file_name = r'E:\汇总-蝇.xlsx'
sheet_name = r'汇总'
col_names = 0
df = readData(file_name,sheet_name,col_names)
new_df = rearrange(df)
new_df = new_df.T
plt.plot(new_df.columns, new_df.loc[2016], label='2016')
plt.plot(new_df.columns, new_df.loc[2017], label='2017')
plt.plot(new_df.columns, new_df.loc[2019], label='2019')
plt.legend(loc='upper right')
new_df = getYearAvg(new_df)
truth = new_df.loc[2020]
new_df = new_df.loc[:2019]
base = (np.median(new_df['year_avg'])+np.mean(new_df['year_avg']))/2
print(new_df)
for i in range(new_df.shape[0]):
for j in range(new_df.shape[1]):
if new_df.loc[2016+i,'year_avg']!= 0:
new_df.iloc[i,j]/=new_df.loc[2016+i,'year_avg']
new_df = getColumnMid(new_df)
print(new_df)
new_df.loc['predict'] = new_df.loc['中位数']*base
new_df.loc['truth'] = truth
new_df=new_df.drop(labels = 'year_avg',axis=1)
print(new_df)
plot(new_df)