利用机器学习方法对猪肉价格预测

猪肉价格预测

  1. 支持向量机回归
  2. 随机森林回归
  3. MLP神经网络回归

问题背景

“猪粮安天下”,生猪自古以来便在国计民生中占据着重要地位,猪肉是我国城乡居民“菜篮子”中不可或缺的产品。但从 2018 年非洲猪瘟爆发以来,生猪产业遭到巨大冲击,生猪市场价格波动频繁,不仅给养殖者造成巨大的经济损失,也给广大消费者造成了很大困扰。2020 年新冠肺炎疫情突袭,再次对逐步恢复的生猪产业产生一定不利影响。
(本文指标选取有待商榷,仅仅做着玩)

导入数据

# 安装库专用

# 通过如下命令设定镜像
options(repos = 'http://mirrors.ustc.edu.cn/CRAN/')
# 查看镜像是否修改
getOption('repos')
# 尝试下载R包
#若有需要,进行安装
#install.packages('h2o')

‘http://mirrors.ustc.edu.cn/CRAN/’

#设置工作路径
setwd("D:/LengPY")
#导入数据
library(readxl)
data<- read_excel("liudata.xlsx")
head(data)
A tibble: 6 × 11
日期活猪仔猪去骨牛肉带骨羊肉豆粕小麦麸玉米育肥猪综合饲料非洲猪瘟新冠疫情
<dttm><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><lgl><lgl>
2006-01-017.569.8918.6019.092.641.241.261.81NANA
2006-02-017.119.4818.6518.762.751.241.271.83NANA
2006-03-016.688.8518.3718.252.691.231.281.83NANA
2006-04-016.217.8218.3318.412.601.211.281.82NANA
2006-05-015.966.9818.3118.352.561.211.341.84NANA
2006-06-016.086.8418.3218.232.541.201.391.86NANA
data1<-data[,2:9]
head(data1)
A tibble: 6 × 8
活猪仔猪去骨牛肉带骨羊肉豆粕小麦麸玉米育肥猪综合饲料
<dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
7.569.8918.6019.092.641.241.261.81
7.119.4818.6518.762.751.241.271.83
6.688.8518.3718.252.691.231.281.83
6.217.8218.3318.412.601.211.281.82
5.966.9818.3118.352.561.211.341.84
6.086.8418.3218.232.541.201.391.86
## 可视化特征之间的相关系数
library(corrplot)
cor <- cor(data1)
corrplot.mixed(cor,tl.col="black",tl.pos = "lt",
               tl.cex = 0.8,number.cex = 0.7)

在这里插入图片描述

可根据相关系数结果,对变量相关性进行初步探索。

一、支持向量机

## 支持向量机回归模型
library(e1071)
library(caret)
library(Metrics)
library(readr)

system.time(
  svmreg <- svm(活猪~.,data =data1,kernel = "radial")
)
   user  system elapsed 
   0.02    0.00    0.02 
summary(svmreg)
Call:
svm(formula = 活猪 ~ ., data = data1, kernel = "radial")


Parameters:
   SVM-Type:  eps-regression 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.1428571 
    epsilon:  0.1 


Number of Support Vectors:  111
set.seed(123)
index <- sample(nrow(data1),round(0.7*nrow(data1)))
train_data <- data1[index,]
test_data <-data1[-index,]
#查看训练集维度
dim(train_data)
  1. 128
  2. 8
## 在训练集上的误差
train_pre <- predict(svmreg,train_data)
train_mae <- mae(train_data$活猪,train_pre)
sprintf("训练集上的绝对值误差: %f",train_mae)

‘训练集上的绝对值误差: 1.007821’

test_pre <- predict(svmreg,test_data)
test_mae <- mae(train_data$活猪,test_pre)
sprintf("测试集上的绝对值误差: %f",test_mae)

‘测试集上的绝对值误差: 6.022539’

data<-data.frame(train_data$活猪,train_pre)

预测j效果良好,测试集误差较大。

