2015年1月11日 星期日

[R] 類神經網絡(neural network)套件實作


        最近很認真的K了Coursera上的machine learning課程,才稍微了解類神經網路(neural network)的運作原理(但是要自己implement演算法什麼的還是離我太遙遠).不過我的精神就是,雖然沒吃過豬肉,好歹也要去看看豬走路吧.而且類神經網路是近年很流行的deep learning的基礎,瞭解一下不吃虧的.
        類神經網絡(http://zh.wikipedia.org/wiki/人工神经网络)的原理是基於模仿人類神經元的連結方式,演算法則是類似logistic regression以及gradient descent(http://bryannotes.blogspot.tw/2014/11/algorithm-stochastic-gradient.html)的方式,利用machine learning的方式找到最佳係數.

        類神經網路分為輸入層(也就是自變項),隱藏層,以及輸出層(應變項)(請見本文大圖),類神經網絡透過節點的組合以及變項之間的權重來找到自變項與應變項之間的關係,進而達到預測的效果.雖然還無法自己寫出演算法,但是總得要會使用別人開發好的XD,以下是範例code:

library(DMwR)
library(nnet)
#範例使用irisdata
data(iris)
#將變項標準化(應變項就不用標準化了XD)
norm_iris <- cbind(Speccies=iris[,5],as.data.frame(scale(iris[,1:4])))
##分別實驗和測試組
set.seed(123)
sample_size=floor(0.7*nrow(iris))
train_ind <- sample(seq_len(nrow(iris)),size = sample_size)
train <- iris[train_ind,]
test <- iris[-train_ind,]
#套套件 size表示中間層要用幾個node, decay是regulization變數
model_nnet <- nnet(Species ~.
, linout = F, size = 3, decay = 0.001
, maxit = 1000, trace = T, data = train)
'''執行後會開始顯示收斂的過程,這邊的value是指SSE,為預測變項與實際變項之間的誤差距離
# weights: 27
initial value 121.313587
iter 10 value 52.827014
iter 20 value 4.824411
iter 30 value 2.359499
iter 40 value 2.070575
iter 50 value 1.986760
iter 60 value 1.972826
iter 70 value 1.956358
iter 80 value 1.933991
iter 90 value 1.920895
iter 100 value 1.901409
iter 110 value 1.865177
iter 120 value 1.839828
iter 130 value 1.823218
iter 140 value 1.820475
final value 1.819114
converged
'''
#將model套到test組
pre_model <- predict(model_nnet, test, type = 'class')
#看一下預測結果
table(pre_model, test$Species)
#看來只有一個預測錯誤
#pre_model setosa versicolor virginica
# setosa 12 0 0
# versicolor 0 16 0
# virginica 0 1 16
summary(model_nnet)
#這個結果代表每個節點之間的權重值(請搭配本文大圖服用)
#a 4-3-3 network with 27 weights
#options were - softmax modelling decay=0.001
# b->h1 i1->h1 i2->h1 i3->h1 i4->h1
# -0.35 -0.74 -1.58 2.78 1.34
# b->h2 i1->h2 i2->h2 i3->h2 i4->h2
#-15.08 -6.88 -6.53 12.13 9.97
# b->h3 i1->h3 i2->h3 i3->h3 i4->h3
# 0.15 0.70 0.50 0.17 0.01
# b->o1 h1->o1 h2->o1 h3->o1
# 3.11 -7.81 -3.20 3.06
# b->o2 h1->o2 h2->o2 h3->o2
# -0.75 9.74 -14.05 -0.72
# b->o3 h1->o3 h2->o3 h3->o3
# -2.36 -1.94 17.25 -2.34
#畫圖
plot.nnet(model_nnet, wts.only = F)
#只顯示權重
plot.nnet(model_nnet, wts.only = T)
更多參考資料
'''
neural network package
http://www.di.fc.ul.pt/~jpn/r/neuralnets/neuralnets.html
visualization
https://beckmw.wordpress.com/tag/nnet/
'''
view raw nnet.R hosted with ❤ by GitHub



4 則留言:

  1. 感謝分享~!
    有個問題想要請問一下
    類神經網路要怎麼樣才能去估計他的結果是否overfitting呢?

    回覆刪除
    回覆
    1. 從數學上的作法就是在loss function中加入penalty, 也就是regularization參數去控制
      http://www.mathworks.com/help/nnet/ug/improve-neural-network-generalization-and-avoid-overfitting.html

      但是實務上可能還是需要配合trail and error的方式去看怎樣的模型效果比較好~

      刪除
  2. 請問Spark MLlib 有類神經網路相關的嗎?我目前沒看到
    http://spark.apache.org/docs/latest/mllib-guide.html

    回覆刪除
    回覆
    1. 還沒有放上spark的套件,但是已經有人在做了
      https://github.com/amplab/SparkNet

      刪除