Khảo sát đặc tính triệu chứng lâm sàng của một bệnh lý là một chủ đề phổ biến trong các luận văn tốt nghiệp của sinh viên Y khoa. Trong đa số trường hợp,mẫu khảo sát gồm 2 phân nhóm Bệnh/Chứng. Dấu hiệu lâm sàng được ghi nhận dưới dạng biến định tính (rời rạc hoặc nhị phân). Sinh viên còn có khuynh hướng chuyển biến số liên tục thành biến rời rạc (discretize). Cuối cùng dữ liệu sẽ có một tập hợp nhiều biến đặc tính/triệu chứng và một biến kết quả (trạng thái bệnh lý), tất cả đều là biến rời rạc.
Cách làm việc này tự bản thân nó không có vấn đề gì, mục tiêu nghiên cứu là khảo sát mối liên hệ giữa (các) triệu chứng và trạng thái bệnh lý. Vấn đề chỉ bắt đầu khi sinh viên lạm dụng bảng chéo và kiểm định Ki bình phương (Chi squared test) để giải quyết vấn đề. Cách làm này có 2 điểm bất lợi đó là:
Tốn kém thời gian và công sức: Phải bắt cặp tuần tự tất cả các tổ hợp có thể giữa Triệu chứng và Bệnh.
Chỉ phân tích đơn biến, nhưng không khảo sát được những liên hệ, tương tác đa chiều giữa nhiều triệu chứng với nhau.
Ngoài phương pháp sơ cấp dùng bảng chéo và kiểm định Ki bình phương, có nhiều giải pháp thay thế từ thống kê truyền thống bao gồm: phân tích logarit tuyến tính, mô hình hồi quy logistic đa biến. Ngoài ra, từ phái Machine learning ta có những giải thuật (algorithm) khác nhau có thể áp dụng như: Cây quyết định, Naive Bayes, mô hình mạng (network analysis), Luật kết hợp (Association rule)…
Trong bài hôm nay, Nhi giới thiệu với các bạn về phương pháp Luật kết hợp (Association rule) như một công cụ thay thế cho bảng chéo/Chi2test trong bài toán khảo sát liên hệ Triệu chứng/bệnh lý.
Association rule rất hiếm khi được áp dụng cho Y học, vì phương pháp này nguyên thủy do Agrawal R.(1993) đề xuất nhằm giải quyết vấn đề trong lĩnh vực hoàn toàn khác, đó là thương mại. Ứng dụng của Association rule là nghiên cứu hành vi của người tiêu dùng dựa trên dữ liệu về các giao dịch, từ đó xây dựng chiến lược Tiếp thị, quảng cáo hiệu quả.
Thí dụ: tìm ra quy luật kết hợp giữa những món hàng trong mỗi giỏ hàng mua tại siêu thị để tạo ra catalogue, tổ chức trưng bày và các combo khuyến mại.
Một thí dụ khác: Tiếp thị chéo - nếu khách hàng mua tựa sách này, hay đĩa DVD này, thì máy tính sẽ tự động giới thiệu một phim khác hay một cuốn sách khác - được xác định là phù hợp, từ các quy luật kết hợp.
Do đó, các bác sĩ và sinh viên Y khoa không biết đến phương pháp này, và không thể ngờ rằng nó tương đồng một cách đáng ngạc nhiên với bài toán mà họ vẫn hay giải quyết bằng hàng loạt bảng chéo.
Chúng ta sẽ cùng làm thử Association rule một lần với nhau nhé ?
Năm 2003, hai bác sĩ người Ba Lan là J.Czerniak và H.Zarzycki khảo sát 6 triệu chứng thực thể trên 120 bệnh nhân bị mắc một trong hai bệnh lý: Viêm bàng quang hoặc Viêm thận-niệu quản.
library(tidyverse)
df=read.csv("https://www.openml.org/data/get_csv/1593752/phpJ1rDu3.csv")%>%as_tibble()
names(df)=c("Temperature","Nausea","LumbarPain","UrinePush","Micturition","UrethraBurn","Type")
df$Type=df$Type%>%recode_factor(.,`yes` = "Urinary_Bladder", `no` = "Nephritis_renal")
head(df) %>%knitr::kable()
Temperature | Nausea | LumbarPain | UrinePush | Micturition | UrethraBurn | Type |
---|---|---|---|---|---|---|
35.5 | no | yes | no | no | no | Nephritis_renal |
35.9 | no | no | yes | yes | yes | Urinary_Bladder |
35.9 | no | yes | no | no | no | Nephritis_renal |
36.0 | no | no | yes | yes | yes | Urinary_Bladder |
36.0 | no | yes | no | no | no | Nephritis_renal |
36.0 | no | yes | no | no | no | Nephritis_renal |
Với dữ liệu này, giả định mục tiêu nghiên cứu của chúng ta là khảo sát mối liên hệ giữa 6 triệu chứng và 2 loại nhiễm trùng niệu cấp; ta phải làm như thế nào ?
Đầu tiên, Nhi sẽ tái hiện lại những gì các em sinh viên Y khoa Việt Nam thường làm với dữ liệu này, đó là dựng 6 bảng chéo cho 6 triệu chứng và với mỗi bảng chéo làm một kiểm định Ki bình phương hoặc Exact Fisher test.
Nhưng trước hết ta sẽ cắt biến Temperature (là 1 biến liên tục) thành một factor nhiều levels:
library(arules)
hist(df$Temperature, main="Equal Interval length",breaks=30,col="gold")
abline(v=discretize(df$Temperature,
method="interval",
categories = 4,onlycuts=TRUE), col="red4")
data=df
data$Temperature=discretize(df$Temperature,
method="interval",
categories = 4,labels=c("Low","Normal","High","VeryHigh"))
data%>%ggplot(aes(x=Temperature))+stat_count(aes(fill=Type),alpha=0.7)+theme_bw()
Qua thăm dò, ta có thể cắt Temperature thành 4 phần với 3 ngưỡng cắt là 37°C, 38.5°C, và 40°C, ta tạm đặt tên là: Low, Normal, High, VeryHigh
library(GGally)
ggpairs(data,
mapping = ggplot2::aes(fill=Type,alpha = 0.8),
upper = list(discrete = "facetbar"),
lower = list(discrete= "facetbar"),
diag = list(discrete = "barDiag")
)
Sau đây là 6 bảng chéo, 6 mosaic plot và 6 kiểm định Ki bình phương:
longdata=data%>%gather(Temperature:UrethraBurn,key="Feature",value="Value")
chisquare=function(crosstab,B){
test1=chisq.test(crosstab)
test2=chisq.test(crosstab,simulate.p.value = T,B=B)
test3=test3=fisher.test(crosstab)
p=Monte_Carlo_pval=test2$p.value[[1]]
print(rbind(Chisqr=test1$statistic[[1]],
df=test1$parameter[[1]],
Chi2p_val=test1$p.value[[1]],
Monte_Carlo_pval=p,
Fisher_exact_pval=test3$p.value[[1]],
Cramer_V=lsr::cramersV(crosstab)))
}
library(vcd)
longdata%>%split(.$Feature)%>%
map(~xtabs(data=.,~.$Value+.$Type))%>%
map(~mosaic(.,shade=TRUE,legend=TRUE,gp = shading_max))
## $LumbarPain
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## no 40 10
## yes 19 51
##
## $Micturition
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## no 10 51
## yes 49 10
##
## $Nausea
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## no 40 51
## yes 19 10
##
## $Temperature
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## High 0 6
## Low 10 10
## Normal 30 14
## VeryHigh 19 31
##
## $UrethraBurn
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## no 30 40
## yes 29 21
##
## $UrinePush
## .$Type Urinary_Bladder Nephritis_renal
## .$Value
## no 0 40
## yes 59 21
longdata%>%split(.$Feature)%>%
map(~xtabs(data=.,~.$Value+.$Type))%>%
map(~chisquare(.,500))
## [,1]
## Chisqr 3.052372e+01
## df 1.000000e+00
## Chi2p_val 3.298098e-08
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.217343e-08
## Cramer_V 5.043454e-01
## [,1]
## Chisqr 5.068483e+01
## df 1.000000e+00
## Chi2p_val 1.084546e-12
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.194339e-13
## Cramer_V 6.499028e-01
## [,1]
## Chisqr 3.27337359
## df 1.00000000
## Chi2p_val 0.07041269
## Monte_Carlo_pval 0.07984032
## Fisher_exact_pval 0.05531820
## Cramer_V 0.16516087
## [,1]
## Chisqr 14.668923186
## df 3.000000000
## Chi2p_val 0.002122591
## Monte_Carlo_pval 0.005988024
## Fisher_exact_pval 0.001376195
## Cramer_V 0.349629842
## [,1]
## Chisqr 2.1043941
## df 1.0000000
## Chi2p_val 0.1468765
## Monte_Carlo_pval 0.1457086
## Fisher_exact_pval 0.1383060
## Cramer_V 0.1324259
## [,1]
## Chisqr 5.511948e+01
## df 1.000000e+00
## Chi2p_val 1.134214e-13
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.184878e-16
## Cramer_V 6.777381e-01
## $LumbarPain
## [,1]
## Chisqr 3.052372e+01
## df 1.000000e+00
## Chi2p_val 3.298098e-08
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.217343e-08
## Cramer_V 5.043454e-01
##
## $Micturition
## [,1]
## Chisqr 5.068483e+01
## df 1.000000e+00
## Chi2p_val 1.084546e-12
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.194339e-13
## Cramer_V 6.499028e-01
##
## $Nausea
## [,1]
## Chisqr 3.27337359
## df 1.00000000
## Chi2p_val 0.07041269
## Monte_Carlo_pval 0.07984032
## Fisher_exact_pval 0.05531820
## Cramer_V 0.16516087
##
## $Temperature
## [,1]
## Chisqr 14.668923186
## df 3.000000000
## Chi2p_val 0.002122591
## Monte_Carlo_pval 0.005988024
## Fisher_exact_pval 0.001376195
## Cramer_V 0.349629842
##
## $UrethraBurn
## [,1]
## Chisqr 2.1043941
## df 1.0000000
## Chi2p_val 0.1468765
## Monte_Carlo_pval 0.1457086
## Fisher_exact_pval 0.1383060
## Cramer_V 0.1324259
##
## $UrinePush
## [,1]
## Chisqr 5.511948e+01
## df 1.000000e+00
## Chi2p_val 1.134214e-13
## Monte_Carlo_pval 1.996008e-03
## Fisher_exact_pval 1.184878e-16
## Cramer_V 6.777381e-01
Kết quả phân tích đơn biến cho thấy ngoài Nausea và UrethraBurn không có liên hệ ý nghĩa với phân loại bệnh lý, 4 triệu chứng còn lại đều có liên hệ ý nghĩa với phân loại nhiễm trùng niệu cấp.
Một cách ngẫu nhiên, bài toán Association rule hoàn toàn phù hợp với vấn đề đang xét, ở 2 điểm sau đây:
Trước khi đi vào chi tiết, Nhi sẽ trình bày một số thuật ngữ của Association rule và nghĩa tương đương khi áp dụng cho Y học:
Trong các bài toán nghiên cứu thị trường, tiếp thị,…, mỗi món hàng được xét gọi là Phần tử (Item), Itemset là một tập hợp nhiều phần tử. Khi áp dụng cho bài toán y học có một số khác biệt, thứ nhất ta phân biệt 2 loại phần tử: Triệu chứng và Bệnh lý. Sự hiện diện của một triệu chứng là 1 phần tử, sự hiện diện của bệnhở mỗi bệnh nhân cũng là một phần tử .
Do ứng dụng ban đầu của luật kết hợp là cho lĩnh vực thương mại, nên mỗi hàng trong dữ liệu được gọi là một lượt giao dịch = transaction. Khi áp dụng cho vấn đề y học, chúng ta không dùng thuật ngữ transaction mà gọi là trường hợp (case) hay quan sát (observation). Mỗi case là tập hợp T gồm các phần tử (yếu tố) đang được xét.
Sự kết hợp diễn ra khi nhiều phần tử đồng thời xuất hiện chung trong một hay nhiều cases. Luật kết hợp là sự liên hệ có điều kiện giữa các tập hợp phần tử. Thí dụ : Bệnh lý Y hiện diện trong điều kiện triệu chứng F… hiện diện. Trong lĩnh vực thương mại, sự kết hợp có định hướng, theo thứ tự thời gian (thí dụ khách hàng mua sản phẩm A, sau đó sẽ mua sản phẩm B). Khi áp dụng cho y học, tính định hướng này có thể đổi thành chiều suy luận: từ triệu chứng A rút ra chẩn đoán B:
Quy luật kết hợp có định hướng thường được trình bày dưới dạng :
\[A \rightarrow B\]
Với A và B là hai tập phần tử độc lập. Dựa vào chiều mũi tên ta gọi A là lhs (bên trái) và B là rhs (bên phải).
Những tham số kỹ thuật của giải thuật Apriori gồm có:
\[support(A \rightarrow B) = P (A\cup B)\] Khi khai triển thuật toán apriori, người dùng sẽ quy định một ngưỡng hỗ trợ tối thiểu, một quy luật chỉ được ghi nhận khi tỉ lệ hiện cao hơn hoặc bằng với ngưỡng tối thiểu này.
Độ tin cậy, là tần số xuất hiện của tập phần tử trong điều kiện xuất hiện một tập phần tử khác. Tương tự với support, confidence cũng có ngưỡng tối thiểu quy định bởi người dùng.
\[confidence(A \rightarrow B) = P (A|B) = \frac{P(A \cup B)}{P(A)}\]
Tham số thứ 3 là lift, là tỉ số giữa confidence và tỉ lệ trường hợp hiện diện A
\[ lift(A \rightarrow B) = \frac{confidence (A \rightarrow B)}{P(B)} = \frac{P(A \cup B)}{P(A)*P(B))}\] # Package arules
Nhi sử dụng giải thuật Apriori trong package arules như sau:
Đầu tiên, ta phải xác định một cách chủ quan các điều kiện cho quy luật kết hợp.
Thí dụ, ta đặt ra một ngưỡng thấp nhất cho số phần tử trong mỗi quy luật là 5, do trong mỗi lần kết hợp như vậy 1 phần tử bắt buộc phải có là Chẩn đoán (Type), do đó minlen=5 có thể hiểu là quy luật phải kết hợp tối thiểu 4 triệu chứng.
Nếu ta đặt ngưỡng này =2 hay =3, điều gì sẽ xảy ra ? Sẽ có nhiều quy luật kết hợp ngẫu nhiên được tìm ra nhưng không có cơ sở thực tế, thí dụ: Nhiệt độ bình thường + Không đau lưng , hoặc Không đau lưng + Không nôn ói… là những hiện tượng không đặc hiệu cho bệnh lý nào cả.
Ta chỉ quan tâm đến những quy luật mà vế bên phải là chẩn đoán, do đó ta ghi rõ điều kiện 2 phần tử : chẩn đoán = viêm bàng quang và chẩn đoán = Viêm thận, niệu quản vào rhs. Nếu không làm như vậy, lần lượt tất cả yếu tố trong dữ liệu sẽ được xét như lhs và rhs và ta sẽ nhận được hàng trăm luật kết hợp mà vế bên phải là 1 triệu chứng chứ không phải bệnh lý.
Tỉ lệ support tối thiểu được định là 20 trường hợp / tổng số 120, các bạn có thể viết dưới dạng xác suất: 0.167 cũng được.
Giá trị confidence tối thiểu =0.9
rules=apriori(data, control = list(verbose=F),
parameter = list(minlen=5,
supp=20/120,
conf=0.9),
appearance = list(rhs=c("Type=Urinary_Bladder",
"Type=Nephritis_renal"),
default="lhs"))
Sau khi có kết quả, Nhi xếp các quy luật theo giá trị lift, từ cao đến thấp
quality(rules)<-round(quality(rules),digits=3)
rules <- sort(rules, by="lift")
inspect(rules)
## lhs rhs support confidence lift count
## [1] {Temperature=Normal,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [2] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [3] {Temperature=Normal,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [4] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [5] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrinePush=yes} => {Type=Urinary_Bladder} 0.250 1 2.034 30
## [6] {Temperature=Normal,
## Nausea=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [7] {Temperature=Normal,
## Nausea=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [8] {LumbarPain=no,
## UrinePush=yes,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [9] {Nausea=no,
## LumbarPain=no,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [10] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [11] {Nausea=no,
## UrinePush=yes,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [12] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.250 1 2.034 30
## [13] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [14] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [15] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [16] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [17] {LumbarPain=yes,
## UrinePush=no,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [18] {Nausea=no,
## UrinePush=no,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.250 1 1.967 30
## [19] {Nausea=no,
## LumbarPain=yes,
## UrinePush=no,
## Micturition=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [20] {Nausea=no,
## LumbarPain=yes,
## UrinePush=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [21] {LumbarPain=yes,
## UrinePush=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [22] {Nausea=no,
## LumbarPain=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [23] {Nausea=no,
## UrinePush=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [24] {Nausea=no,
## LumbarPain=yes,
## UrinePush=yes,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [25] {Nausea=no,
## LumbarPain=yes,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [26] {Nausea=no,
## LumbarPain=yes,
## UrinePush=yes,
## Micturition=no} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [27] {Nausea=no,
## LumbarPain=yes,
## UrinePush=no,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [28] {Nausea=no,
## LumbarPain=yes,
## UrinePush=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
Một điều tế nhị, đó là tuy có 28 quy luật đã được tìm ra, nhưng trong số đó có những quy luật thừa. Thừa ở đây có nghĩa là quy luật với k phần tử không mang lại thông tin nào mới so với quy luật k-1 phần tử. Thí dụ nếu ta đã biết Nausea=no + LumbarPain=no + Micturition=yes kết hợp với Viêm bàng quang, thì một quy luật khác có nội dung Nausea=no + LumbarPain=no + Micturition=yes + Temperature = Normal được xem là thừa, vì phần tử Temperature= Normal là không cần thiết.
Để loại bỏ những quy luật thừa, ta làm như sau:
redundant=is.redundant(rules,measure="confidence")
rule2=rules[!redundant]
inspect(rule2)
## lhs rhs support confidence lift count
## [1] {Temperature=Normal,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [2] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [3] {Temperature=Normal,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [4] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [5] {Temperature=Normal,
## Nausea=no,
## LumbarPain=no,
## UrinePush=yes} => {Type=Urinary_Bladder} 0.250 1 2.034 30
## [6] {Temperature=Normal,
## Nausea=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [7] {Temperature=Normal,
## Nausea=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [8] {LumbarPain=no,
## UrinePush=yes,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [9] {Nausea=no,
## LumbarPain=no,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [10] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [11] {Nausea=no,
## UrinePush=yes,
## Micturition=yes,
## UrethraBurn=yes} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [12] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## Micturition=yes} => {Type=Urinary_Bladder} 0.250 1 2.034 30
## [13] {Nausea=no,
## LumbarPain=no,
## UrinePush=yes,
## UrethraBurn=no} => {Type=Urinary_Bladder} 0.167 1 2.034 20
## [14] {LumbarPain=yes,
## UrinePush=no,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [15] {Nausea=no,
## UrinePush=no,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.250 1 1.967 30
## [16] {Nausea=no,
## LumbarPain=yes,
## UrinePush=no,
## Micturition=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [17] {Nausea=no,
## LumbarPain=yes,
## UrinePush=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [18] {LumbarPain=yes,
## UrinePush=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [19] {Nausea=no,
## LumbarPain=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [20] {Nausea=no,
## UrinePush=yes,
## Micturition=no,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [21] {Nausea=no,
## LumbarPain=yes,
## UrinePush=yes,
## UrethraBurn=yes} => {Type=Nephritis_renal} 0.175 1 1.967 21
## [22] {Nausea=no,
## LumbarPain=yes,
## Micturition=no,
## UrethraBurn=no} => {Type=Nephritis_renal} 0.167 1 1.967 20
## [23] {Nausea=no,
## LumbarPain=yes,
## UrinePush=yes,
## Micturition=no} => {Type=Nephritis_renal} 0.175 1 1.967 21
Kết quả sau khi lọc bỏ 5 quy luật thừa, còn lại 23 quy luật
Ta có thể trình bày kết quả của phân tích Association rule bằng các biểu đồ. Trong số này, thú vị nhất là mạng lưới các quy luật kết hợp: Chúng ta đã phân các triệu chứng ra thành 2 cụm có liên hệ với mỗi phân nhóm bệnh lý, mà các node Rules là giao điểm cho sự kết nối này. Ta đã có trong tay một network mà gí trị thông tin phong phú hơn nhiều so với Chi2 test và bảng chéo.
library(arulesViz)
plot(rule2)
plot(rule2,method= "matrix")
## Itemsets in Antecedent (LHS)
## [1] "{Temperature=Normal,LumbarPain=no,UrinePush=yes,Micturition=yes}"
## [2] "{Temperature=Normal,Nausea=no,LumbarPain=no,Micturition=yes}"
## [3] "{Temperature=Normal,LumbarPain=no,UrinePush=yes,UrethraBurn=no}"
## [4] "{Temperature=Normal,Nausea=no,LumbarPain=no,UrethraBurn=no}"
## [5] "{Temperature=Normal,Nausea=no,LumbarPain=no,UrinePush=yes}"
## [6] "{Temperature=Normal,Nausea=no,UrinePush=yes,Micturition=yes}"
## [7] "{Temperature=Normal,Nausea=no,UrinePush=yes,UrethraBurn=no}"
## [8] "{LumbarPain=no,UrinePush=yes,Micturition=yes,UrethraBurn=yes}"
## [9] "{Nausea=no,LumbarPain=no,Micturition=yes,UrethraBurn=yes}"
## [10] "{Nausea=no,LumbarPain=no,UrinePush=yes,UrethraBurn=yes}"
## [11] "{Nausea=no,UrinePush=yes,Micturition=yes,UrethraBurn=yes}"
## [12] "{Nausea=no,LumbarPain=no,UrinePush=yes,Micturition=yes}"
## [13] "{Nausea=no,LumbarPain=no,UrinePush=yes,UrethraBurn=no}"
## [14] "{LumbarPain=yes,UrinePush=no,Micturition=no,UrethraBurn=no}"
## [15] "{Nausea=no,UrinePush=no,Micturition=no,UrethraBurn=no}"
## [16] "{Nausea=no,LumbarPain=yes,UrinePush=no,Micturition=no}"
## [17] "{Nausea=no,LumbarPain=yes,UrinePush=no,UrethraBurn=no}"
## [18] "{LumbarPain=yes,UrinePush=yes,Micturition=no,UrethraBurn=yes}"
## [19] "{Nausea=no,LumbarPain=yes,Micturition=no,UrethraBurn=yes}"
## [20] "{Nausea=no,UrinePush=yes,Micturition=no,UrethraBurn=yes}"
## [21] "{Nausea=no,LumbarPain=yes,UrinePush=yes,UrethraBurn=yes}"
## [22] "{Nausea=no,LumbarPain=yes,Micturition=no,UrethraBurn=no}"
## [23] "{Nausea=no,LumbarPain=yes,UrinePush=yes,Micturition=no}"
## Itemsets in Consequent (RHS)
## [1] "{Type=Nephritis_renal}" "{Type=Urinary_Bladder}"
plot(rule2,method= "paracoord")
plot(rule2, method="graph",engine="htmlwidget")
Cẩn trọng: Khai phá quy luật kết hợp thì dễ, nhưng diễn giải các quy luật này thì không đơn giản, và Sai lầm đã từng xảy ra trong các nghiên cứu thị trường và hệ thống tư vấn dịch vụ.
Thí dụ, quy luật thứ 1 có nội dung: Chẩn đoán = viêm bàng quang khi Nhiệt độ bình thường (khoảng 36.5-7.5°C), và không có triệu chứng đau lưng, và UrinePush=Yes, Micturition=yes, tuy quy luật này có tần suất hiện diện cao nhất (support = 0.167, tương ứng 20/120 cases), lift cao nhất = 2.034. Tuy nhiên, quy luật kết hợp không có hàm ý so sánh tỉ lệ hay xác suất, tức là ta không thể diễn giải: xác suất viêm bàng quang ở người không đau lưng cao hơn người có đau lưng (đối nghịch với quy luật 14).
Luật kết hợp, do đó thích hợp với mục tiêu thăm dò dữ liệu, phát hiện mối liên hệ giữa các yếu tố và biến kết quả, bao gồm quan hệ tương tác. Tuy nhiên,nó có chỉ có công dụng hạn chế cho mục tiêu diễn dịch hoặc chứng minh một giả thuyết (vì không có yếu tố phản nghiệm, không có ý nghĩa so sánh).
Điều này có phải là nhược điểm của Association rule so với Chi2 test không ? Câu trả lời là không, vì bản thân Chi2 test cũng chỉ có thể được diễn giải cho từng biến độc lập, và với giả thuyết H0 về tính độc lập giữa một Triệu chứng và Bệnh.
Một điểm thú vị khác cần lưu ý, đó là kết quả của luật kết hợp phụ thuộc rất lớn vào cỡ mẫu và bị chi phối bởi những điều kiện chủ quan của người dùng (về ngưỡng support và confidence, số phần tử), cũng như các điều kiện chọn lọc chuyên biệt khác trên rhs, lhs; do đó nó khó sử dụng hơn, và dễ bị ảnh hưởng bởi cảm tính chủ quan hơn so với giải thuật cây quyết định và log-linear hay logistic đa biến.
Luật kết hợp và giải thuật apriori là một công cụ thay thế từ phái Machine learning, cho bài toán khảo sát mối liên hệ giữa các biến rời rạc và định tính, thí dụ liên hệ Triệu chứng/bệnh. Association rule thích hợp để thăm dò dữ liệu và mục tiêu mô tả. So với việc lạm dụng bảng chéo/Kiểm định ki bình phương thì Association rule mang lại nhiều thông tin hơn, nhưng hiệu quả không cao bằng những mô hình Cây quyết định hay logistic đa biến.