2020年10月1日 星期四

[人工智慧] 如何比較模型間的預測能力

在人工智慧的論文裡面, 最重要的就是比較模型之間的預測能力, 模型的預測能力常用所謂的ROC-AUC (Area under curve) 來做表示, 一提到AUC, 有修過統計的應該會有模糊的印象吧(笑), 簡單來說就是利用調整threshold, 來構做ROC(Receiver operating Curve), 並求取底下的面積, 以下為示範案例!

因為本身是癌症科醫師, 因此當然使用癌症相關資料集, 以下用R語言來做示範!

library(xlsx)
library("glmnet")
library(pROC)
library("ggcorrplot")
library("readxl")
library("randomForest")
library(mlbench)
library(Hmisc)
data("BreastCancer")
cohort <- BreastCancer #cohort from NCI library
cohort <- as.data.frame(cohort)      
先來看一下資料分布, 其資料內部主要是乳房腫瘤的切片資料, 以及最後是良性或是惡性, 在許多人工智慧場合, 理論事都應該先做所謂的EDA(exploratory data analysis)來看資料分布, 不過很多人都沒做XD

這裡主要是預測二元資料(binary data), 但是如果多考慮時間的話, 在生物統計上經常性使用所謂的存活分析(survival analysis), 其中Cox proportional hazards model 經常性地被使用, 評估Cox model 的預測能力時, 常用所謂Concordance index, 其發明者就是就是Hmisc包的作者, Frank Harrell, 所以Concordance index 又被叫做 Harrell's concordance index.

這裡借用Hmisc 包的 describe 函數來做EDA

describe(BreastCancer)

其結果如下:


這張圖縱軸是代表每個項目,  橫軸是把連續值分成十個部分, 每個部份去看分布, 做完EDA後, 可以知道Bare Nuclei 的缺失值比較多, 為了避免後續處理出問題, 因此進行缺失值處理
 
cohort <- cohort[complete.cases(cohort), ] # remove NA value

人工智慧最重要的部分就是把資料分成所謂的training set 以及 testing set, 隨機分法非常多種, 這裡就不贅述, 以下是程式碼

sample_size = floor(0.8*nrow(cohort)) 

train_index = sample(seq_len(nrow(cohort)),size = sample_size) 
train =cohort[train_index,] 
test=cohort[-train_index,]

true_values <- as.factor(ifelse(testy=="malignant",1,0))
true_valuestr <- as.factor(ifelse(trainy=="malignant",1,0))
上面這段程式碼就是把資料分成training set: 八成, testing set: 兩成; 以及把良惡性的結果變成factor

之後利用logistic regression 來看跑看看模型:


logitMod <- glm(Class~ Cl.thickness+Cell.size+Cell.shape+Marg.adhesion
                +Epith.c.size+Bare.nuclei
                , data=train, family=binomial(link="logit"))
summary(logitMod)

final_y <- predict(logitMod,testx,type="response")
roc1<-roc(true_values,final_y,direction = "<")
ggroc(roc1,legacy.axes="TRUE")
auc1<-auc(roc1)


final_ytr <- predict(logitMod,trainx,type="response")
roctr<-roc(true_valuestr,final_ytr,direction = "<")
ggroc(roctr,legacy.axes="TRUE")
auctr1<-auc(roctr)

下面是先放testing cohort 的 ROC curve (AUC= 0.907)

可以注意到橫軸是1-specificity, 縱軸是所謂的sensitivity, 這張圖就是利用調整threshold, 來改變sensitivity以及spectivity來完成的
接下來是看training cohort (AUC=1)


雖然logistic regression 表現已經相當驚人(AUC =0.907), 但還是想跟別的模型比較, 因此使用常見的機器學習模型, 隨機森林, random forest 來做示範, 程式碼如下:


#random forest
rf <- randomForest(Class~ Cl.thickness+Cell.size+Cell.shape+Marg.adhesion
                   +Epith.c.size+Bare.nuclei
                   , data=train,ntree=50,sampsize=100)

final_yrf <- predict(rf,testx,type="prob")
roc1rf<-roc(true_values,final_yrf[,2],direction = "<")
ggroc(roc1rf,legacy.axes="TRUE")
aucrf<-auc(roc1rf)


final_ytrrf <- predict(rf,trainx,type="prob")
roctrrf<-roc(true_valuestr,final_ytrrf[,2],direction = "<")
ggroc(roctrrf,legacy.axes="TRUE")
auctrrf<-auc(roctrrf)

下面還是先放模型在 testing cohort 的表現 (AUC=0.987)




在下面才放模型在training cohort的表現(AUC=0.997)

最後用Delong test 對兩個模型在testing cohort的表現進行比較 
roc.test(roc1,roc1rf,method="delong")

p-value = 0.005132,明顯random forest表現比較好
 
reference:
1. https://rpubs.com/skydome20/R-Note10-Missing_Value

沒有留言:

張貼留言