total_pre <- predict(svmreg,data1[2:8])
total_mae <- mse(data1$活猪,total_pre)
sprintf("全部上的绝对值误差: %f",total_mae)

‘全部上的绝对值误差: 1.651221’

输出对应预测结果:

data5<-data.frame(total_pre,data1$活猪)
colnames(data5)<-c('预测','实际')
data5
A data.frame: 183 × 2
预测实际
<dbl><dbl>
1 7.081429 7.56
2 7.326892 7.11
3 7.125876 6.68
4 6.871381 6.21
5 6.957324 5.96
6 7.221186 6.08
7 7.400246 6.47
8 7.658352 7.17
9 7.709680 7.84
10 7.599010 7.93
11 7.786543 8.33
12 8.612998 9.18
13 8.892967 9.55
14 9.065229 9.20
15 9.556271 8.91
16 9.566126 9.02
1710.18416510.20
1811.07995611.37
1912.17209313.12
2013.36289414.27
2114.09594113.60
2213.87140013.21
2314.40334314.13
.........
17134.9867935.93
17234.0710233.41
17334.4410729.50
17434.5429930.97
17533.6316735.73
17632.1018136.50
17729.4296535.20
17831.7515230.93
17932.8146429.23
18032.5977932.40
18129.8033635.17
18229.0178031.43
18329.5993227.90

二、随机森林

library(readr)
library(VIM)
library(rpart)
library(rpart.plot)
library(Metrics)
library(ROCR)
library(tidyr)
library(randomForest)
library(ggRandomForests)
set.seed(123)
index <- sample(nrow(data1),round(0.7*nrow(data1)))
train_data <- data1[index,]
test_data <-data1[-index,]

rfreg <- randomForest(活猪~.,data = train_data,ntree=500)
summary(rfreg)
                Length Class  Mode     
call              4    -none- call     
type              1    -none- character
predicted       128    -none- numeric  
mse             500    -none- numeric  
rsq             500    -none- numeric  
oob.times       128    -none- numeric  
importance        7    -none- numeric  
importanceSD      0    -none- NULL     
localImportance   0    -none- NULL     
proximity         0    -none- NULL     
ntree             1    -none- numeric  
mtry              1    -none- numeric  
forest           11    -none- list     
coefs             0    -none- NULL     
y               128    -none- numeric  
test              0    -none- NULL     
inbag             0    -none- NULL     
terms             3    terms  call     
## 可视化模型随着树的增加误差OOB的变化
par(family = "STKaiti")
plot(rfreg,type = "l",col = "red",main = "随机森林回归")

在这里插入图片描述

可发现,在trees数量 30时即可获得较好结果。

## 使用ggrandomforest包可视化误差
plot(gg_error(rfreg))+labs(title = "随机森林回归")

在这里插入图片描述

## 可视化变量的重要性
importance(rfreg)
A matrix: 7 × 1 of type dbl
IncNodePurity
仔猪1938.7910
去骨牛肉1623.8613
带骨羊肉1522.7004
豆粕 143.6410
小麦麸 517.8845
玉米 215.0726
育肥猪综合饲料 406.2389
varImpPlot(rfreg,pch = 20, main = "Importance of Variables")

在这里插入图片描述
#可发现仔猪、牛、羊肉对猪肉价格影响较大,因为互为替代品或前提(仔猪),故结果较为合理。

## 对测试集进行预测,并计算 Mean Squared Error
rfpre <- predict(rfreg,test_data)
sprintf("均方根误差为: %f",mse(test_data$活猪,rfpre))

‘均方根误差为: 1.646604’

## 参数搜索,寻找合适的 mtry参数,训练更好的模型
## Tune randomForest for the optimal mtry parameter
set.seed(1234)
rftune <- tuneRF(x = test_data[,2:8],y = test_data$活猪,
                 stepFactor=1.5,ntreeTry = 500)
mtry = 2  OOB error = 2.785136 
Searching left ...
Searching right ...
mtry = 3 	OOB error = 2.63388 
0.05430821 0.05 
mtry = 4 	OOB error = 2.531242 
0.03896842 0.05 

