исвязаны между собой. Я постараюсь проиллюстрировать это с помощью диагностического теста. Допустим, у вас есть диагностический тест, который измеряет уровень маркера крови. Известно, что люди, имеющие определенное заболевание, имеют более низкие уровни этого маркера по сравнению со здоровыми людьми. Сразу становится ясно, что вы должны выбрать пороговое значение, ниже которого человек классифицируется как «больной», тогда как люди с ценностями выше этого порогового значения считаются здоровыми. Однако весьма вероятно, что распределение маркера крови значительно различается дажесредибольных и здоровых людей. У некоторых здоровых людей может быть очень низкий уровень маркера крови, даже если они совершенно здоровы. И некоторые больные люди имеют высокий уровень маркера крови, хотя у них есть заболевание.αβ
Существует четыре возможных варианта:
- больной человек правильно идентифицирован как больной (истинно положительный = TP)
- больной человек ошибочно классифицируется как здоровый (ложноотрицательный = FN)
- здоровый человек правильно идентифицирован как здоровый (истинно отрицательный = TN)
- здоровый человек ошибочно классифицируется как больной (ложноположительный = ФП)
Эти возможности можно проиллюстрировать с помощью таблицы 2x2 :
Sick Healthy
Test positive TP FP
Test negative FN TN
α = F P / ( F P + T N ) β β = F N / ( T P + F N )α обозначает частоту ложных срабатываний, которая равна . - это ложноотрицательный показатель, который равен . Я написал простой сценарий, чтобы проиллюстрировать ситуацию графически.α = Fп/ (Fп+ TN)ββ= FN/ (Tп+ FN)R
alphabeta <- function(mean.sick=100, sd.sick=10, mean.healthy=130, sd.healthy=10, cutoff=120, n=10000, side="below", do.plot=TRUE) {
popsick <- rnorm(n, mean=mean.sick, sd=sd.sick)
pophealthy <- rnorm(n, mean=mean.healthy, sd=sd.healthy)
if ( side == "below" ) {
truepos <- length(popsick[popsick <= cutoff])
falsepos <- length(pophealthy[pophealthy <= cutoff])
trueneg <- length(pophealthy[pophealthy > cutoff])
falseneg <- length(popsick[popsick > cutoff])
} else if ( side == "above" ) {
truepos <- length(popsick[popsick >= cutoff])
falsepos <- length(pophealthy[pophealthy >= cutoff])
trueneg <- length(pophealthy[pophealthy < cutoff])
falseneg <- length(popsick[popsick < cutoff])
}
twotable <- matrix(c(truepos, falsepos, falseneg, trueneg), 2, 2, byrow=T)
rownames(twotable) <- c("Test positive", "Test negative")
colnames(twotable) <- c("Sick", "Healthy")
spec <- twotable[2,2]/(twotable[2,2] + twotable[1,2])
alpha <- 1 - spec
sens <- pow <- twotable[1,1]/(twotable[1,1] + twotable[2,1])
beta <- 1 - sens
pos.pred <- twotable[1,1]/(twotable[1,1] + twotable[1,2])
neg.pred <- twotable[2,2]/(twotable[2,2] + twotable[2,1])
if ( do.plot == TRUE ) {
dsick <- density(popsick)
dhealthy <- density(pophealthy)
par(mar=c(5.5, 4, 0.5, 0.5))
plot(range(c(dsick$x, dhealthy$x)), range(c(c(dsick$y, dhealthy$y))), type = "n", xlab="", ylab="", axes=FALSE)
box()
axis(1, at=mean(pophealthy), lab=substitute(mu[H[0]]~paste("=",m, sep=""), list(m=mean.healthy)), cex.axis=1.5,tck=0.02)
axis(1, at=mean(popsick), lab=substitute(mu[H[1]]~paste("=",m, sep=""), list(m=mean.sick)), cex.axis=1.5, tck=0.02)
axis(1, at=cutoff, lab=substitute(italic(paste("Cutoff=",coff, sep="")), list(coff=cutoff)), pos=-0.004, tick=FALSE, cex.axis=1.25)
lines(dhealthy, col = "steelblue", lwd=2)
if ( side == "below" ) {
polygon(c(cutoff, dhealthy$x[dhealthy$x<=cutoff], cutoff), c(0, dhealthy$y[dhealthy$x<=cutoff],0), col = "grey65")
} else if ( side == "above" ) {
polygon(c(cutoff, dhealthy$x[dhealthy$x>=cutoff], cutoff), c(0, dhealthy$y[dhealthy$x>=cutoff],0), col = "grey65")
}
lines(dsick, col = "red", lwd=2)
if ( side == "below" ) {
polygon(c(cutoff,dsick$x[dsick$x>cutoff],cutoff),c(0,dsick$y[dsick$x>cutoff],0) , col="grey90")
} else if ( side == "above" ) {
polygon(c(cutoff,dsick$x[dsick$x<=cutoff],cutoff),c(0,dsick$y[dsick$x<=cutoff],0) , col="grey90")
}
legend("topleft",
legend=(c(as.expression(substitute(alpha~paste("=", a), list(a=round(alpha,3)))),
as.expression(substitute(beta~paste("=", b), list(b=round(beta,3)))))), fill=c("grey65", "grey90"), cex=1.2, bty="n")
abline(v=mean(popsick), lty=3)
abline(v=mean(pophealthy), lty=3)
abline(v=cutoff, lty=1, lwd=1.5)
abline(h=0)
}
#list(specificity=spec, sensitivity=sens, alpha=alpha, beta=beta, power=pow, positiv.predictive=pos.pred, negative.predictive=neg.pred)
c(alpha, beta)
}
Давайте посмотрим на пример. Мы предполагаем, что средний уровень маркера крови среди больных составляет 100 со стандартным отклонением 10. У здоровых людей средний уровень в крови составляет 140 со стандартным отклонением 15. Клиницист устанавливает порог в 120.
alphabeta(mean.sick=100, sd.sick=10, mean.healthy=140, sd.healthy=15, cutoff=120, n=100000, do.plot=TRUE, side="below")
Sick Healthy
Test positive 9764 901
Test negative 236 9099
Вы видите, что затененные области связаны друг с другом. В этом случае и . Но что произойдет, если врач установил срез по-другому? Давайте установим его немного ниже, до 105 и посмотрим, что произойдет.β = 236 / ( 236 + 9764 ) ≈ 0,024α = 901 / ( 901 + 9099 ) ≈ 0,09β= 236 / ( 236 + 9764 ) ≈ 0,024
Sick Healthy
Test positive 6909 90
Test negative 3091 9910
Наш очень низкий сейчас, потому что почти нет здоровых людей с диагнозом "больной". Но наша увеличилась, потому что больные люди с высоким уровнем маркера крови теперь ошибочно классифицируются как здоровые.βαβ
Наконец, давайте посмотрим, как изменяются и для разных срезов:βαβ
cutoffs <- seq(0, 200, by=0.1)
cutoff.grid <- expand.grid(cutoffs)
plot.frame <- apply(cutoff.grid, MARGIN=1, FUN=alphabeta, mean.sick=100, sd.sick=10, mean.healthy=140, sd.healthy=15, n=100000, do.plot=FALSE, side="below")
plot(plot.frame[1,]~cutoffs, type="l", las=1, xlab="Cutoff value", ylab="Alpha/Beta", lwd=2, cex.axis=1.5, cex.lab=1.2)
lines(plot.frame[2,]~cutoffs, col="steelblue", lty=2, lwd=2)
legend("topleft", legend=c(expression(alpha), expression(beta)), lwd=c(2,2),lty=c(1,2), col=c("black", "steelblue"), bty="n", cex=1.2)
Вы можете сразу увидеть, что соотношениеαβ
Здесь у нас есть «идеальный» тест в том смысле, что отсечение 150 отличает больных от здоровых.
Настройки Бонферрони
αββ0.020,31α0,090,01