Ví dụ khi sử dụng độ chính xác làm thước đo kết quả sẽ dẫn đến kết luận sai


8

Tôi đang xem xét các biện pháp hiệu suất khác nhau cho các mô hình dự đoán. Rất nhiều đã được viết về các vấn đề sử dụng độ chính xác, thay vì một cái gì đó liên tục hơn để đánh giá hiệu suất mô hình. Frank Harrell http://www.fharrell.com/post/ class-damage / cung cấp một ví dụ khi thêm một biến thông tin vào mô hình sẽ dẫn đến giảm độ chính xác, rõ ràng phản trực giác và kết luận sai.

nhập mô tả hình ảnh ở đây

Tuy nhiên, trong trường hợp này, điều này dường như được gây ra bởi việc có các lớp mất cân bằng, và do đó nó có thể được giải quyết chỉ bằng cách sử dụng độ chính xác cân bằng thay thế ((Sens + spec) / 2). Có một số ví dụ trong đó việc sử dụng độ chính xác trên một tập dữ liệu cân bằng sẽ dẫn đến một số kết luận rõ ràng sai hoặc phản trực giác?

Biên tập

Tôi đang tìm kiếm thứ gì đó mà độ chính xác sẽ giảm ngay cả khi mô hình rõ ràng tốt hơn hoặc sử dụng độ chính xác sẽ dẫn đến lựa chọn tích cực sai về một số tính năng. Thật dễ dàng để tạo ra các ví dụ tiêu cực sai, trong đó độ chính xác là giống nhau cho hai mô hình trong đó một mô hình rõ ràng tốt hơn bằng cách sử dụng các tiêu chí khác.



2
Bài đăng của Stephan được liên kết ở trên là một tài nguyên tuyệt vời và có mọi thứ bạn cần. Bước đầu tiên của bạn về việc giả định rằng một phân loại bắt buộc (quyết định sớm) là cần thiết đã dẫn đến một vấn đề. Và (Sens + spec) / 2 không phải là điểm chính xác phù hợp; tối ưu hóa nó sẽ dẫn đến việc chọn các tính năng sai và cho chúng các trọng số sai, chưa kể đến việc bỏ qua thông tin hữu ích đến từ xác suất, chẳng hạn như các khu vực "không quyết định".
Frank Harrell

Tôi hiểu giá trị của các dự đoán xác suất, nhưng tôi đang tìm kiếm các ví dụ trong đó những điều xấu mà bạn đề cập thực sự xảy ra đối với dữ liệu cân bằng hoặc độ chính xác cân bằng.
rep_ho

BTW: theo độ chính xác của Gneiting & Raftery 2007 là đúng (mặc dù không hoàn toàn đúng). Có ý kiến ​​gì về điều đó? amstat.tandfonline.com/doi/abs/10.1198/ từ
rep_ho

Tôi hy vọng rằng câu trả lời của tôi là hữu ích. (@FrankHarrell: mọi bình luận đều được hoan nghênh.) Độ chính xác cân bằng sẽ không hữu ích ở đây. Về độ chính xác như một quy tắc chấm điểm thích hợp nhưng không hoàn toàn đúng: bạn có thể quan tâm đến Độ chính xác có phải là quy tắc chấm điểm không chính xác trong cài đặt phân loại nhị phân không? Nếu chủ đề đó không trả lời câu hỏi của bạn, hãy xem xét việc hỏi một câu hỏi mới (và chỉ ra lý do tại sao chủ đề hiện tại không phải là một câu trả lời để nó không bị đóng lại).
Stephan Kolassa

Câu trả lời:


13

Tôi sẽ lừa dối.

Cụ thể, tôi đã lập luận thường xuyên (ví dụ, ở đây ) rằng phần thống kê của mô hình hóa và dự đoán chỉ mở rộng để đưa ra dự đoán xác suất cho tư cách thành viên của lớp (hoặc đưa ra mật độ dự đoán, trong trường hợp dự báo bằng số). Đối xử với một trường hợp cụ thể như thể nó thuộc về một lớp cụ thể (hoặc dự đoán điểm trong trường hợp số), không còn là thống kê chính xác nữa. Nó là một phần của khía cạnh lý thuyết quyết định .

