项目名称:用时间序列模型"prphet"预测全国各农产品价格

  • 客户需求

根据全国往年各农产品数据预测其未来1年内的的价格走势
数据来源:全国农产品价格数据库
网址:http://nc.mofcom.gov.cn/channel/jghq2017/index.shtml
获取方法:python 爬虫

  • 步骤1 数据抽取

以2019年8月为结束时间,选取宽度为2年的时间段作为分析观测窗口,抽取观测窗口内所有有记录的农产品价格信息形成历史数据,对于后续新增的客户详细信息,以后需新增数据中的最新时间点为结束时间,采用上述同样方法进行抽取,形成增量数据。

从全国农产品价格数据库提取数据,抽取2014年2月10日至2019年4月8日内所有农产品的详细数据。总共有2,406,171条详细数据。其中包括了记录ID(主键)、信息录入时间、产品名称、产品分类ID、价格、报价市场、页码
共获得2018年的1月至2019年8月共175万余条数据,数据来源为全国各大水果批发市场
提取字段、爬虫采集时间、批发市场ID共9条属性 分别为:
在这里插入图片描述

  • 步骤2 数据探索分析+属性规约

原数据中属性太多,根据 时间序列预测模型prophet 选择与prophet指标相关的三个属性:cai_product(产品名称)
cai_price(产品价格),cai_date(信息录入时间)
本案例的探索分析是对数据进行缺失值分析与异常值分析,分析出数据的规律以及异常值。通过对数据观察发现原始数据中并无空值或异常值 查找各属性观测值中空值个数、最大值、最小值的python代码及结果如下图所示:

表1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过对数据的观察发现原始数据中并无空值,也无异常值,cai_price的最大值来自 澳洲龙虾 为760元/公斤。

  • 步骤3模型构建
    Prophet 的输入量往往是一个包含两列的数据框:ds 和 y 。ds 列必须包含日期(YYYY-MM-DD)或者是具体的时间点(YYYY-MM-DD HH:MM:SS)。 y 列必须是数值变量,表示我们希望去预测的量。
    通过查询可知cai_product 共323个品类 [‘大米’, ‘玉米’, ‘大豆’, ‘国光苹果’, ‘花生油’, '面粉’]……我们需要依次对各品类进行时间序列预测共计生成323个表。首先提取323个品类名称保存到csv文件中

代码如下

import pymysql
import csv
import pandas as pd
list01=[]
coon = pymysql.connect(
     host = 'localhost',user = 'root',passwd = 'root',
     port = 3306,db = 'weifang',charset = 'utf8'
     #port必须写int类型
     #charset必须写utf8,不能写utf-8
   )
cur = coon.cursor()  #建立游标
cur.execute("select distinct cai_product from mofcom_price")  #查询数据
res = cur.fetchall()    #获取结果
#res=list(res)
#这里res将每一个查询结果用元组的形式保存在一个大的元组里面我们需要把他们提取出来
for i in res:

    list01.append(i[0])

print(list01) #这个list就包含了所有作物的名称
#即使你创建的dataframe只有一列 columns也要用列表形式而不能是name='cai_product'
name=['cai_product']
test=pd.DataFrame(columns=name,data=list01)
test.to_csv('/Users/bing/Desktop/dami/cai_product.csv',encoding='GBK')
cur.close()     #关闭游标
coon.close()    #关闭连接

结果如下
在这里插入图片描述
目前所有品类信息都保存在cai_product.csv 文件里了

接下来我尝试了另一种连接数据库的尝试——sqlalchemy 与pymysql不同的是sqlalchemy,tuple在表示一行很难看出表的结构。如果把一个tuple用class实例来表示,就可以更容易地看出表的结构来:sqlalchemy相较于我们刚才所使用的pymysql方法优点在于此处

import pandas as pd
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from pandas.core.frame import DataFrame
from fbprophet import Prophet
from pandas.plotting import register_matplotlib_converters
list02=[]
list03=[]
dic={}
#读取用sql提取出来的所有cai_product品类都有哪些
data11 = pd.read_csv('/Users/bing/Desktop/dami/cai_product.csv')

#这里用了循环语句 for ii in data11[“cai_product”]:即把我们刚才得到的323个品类每一类都执行一次下面的预测操作

for ii in data11['cai_product']:
    #选中所有代码然后按tab键可以整行缩进
    engine = create_engine('mysql+pymysql://root:root@localhost/weifang')
    DBSession = sessionmaker(bind=engine)
    session = DBSession()
    Base = declarative_base()

    class product(Base):
        __tablename__ = 'mofcom_price'
        #告诉程序我都需要哪些内容
        id = Column(Integer, primary_key=True)
        cai_product = Column(String(50))
        cai_date = Column(String(100))
        cai_price= Column(String(100))
    my_product = session.query(product).filter_by(cai_product =ii).order_by(product.id).all()
    for i in my_product:
        b = i.cai_price.index("元/公斤")
        c = i.cai_price[:b]
        c = float(c)
        list02.append(i.cai_date)
        list03.append(c)

    dic={'ds':list02,"y":list03}

    data=pd.DataFrame(dic)
    print(data.tail())
  1. 拟合模型
    m = Prophet()
    m.fit(data)
    预测过程则需要建立在包含日期 ds 列的数据框基础上。通过使用辅助的方法 Prophet.make_future_dataframe 来将未来的日期扩展指定的天数,得到一个合规的数据框。默认情况下,这样做会自动包含历史数据的日期,因此我们也可以用来查看模型对于历史数据的拟合效果。

  2. 构建待预测日期数据框,periods = 365 代表除历史数据的日期外再往后推 365 天
    future = m.make_future_dataframe(periods=365)
    future.tail()
    predict 方法将会对每一行未来 future 日期得到一个预测值(称为 yhat )。如果你传入了历史数据的日期,它将会提供样本的模型拟合值。预测 forecast 创建的对象应当是一个新的数据框,其中包含一列预测值 yhat ,以及成分的分析和置信区间。
    在此案例中我们将预测到2020年3月30号

  3. 预测数据集
    forecast = m.predict(future)
    forecast[[‘ds’, ‘yhat’, ‘yhat_lower’, ‘yhat_upper’]].tail()

    def main():
        m = Prophet()
        m.fit(data)
        future = m.make_future_dataframe(periods=365)
        print(future.tail())

        forecast = m.predict(future)
        print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
        print(type(forecast))
        #register_matplotlib_converters()
        #fig1 = m.plot(forecast)
        #fig1.show()
        #fig2 = m.plot_components(forecast)
        #fig2.show()
        #将结果保存到csv文件中去
        forecast.to_csv('/Users/bing/Desktop/dami/forecast'+ii+'.csv')
        #name_attribute = ['ds', 'yhat', 'yhat_lower', 'yhat_upper']
        #writerCSV = pd.DataFrame(columns=name_attribute, data=forecast['ds', 'yhat', 'yhat_lower', 'yhat_upper'])
        #writerCSV.to_csv('/Users/bing/Desktop/no_fre.csv', encoding='utf-8')




    main()

    session.commit()
    session.close()

最终将预测结果以csv文件的形式保存
最终共得到323个csv文件

打开一个白梨的预测结果 长这样 最后的yhat即为预测值,可以看到在2020年4月7日,预测其售价为9.8075247元/公斤
在这里插入图片描述在这里插入图片描述

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值