在这里插入图片描述

print(rftune)
  mtry OOBError
2    2 2.785136
3    3 2.633880
4    4 2.531242
## OOBError误差最小的mtry参数为6

## 建立优化后的随机森林回归模型
rfregbest <- randomForest(活猪~.,data = train_data,ntree=500,mtry = 6)

## 可视化两种模型随着树的增加误差OOB的变化
rfregerr <- as.data.frame(plot(rfreg))

在这里插入图片描述

colnames(rfregerr) <- "rfregerr"
rfregbesterr <- as.data.frame(plot(rfregbest))

在这里插入图片描述

colnames(rfregerr) <- "rfregerr"
rfregbesterr <- as.data.frame(plot(rfregbest))

在这里插入图片描述

colnames(rfregbesterr) <- "rfregbesterr"
plotrfdata <- cbind.data.frame(rfregerr,rfregbesterr)
plotrfdata$ntree <- 1:nrow(plotrfdata)
plotrfdata <- gather(plotrfdata,key = "Type",value = "Error",1:2)
ggplot(plotrfdata,aes(x = ntree,y = Error))+
  geom_line(aes(linetype = Type,colour = Type),size = 0.9)+
  theme(legend.position = "top")+
  ggtitle("随机森林回归模型")+
  theme(plot.title = element_text(hjust = 0.5))

在这里插入图片描述

## 使用优化后的随机森林回归模型,对测试集进行预测,并计算 Mean Squared Error
rfprebest <- predict(rfregbest,test_data[,2:8])
sprintf("优化后均方根误差为: %f",mse(test_data$活猪,rfprebest))

‘优化后均方根误差为: 1.660115’

## 使用优化后的随机森林回归模型,对测试集进行预测,并计算 Mean Squared Error
#全部数据
total <- predict(rfregbest,data1[,2:8])
sprintf("优化后均方根误差为: %f",mse(data1$活猪,total))

‘优化后均方根误差为: 0.773364’

#预测结果
totalpre<-data.frame(data1$活猪,total)
totalpre
<tr><th scope=row>172</th><td>33.41</td><td>33.70117</td></tr>
<tr><th scope=row>173</th><td>29.50</td><td>31.42532</td></tr>
<tr><th scope=row>174</th><td>30.97</td><td>32.10734</td></tr>
<tr><th scope=row>175</th><td>35.73</td><td>34.39926</td></tr>
<tr><th scope=row>176</th><td>36.50</td><td>35.47128</td></tr>
<tr><th scope=row>177</th><td>35.20</td><td>34.27110</td></tr>
<tr><th scope=row>178</th><td>30.93</td><td>32.03528</td></tr>
<tr><th scope=row>179</th><td>29.23</td><td>31.95318</td></tr>
<tr><th scope=row>180</th><td>32.40</td><td>32.44584</td></tr>
<tr><th scope=row>181</th><td>35.17</td><td>33.15130</td></tr>
<tr><th scope=row>182</th><td>31.43</td><td>32.34892</td></tr>
<tr><th scope=row>183</th><td>27.90</td><td>32.95256</td></tr>
A data.frame: 183 × 2
data1.活猪total
<dbl><dbl>
1 7.56 7.745717
2 7.11 7.473767
3 6.68 6.802603
4 6.21 6.484864
5 5.96 6.340616
6 6.08 6.334053
7 6.47 6.463621
8 7.17 7.035551
9 7.84 6.900711
10 7.93 6.985457
11 8.33 7.875041
12 9.18 9.065969
13 9.55 9.289838
14 9.20 9.244121
15 8.91 9.259116
16 9.02 9.250085
1710.20 9.805307
1811.3710.590388
1913.1213.012034
2014.2713.206428
2113.6013.403372
2213.2113.176563
2314.1313.715155
2415.4615.510558
## 数据准备
index <- order(test_data$活猪)
X <- sort(index)
Y1 <- test_data$活猪[index]
rfpre2 <- rfpre[index]
rfprebest2 <- rfprebest[index]