Và các quyết định không chỉ được đưa ra dựa trên dự đoán xác suất, mà còn về chi phí phân loại sai, và trên một loạt các hành động có thể khác . Ví dụ, ngay cả khi bạn chỉ có hai lớp khả thi là "bệnh" hoặc "khỏe mạnh", bạn có thể có một loạt các hành động có thể xảy ra tùy thuộc vào khả năng bệnh nhân mắc bệnh, vì đã gửi anh ta về nhà vì anh ta Gần như chắc chắn là khỏe mạnh, để cho anh ta hai viên aspirin, để chạy các xét nghiệm bổ sung, gọi ngay xe cứu thương và đưa anh ta vào hỗ trợ cuộc sống.

Đánh giá độ chính xác giả định trước một quyết định như vậy. Độ chính xác như một thước đo đánh giá để phân loại là một lỗi danh mục .

Vì vậy, để trả lời câu hỏi của bạn, tôi sẽ đi theo con đường của một lỗi danh mục như vậy. Chúng tôi sẽ xem xét một kịch bản đơn giản với các lớp cân bằng trong đó phân loại mà không quan tâm đến chi phí phân loại sai thực sự sẽ đánh lừa chúng tôi rất tệ.


Giả sử một bệnh dịch của Gutrot Malignant lan tràn trong dân chúng. May mắn thay, chúng ta có thể sàng lọc tất cả mọi người một cách dễ dàng đối với một số đặc điểm t ( 0t1 ), và chúng tôi biết rằng xác suất của việc phát triển MG phụ thuộc tuyến tính trên t , p= =γt đối với một số tham số γ ( 0γ1 ). Các tính trạng t được phân bố đồng đều trong quần thể.

May mắn thay, có một loại vắc-xin. Thật không may, nó đắt tiền, và các tác dụng phụ rất khó chịu. (Tôi sẽ để trí tưởng tượng của bạn cung cấp các chi tiết.) Tuy nhiên, chúng tốt hơn là chịu đựng MG.

Vì lợi ích của sự trừu tượng, tôi thừa nhận rằng có thực sự chỉ có hai hướng hành động cho bất kỳ bệnh nhân nào đó, đưa giá trị đặc điểm của họ t : hoặc tiêm, hoặc không tiêm.

Vì vậy, câu hỏi là: làm thế nào chúng ta nên quyết định ai nên tiêm phòng và ai không, cho t ? Chúng tôi sẽ thực dụng về điều này và nhằm mục đích có tổng chi phí dự kiến ​​thấp nhất. Rõ ràng là điều này đi xuống để lựa chọn một ngưỡng θ và để tất cả mọi người tiêm với tθ .


Mô hình và quyết định 1 được định hướng chính xác. Phù hợp với một mô hình. May mắn thay, chúng tôi đã biết mô hình. Chọn ngưỡng θ nhằm tối đa hóa độ chính xác khi phân loại bệnh nhân , và tiêm phòng cho tất cả mọi người với tθ . Chúng ta dễ dàng thấy rằng θ= =12γ là con số kỳ diệu - tất cả mọi người vớitθcó cơ hội cao hơn của nhiễm MG hơn không, và ngược lại, vì vậy đâyngưỡng khả năng phân loạisẽ phát huy tối đa độ chính xác. Giả sử các lớp cân bằng,γ= =1, chúng tôi sẽ tiêm chủng một nửa dân số. Đủ vui, nếuγ<12 , chúng tôi sẽ tiêm phòng choai. (Chúng tôi chủ yếu quan tâm đến các lớp cân bằng, vì vậy, hãy bỏ qua việc chúng tôi chỉ để một phần dân số chết một cái chết đau đớn khủng khiếp.)

Không cần phải nói, điều này không tính đến chi phí chênh lệch của phân loại sai.


Model-and-quyết định 2 đòn bẩy cả dự đoán xác suất của chúng tôi ( "được đặc điểm của bạn t , khả năng bạn mắc MG là γt ") các cơ cấu chi phí.

