美文网首页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