Learn R | 機器學習中的人工神經網路(七)
一、概率分割值與模型應用
在二分類的問題中,B-P演算法給出的是預測不同類別的概率,一般情況下,我們默認大於0.5為一類,小於0.5為另一類,但這並非適用於所有的情況(在上面的例子中就幾乎沒有大於0.5的觀測),所以,我們需要在確認預測模型合理的基礎上根據概率值和實際類別找到一個恰當的概率分割值,並為後續的類別預測提供概率依據。尋找合適的概率分割值最簡便的方法就是繪製ROC曲線。
關於ROC曲線的內容,之前我們已經在文章機器學習中的分類器評價中有過詳細介紹與R應用,這裡不再過多展開,直接應用於購物決策模型。
> library(ROCR)n# 查看預測概率值得分布情況n> summary(BP_model$net.result[[1]])n V1 n Min. :0.1724463 n 1st Qu.:0.1831697 n Median :0.4483683 n Mean :0.3758625 n 3rd Qu.:0.4483692 n Max. :0.8009425 n
> BP_model_pred <- ROCR::prediction(predictions = as.vector(BP_model$net.result),labels = BP_model$response)n
# 計算標準ROC曲線n> perf_1 <- performance(BP_model_pred,measure = "tpr",x.measure = "fpr")n# 計算在不同的概率分割值下的精度值n> perf_2 <- performance(BP_model_pred,measure = acc)n> par(mfrow=c(1,2))n> plot(perf_1,colorize=TRUE,print.cutoffs.at=c(0.2,0.3,0.46))n> plot(perf_2)n
從圖中可以看到,分割值在0.3附近時的總體預測精度較高(相對於其他預測值而言),因此選用0.3來查看模型的預測效果
# 合併實際值與概率值n> BP_model_out <- cbind(BP_model$response,BP_model$net.result[[1]])n# 以前面所選取的0.46為分割值n> BP_model_out <- cbind(BP_model_out,ifelse(BP_model_out[,2]>0.3,1,0))n> confm_BP <- table(BP_model_out[,1],BP_model_out[,3])n# 查看預測情況n> confm_BPn n 0 1n 0 110 159n 1 26 136n# 精度的混淆矩陣計算n> model_accuracy <- sum(diag(confm_BP))/sum(confm_BP)n> model_accuracyn[1] 0.5707656613n
最終的預測精度為0.57,從實際應用的角度來看這並不是一個很理想的結果,並且造成這個問題的原因有很多種:有可能是輸入變數較少,且年齡變數並不是很重要;也有可能是樣本量存在較大的不平衡性等等。
二、B-P反向傳播網路演算法的R實現(下)
除了nerualnet包外,nnet包也可實現傳統B-P反向傳播網路的分類與回歸預測,nnet函數所對應的是三層網路結構,其中輸入節點個數等於輸入變數個數,網路結構中只包含一個隱層,隱節點個數需要自行制定。在輸出節點上,二分類與回歸問題的輸出節點個性為1,多分類問題的輸出節點個數等於輸出變數的類別數,函數調用公式如下:
> library(nnet)n> nnet(formula, data, size, linout = FALSE, entropy = FALSE, softmax = FALSE,n+ maxit = 100, abstol = 1.0e-4,rang=, ...)n# size:指定隱節點的個數,若為0,則表示沒有隱層n# linout:指定輸出節點的激活函數是否為非線性函數(FALSE),等同於neuralnet函數中的linear.output參數n# entropy:用於指定損失函數是否採用交互熵,默認值FALSE表示損失函數採用誤差平方和的形式n# maxit:用於指定迭代停止條件(默認值為100)n# asstol:用於指定迭代終止條件(默認權重的最大調整量小於0.0001時終止)n# rang:初始權值設置n
nnet函數同樣是返回一個包含眾多計算結果的列表,主要包括:
- wts:各個節點的連接權重
- value:迭代結束時的損失函數值
- fitted.values:各觀測值的預測值
接下來我們使用iris數據集進行實例應用
# 由於iris的三個類別是依次排放的,所以分別選取三個類別中的一半數據,另一半數據用於預測n> samp <- c(sample(1:50,25), sample(51:100,25), sample(101:150,25))n> iris_BP_model <- nnet(Species ~.,data=iris,subset=samp,size=2,n+ decay=5e-4,maxit=200,rang=0.1)n# weights: 19ninitial value 82.454757 niter 10 value 5.023250niter 20 value 1.704374niter 30 value 1.363625niter 40 value 1.034265niter 50 value 0.836535niter 60 value 0.663559niter 70 value 0.508247niter 80 value 0.458844niter 90 value 0.454878niter 100 value 0.452772niter 110 value 0.451688niter 120 value 0.451637niter 130 value 0.451611niter 140 value 0.451608niter 150 value 0.451604nfinal value 0.451603 nconvergedn
# 查看各節點的連接權重n> iris_BP_model$wtsn [1] -13.5998052 -1.8310668 -3.0578977 4.6411105 6.1645348 -0.4407630n [7] -0.7275046 -1.6887599 2.8663385 1.2836032 5.6841556 -2.0217133n[13] -8.0278244 -2.1551987 -10.3863178 8.9266475 -3.5287213 12.4070827n[19] -0.8983970n
# 查看各觀測點的預測概率n> head(iris_BP_model$fitted.values)n setosa versicolor virginican47 0.9994819 0.0004160316 0.0001020329n50 0.9994715 0.0004255016 0.0001030025n25 0.9993477 0.0005386196 0.0001137282n26 0.9993965 0.0004938045 0.0001096519n12 0.9994443 0.0004502070 0.0001054746n23 0.9994978 0.0004016601 0.0001005366n
# 對另一半數據進行預測n> iris_pred_table <- table(iris$Species[-samp], predict(iris_BP_model, n+ iris[-samp,], type = "class"))n> iris_pred_tablen n setosa versicolor virginican setosa 25 0 0n versicolor 0 24 1n virginica 0 4 21n> model_accuracy <- sum(diag(iris_pred_table))/sum(iris_pred_table)n> model_accuracyn[1] 0.9333333n
以上就是nnet函數的簡單應用,與nerualnet函數相比,nnet有著兩個主要優勢:
- predict函數可直接對nnet對象進行預測
- 當輸出變數為多分類值時,只需定義為因子,nnet函數就可進行多分類的預測(輸出概率值);若不定義為因子,nnet將按回歸預測處理
References:
- R語言數據挖掘 (豆瓣)
- 機器學習 (豆瓣)
- Package 『neuralnet』
- nnet package | R Documentation
- First nerualnet in R
- 機器學習_R與神經網路之Neuralnet包 - BI咖啡館
推薦閱讀:
※PolYamoR的簡介:Python和R之間的雙向翻譯器
※R|數據處理|list的轉化與轉置
※R語言金融波動率建模|基於SGED分布的變參數ARIMA+EARCH動態預測模型的研究
※【Kaggle實例分析】Titanic Machine Learning from Disaster
※乾貨--線性回歸模型與CART樹的比較