Đầu tiên, đây là một biểu đồ nhỏ. Trục hoành cho đặc điểm, trục dọc xác suất MG. Tam giác mờ cho tỷ lệ dân số sẽ ký hợp đồng MG. Đường thẳng đứng cho một số đặc biệt θ . Dòng đứt ngang ở γθ sẽ làm cho các tính toán bên dưới một chút đơn giản để làm theo. Chúng tôi giả định γ>12 , chỉ để làm cho cuộc sống dễ dàng hơn.

phân loại

Hãy cung cấp cho tên chi phí của chúng tôi và tính toán đóng góp của họ so với tổng chi phí dự kiến, trao θγ (và thực tế là những đặc điểm được phân bố đều trong dân số).

  • Đặt c++ biểu thị chi phí cho một bệnh nhân đã được tiêm phòng và sẽ ký hợp đồng với MG. Với θ , tỷ lệ dân số người phải gánh chịu chi phí này là hình thang bóng mờ ở góc dưới bên với diện tích
    (1-θ)γθ+12(1-θ)(γ-γθ).
  • Đặt c+- biểu thị chi phí cho một bệnh nhân đã được tiêm phòng và sẽ không ký hợp đồng với MG. Với θ , tỷ lệ dân số người phải gánh chịu chi phí này là hình thang không có chụp ở phía trên bên phải với diện tích
    (1-θ)(1-γ)+12(1-θ)(γ-γθ).
  • Đặt c-- biểu thị chi phí cho một bệnh nhân không được tiêm phòng và sẽ không ký hợp đồng với MG. Với θ , tỷ lệ dân số người phải gánh chịu chi phí này là hình thang không có chụp ở phía trên bên trái có diện tích
    θ(1-γθ)+12θγθ.
  • Đặt c-+ biểu thị chi phí cho một bệnh nhân không được tiêm phòng và sẽ ký hợp đồng với MG. Với θ , tỷ lệ dân số người phải gánh chịu chi phí này là tam giác bóng mờ ở phía dưới bên trái, với diện tích
    12θγθ.

(Trong mỗi hình thang, trước tiên tôi tính diện tích của hình chữ nhật, sau đó thêm diện tích của hình tam giác.)

Tổng số dự kiến chi phí là

c++((1-θ)γθ+12(1-θ)(γ-γθ))+c+-((1-θ)(1-γ)+12(1-θ)(γ-γθ))+c--(θ(1-γθ)+12θγθ)+c-+12θγθ.

Phân biệt và đặt đạo hàm về 0, chúng tôi thu được rằng chi phí dự kiến ​​được giảm thiểu bằng

θ*= =c+--c--γ(c-++c+--c++-c--).

Giá trị này chỉ bằng với giá trị tối đa hóa chính xác của θ cho cấu trúc chi phí rất cụ thể, cụ thể là khi và chỉ khi

12γ= =c+--c--γ(c-++c+--c++-c--),
hoặc
12= =c+--c--c-++c+--c++-c--.

Như một ví dụ, giả sử rằng γ= =1 cho các lớp cân bằng và chi phí là

c++= =1,c+-= =2,c-+= =10,c--= =0.
đó độ chính xác tối đa hóaθ= =12 sẽ mang lại chi phí dự kiến1.875, trong khi chi phí giảm thiểuθ= =211 sẽ mang lại chi phí dự kiến ​​là1.318.

Trong ví dụ này, dựa trên các quyết định của chúng tôi về phân loại phi xác suất mà độ chính xác tối đa hóa đã dẫn đến việc tiêm chủng nhiều hơn và chi phí cao hơn so với sử dụng quy tắc quyết định sử dụng rõ ràng cấu trúc chi phí chênh lệch trong bối cảnh dự đoán xác suất.


Điểm mấu chốt: độ chính xác chỉ là một tiêu chí quyết định hợp lệ nếu

  • có một mối quan hệ một-một giữa các lớp và các hành động có thể
  • chi phí của các hành động được áp dụng cho các lớp theo một cấu trúc rất cụ thể.

Trong trường hợp chung, việc đánh giá độ chính xác sẽ hỏi một câu hỏi sai và tối đa hóa độ chính xác là một lỗi được gọi là lỗi loại III: cung cấp câu trả lời đúng cho câu hỏi sai.


