美文网首页R炒面
83-预测分析-R语言实现-神经网络

83-预测分析-R语言实现-神经网络

作者: wonphen | 来源:发表于2020-10-14 13:16 被阅读0次
> library(pacman)
> p_load(dplyr, readxl, caret)

预测任务:利用建筑物的各种特性,例如表面积和屋顶面积,预测建筑物的能源效率,其中效率以供暖负荷和制冷负荷来表示。

1、读取数据

> enb <- read_xlsx("data_set/ENB2012_data.xlsx")
> 
> names(enb) <- c("relcompactness", "surfarea", "wallarea", "roofarea", "height", 
+                 "orientation", "glazarea", "glazareadist", "heatload", 
+                 "coolload")
> 
> DataExplorer::profile_missing(enb)
## # A tibble: 10 x 3
##    feature        num_missing pct_missing
##    <fct>                <int>       <dbl>
##  1 relcompactness           0           0
##  2 surfarea                 0           0
##  3 wallarea                 0           0
##  4 roofarea                 0           0
##  5 height                   0           0
##  6 orientation              0           0
##  7 glazarea                 0           0
##  8 glazareadist             0           0
##  9 heatload                 0           0
## 10 coolload                 0           0

数据集不存在缺失值。

2、转换为虚拟变量

orientation和glazareadist分别表示建筑朝向和玻璃面积分布情况,应该为因子型变量。

> enb <- mutate(enb, across(c(orientation, glazareadist), as.factor))
> 
> str(enb)
## tibble [768 × 10] (S3: tbl_df/tbl/data.frame)
##  $ relcompactness: num [1:768] 0.98 0.98 0.98 0.98 0.9 0.9 0.9 0.9 0.86 0.86 ...
##  $ surfarea      : num [1:768] 514 514 514 514 564 ...
##  $ wallarea      : num [1:768] 294 294 294 294 318 ...
##  $ roofarea      : num [1:768] 110 110 110 110 122 ...
##  $ height        : num [1:768] 7 7 7 7 7 7 7 7 7 7 ...
##  $ orientation   : Factor w/ 4 levels "2","3","4","5": 1 2 3 4 1 2 3 4 1 2 ...
##  $ glazarea      : num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist  : Factor w/ 6 levels "0","1","2","3",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ heatload      : num [1:768] 15.6 15.6 15.6 15.6 20.8 ...
##  $ coolload      : num [1:768] 21.3 21.3 21.3 21.3 28.3 ...

为了让神经网络能够处理这些因子变量,需要先将它们转换为虚拟变量。

> dum <- dummyVars(heatload + coolload ~ ., data = enb)
> enb.new <- predict(dum, newdata = enb) %>% 
+   as_tibble() %>% 
+   bind_cols(enb[, c(9, 10)])
> str(enb.new)
## tibble [768 × 18] (S3: tbl_df/tbl/data.frame)
##  $ relcompactness: num [1:768] 0.98 0.98 0.98 0.98 0.9 0.9 0.9 0.9 0.86 0.86 ...
##  $ surfarea      : num [1:768] 514 514 514 514 564 ...
##  $ wallarea      : num [1:768] 294 294 294 294 318 ...
##  $ roofarea      : num [1:768] 110 110 110 110 122 ...
##  $ height        : num [1:768] 7 7 7 7 7 7 7 7 7 7 ...
##  $ orientation.2 : num [1:768] 1 0 0 0 1 0 0 0 1 0 ...
##  $ orientation.3 : num [1:768] 0 1 0 0 0 1 0 0 0 1 ...
##  $ orientation.4 : num [1:768] 0 0 1 0 0 0 1 0 0 0 ...
##  $ orientation.5 : num [1:768] 0 0 0 1 0 0 0 1 0 0 ...
##  $ glazarea      : num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.0: num [1:768] 1 1 1 1 1 1 1 1 1 1 ...
##  $ glazareadist.1: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.2: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.3: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.4: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.5: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ heatload      : num [1:768] 15.6 15.6 15.6 15.6 20.8 ...
##  $ coolload      : num [1:768] 21.3 21.3 21.3 21.3 28.3 ...

3、标准化

