2013-03-23 8 views
8

Ich verwende GAM, um Zeittrends in einer logistischen Regression zu modellieren. Aber ich möchte den angepassten Spline daraus extrahieren, um ihn zu einem anderen Modell hinzuzufügen, das nicht in GAM oder GAMM eingebaut werden kann.So extrahieren Sie angepasste Splines aus einem GAM (`mgcv :: gam`)

So habe ich 2 Fragen:

  1. Wie kann ich eine glattere im Laufe der Zeit passen, so dass ich einen Knoten zwingen, an einem bestimmten Ort zu sein, während das Modell lassen Sie die anderen Knoten zu finden?

  2. Wie kann ich die Matrix aus dem angepassten GAM extrahieren, sodass ich sie als Imput für ein anderes Modell verwenden kann?

Die Arten von Modellen, die ich sind an folgende Formular leite:

gam <- gam(mortality.under.2~ maternal_age_c+ I(maternal_age_c^2)+ 
      s(birth_year,by=wealth2) + wealth2 + sex + 
      residence + maternal_educ + birth_order, 
      data=colombia2, family="binomial") 

ich die umfangreiche Dokumentation der GAM gelesen habe, aber ich bin immer noch nicht sicher. Jeder Vorschlag wird sehr geschätzt.

+0

Es ist nicht so einfach, "die Splines zu extrahieren". Obwohl ich glücklich wäre, falsch bewiesen zu werden. Für den Zweck 2) könnte man "Predicate" auf einem Gitter verwenden. "Ich benutze package :: rms, weil man damit alle Operationen ausführen kann. –

+0

danke, aber wie würdest du das mit RMS machen? – Tom

+0

Kurzschließen ein wenig Vorbereitung arbeiten und einige Vermutungen über die variable Struktur machen: 'fit <- lrm (mortality.under.2_rcs (mütterliche_age_c, 3) + rcs (geburtsjahr, 3)% ia% rcs (wohlstand2, 3) + geschlecht + wohnsitz + mütterliche_educ + birth_order, data = colombia2)); Funktion (pass) ' –

Antwort

21

In mgcv::gam gibt es eine Möglichkeit, dies zu tun (Ihre Q2), über die predict.gam Methode und type = "lpmatrix".

?predict.gam hat auch ein Beispiel, das ich unten reproduzieren:

library(mgcv) 
n <- 200 
sig <- 2 
dat <- gamSim(1,n=n,scale=sig) 

b <- gam(y ~ s(x0) + s(I(x1^2)) + s(x2) + offset(x3), data = dat) 

newd <- data.frame(x0=(0:30)/30, x1=(0:30)/30, x2=(0:30)/30, x3=(0:30)/30) 

Xp <- predict(b, newd, type="lpmatrix") 

################################################################## 
## The following shows how to use use an "lpmatrix" as a lookup 
## table for approximate prediction. The idea is to create 
## approximate prediction matrix rows by appropriate linear 
## interpolation of an existing prediction matrix. The additivity 
## of a GAM makes this possible. 
## There is no reason to ever do this in R, but the following 
## code provides a useful template for predicting from a fitted 
## gam *outside* R: all that is needed is the coefficient vector 
## and the prediction matrix. Use larger `Xp'/ smaller `dx' and/or 
## higher order interpolation for higher accuracy. 
################################################################### 

xn <- c(.341,.122,.476,.981) ## want prediction at these values 
x0 <- 1   ## intercept column 
dx <- 1/30  ## covariate spacing in `newd' 
for (j in 0:2) { ## loop through smooth terms 
    cols <- 1+j*9 +1:9  ## relevant cols of Xp 
    i <- floor(xn[j+1]*30) ## find relevant rows of Xp 
    w1 <- (xn[j+1]-i*dx)/dx ## interpolation weights 
    ## find approx. predict matrix row portion, by interpolation 
    x0 <- c(x0,Xp[i+2,cols]*w1 + Xp[i+1,cols]*(1-w1)) 
} 
dim(x0)<-c(1,28) 
fv <- x0%*%coef(b) + xn[4];fv ## evaluate and add offset 
se <- sqrt(x0%*%b$Vp%*%t(x0));se ## get standard error 
## compare to normal prediction 
predict(b,newdata=data.frame(x0=xn[1],x1=xn[2], 
     x2=xn[3],x3=xn[4]),se=TRUE) 