Mã R:

rm(list=ls())
gamma <- 0.7

cost_treated_positive <- 1          # cost of treatment, side effects unimportant
cost_treated_negative <- 2          # cost of treatment, side effects unnecessary
cost_untreated_positive <- 10       # horrible, painful death
cost_untreated_negative <- 0        # nothing

expected_cost <- function ( theta ) {
    cost_treated_positive * ( (1-theta)*theta*gamma + (1-theta)*(gamma-gamma*theta)/2 ) +
    cost_treated_negative * ( (1-theta)*(1-gamma) + (1-theta)*(gamma-gamma*theta)/2 ) +
    cost_untreated_negative *( theta*(1-gamma*theta) + theta*gamma*theta/2 ) +
    cost_untreated_positive * theta*gamma*theta/2
}

(theta <- optim(par=0.5,fn=expected_cost,lower=0,upper=1,method="L-BFGS-B")$par)
(cost_treated_negative-cost_untreated_negative)/
    (gamma*(cost_treated_negative+cost_untreated_positive-cost_treated_positive-cost_untreated_negative))

plot(c(0,1),c(0,1),type="n",bty="n",xaxt="n",xlab="Trait t",yaxt="n",ylab="MG probability")
rect(0,0,1,1)
axis(1,c(0,theta,1),c(0,"theta",1),lty=0,line=-1)
axis(2,c(0,1),lty=0,line=-1,las=1)
axis(4,c(0,gamma,1),c(0,"gamma",1),lty=0,line=-1.8,las=1)
polygon(c(0,1,1),c(0,0,gamma),col="lightgray")
abline(v=theta,col="red",lwd=2)
abline(h=gamma*theta,lty=2,col="red",lwd=2)

expected_cost(1/(2*gamma))
expected_cost(theta)

1
Bài đăng tuyệt vời! Chỉ cần đăng nhập để bày tỏ cảm ơn của tôi!
Wolfone

"mà còn về chi phí phân loại sai" Tôi không nghĩ nó đúng: giống như tính toán của bạn cho thấy, nó cũng (khá đáng ngạc nhiên!) cũng phụ thuộc vào chi phí phân loại chính xác !
Tamas Ferenci

cd+= =c-+-c++cd-= =c+--c--θ*= =cd-γ(cd-+cd+)

Chúng ta cũng có thể thực hiện một âm mưu này:levelplot( thetastar ~ cdminus + cdplus, data = data.table( expand.grid( cdminus = seq( 0, 10, 0.01 ), cdplus = seq( 0, 10, 0.01 ) ) )[ , .( cdminus, cdplus, thetastar = cdminus/(cdminus + cdplus) ) ] )
Tamas Ferenci

θ=1/γ1+cd+cd-

4

Có thể đáng để thêm một ví dụ khác, có lẽ đơn giản hơn vào câu trả lời xuất sắc của Stephen.

T|D~N(μ-,σ2)T|D~N(μ+,σ2).
pD~Bern(p)

bb

(DDTp(1-Φ+(b))(1-p)(1-Φ-(b))TpΦ+(b)(1-p)Φ-(b)).


Cách tiếp cận dựa trên độ chính xác

p(1Φ+(b))+(1p)Φ(b),

b1πσ2

-pφ+(b)+φ-(b)-pφ-(b)= =0e-(b-μ-)22σ2[(1-p)-pe-2b(μ--μ+)+(μ+2-μ-2)2σ2]= =0
(1p)pe2b(μμ+)+(μ+2μ2)2σ2=02b(μμ+)+(μ+2μ2)2σ2=log1pp2b(μ+μ)+(μ2μ+2)=2σ2log1pp
b=(μ+2μ2)+2σ2log1pp2(μ+μ)=μ++μ2+σ2μ+μlog1pp.

Lưu ý rằng điều này - tất nhiên - không phụ thuộc vào chi phí.

Nếu các lớp được cân bằng, tối ưu là trung bình của các giá trị thử nghiệm trung bình ở người ốm và người khỏe mạnh, nếu không, nó bị thay thế dựa trên sự mất cân bằng.


Phương pháp dựa trên chi phí