在训练神经网络时,为防止饱和现象(因为当优化过程的误差函数的梯度绝对值变得非常小时,非线性神经元激活函数有非常大或非常小的输入,会导致优化过程认为已经达到收敛而终止),需要先对数据进行比例缩放,这样做同时有助于收敛。
将数据维度比例缩放到单位区间[-1, 1]。

> rng <- preProcess(enb.new, method = "range")
> enb.rng <- predict(rng, newdata = enb.new)
> 
> str(enb.rng)
## tibble [768 × 18] (S3: tbl_df/tbl/data.frame)
##  $ relcompactness: num [1:768] 1 1 1 1 0.778 ...
##  $ surfarea      : num [1:768] 0 0 0 0 0.167 ...
##  $ wallarea      : num [1:768] 0.286 0.286 0.286 0.286 0.429 ...
##  $ roofarea      : num [1:768] 0 0 0 0 0.111 ...
##  $ height        : num [1:768] 1 1 1 1 1 1 1 1 1 1 ...
##  $ orientation.2 : num [1:768] 1 0 0 0 1 0 0 0 1 0 ...
##  $ orientation.3 : num [1:768] 0 1 0 0 0 1 0 0 0 1 ...
##  $ orientation.4 : num [1:768] 0 0 1 0 0 0 1 0 0 0 ...
##  $ orientation.5 : num [1:768] 0 0 0 1 0 0 0 1 0 0 ...
##  $ glazarea      : num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.0: num [1:768] 1 1 1 1 1 1 1 1 1 1 ...
##  $ glazareadist.1: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.2: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.3: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.4: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glazareadist.5: num [1:768] 0 0 0 0 0 0 0 0 0 0 ...
##  $ heatload      : num [1:768] 0.257 0.257 0.257 0.257 0.4 ...
##  $ coolload      : num [1:768] 0.281 0.281 0.281 0.281 0.468 ...

4、拆分训练集和测试集

> set.seed(123)
> ind <- createDataPartition(enb.rng$coolload, p = 0.8, list = F)
> dtrain <- enb.rng[ind, ]
> dtest <- enb.rng[-ind, ]

5、建立神经网络模型

5.1 使用caret包训练

输出变量只选一个,heatload。(暂不清楚caret包能否同时训练两个因变量的模型,以及如何设置参数)

> set.seed(123)
> fit.neur <- train(form = heatload ~ ., method = "neuralnet", data = dtrain[, -18])

5.2 使用neuralnet包训练

输出变量有两个,heatload 和 coolload。10个隐藏层,激活函数选择logistic,误差函数选择sse,它对应的是误差平方和。linear.output = TRUE表示输出层的神经元不应用logistic激活函数,因为这是一个回归任务,需要得到线性的输出,否则输出就会被约束到[0, 1]之间。

> # 使用原始函数可以同时预测两个因变量
> f <- as.formula(paste0("heatload + coolload ~ ", 
+                        paste(names(dtrain)[1:(ncol(dtrain) - 2)],
+                              collapse = " + ")))
> neur <- neuralnet::neuralnet(f, data = dtrain, hidden = 10, 
+                              act.fct = "logistic", linear.output = T,
+                              err.fct = "sse", rep = 1)
> neur$response %>% head()
##    heatload  coolload
## 1 0.2572122 0.2809049
## 2 0.2572122 0.2809049
## 3 0.2572122 0.2809049
## 4 0.4165543 0.3899811
## 5 0.3963332 0.3840560
## 6 0.3685630 0.5036359

6、测试集上的性能

6.1 caret包

> test.pred <- predict(fit.neur, newdata = dtest[, -c(17:18)])
> cor(test.pred, dtest$heatload)
## [1] 0.9966901

预测值与实际值之间的相关性相当高。

6.2 neuralnet包

> test.hat <- predict(neur, newdata = dtest[, -c(17, 18)])
> 
> # 查看预测值与原始值之间的相关度
> cor(test.hat[, 1], dtest$heatload)
## [1] 0.9980793
> cor(test.hat[, 2], dtest$coolload)
## [1] 0.9936744

预测值与实际值之间的相关性非常高,说明模型的性能接近完美。

相关文章

网友评论

    本文标题:83-预测分析-R语言实现-神经网络

    本文链接:https://www.haomeiwen.com/subject/bmzipktx.html