回顧近半年來資料分析的工作內容,主要都是在處理一類分類,趁著工作到一段落,把這半年以來的經驗做個紀錄以供未來回顧,同時提供一些過來人的經驗,希望能幫到有緣的讀者。另外,由於簽了保密協議,無法使用真實資料做示範,故會以鳶尾花資料為例1來說明R語言中如何進行一類分類。
本文的架構如下,於第二節簡述何為一類分類,第三節提供4種常見的一類分類演算法在R語言中如何實現並簡述其概念,第四節介紹一類分類演算法的評估指標,第五節回顧整個學習過程中掉過的坑或遇到很好的資源或對我而言重要的個人成長,當雜記看吧,希望能博君一笑XD
說來蠻奇妙的,第一次看到 “一類分類” 這個詞是在學生時代閱讀台大林智仁教授的LIBSVM工具包,其中提到該包支援一類支援向量機(one-class SVM),當下我是一頭霧水,一類有什麼好分類的,殊不知未來工作就是要與之奮鬥@@
所以話說回來,什麼是一類分類呢?它憑什麼有一個自己的專屬名稱呢?相較於令人困惑的一類分類,吾人將先說明二類分類是什麼再回頭解釋一類分類是什麼。一個常見的二分類例子為判斷性別,如給機器一張人頭像照片,看其否能辨別是男是女。讓機器去學習如何判別男女會經過如下步驟首先,提供大量的標準答案來讓機器去“學習”隱藏在照片後的規則,接著利用獨立的資料對機器進行考試(不提供答案)以判斷其學習成效。最後,如果學習成效良好,機器學習到的規則就可以拿可以拿來做進一步的應用,如預測新資料。這一個完整的過程,有兩個條件需要被滿足,一為大量的資料,二為要有標準答案。需要大量資料的原因為樣本數大的結果比較可信,以推估全校的平均身高而言,當全校師生為2000人時,你願意採用隨機抽出20人的平均身高或是200人的平均身高?毫無疑問的,隨機抽取的人數當然是越多越好。至於需要標準答案的原因則是指每個樣本都需要能被正確分類的(機器學習中稱此為貼上標籤),由於知道正確的結果,所以機器學習方向錯誤時,就可以被導正。
在知道二類分類與其需要被滿足的兩個條件後,讓我們來看機器會怎麼面對這個問題—判斷一個人是否生病。套用上述的邏輯,首先第一步是蒐集樣本,徵求健康的人與患者,接著就會卡住了,健康的人還好說,生病的人非常難以尋找,尤其是患有罕見疾病(發生率小於千分之一)的人。所以在某些二類分類情況中,因某類的資料獲取非常困難所導致樣本數不足的問題,會造成機器學習的效果相當不好。其次,假設歷經千辛萬苦我們蒐集到了病人的資料,這時只要對資料做完標籤後,就可以讓機器放開手腳了,但是怎麼貼標籤呢,窮舉出所有病的情況一個一個貼標籤是不切實際的,所以用二類分類的方式是不可行的。為了處理這樣的問題,於是有了一類分類。在判斷一個人是否生病時,一類分類的概念為只專注於學習健康的人特徵,當遇到不具備健康特徵的人時,就判斷其不健康,這樣的好處在於避免掉了收集資料的困難以及無法定義特定對象的問題,而實務中的某些情況,的確也適用於這樣的例子:例如金融界的詐欺偵測,因為詐欺者的資料難以收集也不容易去定義全部詐欺的行為,所以針對詐欺者專門寫一套辨識方式相當不可行。
機器學習的過程主要為挑選特徵搭配演算法來達到研究目的,亦有人稱這個過程為建模。本節將會透過鳶尾花資料介紹4種一類分類演算法,分別是一類支援向量機(One class support vector machine)、高斯混合模型(Gaussian mixture model)、自編碼器(Autoencoder)、孤立森林(Isolation forest)。
鳶尾花資料[1]在R中可以直接被呼叫。如下所示,該資料收集了三種鳶尾花品種的花萼及花瓣之長度與寬度,共有4個特徵,每個品種的樣本數為50。挑鳶尾花資料集的原因為這是一個赫赫有名的分類例子,這筆資料從1936開始就被廣泛研究,文獻的方法比較中常看到該資料集被拿來測試,所以可以去除機器學習中最繁重的清資料與特徵工程的部分,讓焦點更注重於演算法本身。
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
##
## setosa versicolor virginica
## 50 50 50
要進行建模的階段時,個人習慣先看一下資料的樣貌,也就是探索性資料分析(Exploratory Data analysis),沒問題再進入下一步。2。在R中一個簡易的方式為利用指令 ‘describe’ 看一下基本的敘述統計量,如對資料沒有疑慮後,再進行建模。為了因應一類分類的需要,將三個品種的標籤改為屬於山鳶尾(setosa)與不屬於山鳶尾(Non-setosa)。
| vars | n | mean | sd | median | trimmed | mad | min | max | range | skew | kurtosis | se | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sepal.Length | 1 | 150 | 5.843333 | 0.8280661 | 5.80 | 5.808333 | 1.03782 | 4.3 | 7.9 | 3.6 | 0.3086407 | -0.6058125 | 0.0676113 |
| Sepal.Width | 2 | 150 | 3.057333 | 0.4358663 | 3.00 | 3.043333 | 0.44478 | 2.0 | 4.4 | 2.4 | 0.3126147 | 0.1387047 | 0.0355883 |
| Petal.Length | 3 | 150 | 3.758000 | 1.7652982 | 4.35 | 3.760000 | 1.85325 | 1.0 | 6.9 | 5.9 | -0.2694109 | -1.4168574 | 0.1441360 |
| Petal.Width | 4 | 150 | 1.199333 | 0.7622377 | 1.30 | 1.184167 | 1.03782 | 0.1 | 2.5 | 2.4 | -0.1009166 | -1.3581792 | 0.0622364 |
| Species* | 5 | 150 | 2.000000 | 0.8192319 | 2.00 | 2.000000 | 1.48260 | 1.0 | 3.0 | 2.0 | 0.0000000 | -1.5199333 | 0.0668900 |
至於選入模型的特徵,則是參照前人的研究,使用花瓣的長度與寬度。如下圖所示,以花瓣為特徵時,山鳶尾與另外兩個品種能很好的被區分開來。
最後將山鳶尾的資料分成訓練集資料與測試集資料,兩者的比例為8:2。另外,非山鳶尾的資料也通通作為測試集。
一類支援向量機的概念為透過對一類樣本去建立一個決策邊界,該邊界可以想像為空間中的一個超球體,該球體的半徑盡可能極小,但是包含了全部的某一類樣本,所以當一筆資料無法進入該球體時則被判斷為異常。執行的程式如下:
library("e1071")
svm.tuned.model<-tune.svm(~.,data=train.data,
, nu = seq(2^(-7),2^(-4),length=10)
, gamma = seq(2^(-8),2^(-3),length=10)
)
#plot(svm.tuned.model)
svm.model<-svm.tuned.model$best.model
pred1 <- predict(svm.model, train.data,decision.value=T)
pred2 <- predict(svm.model, test.data,decision.value=T)
svm.result<-factor(pred2,c(F,T),c("Non-setosa","Setosa"))
svm.confusion.matrix<-table(svm.result,setosa_binary[test_index])
svm.confusion.matrix##
## svm.result Non-setosa Setosa
## Non-setosa 100 2
## Setosa 0 8
高斯混合模型為針對某一類樣本去進行配適,當估計完成,得到對應的密度函數參數後,即可用來評估新資料是否與這群樣本來自於同樣的分類。如果可能性很高,則判斷為同類 ; 如果可能性很低,則判斷為異類。可能性的高低會由一個臨界值來判斷,臨界值的判斷很吃經驗,根據Tax的論文[2],它給出一個參考的方式,訓練集資料的前5%。執行的程式如下:
## Package 'mclust' version 5.4.5
## Type 'citation("mclust")' for citing this R package in publications.
##
## Attaching package: 'mclust'
## The following object is masked from 'package:psych':
##
## sim
GMM.model<-densityMclust(train.data,G=1)
train.density<-predict.densityMclust(GMM.model,train.data)
threshold<-quantile(train.density,0.05)
GMM.predict<-predict.densityMclust(GMM.model,test.data)
GMM.result<-factor(GMM.predict>threshold,c(F,T),c("Non-setosa","Setosa"))
GMM.confusion.matrix<-table(GMM.result,setosa_binary[test_index])
GMM.confusion.matrix##
## GMM.result Non-setosa Setosa
## Non-setosa 100 2
## Setosa 0 8
自編碼器為對資料做壓縮再做還原的一個過程,這項工具原本是作為萃取資料特徵(降維)用的,如果資料能被壓縮後又成功還原就代表著資料的壓縮方式是正確且有效的。但是在一類分類中它卻有了不同的應用,如果單一類別的資料能被成功壓縮又還原,那另一類型的資料進來會發生什麼事呢?答案就是其沒有辦法被正確的還原,因為機器學習到的壓縮資料並不適用於不同類的資料,尤其是在資料長得非常不一樣的時候,所以可以根據還原的程度去判斷一筆資料是否為異常值。執行的程式如下:
#install.packages("ANN2")
library(ANN2, quietly=TRUE)
AE.model<-autoencoder(X=train.data,hidden.layers=c(2),
activ.functions = "linear",batch.size = 8,
random.seed=20200409,verbose=F)# begin compress## Warning: small validation set, only 4 observations
#plot(AE.model) # to see is it overfitting
rec_train<-reconstruct(AE.model,train.data)# train data reconstruct
rec_test<-reconstruct(AE.model,test.data)# test data reconstruct
threshold<-quantile(rec_train$anomaly_scores,0.95)
AE.predict<-rec_test$anomaly_scores
AE.result<-factor(AE.predict<threshold,c(F,T),c("Non-setosa","Setosa"))
AE.confusion.matrix<-table(AE.result,setosa_binary[test_index])
AE.confusion.matrix##
## AE.result Non-setosa Setosa
## Non-setosa 100 0
## Setosa 0 10
孤立森林(Isolation Forest,iForest)是劉飛博士在莫納什大學就讀期間在陳開明教授和周志華教授的指導下於 2008 年發表的。其主要思想為對資料建立很多棵分類樹將資料中的樣本點分開,由於異常點在資料中占的比例比較少,且在一些特徵上與正常點有差異,所以在分類時,異常點更容易被區分開。而正常樣本由於佔較大的比例且彼此之間特徵差異很小故很難區分開。基於異常值少而且不一樣這樣的特性,iForest透過衡量分類時各樣本是否容易被區分開的程度來尋找異常值。所以圖形上來看,異常值容易被區分開所以會接近分類樹的根部;而正常值因不容易區分,所以會遠離分類樹的根部。基於這樣的特性,可用分類樣本所需的路徑長度(距離分類樹根部的遠近)來衡量資料是否容易被區分開。當路徑越長說明該資料越難以分開,原文中有將路徑的長度轉換成異常分數 (s),並建議了如下的評估: 當異常分數很接近 1時,可以斷定其為異常值;當異常分數遠遠小於0.5時,推論其為正常值是相當安全的;當所有的資料的異常分數都約莫等於 0.5時,則資料中沒有明顯的異常值。執行的程式如下:
h2o.init()
trainData_hex = as.h2o( train.data )
testData_hex = as.h2o( test.data )
iforest.model<-h2o.isolationForest(trainData_hex,sample_rate = 0.6,seed=20200411)## Warning in .h2o.startModelJob(algo, params, h2oRestApiVersion): Stopping tolerance is ignored for _stopping_rounds=0..
iForest.predict<-as.vector(h2o.predict(iforest.model,testData_hex)$predict)
threshold=0.9
iForest.result<-factor(iForest.predict<threshold,c(F,T),c("Non-setosa","Setosa"))
iForest.confusion.matrix<-table(iForest.result,setosa_binary[test_index])
h2o.shutdown(prompt = F)##
## iForest.result Non-setosa Setosa
## Non-setosa 100 1
## Setosa 0 9
在進行完分類後,各演算法在測試集的結果可透過混淆矩陣表示。如
| 實際為陰性(Negative) | 實際為陽性(Positive) | |
|---|---|---|
| 檢測結果為陰性 | 真陰(True Negative, TN) | 偽陰(False Negative, FN) |
| 檢測結果為陽性 | 偽陽(False Positive, FP) | 真陽(True Positive, TP) |
一般而言,吾人會希望混淆矩陣中分類正確的結果(TP與TN)越高越好,一個常見的指標為準確度(Accuracy),其透過計算正確分類資料佔全部資料的比重來衡量分類結果。 \[\begin{equation} Accuracy=\frac{TP+TN}{TP+FP+TN+FN} \end{equation}\]
然準確度這個指標在兩類資料極度不平衡的情況下,會是一個不好的度量方式。假設吾人收集了10000個樣本,其中有兩名罕病患者,如吾人預測全部的樣本均為陰性,此時的準確度為 \[\begin{equation} Accuracy=\frac{TN+TP}{TP+FP+TN+FN}=\frac{9998+0}{0+0+9998+2}=99.98\% \end{equation}\]
但是患者實際上有罕病且被正確判斷出來的比率為0。這種準確度很高但是模型實際的判斷能力很差的現象稱為準確度悖論(Accuracy paradox)。因為有準確度悖論這項議題的存在,所以單看精準度是不夠的,這裡吾人另外考慮以F1分數(\(F_{1}-score\))與特異度(Specificity)來做衡量。將先說明F1分數後再說明特異度。F1分數為準確率(Precision)與召回率(Recall)的調和平均數3。 \[\begin{equation} F_{1}-score=\frac{2 \times Recall \times Precision}{Recall + Precision} \end{equation}\] \[\begin{equation} Precision=\frac{TP}{FP+TP} \end{equation}\] \[\begin{equation} Recall=\frac{TP}{TP+FN} \end{equation}\]
精確度代表在所有被判斷為陽性的個體中,確實為陽性之比率,亦有人稱該值為陽性預測值(Positive Predictive Value,PPV);召回率代表在所有實際為陽性的個體中,被正確判斷為陽性之比率。在上述預測全部的樣本均為陰性極端的例子裡,精確度與召回率的分子TP均為0。代表兩指標均可反映出預測全部資料為陰性是一個不適當的方式。至於F1分數則可以讓吾人很好的去同時衡量精確度與召回率,例如A與B兩模型出來的結果中A模型準確率結果較優而B模型則是召回率較好,此時可以根據F1分數較高者來決定較佳的模型。說明完F1分數後,接著說明特異度。其計算方式為 \[\begin{equation} Specificity=\frac{TN}{FP+TN} \end{equation}\]
特異度的涵義為所有實際為陰性的個體中,被正確判斷為陰性之比率。觀察準確率、召回率與特異度的分子後,可以發現特異度所要衡量的事情與前兩者指標不同,前兩者關心的事情為正確判斷為陽性的個數(TP),而特異度則是關心正確被判斷為陰性的個數(TN)。所以最後的結果評估時,吾人不會只看單一指標,而是會同時考量多個指標。
最後從下表的結果比較中可以看出4種演算法的結果在各指標的數值都至少有8成,而自編碼器的結果甚至達到百分之百正確,但這並不意味著自編碼器是最好的模型,個人實務上的經驗是特徵搭配演算法才會有最好的結果。
#library("caret")
output<-rbind(confusionMatrix(svm.confusion.matrix)$byClass,
confusionMatrix(GMM.confusion.matrix)$byClass,
confusionMatrix(AE.confusion.matrix)$byClass,
confusionMatrix(iForest.confusion.matrix)$byClass)
finaloutput<-output[,c(1,2,5,6,7)]
rownames(finaloutput)<-c("一類支援向量機(One class support vector machine)","高斯混合模型 (Gaussian mixture model)","自編碼器(Autoencoder)","孤立森林 (Isolation Forest)")| Sensitivity | Specificity | Precision | Recall | F1 | |
|---|---|---|---|---|---|
| 一類支援向量機(One class support vector machine) | 1 | 0.8 | 0.9803922 | 1 | 0.9900990 |
| 高斯混合模型 (Gaussian mixture model) | 1 | 0.8 | 0.9803922 | 1 | 0.9900990 |
| 自編碼器(Autoencoder) | 1 | 1.0 | 1.0000000 | 1 | 1.0000000 |
| 孤立森林 (Isolation Forest) | 1 | 0.9 | 0.9900990 | 1 | 0.9950249 |
這裡紀錄這半年來記憶深刻的文獻,至於一些零碎的感想或是摔過的坑則放在後記。
最後,最重要的,你聽過咖啡贊助計畫嗎?我想把它反過來做,因為我注重文章的品質,所以如果以上內容有誤,請你告訴我,我會請你喝咖啡的。或是任何你認為可以補充或是想多了解的,請聯絡我。附上我的信箱:dindinlin123@gmail.com
[1] R.A. FISHER, THE USE OF MULTIPLE MEASUREMENTS IN TAXONOMIC PROBLEMS, Annals of Eugenics. 7 (1936) 179–188. https://doi.org/10.1111/j.1469-1809.1936.tb02137.x.
[2] D.M.J. Tax, One-class classification, PhD thesis, 2001.
[3] Y. Sasaki, The truth of the F-measure, Teach Tutor Mater. (2007) 1–5. http://www.cs.odu.edu/{~}mukka/cs795sum09dm/Lecturenotes/Day3/F-measure-YS-26Oct07.pdf.
[4] C.-C. Chang, C.-J. Lin, LibSVM: A Library of Support Vector Machines, (2001) 1–39.
[5] P.-H. Chen, C.-J. Lin, B. Schölkopf, A tutorial on \(\nu\)-support vector machines, Applied Stochastic Models in Business and Industry. 21 (2005) 111–136. https://doi.org/10.1002/asmb.537.
[6] G. E. Hinton* and R. R. Salakhutdinov, Reducing the Dimensionality of Data with Neural Networks, Science. 313 (2006) 504–507.
[7] F.T. Liu, K.M. Ting, Z.-H. Zhou, Isolation Forest, in: Proceedings of the 2008 Eighth Ieee International Conference on Data Mining, IEEE Computer Society, Washington, DC, USA, 2008: pp. 413–422. https://doi.org/10.1109/ICDM.2008.17.
[8] S.S. Khan, M.G. Madden, One-class classification: Taxonomy of study and review of techniques, Knowledge Engineering Review. 29 (2014) 345–374. https://doi.org/10.1017/S026988891300043X.
[9] M. Markou, S. Singh, Novelty detection: a review—part 1: statistical approaches, Signal Processing. 83 (2003) 2481–2497. https://doi.org/https://doi.org/10.1016/j.sigpro.2003.07.018.
[10] V. Chandola, A. Banerjee, V. Kumar, Anomaly Detection: A Survey, ACM Comput. Surv. 41 (2009). https://doi.org/10.1145/1541880.1541882.
[11] N.V. Chawla, K.W. Bowyer, L.O. Hall, W.P. Kegelmeyer, SMOTE: Synthetic Minority Over-sampling Technique, Journal of Artificial Intelligence Research. 16 (2002) 321–357.