├── 01.中间数据 ├── .gitattributes ├── 任务2-1 data_code.csv ├── 任务2-2 data_gp.csv └── 任务3-4 农产品预测价格结果.xlsx ├── 02.代码 ├── 任务2 数据预处理.py └── 任务3 模型构建及应用.py ├── 03.报告 └── 多种农产品价格智能预测.docx ├── Python多种农产品价格预测实训方案V3.0.2.pdf ├── README.md └── 数据 ├── .gitattributes ├── farming2.csv └── product_market.csv /01.中间数据/.gitattributes: -------------------------------------------------------------------------------- 1 | *.csv filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /01.中间数据/任务2-1 data_code.csv: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f1d18f5459623bb27302b09c7bf41edba9893245c80f32927159defb690e6d7 3 | size 113009 4 | -------------------------------------------------------------------------------- /01.中间数据/任务2-2 data_gp.csv: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0d26d66855795620fc17bbcc6b5d5f1509cc2ae7cec93e46f6973b05c0ff4168 3 | size 119507816 4 | -------------------------------------------------------------------------------- /01.中间数据/任务3-4 农产品预测价格结果.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MILU-YOU/Price-prediction/f94fc6a8f5261f2c6158bc4934ca5e00383e6385/01.中间数据/任务3-4 农产品预测价格结果.xlsx -------------------------------------------------------------------------------- /02.代码/任务2 数据预处理.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from pandas import to_datetime 4 | import matplotlib.pyplot as plt 5 | from scipy.interpolate import interp1d 6 | # 读取farming2.csv及product_market.csv文件 7 | data=pd.read_csv('C:\\Users\\LYF\\Desktop\\farming2.csv',encoding='gbk') 8 | data2=pd.read_csv('C:\\Users\\LYF\\Desktop\\product_market.csv') 9 | # 查看数据长度 10 | data.shape 11 | # 去除重复行 12 | data.drop_duplicates(subset=None, keep='first', inplace=True) 13 | # 查看去重后数据长度 14 | data.shape 15 | # 删除无关行 16 | data.drop(data.columns[[0,2,4,5,6,7,11]],axis=1,inplace=True) 17 | # 查看farming2.csv文件农产品映射值和市场名称映射值组合种类 18 | data_code=data.drop_duplicates(subset=data.columns[[0,1]], keep='first', inplace=False) 19 | data_code.shape 20 | # 查看product_market.csv文件农产品映射值和市场名称映射值组合种类 21 | data2_code=data2.drop_duplicates(subset=['农产品名称映射值','市场名称映射值'], keep='first', inplace=False) 22 | data2_code.shape 23 | #查找并导出相同农产品映射值 24 | #合并2个表中的组合种类 25 | datacd_sum=pd.concat([data_code,data2_code]) 26 | #保留了第一次出现的相同项和不同项 27 | datacd_same=datacd_sum.drop_duplicates(subset=['农产品名称映射值','市场名称映射值'],keep='first', inplace=False) 28 | datacd_same.shape 29 | #保留了不同项 30 | datacd_norepeat=datacd_sum.drop_duplicates(subset=['农产品名称映射值','市场名称映射值'],keep=False, inplace=False) 31 | datacd_norepeat.shape 32 | #相同+2*不同 33 | datacd_sum2=pd.concat([datacd_same,datacd_norepeat]) 34 | #相同+2*不同-2*不同 35 | data_cd=datacd_sum2.drop_duplicates(subset=['农产品名称映射值','市场名称映射值'],keep=False, inplace=False) 36 | data_cd.to_csv('C:\\Users\\LYF\\Desktop\\data_code.csv') 37 | #对多个同一时间的同一商品价格取平均,以平均值代替多组数据 38 | data_copy=data 39 | data_copy.groupby(['市场名称映射值','农产品名称映射值','数据发布时间'])[['平均交易价格','最高交易价格','最低交易价格']].mean() 40 | data_group=data_copy.groupby(['市场名称映射值','农产品名称映射值','数据发布时间'])[['平均交易价格','最高交易价格','最低交易价格']].mean() 41 | #平铺数据 42 | data_group=data_group.reset_index() 43 | #测试是否替换成功 44 | data.drop_duplicates(subset=['市场名称映射值','数据发布时间','农产品名称映射值'],keep='first',inplace=True) 45 | data.shape 46 | #若平均值为0,最高最低值不为0,将最高最低值取平均后填补平均值 47 | #选取数据取平均 48 | data_pj=data_group.loc[(data_group['平均交易价格'] == 0)& (data_group['最高交易价格']!= 0)&(data_group['最低交易价格']!= 0)] 49 | data_pj['平均交易价格']=(data_pj['最高交易价格']+data_pj['最低交易价格'])/2 50 | data_pj 51 | #与原数据合并,删除未填补的数据 52 | data_gpsum=pd.concat([data_pj,data_group]) 53 | data_gp=data_gpsum.drop_duplicates(subset=['市场名称映射值','数据发布时间','农产品名称映射值'],keep='first') 54 | data_gp 55 | #测试是否成功填充 56 | data_pjtext=data_gp.loc[(data_gp['平均交易价格'] == 0)& (data_gp['最高交易价格']!= 0)&(data_gp['最低交易价格']!= 0)] 57 | data_pjtext.shape 58 | #时间标准化 59 | data['数据发布时间']=pd.to_datetime(data['数据发布时间'],format="%Y/%m/%d ") 60 | #检测是否标准化成功 61 | data.dtypes 62 | -------------------------------------------------------------------------------- /02.代码/任务3 模型构建及应用.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | from sklearn import preprocessing 5 | from sklearn.model_selection import train_test_split 6 | 7 | 8 | pd.set_option('display.max_columns',1000) 9 | pd.set_option('display.width',1000) 10 | 11 | data1 = pd.read_csv('data_code.csv',encoding='gbk') # 导入data_code.csv文件 12 | data2 = pd.read_csv('data_gp.csv') # 导入data_gp.csv文件 13 | 14 | name = data1['农产品名称映射值'] 15 | loc = data1['市场名称映射值'] 16 | name = name.to_numpy() 17 | loc = loc.to_numpy() 18 | 19 | for k in range(name.size): 20 | data3 = data2.loc[data2['农产品名称映射值'] == name[k]] # 从data_gp.csv中找到需要预测的农产品的训练数据 21 | data3 = data3.loc[data3['市场名称映射值'] == loc[k]] 22 | data3 = pd.DataFrame.drop_duplicates(data3,subset='数据发布时间',keep='last') # 按时间去重 23 | data3 = data3.sort_values(by = '数据发布时间',ascending=True) # 按日期排序 24 | 25 | data3['数据发布时间'] = pd.to_datetime(data3['数据发布时间']) # 时间标准化 26 | x = data3['数据发布时间'].dt.day # 提取发布时间的日期 27 | y = data3['平均交易价格'] 28 | 29 | def unique_cols(df): # 判断平均价格是否一直保持不变 30 | a = df.to_numpy() 31 | return(a[0] == a[1:]).all(0) 32 | 33 | if unique_cols(y) == 1: # 如果是,则预测价格也保持不变 34 | y = y.to_numpy() 35 | y_pre = y[0] 36 | print(name[k],'产品预测价格为:',y_pre) 37 | print('*************************') 38 | 39 | else: # 不是则进行价格预测 40 | x = x.astype(float) 41 | y = y.astype(float) 42 | 43 | x1 = preprocessing.minmax_scale(x) 44 | y1 = preprocessing.minmax_scale(y) 45 | 46 | x1 = np.array(x1) # 将时间列转化为一维数组 47 | y1 = np.array(y1) # 平均交易价格设为y,并将该列转化为一维数组 48 | 49 | 50 | # 划分训练集和测试集 51 | x_train,x_test,y_train,y_test = train_test_split(x1,y1,test_size=0.2) 52 | 53 | # 模型训练 54 | def sigmoid(x): # 网络激活函数 55 | return 1/(1+np.exp(-x)) 56 | 57 | yita = 0.15 # 学习速率 58 | out_in = np.array([0.0,0,0,0,-1]) #输出层的输入 59 | w_mid = np.zeros([2,4]) #隐层神经元的权值&阈值 60 | w_out = np.zeros([5]) # 输出层神经元的权值&阈值 61 | delta_w_out = np.zeros([5]) 62 | delta_w_mid = np.zeros([2,4]) 63 | Err = [] 64 | for j in range(1000): 65 | error = [] 66 | for it in range(x_train.size): 67 | net_in = np.append(x_train[it], -1) # 网络输入 68 | real = y_train[it] 69 | 70 | for i in range(4): 71 | out_in[i] = sigmoid(sum(net_in * w_mid[:, i])) #从输入到隐层的传输过程 72 | 73 | res = sigmoid(sum(out_in * w_out)) # 模型预测值 74 | error.append(abs(real - res)) 75 | 76 | 77 | delta_w_out = yita*res*(1-res)*(real-res)*out_in # 输出层权值的修正量 78 | delta_w_out[4] = - yita*res*(1-res)*(real-res) # 输出层阈值的修正量 79 | w_out = w_out + delta_w_out # 更新 80 | 81 | for i in range(4): 82 | delta_w_mid[:, i] = yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res)*net_in # 中间层神经元的权值修正量 83 | delta_w_mid[1,i] = -yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res) #中间层神经元的阈值修正量 84 | w_mid = w_mid + delta_w_mid # 更新 85 | Err.append(np.mean(error)) # 计算平均误差 86 | 87 | # 代入测试集进行模型评估 88 | error_te = [] 89 | for it in range(x_test.size): 90 | net_in = np.append(x_test[it], -1) # 网络输入 91 | real = y_test[it] 92 | 93 | for i in range(4): 94 | out_in[i] = sigmoid(sum(net_in * w_mid[:, i])) # 从输入到隐层的传输过程 95 | 96 | res = sigmoid(sum(out_in * w_out)) # 模型预测值 97 | 98 | error_te.append(abs(real - res)) 99 | print('模型测试集平均误差为:',np.mean(error_te)) 100 | 101 | # 价格预测 102 | x_true = np.array(range(32)) 103 | x_true = x_true[1:32] 104 | x_true = preprocessing.minmax_scale(x_true) 105 | for it in range(31): 106 | net_in = np.append(x_true[it], -1) # 网络输入 107 | for i in range(4): 108 | out_in[i] = sigmoid(sum(net_in * w_mid[:, i])) #从输入到隐层的传输过程 109 | res = sigmoid(sum(out_in * w_out)) # 模型预测值 110 | y_pre = res * (y.max()-y.min())+y.min() #标准化还原 111 | print(name[k],'产品在',it+1,'号的预测价格为',y_pre) 112 | 113 | print('*************************') -------------------------------------------------------------------------------- /03.报告/多种农产品价格智能预测.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MILU-YOU/Price-prediction/f94fc6a8f5261f2c6158bc4934ca5e00383e6385/03.报告/多种农产品价格智能预测.docx -------------------------------------------------------------------------------- /Python多种农产品价格预测实训方案V3.0.2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MILU-YOU/Price-prediction/f94fc6a8f5261f2c6158bc4934ca5e00383e6385/Python多种农产品价格预测实训方案V3.0.2.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 多种农产品智能价格预测 2 | 3 | ## 项目介绍 4 | 该项目是利用python对历史所给农产品的数据进行预处理,分析及建模,并预测所选取的935种农产品价格。本项目主要涉及技术为利用 Pandas 库进行数据预处理,缺少值填充,利用sklearn 模块建模模型并预测。 5 | 6 | 这是泰迪工作室中的一个b级项目,可以用来作为数据分析的题目练练手。本人是用ANN进行建模的,平均误差大概在25%,效果并不是很理想。问题在于项目所给的历史数据有些农产品只有两三个月的数据,而有些农产品又有 7 | 好几年的数据,且多数农产品价格与时间的因果关系并不明显。这就造成我在模型选择上的犹豫,我想过利用长短期记忆网络来实现,但是该网络一般都需要有大量的历史数据, 8 | 起码是横跨一年的历史数据才能体现出价格在季节性上的变化趋势,并且还要保证时间序列的稳定性。显然所给的数据并不满足这种条件,所以我放弃了这种方法。 9 | 我又注意到题目要求预测的都是935种农产品中16年1月份每天的价格,所以我推测是用模型拟合每种农产品在一个月30天中价格的变化趋势。所以我把每种产品以往每个月的历史数据导入ANN中进行拟合,最终得到的结果就是 10 | 如果该农产品在一个月中价格变化有规律,那么模型就会尽量去拟合这种趋势,而价格的实际值大约是每个月该天价格的平均值。 11 | 12 | 因为是初次使用python和接触数据分析,代码上可能不够简介美观(比如ANN可以直接使用sklearn库里现有的,但本人是从头构建的),关注重点放在了模型建立上,而最终的结果个人并不是很满意,如果你也尝试去做这个项目或者有更好的意见建议,欢迎在issues中留言或者pull requests。 13 | -------------------------------------------------------------------------------- /数据/.gitattributes: -------------------------------------------------------------------------------- 1 | *.csv filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /数据/farming2.csv: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:335845ae4adf6dec8e7c18f72cb667185ad6079590ba8c95343d8e2123cc283e 3 | size 292349119 4 | -------------------------------------------------------------------------------- /数据/product_market.csv: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:995695df226751b6686d044db121d61e98ec8c9995c725c80dde05f94ea602f6 3 | size 4936757 4 | --------------------------------------------------------------------------------