dass der gesamte Prozess durchläuft auch die Vorhersage Schritt, die außerhalb R oder des GAM-Modell durchgeführt werden würde. Sie werden das Beispiel etwas modifizieren müssen, um das zu tun, was Sie wollen, da das Beispiel alle Ausdrücke im Modell auswertet und Sie neben dem Spline zwei weitere Begriffe haben - im Wesentlichen tun Sie das Gleiche, aber nur für die Spline-Terme, die umfasst das Auffinden der relevanten Spalten und Zeilen der Xp Matrix für den Spline. Dann sollten Sie auch beachten, dass der Spline zentriert ist, so dass Sie das auch rückgängig machen können oder wollen.

Wählen Sie für Ihr Q1 im Beispiel die entsprechenden Werte für den Vektor/Matrix xn. Diese entsprechen den Werten für den n Term im Modell. Legen Sie also die gewünschten Werte auf einen Mittelwert fest und variieren Sie dann den Wert, der dem Spline zugeordnet ist.

Wenn Sie all dies in R tun, wäre es einfacher, nur den Spline bei den Werten der Spline-Kovariate zu bewerten, für die Sie Daten haben, die in das andere Modell gehen. Ihr, dass ein Datenrahmen von Werten, bei denen durch die Schaffung von an vorherzusagen, dann

predict(mod, newdata = newdat, type = "terms") 

verwenden, wo mod das aufgezogene GAM-Modell (via mgcv::gam) ist, newdat wird der Datenrahmen eine Spalte für jede Variable in der enthält Modell (einschließlich der parametrischen Terme; legen Sie die Terme fest, die nicht geändert werden sollen, zu einem konstanten Mittelwert [sagen Sie den Durchschnitt der Variablen im Datensatz] oder zu einem bestimmten Level, wenn ein Faktor vorhanden ist). Der type = "terms" Teil gibt eine Matrix für jede Zeile in newdat mit dem "Beitrag" zum angepassten Wert für jeden Term im Modell zurück, einschließlich des Spline-Terms. Nehmen Sie einfach die Spalte dieser Matrix, die dem Spline entspricht - wieder ist es zentriert.

Vielleicht habe ich Ihr Q1 falsch verstanden. Wenn Sie die Knoten steuern möchten, finden Sie unter knots Argument mgcv::gam.Standardmäßig setzt mgcv::gam einen Knoten an den äußersten Punkten der Daten und dann werden die restlichen "Knoten" gleichmäßig über das Intervall verteilt. mgcv::gam nicht finden Sie die Knoten - es legt sie für Sie und Sie können steuern, wo es sie über die knots Argument platziert.

+1

Das ist eine sehr hilfreiche Antwort. Da ich nicht so einfach zusätzliche Punkte spenden kann, werde ich sehen, ob ich einige Ihrer Antworten auf die Verbesserungsvorschläge finden kann. Sollte nicht zu schwer sein. Sie sind ein ausgezeichneter Lehrer mit einer tiefen Wissensbasis, Gavin. –

+0

Das ist eine wirklich großartige Erklärung. Meine Frage war in der Tat nicht klar. Ich möchte eine Mischung von Prozeduren machen. Ich möchte einen oder zwei Knoten nicht an einem bestimmten Ort platzieren ** und ** lasse das Programm die restlichen Knoten setzen, was auch immer benötigt wird; Es ist möglich? Danke – Tom

+0

@AntonioPedroRamos Wie gesagt, das einzige was 'mgcv :: gam' tut, ist die Knoten an den Endpunkten und gleichmäßig dazwischen zu platzieren. Sie müssen alle Knoten selbst positionieren, wenn Sie einige der Knotenpositionen auswählen möchten. IIRC diese bestraften Regressionsmodelle sind nicht sehr empfindlich auf die Knotenlage. –