c++p(1Φ+(b))+c+(1p)(1Φ(b))+c+pΦ+(b)+c(1p)Φ(b).
b
c++pφ+(b)c+(1p)φ(b)+c+pφ+(b)+c(1p)φ(b)==φ+(b)p(c+c++)+φ(b)(1p)(cc+)==φ+(b)pcd+φ(b)(1p)cd=0,
cd+=c+c++ and cd=c+c.

The optimal threshold is therefore given by the solution of the equation

φ+(b)φ(b)=(1p)cdpcd+.
Two things should be noted here:

  1. This results is totally generic and works for any distribution of the test results, not only normal. (φ in that case of course means the probability density function of the distribution, not the normal density.)
  2. Whatever the solution for b is, it is surely a function of (1p)cdpcd+. (I.e., we immediately see how costs matter - in addition to class imbalance!)

I'd be really interested to see if this equation has a generic solution for b (parametrized by the φs), but I would be surprised.

Nevertheless, we can work it out for normal! 2πσ2s cancel on the left hand side, so we have

e12((bμ+)2σ2(bμ)2σ2)=(1p)cdpcd+(bμ)2(bμ+)2=2σ2log(1p)cdpcd+2b(μ+μ)+(μ2μ+2)=2σ2log(1p)cdpcd+
therefore the solution is
b=(μ+2μ2)+2σ2log(1p)cdpcd+2(μ+μ)=μ++μ2+σ2μ+μlog(1p)cdpcd+.

(Compare it the the previous result! We see that they are equal if and only if cd=cd+, i.e. the differences in misclassification cost compared to the cost of correct classification is the same in sick and healthy people.)


A short demonstration

Let's say c=0 (it is quite natural medically), and that c++=1 (we can always obtain it by dividing the costs with c++, i.e., by measuring every cost in c++ units). Let's say that the prevalence is p=0.2. Ngoài ra, hãy nói rằngμ-= =9,5, μ+= =10,5σ= =1.

Trong trường hợp này:

library( data.table )
library( lattice )

cminusminus <- 0
cplusplus <- 1
p <- 0.2
muminus <- 9.5
muplus <- 10.5
sigma <- 1

res <- data.table( expand.grid( b = seq( 6, 17, 0.1 ),
                                cplusminus = c( 1, 5, 10, 50, 100 ),
                                cminusplus = c( 2, 5, 10, 50, 100 ) ) )
res$cost <- cplusplus*p*( 1-pnorm( res$b, muplus, sigma ) ) +
  res$cplusminus*(1-p)*(1-pnorm( res$b, muminus, sigma ) ) +
  res$cminusplus*p*pnorm( res$b, muplus, sigma ) +
  cminusminus*(1-p)*pnorm( res$b, muminus, sigma )

xyplot( cost ~ b | factor( cminusplus ), groups = cplusminus, ylim = c( -1, 22 ),
        data = res, type = "l", xlab = "Threshold",
        ylab = "Expected overall cost", as.table = TRUE,
        abline = list( v = (muplus+muminus)/2+
                         sigma^2/(muplus-muminus)*log((1-p)/p) ),
        strip = strip.custom( var.name = expression( {"c"^{"+"}}["-"] ),
                              strip.names = c( TRUE, TRUE ) ),
        auto.key = list( space = "right", points = FALSE, lines = TRUE,
                         title = expression( {"c"^{"-"}}["+"] ) ),
        panel = panel.superpose, panel.groups = function( x, y, col.line, ... ) {
          panel.xyplot( x, y, col.line = col.line, ... )
          panel.points( x[ which.min( y ) ], min( y ), pch = 19, col = col.line )
        } )

Kết quả là (các điểm mô tả chi phí tối thiểu và đường thẳng đứng hiển thị ngưỡng tối ưu với cách tiếp cận dựa trên độ chính xác):

Chi phí tổng thể dự kiến

