Klassifikation mit Hilfe eines Markergens

Werbung
Statistik für Bioinformatiker SoSe 2003
Rainer Spang
Klassifikation mit Hilfe eines Markergens
Im 13. Kapitel der Vorlesung wurde gezeigt, wie man mit Hilfe von Trainingsdaten einen
kritischen Wert bestimmt, der neue Patienten einer Klasse zuweist. Das werden wir heute mit
R simulieren.
Gegeben sind die Expressionswerte eines Gens von jeweils 20 Patienten aus Klasse 1 und Klasse
2 und wir wissen natürlich, welcher Patient zu welcher Klasse gehört. Das sind unsere Trainingsdaten. Wir unterstellen Normalverteilungen mit gleichen Varianzen. Aus dem Vergleich
der Likelihoods kennen wir den kritischen Wert C1 :
C1 =
Mittelwert(Klasse 1) + Mittelwert(Klasse 2)
2
Wir können uns auch überlegen, einen anderen kritischen Wert zu berechnen. Wie wäre es mit
dem Median anstelle des Mittelwertes? Bei jeder symmetrischen unimodalen Verteilung wie
der Normalverteilung ist der theoretische Median gleich dem Erwartungswert. Der empirische
Median ist daher wie der Mittelwert auch ein Schätzer für den Erwartungswert. Er ist ein
robuster Schätzer, d.h. (wenige) Ausreißer fallen nicht ins Gewicht. Als alternativen kritischen
Wert C2 berechnen wir:
C2 =
Median(Klasse 1) + Median(Klasse 2)
2
Welcher kritische Wert ist jetzt besser, d.h. führt zu weniger Fehlern bei der Klassifikation? Dazu führen wir eine Leave-one-out-Kreuzvalidierung durch. Die Idee hierbei ist, dass wir eine
Beobachtung aus unseren Trainingsdaten entnehmen und die Klassifikatoren auf dem reduzierten Trainingsset lernen. Der Vorteil ist, dass wir die Klassenzugehörigkeit des Testsamples
jetzt kennen. Wir klassifizieren das Testsample und merken uns, ob wir richtig klassifiziert haben. Dann entnehmen wir eine andere Beobachtung aus dem ursprünglichen Trainingsset und
wiederholen die Prozedur (d.h. lernen neu und klassifizieren). Das wird so lange wiederholt, bis
wir jede Beobachtung einmal klassifiziert haben. Am Ende berechnen wir die Fehlerhäufigkeit
(“Kreuzvalidierungsfehler”).
Jetzt würde man die Methode mit dem kleinsten Kreuzvalidierungsfehler nehmen und den
kritischen Wert aus dem gesamten Trainingsset bestimmen. Die Methode wird nun auf einem
unabhängigen Testset evaluiert, das man vorher nie miteinbezogen hat. In der Regel kennt
man auch die Klassenzugehörigkeit des Testsets und kann den Testfehler bestimmen. Kennt
man die Klassen des Testsets nicht, entspricht das der Situation, dass man neue Patienten mit
unbekannter Diagnose hat.
Aufgabe.
1. Simuliere ein Trainingsset mit 40 Beobachtungen, wobei die ersten 20 aus einer Normalverteilung N (µ1 , σ) und die anderen 20 aus N (µ2 , σ) stammen. Die Parameter sind
frei wählbar, so dass man ausprobieren kann, wie die Klassifikatoren in verschiedenen
Situationen abschneiden (kleine/große Differenz der Mittelwerte, kleine/große Varianz).
Berechne die Kreuzvalidierungsfehler der obigen kritischen Werte C1 und C2 ! Welchen
würde man bevorzugen?
2. Lerne die kritischen Werte auf dem gesamten Trainingsset. Klassifiziere die Trainingsdaten und berechne die Trainingsfehler!
3. Ziehe jeweils 20 neue Werte aus den obigen beiden Verteilungen und klassifiziere diese! Der Vorteil: Wir kennen auch hier die Klassenzugehörigkeit und können somit die
Testfehler bestimmen.
4. Wir kennen die theoretischen Verteilungen, aus denen unsere beobachteten Werte stammen (obige Normalverteilungen). Jetzt können wir noch den theoretischen Fehler, den
Bayesfehler, berechnen. D.h. selbst wenn wir den wahren kritischen Wert
C=
µ1 + µ2
2
nehmen, machen wir Fehler, wenn sich die Verteilungen stark überlagern.
0.4
0.0
0.2
Dichte
0.6
0.8
Die folgende Graphik zeigt die Dichten zweier Normalverteilungen und den daraus resultierenden kritischen Wert C. Der Bayesfehler setzt sich zusammen aus der Fläche unter
der hellen Kurve links von C und der Fläche unter der dunklen Kurve rechts von C.
−2
−1
0
1
2
3
Genexpression
Berechne für die oben gewählten beiden Normalverteilungen den Bayesfehler (siehe dazu
die Funktion pnorm)!
Lösung in R
# mu1 > mu2 !
mu1 <- 1
mu2 <- 0
sigma <- 0.5
# leave one out cross-validation
data <- c(rnorm(20,mean=mu1,sd=sigma),rnorm(20,mean=mu2,sd=sigma))
true <- c(numeric(20)+1,numeric(20))
z1 <- numeric(40)
z2 <- numeric(40)
for (i in 1:40){
data.cv <- data[-i]
true.cv <- true[-i]
class1 <- (mean(data.cv[true.cv==1])+mean(data.cv[true.cv==0]))/2
class2 <- (median(data.cv[true.cv==1])+median(data.cv[true.cv==0]))/2
if (data[i]>class1){z1[i] <- 1}
if (data[i]>class2){z2[i] <- 1}
}
cv.error1 <- mean(abs(true-z1))
cv.error2 <- mean(abs(true-z2))
cat(’cv.error \n’)
print(c(cv.error1,cv.error2))
# klassifikation der trainingsdaten
class1 <- (mean(data[true==1])+mean(data[true==0]))/2
class2 <- (median(data[true==1])+median(data[true==0]))/2
z1 <- numeric(40)
z2 <- numeric(40)
z1[data>class1] <- 1
z2[data>class2] <- 1
train.error1 <- mean(abs(true-z1))
train.error2 <- mean(abs(true-z2))
cat(’training.error \n’)
print(c(train.error1,train.error2))
# testdaten
data.test <- c(rnorm(20,mean=mu1,sd=sigma),rnorm(20,mean=mu2,sd=sigma))
z1 <- numeric(40)
z2 <- numeric(40)
z1[data.test>class1] <- 1
z2[data.test>class2] <- 1
test.error1 <- mean(abs(true-z1)) # der Vektor der class labels bleibt gleich
test.error2 <- mean(abs(true-z2))
cat(’test.error \n’)
print(c(test.error1,test.error2))
# bayesfehler
class <- (mu1+mu2)/2
bayes <- (pnorm(class,mean=mu1,sd=sigma) ...
+ pnorm(class,mean=mu2,sd=sigma,lower.tail=F))/2
cat(’bayes.error \n’)
print(bayes)
# plot
seq1 <- seq(mu1-3,mu1+3,by=0.01)
seq2 <- seq(mu2-3,mu2+3,by=0.01)
plot(seq1,dnorm(seq1,mean=mu1,sd=sigma),xlim=c(seq1[1],seq2[length(seq2)]), ...
col=’red’,type=’l’,xlab=’Genexpression’,ylab=’Dichte’)
lines(seq2,dnorm(seq2,mean=mu2,sd=sigma),col=’blue’)
lines(c(class,class),c(0,1))
points(data.test[1:20],numeric(20),col=’red’)
points(data.test[21:40],numeric(20),col=’blue’)
0.6
0.4
0.2
0.0
Dichte
cv.error
[1] 0.20 0.25
training.error
[1] 0.200 0.225
test.error
[1] 0.200 0.175
bayes.error
[1] 0.1586553
0.8
Output.
●
−2
●● ● ●
−1
●
● ●●
●●
●●●●
●●
● ●● ●●●●●
● ●●
●● ●● ● ● ●
0
1
Genexpression
●
●
2
3
Herunterladen