1.資料來源:
筆者使用一個肺癌病人的資料,此資料總共47筆,主要的outcome是PCR的陽性與否(Yes=陽性;No=陰性),這個資料蒐集了MRI測量的各種數據,筆者後面的示範主要會用腫瘤的大小(Tumor size)來做分析,腫瘤的大小(Tumor size)在資料當中有分幾個時間點的測量(R0, R1, R2),除此之外,筆者再去計算不同時間點腫瘤大小(Tumor size)的差異,因此還可以得到額外的三個欄位(特徵),筆者想根據這六個特徵去跟outcome跑ROC的分析,想藉此了解哪一個特徵比較可以用來區別PCR的結果。
2匯入R package:
#可參考筆者R軟件包-caret介紹的文章” https://topepo.github.io/caret/model-training-and-tuning.html”
library(caret)
#用於讀取外部資料集
library(haven)
3.讀取資料
#讀入SPSS資料
data <- read_sav("sample_20210528.sav")
#指定PCR為一個factor(類別變項),這邊需要設定,不然後面跑cross-validation的時候會有問題
data$PCR <- as.factor(data$PCR)
#標記0跟1是甚麼
levels(data$PCR)=c("No","Yes")
#這樣可以直接使用資料的變項,不需要特別指定資料來源
attach(data)
#產生需要變項的list(清單)
variable.list=c("PCR","R0_size.cm","R1_size.cm","R2_size.cm",
"Diff_R1R0_Tumor_size.cm","Diff_R2R0_Tumor_size.cm","Diff_R2R1_Tumor_size.cm")
#根據list保留所需變項,根據這步驟,資料會只保留7個變項
data1 <- data[,variable.list]
4.分析前處理:
筆者會先將之後要建模的內容先存成物件,這樣後續分析的時候語法可以比較精簡整齊,只需要做不同fit的替換,目前總共會需要跑六個模型
#Tumor size
fit1<- (PCR~R0_size.cm)
fit2 <- (PCR~R1_size.cm)
fit3 <- (PCR~R2_size.cm)
fit4 <- (PCR~Diff_R1R0_Tumor_size.cm)
fit5 <- (PCR~Diff_R2R0_Tumor_size.cm)
fit6 <- (PCR~Diff_R2R1_Tumor_size.cm)
5.Validation 的參數設定:
在caret的套件中,提供了許多內部驗證的做法,之所以要做內部驗證是因為筆者的資料樣本相當的小,沒辦法做將資料7(建模):3(測試)的分割,因此只能透過內部驗證的方式來去驗證模型,筆者這邊採取5-fold validation重複10次的方式。
#number: N fold; repeats:重複次數
train_control <- trainControl(method="repeatedcv", number=5,repeats=10,
summaryFunction = twoClassSummary, classProbs = TRUE, savePredictions = T)
6.執行羅吉斯迴歸(Logistic regression):
這邊的分析,主要會用到caret支援的”glm”方法,讓筆者可以去執行羅吉斯迴歸,在執行的過程會根據train_control對於內部驗證的設定去執行分析,metric="ROC"代表分析過程中會得到AUC的結果,以筆者的例子來說會得到50次的做完5-fold cross-validation AUC結果。
## Logistic regression
#固定起始子,讓分析的結果是可重複的
# preprocess:將自變項做一些預處理,筆者將自變項作標準化,目的在於避免資料有出現變異過大的情形,影響建模結果
set.seed(123)
Logistic1 <-train(fit1,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
Logistic2 <-train(fit2,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
Logistic3 <-train(fit3,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
Logistic4 <-train(fit4,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
Logistic5 <-train(fit5,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
Logistic6 <-train(fit6,data=data,method="glm",family="binomial",metric="ROC",
trControl=train_control,preProcess = c("center","scale"))
當我們試著把Logistic1的結果給印出來,會得到50次5-fold cross-validation平均的AUC=0.71,敏感度平均為0.98,特異度平均為0.02。
7.模型間AUC的比較:
這邊我們透過resamples(),將6個模型50次的AUC結果給擷取出來,透過這個方法也會順便將敏感度、特異度給輸出,有了這個方法我們可以把這些數據做進一步的應用,筆者主要是把6個模型的結果輸出,並透過bwplot(),將AUC的結果加以視覺化呈現
rValues <- resamples(list(model1=Logistic1,model2=Logistic2,model3=Logistic3,
model4=Logistic4,model5=Logistic5,model6=Logistic6))
#印出所有結果
rValues$values
#跑基本的描述性統計
summary(rValues$values)
#針對AUC結果繪製盒型圖
bwplot(rValues,metric="ROC", ylab="ML methods")
8.結果解讀:
從盒型圖可以看到model 1、model 3的AUC結果相較於其他模型來的高,初步可以發現到R0、R1時間點的tumor size似乎對於區別PCR結果有較大的幫助,也許有助於之後病人的篩檢以及治療策略的制定。
參考資料:
https://zhuanlan.zhihu.com/p/30616837
https://topepo.github.io/caret/model-training-and-tuning.html
留言列表