实战:简单的基于周期因子的时间序列预测

前言

时间序列预测第一次尝试,效果很差劲hhhh,但总算是迈出了第一步。

思路

  1. 原excel的样子:
时间(单位:月)密度(只/笼)
2016/1/10.54
2016/2/10.21
…………
2016/12/10.1
2017/1/10.2
…………
2020/11/10.1
  1. 从excel中提取这两列表格,并转换为以年份为行,月份为列的表格:
    以2020年的数据作为真实值(truth)
123456789101112
2016
2017
……
2019
  1. 根据周期因子的方法求年均值,并在表格右侧新建一列
123456789101112year_avg
2016
2017
……
2019
  1. 将所有数据除以年均值
  2. 求每列(不同年份相同月份)的中位数,添加在最后一行,以年均值的中位数作为base
123456789101112year_avg
2016
2017
……
2019
中位数
  1. base*每一个月的中位数得到预测值(predict)添加在最后一行,并加入2020的数据
123456789101112year_avg
2016
2017
……
2019
中位数
predict
2020
  1. 用matplotlib画图一下
    结果如下:(差距很大。。)
    在这里插入图片描述

分析

我认为是数据体量太小(仅有三年数据)且每年的变化过大,周期性不明显所导致无法很准确的预测值。进一步来说,在数据小的情况下,又想要预测完整的数据,就更显得吃力,所以应该要通过已有的数据,预测未来一两个月的值,不要贪多。

  • 本人小白一个,如果大家有更好的见解或本人有什么失误之处,欢迎在评论区指出!

代码

import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd
import xlrd

matplotlib.rc("font",family='FangSong') # 解决matplotlib不能打印中文的问题

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] # p表示ρ,密度
        df.loc[i,'时间(单位:月)'] = xlrd.xldate.xldate_as_datetime(sheet.row_values(i)[0],0) # excel的时间转成datetime
        if p != '':
            df.loc[i,'密度(只/笼)'] = sheet.row_values(i)[1]
        else:
            df.loc[i, '密度(只/笼)'] = np.nan
    # print(df)
    return df

def rearrange(df):
    new_df = pd.DataFrame([])
    # print(new_df.loc[:,2016])
    j = 0
    k = 1
    for i in range(df.shape[0]):
        if k % 13 == 0: # 每隔12个月
            k = 1
            j += 1
        new_df.loc[k,2016+j] = df.loc[i+1,'密度(只/笼)']
        k+=1
    # print(new_df)
    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
    # print(df)
    return df

def getColumnMid(df):
    df.loc['中位数'] = df.median().T
    # print(df)
    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')
    # plt.show()
    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 # 尝试了只用中位数,只用平均数等别的方法找base

    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)


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值