II. Univariate Statistik I: Das Lineare Modell 57
5.2.1. Nicht-lineare Regression
Bei der nicht-linearen Regression wird eine Funktion durch die Daten gelegt, die keine Gerade ist. Da viele nicht-lineare Zusammenh¨ange aber linearisierbar sind (etwa Potenzfunktionen durch Logarithmisierung der x- und y-Werte), sprechen wir bei der nicht-linearen Regression im engeren Sinn nur dann, wenn eine solche Linearisierung nicht m¨oglich ist. Die nicht-lineare Regression k¨onnte dazu verleiten, nach einer Gleichung zu suchen, die die Daten m¨oglichst gut ann¨ahert, ohne R¨ucksicht auf die Angemessenheit der Gleichung. In der Praxis spielt dieses Herumstochern keine Rolle, da es eine Unmenge Gleichungen gibt, die wir aber nicht alle fitten k¨onnen oder wollen. Der Sinn wird vielmehr deutlich, wenn wir eine bestimmte, theoretisch abgeleitete Formel mit den Daten in Einklang bringen wollen.
Die Theorie hinter der nicht-linearen Regression ist denkbar einfach: Wir suchen die Para-meter eines nicht-linearen Regressionsmodells, die dazu f¨uhren, dass die Abweichungsquadrate zwischen beobachteten und vorhergesagten y-Werten minimal sind.8 Der Rest besteht in der technischen Umsetzung in der jeweiligen Software.
Beginnen wir mit einem einfachen Beispiel: Wir haben die Aktivit¨at eines Enzyms in Abh¨angigkeit seiner Konzentration gemessen. Wir erwarten eine Michaelis-Menten-Kinetik der Form v = vKmaxm+c∗c, wobei v die Aktivit¨at (Umsatzgeschwindigkeit) des Enzyms, vmax die maximale Aktivit¨at, Km die Halbaktivit¨atskon-zentration (= MM-Konstante) und schließlich c die KonHalbaktivit¨atskon-zentration des Enzyms ist. Zun¨achst generieren wir ein paar entsprechende Daten.
> noise <- rnorm(101, 0, 0.1)
> c.e <- seq(0, 10, 0.1)
> Km <- 1
> vmax <- 2
8Dieser Methode implizit ist die Annahme, dass die Daten normalverteilt sind. Nur dann sind die Abwei-chungsquadrate aus dem maximum likelihood-Ansatz ableitbar (siehe S. 21).
> v.e <- (vmax * c.e)/(Km + c.e) + noise
> plot(v.e ~ c.e)
Jetzt k¨onnen wir unsere MM-Kinetik fitten. Dazu benutzen wir dieR-Funktion nls. Die Modellformel wird spezifiziert, und den zu bestimmenden Parametern werden Anfangswerte zugedacht. Diese sollten ungleich Null sein! Sie sind lediglich der Ausgangspunkt einer iterativen Ann¨aherung an die besten Parameterwerte und ihr Wert nicht mehr als eine erste Sch¨atzung.
> fm <- nls(v.e ~ (vmax * c.e)/(Km + c.e), start = list(vmax = 1, + Km = 0.5))
> summary(fm)
Formula: v.e ~ (vmax * c.e)/(Km + c.e) Parameters:
Estimate Std. Error t value Pr(>|t|) vmax 1.95864 0.02254 86.89 <2e-16 ***
Km 0.89835 0.05427 16.55 <2e-16 ***
---Signif. codes: 0 *** 0.001 ** 0.01 * 0.05 . 0.1 1 Residual standard error: 0.09252 on 99 degrees of freedom
Im output erscheint zus¨atzlich zu den Parametern (und einem t-Test auf Unterschiedlichkeit von 0) der Standardfehler der Residuen sowie eine Korrelationsmatrix der Parameter. Mit dieser hat es folgende Be-wandtnis: Wenn wir einen Wert f¨ur vmax vorgeben, so gibt es einen optimalen Km-Wert. ¨andern wir vmax, so ¨andert sich auch dieser optimale Km. Die Korrelation der beiden gibt an, wie unabh¨angig sich der eine Parameter vom anderen w¨ahlen l¨asst, bzw. eben wie stark die beiden korreliert sind.
Um eine Regressionskurve in die Datenpunkte zu legen benutzen wir wieder die Funktion predict(). Das Ergebnis ist in Abbildung 5.5 dargestellt.
Und - nein, es gibt keinen R2-Wert f¨ur nicht-lineare Regressionsmodelle! Dieser ist allgemein nicht definiert, so wurde uns berichtet. So ist der R2-Wert einer linearen Regression ja ein Maß f¨ur die Verbesserung gegen¨uber dem Nullmodell, in dem nur der Achsenabschnitt gefittet wird. Bei nicht-linearen Modellen aber gibt es kein Standardnullmodell, mit dem man es vergleichen kann. Zudem muss das Nullmodell ja auch im Regressionsmodell genestet sein:
was soll das in der nicht-linearen Regression sin? In derR-help mailing list kann man lange Email-Wechsel dar¨uber lesen, wieso ein R2-Wert kein sinnvolles Maß ist, was man stattdessen benutzen soll, und wie man mit Herausgebern umgehen soll, die einen R2-Wert fordern. Diese Lekt¨ure sei empfohlen, aber nicht hier abgedruckt.
> lines(seq(0, 10, by = 0.1), predict(fm, newdata = data.frame(c.e = seq(0, + 10, by = 0.1))))
Als n¨achstes wollen wir eine Regression f¨ur zwei unterschiedliche Enzyme rechnen, also einen Faktor mit in die Regression hineinnehmen. Dazu simulieren wir zun¨achst einen Datensatz mit zwei leicht unterschiedli-chen Enzymkinetiken, die wir dann in eine Tabelle (data.frame) umformen.
> noise <- rnorm(50, 0.1, 0.1)
> c.e <- seq(0.2, 10, 0.2)
> Km1 <- 1
> vmax1 <- 2
> v.e1 <- (vmax1 * c.e)/(Km1 + c.e) + noise
> Km2 <- 1.2
> vmax2 <- 2.2
> v.e2 <- (vmax2 * c.e)/(Km2 + c.e) + noise
> MM2 <- data.frame(c.e = c(c.e, c.e), stack(data.frame(v.e1, v.e2)))
> colnames(MM2) <- c("c.e", "v", "enzym")
> MM2$enzym <- factor(MM2$enzym, labels = c("enz1", "enz2"))
0 2 4 6 8 10
0.00.51.01.52.0
c.e
v.e
Abbildung 5.5.: Michaelis-Menton-Kinetik-Daten und nicht-linear gefittete Funktion.
Jetzt k¨onnen wir aus dem package nlme die Funktion nlsList benutzen, um eine nicht-lineare Regression durchzuf¨uhren. Durch einen senkrechten Strich (|) wird diese Regression bedingt nach dem Faktor enzym berechnet.
> library(nlme)
> fm2 <- nlsList(v ~ (vmax * c.e)/(Km + c.e) | enzym, start = c(vmax = 1, + Km = 0.5), data = MM2)
> summary(fm2) Call:
Model: v ~ (vmax * c.e)/(Km + c.e) | enzym Data: MM2
Coefficients:
vmax
Estimate Std. Error t value Pr(>|t|) enz1 2.109743 0.03498065 60.31173 6.828369e-47 enz2 2.303018 0.03828896 60.14834 7.124948e-47
Km
Estimate Std. Error t value Pr(>|t|) enz1 0.9266136 0.07953195 11.65083 1.395194e-15 enz2 1.0998460 0.08629158 12.74569 4.921672e-17
Residual standard error: 0.1004273 on 96 degrees of freedom
Wir erhalten also nur die Koeffizienten der beiden Modelle und keinen Test auf ihre Unterschiedlichkeit. Der t-Test auf Unterschiedlichkeit funktioniert wie folgt (siehe Gleichung 4.4 f¨ur die t-Testformel). Zun¨achst speichern wir die Koeffizienten und ihre Standardfehler unter neuem Namen.
> coef.vmax <- coef(summary(fm2))[, , 1][1:2]
> coef.vmax.se <- coef(summary(fm2))[, , 1][3:4]
Dann wenden wir Formel 4.4 an, wobei nat¨urlich se =√s
(n), und somit se2= sn2.
> t.wert <- as.numeric(coef.vmax[1] - coef.vmax[2]/sqrt(sum(coef.vmax.se^2)))
> pt(t.wert, 48)
[1] 5.951791e-40
Wir erhalten also eine t-Wert von −37 (minus, da die Differenz der Mittelwerte negativ ist; das Vorzeichen ist beim t-Test aber irrelevant). Unsere Daten fußen auf 50 Datenpunkten, wir ziehen f¨ur die zwei Gruppen zwei Freiheitsgrade und erhalten df=48. Der Wahrscheinlichkeitswert wird mittels der pt-Funktion ermittelt und ist extrem klein. Also sind die Koeffizienten f¨ur vmax signifikant verschieden. Entsprechendes f¨ur Km sieht dann so aus:
> coef.Km <- coef(summary(fm2))[, , 2][1:2]
> coef.Km.se <- coef(summary(fm2))[, , 2][3:4]
> t.wert2 <- as.numeric(coef.Km[1] - coef.Km[2]/sqrt(sum(coef.Km.se^2)))
> pt(t.wert2, 48) [1] 2.355718e-11
Konz.
Aktivit.
0.5 1.0 1.5 2.0
0 2 4 6 8 10
enz1 enz2
0 2 4 6 8 10
Abbildung 5.6.: Vergleich zweier Enzyme bez¨uglich ihrer Aktivit¨at. Diese Abbildung ist mit dem xyplot-Befehl erzeugt worden.
Im folgenden wollen wir diese beiden Kurven einmal zusammen plotten (hier nicht abgebildet!).
> plot(v[51:100] ~ c.e[51:100], xlab = "Enzymkonzentration", ylab = "Aktivit.", + data = MM2)
> points(v[1:50] ~ c.e[1:50], pch = 16, data = MM2)
> xx <- seq(0, 10, by = 0.1)
> for (i in 1:2) {
+ pred <- coef(fm2)[i, 1] * xx/(coef(fm2)[i, 2] + xx) + lines(xx, pred, lty = i)
+ }
Im Zusatzpacket lattice sind graphische Zusatzfunktionen enthalten, die ein sehr komfortables bedingtes plotten erlauben. Damit kann man sowohl einfache xy-plots machen (siehe den ersten Befehl), als auch (¨uber das package nlme) xy-plots mit vorhergesagter Regressionlinie (Abbildung 5.6).
> library(lattice)
> attach(MM2)
> trellis.par.set(background = list(col = "white"))
> xyplot(v ~ c.e | enzym, data = MM2)
> plot(augPred(fm2, primary = ~c.e), xlab = list("Konz.", cex = 1.5), + ylab = list("Aktivit.", cex = 1.5))