Chúng ta có thể thấy rất tốt cách tối ưu dựa trên chi phí có thể khác với tối ưu dựa trên độ chính xác. Bạn nên suy nghĩ về lý do tại sao: nếu việc phân loại một người bệnh sai lầm khỏe mạnh sẽ tốn kém hơn so với cách khác (c-+ cao, c+- là thấp) so với ngưỡng đi xuống, vì chúng tôi muốn phân loại dễ dàng hơn vào loại bệnh, mặt khác, nếu việc phân loại một người khỏe mạnh bị bệnh nhầm hơn so với cách khác là tốn kém hơn (c-+ chậm, c+-là cao) so với ngưỡng tăng lên, vì chúng tôi muốn phân loại dễ dàng hơn vào danh mục lành mạnh. (Kiểm tra những cái này trên hình!)


Một ví dụ thực tế

Chúng ta hãy xem xét một ví dụ thực nghiệm, thay vì dẫn xuất lý thuyết. Ví dụ này về cơ bản sẽ khác nhau từ hai khía cạnh:

  • Thay vì giả định tính quy tắc, chúng tôi sẽ chỉ sử dụng dữ liệu theo kinh nghiệm mà không có bất kỳ giả định nào như vậy.
  • Thay vì sử dụng một thử nghiệm duy nhất và kết quả của nó trong các đơn vị riêng của mình, chúng tôi sẽ sử dụng một số thử nghiệm (và kết hợp chúng với hồi quy logistic). Ngưỡng sẽ được đưa ra xác suất dự đoán cuối cùng. Đây thực sự là cách tiếp cận ưa thích, xem Chương 19 - Chẩn đoán - trong BBR của Frank Harrell .

Bộ dữ liệu ( acathtừ gói Hmisc) là từ Databank Bệnh tim mạch của Đại học Duke, và chứa liệu bệnh nhân có bị bệnh mạch vành đáng kể hay không, như được đánh giá bằng thông tim, đây sẽ là tiêu chuẩn vàng của chúng tôi, tức là tình trạng bệnh thật và "xét nghiệm" "Sẽ là sự kết hợp giữa tuổi, giới tính, mức cholesterol và thời gian xuất hiện của đối tượng:

library( rms )
library( lattice )
library( latticeExtra )
library( data.table )

getHdata( "acath" )
acath <- acath[ !is.na( acath$choleste ), ]
dd <- datadist( acath )
options( datadist = "dd" )

fit <- lrm( sigdz ~ rcs( age )*sex + rcs( choleste ) + cad.dur, data = acath )

Đáng để vạch ra các rủi ro dự đoán theo thang đo logit, để xem mức độ bình thường của chúng (về cơ bản, đó là những gì chúng tôi đã giả định trước đây, với một thử nghiệm duy nhất!):

densityplot( ~predict( fit ), groups = acath$sigdz, plot.points = FALSE, ref = TRUE,
             auto.key = list( columns = 2 ) )

Phân phối rủi ro dự đoán

Chà, họ hầu như không bình thường ...

Hãy tiếp tục và tính toán chi phí tổng thể dự kiến:

ExpectedOverallCost <- function( b, p, y, cplusminus, cminusplus,
                                 cplusplus = 1, cminusminus = 0 ) {
  sum( table( factor( p>b, levels = c( FALSE, TRUE ) ), y )*matrix(
    c( cminusminus, cplusminus, cminusplus, cplusplus ), nc = 2 ) )
}

table( predict( fit, type = "fitted" )>0.5, acath$sigdz )

ExpectedOverallCost( 0.5, predict( fit, type = "fitted" ), acath$sigdz, 2, 4 )

Và hãy vẽ nó cho tất cả các chi phí có thể (một lưu ý tính toán: chúng ta không cần phải lặp đi lặp lại một cách vô thức qua các số từ 0 đến 1, chúng ta có thể xây dựng lại đường cong một cách hoàn hảo bằng cách tính toán cho tất cả các giá trị duy nhất của xác suất dự đoán):

ps <- sort( unique( c( 0, 1, predict( fit, type = "fitted" ) ) ) )

xyplot( sapply( ps, ExpectedOverallCost,
                p = predict( fit, type = "fitted" ), y = acath$sigdz,
                cplusminus = 2, cminusplus = 4 ) ~ ps, type = "l", xlab = "Threshold",
        ylab = "Expected overall cost", panel = function( x, y, ... ) {
          panel.xyplot( x, y, ... )
          panel.points( x[ which.min( y ) ], min( y ), pch = 19, cex = 1.1 )
          panel.text( x[ which.min( y ) ], min( y ), round( x[ which.min( y ) ], 3 ),
                      pos = 3 )
        } )