plotdata <- data.frame(X = X,Y1 = Y1,rfpre =rfpre2,rfprebest = rfprebest2)
plotdata <- gather(plotdata,key="model",value="value",c(-X))

## 可视化模型的预测误差
ggplot(plotdata,aes(x = X,y = value))+
  geom_line(aes(linetype = model,colour = model),size = 0.8)+
  theme(legend.position = c(0.1,0.8),
        plot.title = element_text(hjust = 0.5))+
  ggtitle("随机森林回归模型")

在这里插入图片描述

可发现预测结果良好,在猪瘟 时期价格预测偏差较大,可能 是未量化猪瘟i直接影响,故 可考虑进行改进。

三、 MLP神经网络

library(RSNNS)
set.seed(123)
index <- sample(nrow(data1),round(0.7*nrow(data1)))
train_data <- data1[index,]
test_data <-data1[-index,]
dim(train_data)

## 数据max-min归一化到0-1之间
data1[,2:8] <- normalizeData(data1[,2:8],"0_1")
## 猪肉价归一化到0-1之间,并获取归一化参数
price <- normalizeData(data1$活猪,type = "0_1")
NormParameters <- getNormParameters(price)

  1. 128
  2. 8
head(data1)
A tibble: 6 × 8
活猪仔猪去骨牛肉带骨羊肉豆粕小麦麸玉米育肥猪综合饲料
<dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
7.560.0299872190.00463548250.0133678310.23954370.073684210.0000000000.000000000
7.110.0259561500.00533782830.0086244070.28136880.073684210.0064516130.011049724
6.680.0197620690.00140469170.0012936610.25855510.063157890.0129032260.011049724
6.210.0096352370.00084281500.0035935030.22433460.042105260.0129032260.005524862
5.960.0013764620.00056187670.0027310620.20912550.042105260.0516129030.016574586
6.080.0000000000.00070234580.0010061810.20152090.031578950.0838709680.027624309
hist(price)

在这里插入图片描述

## 数据切分
set.seed(123)
datasplist <- splitForTrainingAndTest(data1[,2:8],price,
                                      ratio = 0.3)

## MLP回归模型
system.time(
mlpreg <- mlp(datasplist$inputsTrain,datasplist$targetsTrain,maxit = 200,
              size = c(100,50,100,50),learnFunc = "Rprop",
              inputsTest=datasplist$inputsTest,
              targetsTest = datasplist$targetsTest,
              metric = "RSME")
)
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"
Warning message in snnsObject$setUnitName(num, iNames[[i]]):
"SNNS error message in setUnitName : SNNS-Kernel Error: Symbol pattern invalid (must match [A-Za-z][^|, ]*)"



   user  system elapsed 
  13.86    0.00   14.25 
## 可视化模型的效果
plotIterativeError(mlpreg,main = "MLP Iterative Erro")

在这里插入图片描述

plotRegressionError(datasplist$targetsTrain,mlpreg$fitted.values,
                    main="MLP train fit")

在这里插入图片描述

plotRegressionError(datasplist$targetsTest,mlpreg$fittedTestValues,
                    main="MLP test fit")

在这里插入图片描述

## 在训练集上的误差
mlppre_train <- denormalizeData(mlpreg$fitted.values,NormParameters)
mlp_train <- denormalizeData(datasplist$targetsTrain,NormParameters)
train_mae <- mae(mlp_train,mlppre_train)
sprintf("训练集上的绝对值误差: %f",train_mae)

‘训练集上的绝对值误差: 0.456312’

mlppre_test <- denormalizeData(mlpreg$fittedTestValues,NormParameters)
mlp_test <- denormalizeData(datasplist$targetsTest,NormParameters)
test_mae <- mae(mlp_test,mlppre_test)
sprintf("测试集上的绝对值误差: %f",test_mae)

‘测试集上的绝对值误差: 6.967324’

测试集误差较大,需加以改进。

如对猪瘟及新冠疫情进行加入分析。结合RNN等方法,获得更精准结果。

  • 7
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值