机器学习识别乳腺癌
簡介
人工神經網絡是一種類似于大腦神經突觸連接的結構進行信息處理的數學模型,由大量的輸入層節點、隱藏層節點和輸出層節點連接構成。有關神經網絡算法最核心的三個問題就是:選擇激活函數、隱藏層數目和節點的確定以及權重的設置。
- 其中最為常用的是Logistic激活函數、雙曲正切激活函數和高斯激活函數,R中一般默認使用Logistic激活函數。通常情況下,激活函數的輸出信號值范圍可以是(0,1)、(-1,1)、(-∞,∞),而輸入信號之和的范圍可以是(-∞,∞),如果仔細看圖的話,會發現隨著輸入信號之和的絕對值越大,輸出信號值始終為0或1或-1,這樣的結果將會失真。所以一般需要將輸入信號X變量壓縮到0附近,通常的做法是數據標準化,以下自定義標準化函數:
前一種是最大最小標準化,后一種是標準正態化。如果數據集基本服從正態分布的話,可以考慮使用后一種標注化方法;否則就使用前一種標準化方法。
選擇隱藏層數目和節點數量
如上文中的神經網絡圖所示,只有1層隱藏層,稱其為單層網絡,單層網絡一般可用于基本的模式分類,特別是可用于能夠線性分割的模式,但實際中往往需要更多的隱藏層,目前多層前饋網絡已成為人工神經網絡拓撲結構的事實標準。多層隱藏層的神經網絡圖:除了隱藏層數目可以改動,其每層的節點數量也可以靈活的改變,對于節點數量的選擇可以通過循環測試,最終挑選出比較理想的節點數量。
一般情況下,隨著隱藏層數目和節點數量的增加,使神經網絡顯得尤為復雜,實現復雜問題的學習,但是這樣的模型會產生過擬合的風險,而且計算量的增加導致訓練緩慢。權重的設置
通過調整連接權重訓練神經網絡模型的計算量非常巨大,因此很少將其應用到真實世界的學習任務中。幸運的是,一種有效的訓練人工神經網絡的方法被發現,其可以解決權重的設置的問題,該算法使用了一種后向傳播誤差的策略(Backpropagation)。
神經網絡算法優缺點
- 優點:
1)適用于分類和數值預測問題
2)對數據幾乎不作任何假設條件 - 缺點:
1)計算量大、訓練緩慢,尤其是網絡拓撲結構相當復雜時
2)容易發生過擬合
3)輸出結果很難解釋
有關R中神經網絡算法的實現可以使用自帶的nnet包,也可以使用neuralnet包,還可以使用一套完整的神經網絡功能包RSNNS。
nnet包中的函數nnet()語法: nnet(formula, data, weights, ...,subset, na.action, contrasts = NULL)nnet(x, y, weights, size, Wts, mask,linout = FALSE, entropy = FALSE, softmax = FALSE,censored = FALSE, skip = FALSE, rang = 0.7, decay = 0,maxit = 100, Hess = FALSE, trace = TRUE, MaxNWts = 1000,abstol = 1.0e-4, reltol = 1.0e-8, ...) formula:模型的公式表達形式,類似于y~x1+x2+x3 data:指定要分析的數據對象 weights:代表各類樣本在模型中所占比重,默認將各類樣本按原始比重建立模型 subset:可提取目標數據集的子集作為模型的訓練樣本 na.action:處理缺失值的方法,默認忽略缺失值 x:為輸入的自變量矩陣或數據框 y:為輸入的因變量,但必須經過class.ind()函數的預處理 size指定隱藏層節點個數,通常為輸入變量個數的1.2至1.5倍 Wts:設置初始的權重,默認情況將隨機產生權重值 mask:指定哪個參數需要最優化,默認全部參數都需要最優化 linout:指定線性輸出還是Logistic輸出,默認為Logistic輸出 rang:設置初始權重值的范圍[-rang,rang] decay:指模型建立過程中,模型權重值的衰減精度,默認為0 maxit:指定模型的最大迭代次數 RSNNS包中的mlp()函數--多層前饋網絡 mlp(x, y, size = c(5), maxit = 100,initFunc = "Randomize_Weights", initFuncParams = c(-0.3, 0.3),learnFunc = "Std_Backpropagation", learnFuncParams = c(0.2, 0),updateFunc = "Topological_Order", updateFuncParams = c(0),hiddenActFunc = "Act_Logistic", shufflePatterns = TRUE, linOut = FALSE,inputsTest = NULL, targetsTest = NULL, pruneFunc = NULL,pruneFuncParams = NULL, ...) x:為輸入的自變量矩陣或數據框 y:為輸入的因變量 size:指定每個隱藏層的節點數,默認是單層5節點的拓撲結構 maxit:指定模型的最大迭代次數 initFunc:指定權重的初始函數 initFuncParams:權重的初始值默認在(-0.3, 0.3)之間 learnFunc:指定計算神經網絡的算法類型,默認為標準后向傳播算法 learnFuncParams:指定學習算法參數的初始值,即學習速率和最大輸出誤差 updateFunc:指定替換的算法類型 hiddenActFunc:指定隱藏層的算法類型 linOut:指定輸出層的激活函數,可以是線性或Logistic neuralnet包中的neuralnet()函數語法 neuralnet(formula, data, hidden = c(1), threshold = 0.01, stepmax = 1e+05, rep = 1, startweights = NULL, learningrate.limit = NULL, learningrate.factor = list(minus = 0.5, plus = 1.2), learningrate=NULL, lifesign = "none", lifesign.step = 1000, algorithm = "rprop+", err.fct = "sse", act.fct = "logistic", linear.output = TRUE, exclude = NULL, constant.weights = NULL, likelihood = FALSE) formula:模型的公式表達形式,類似于y~x1+x2+x3,不允許y~.的格式 data:指定要分析的數據對象 hidden:指定每個隱藏層的節點數,默認是單層1節點的拓撲結構 threshold:指定誤差函數的偏差閾值,默認為0.01 stepmax:指定模型的最大迭代次數 rep:指定神經網絡訓練的次數 startweights:設置初始的權重,默認情況將隨機產生權重值 learningrate.limit:指定學習速率的最小最大值,該參數僅對RPROP和 GRPROP方法起效 learningrate:可為后向傳播算法指定學習速率 algorithm:指定計算神經網絡的算法類型 但該包只能處理連續型因變量的預測。應用
本文嘗試使用神經網絡算法對乳腺癌進行分類,數據來自于《機器學習與R語言》中的案例,數據包括569條樣本和32個變量。
#讀取數據 cancer <- read.csv(file = file.choose()) str(cancer) 除樣本的標識號ID以外,diagnosis變量為目標變量,其余都是數值型變量。 #數據標準化 cancer_stand <- sapply(cancer[,-c(1,2)], standard1) #數據合并 cancer_stand <- as.data.frame(cbind(diagnosis = cancer$diagnosis, cancer_stand)) #將目標變量轉換為因子 cancer_stand$diagnosis <- factor(cancer_stand$diagnosis, levels = c(1,2), labels = c('B','M'))#構建訓練樣本集和測試樣本集 set.seed(1234) index <- sample(c(1,2), nrow(cancer_stand), replace = TRUE, prob = c(0.8,0.2)) train <- cancer_stand[index == 1,] test <- cancer_stand[index == 2,]#使用nnet包中的nnet()函數建模 library(nnet) #通過循環,確定最佳的節點數 err1 <- 0 err2 <- 0 for (i in 1:45){set.seed(1234)model <- nnet(diagnosis ~ ., data = train, maxit = 300, size = i, trace = FALSE)err1[i] <- sum(predict(model, train, type = 'class') != train$diagnosis)/nrow(train)err2[i] <- sum(predict(model, test, type = 'class') != test$diagnosis)/nrow(test) } plot(err1, type = 'b', col = 'black', lty = 2, lwd = 2, ylab = '誤差', xlab = '節點數', ylim = c(0,0.05), pch = 10) lines(err2, type = 'b', col = 'blue', lty = 2, lwd = 2, pch = 23) legend(locator(1), legend = c('訓練集誤差率','測試集誤差率'), col = c('black','blue'), lty = c(2,2), lwd = c(2,2), bty = 'n',pch = c(10,23)) 通過返回的圖形結果,選擇最佳的節點數為4#通過循環,確定最大迭代次數 err1 <- numeric() err2 <- numeric() for (i in 1:500){set.seed(1234)model <- nnet(diagnosis ~ ., data = train, maxit = i, size = 4, trace = FALSE)err1[i] <- sum(predict(model, train, type = 'class') != train$diagnosis)/nrow(train)err2[i] <- sum(predict(model, test, type = 'class') != test$diagnosis)/nrow(test) } plot(err1, type = 'l', col = 'black', lty = 1, ylab = '誤差', xlab = '節點數') lines(err2, type = 'l', col = 'blue', lty = 4) legend(locator(1), legend = c('訓練集誤差率','測試集誤差率'), col = c('black','blue'), lty = c(1,4), bty = 'n') 通過返回的圖形結果,選擇最大迭代次數為50#建立最終的神經網絡模型 set.seed(1234) model_nnet <- nnet(diagnosis ~ ., data = train, maxit = 50, size = 4, trace = FALSE) pred_nnet <- predict(model_nnet, test, type = 'class') #預測精度 Freq_nnet <- table(test$diagnosis, pred_nnet) Freq_nnet accuracy_nnet <- sum(diag(Freq_nnet))/sum(Freq_nnet) accuracy_nnet 模型準確判斷率超過99%,模型非常完美的刻畫了數據。#使用RSNNS包中的mlp()函數建模 library(RSNNS) #將數據順序打亂 data_cancer = cancer[sample(1:nrow(cancer),length(1:nrow(cancer))),2:ncol(cancer)] #定義網絡輸入 cancerValues= data_cancer[,-1] #定義網絡輸出,并將數據進行格式轉換 cancerTargets = decodeClassLabels(data_cancer[,1]) #從中劃分出訓練樣本和檢驗樣本 set.seed(1234) model_cancer = splitForTrainingAndTest(cancerValues, cancerTargets, ratio=0.20) #數據標準化 model_cancer = normTrainingAndTestSet(model_cancer, type = '0_1') #利用mlp命令執行前饋反向傳播神經網絡算法 model_mlp = mlp(model_cancer$inputsTrain, model_cancer$targetsTrain, size=4, maxit=100, inputsTest=model_cancer$inputsTest, targetsTest=model_cancer$targetsTest) #利用上面建立的模型進行預測 pred_mlp = predict(model_mlp, model_cancer$inputsTest) #生成混淆矩陣,觀察預測精度 Freq_mlp <- confusionMatrix(model_cancer$targetsTest,pred_mlp) Freq_mlp accuracy_mlp <- sum(diag(Freq_mlp))/sum(Freq_mlp) accuracy_mlp 模型的預測能力也非常高,準確率超過95%,但相比于nnet()函數準確率明顯下降。總結
- 上一篇: 分享这两年从事Linux系统运维行业的感
- 下一篇: 结构与秩序是人类认识世界的结果也是工具