Chi phí tổng thể dự kiến ​​là một hàm của ngưỡng

Chúng ta có thể thấy rất rõ nơi chúng ta nên đặt ngưỡng để tối ưu hóa chi phí chung dự kiến ​​(không sử dụng độ nhạy, độ đặc hiệu hoặc giá trị dự đoán ở bất cứ đâu!). Đây là cách tiếp cận chính xác.

Điều đặc biệt là hướng dẫn để đối chiếu các số liệu này:

ExpectedOverallCost2 <- function( b, p, y, cplusminus, cminusplus,
                                  cplusplus = 1, cminusminus = 0 ) {
  tab <- table( factor( p>b, levels = c( FALSE, TRUE ) ), y )
  sens <- tab[ 2, 2 ] / sum( tab[ , 2 ] )
  spec <- tab[ 1, 1 ] / sum( tab[ , 1 ] )
  c( `Expected overall cost` = sum( tab*matrix( c( cminusminus, cplusminus, cminusplus,
                                                   cplusplus ), nc = 2 ) ),
     Sensitivity = sens,
     Specificity = spec,
     PPV = tab[ 2, 2 ] / sum( tab[ 2, ] ),
     NPV = tab[ 1, 1 ] / sum( tab[ 1, ] ),
     Accuracy = 1 - ( tab[ 1, 1 ] + tab[ 2, 2 ] )/sum( tab ),
     Youden = 1 - ( sens + spec - 1 ),
     Topleft = ( 1-sens )^2 + ( 1-spec )^2
  )
}

ExpectedOverallCost2( 0.5, predict( fit, type = "fitted" ), acath$sigdz, 2, 4 )

res <- melt( data.table( ps, t( sapply( ps, ExpectedOverallCost2,
                                        p = predict( fit, type = "fitted" ),
                                        y = acath$sigdz,
                                        cplusminus = 2, cminusplus = 4 ) ) ),
             id.vars = "ps" )

p1 <- xyplot( value ~ ps, data = res, subset = variable=="Expected overall cost",
              type = "l", xlab = "Threshold", ylab = "Expected overall cost",
              panel=function( x, y, ... ) {
                panel.xyplot( x, y,  ... )
                panel.abline( v = x[ which.min( y ) ],
                              col = trellis.par.get()$plot.line$col )
                panel.points( x[ which.min( y ) ], min( y ), pch = 19 )
              }  )
p2 <- xyplot( value ~ ps, groups = variable,
              data = droplevels( res[ variable%in%c( "Expected overall cost",
                                                     "Sensitivity",
                                                     "Specificity", "PPV", "NPV" ) ] ),
              subset = variable%in%c( "Sensitivity", "Specificity", "PPV", "NPV" ),
              type = "l", xlab = "Threshold", ylab = "Sensitivity/Specificity/PPV/NPV",
              auto.key = list( columns = 3, points = FALSE, lines = TRUE ) )
doubleYScale( p1, p2, use.style = FALSE, add.ylab2 = TRUE )

Dự kiến ​​tổng chi phí và số liệu truyền thống là một hàm của ngưỡng

Bây giờ chúng ta có thể phân tích các số liệu đôi khi được quảng cáo cụ thể là có thể đưa ra mức cắt tối ưu mà không phải trả chi phí, và tương phản với phương pháp dựa trên chi phí của chúng tôi! Hãy sử dụng ba số liệu thường được sử dụng nhất:

  • Độ chính xác (tối đa hóa độ chính xác)
  • Quy tắc Youden (tối đa hóa SenS+Spec-1)
  • Quy tắc Topleft (tối thiểu hóa (1-SenS)2+(1-Spec)2)

(Để đơn giản, chúng tôi sẽ trừ các giá trị trên từ 1 cho quy tắc Youden và Chính xác để chúng tôi có vấn đề tối thiểu hóa ở mọi nơi.)

Hãy xem kết quả:

p3 <- xyplot( value ~ ps, groups = variable,
              data = droplevels( res[ variable%in%c( "Expected overall cost", "Accuracy",
                                                     "Youden", "Topleft"  ) ] ),
              subset = variable%in%c( "Accuracy", "Youden", "Topleft"  ),
              type = "l", xlab = "Threshold", ylab = "Accuracy/Youden/Topleft",
              auto.key = list( columns = 3, points = FALSE, lines = TRUE ),
              panel = panel.superpose, panel.groups = function( x, y, col.line, ... ) {
                panel.xyplot( x, y, col.line = col.line, ... )
                panel.abline( v = x[ which.min( y ) ], col = col.line )
                panel.points( x[ which.min( y ) ], min( y ), pch = 19, col = col.line )
              } )
doubleYScale( p1, p3, use.style = FALSE, add.ylab2 = TRUE )

Lựa chọn để chọn mức cắt tối ưu

Tất nhiên điều này liên quan đến một cấu trúc chi phí cụ thể, c--= =0, c++= =1, c+-= =2, c-+= =4(điều này rõ ràng chỉ quan trọng đối với quyết định chi phí tối ưu). Để nghiên cứu ảnh hưởng của cấu trúc chi phí, chúng ta chỉ chọn ngưỡng tối ưu (thay vì theo dõi toàn bộ đường cong), nhưng vẽ nó như là một hàm của chi phí. Cụ thể hơn, như chúng ta đã thấy, ngưỡng tối ưu phụ thuộc vào bốn chi phí chỉ thông quacd-/cd+ tỷ lệ, vì vậy, hãy vẽ biểu đồ cắt tối ưu là một chức năng của điều này, cùng với các số liệu thường được sử dụng không sử dụng chi phí:

res2 <- data.frame( rat = 10^( seq( log10( 0.02 ), log10( 50 ), length.out = 500 ) ) )
res2$OptThreshold <- sapply( res2$rat,
                             function( rat ) ps[ which.min(
                               sapply( ps, Vectorize( ExpectedOverallCost, "b" ),
                                       p = predict( fit, type = "fitted" ),
                                       y = acath$sigdz,
                                       cplusminus = rat,
                                       cminusplus = 1,
                                       cplusplus = 0 ) ) ] )

xyplot( OptThreshold ~ rat, data = res2, type = "l", ylim = c( -0.1, 1.1 ),
        xlab = expression( {"c"^{"-"}}["d"]/{"c"^{"+"}}["d"] ), ylab = "Optimal threshold",
        scales = list( x = list( log = 10, at = c( 0.02, 0.05, 0.1, 0.2, 0.5, 1,
                                                   2, 5, 10, 20, 50 ) ) ),
        panel = function( x, y, resin = res[ ,.( ps[ which.min( value ) ] ),
                                             .( variable ) ], ... ) {
          panel.xyplot( x, y, ... )
          panel.abline( h = resin[variable=="Youden"] )
          panel.text( log10( 0.02 ), resin[variable=="Youden"], "Y", pos = 3 )
          panel.abline( h = resin[variable=="Accuracy"] )
          panel.text( log10( 0.02 ), resin[variable=="Accuracy"], "A", pos = 3 )
          panel.abline( h = resin[variable=="Topleft"] )
          panel.text( log10( 0.02 ), resin[variable=="Topleft"], "TL", pos = 1 )
        } )

Ngưỡng tối ưu cho các chi phí khác nhau

Các đường nằm ngang chỉ ra các cách tiếp cận không sử dụng chi phí (và do đó không đổi).

Một lần nữa, chúng tôi thấy rằng chi phí phân loại sai trong nhóm khỏe mạnh tăng lên so với nhóm bệnh, ngưỡng tối ưu tăng: nếu chúng tôi thực sự không muốn những người khỏe mạnh được phân loại là bệnh, chúng tôi sẽ sử dụng mức cắt cao hơn (và cách khác xung quanh, tất nhiên!).

Và cuối cùng, chúng ta lại thấy một lần nữa tại sao những phương pháp không sử dụng chi phí lại không ( và không thể! ) Luôn luôn tối ưu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.