J'ai couru une régression:
CopierDataRegression <- lm(V1~V2, data=CopierData1)
et ma tâche était d'obtenir un
V2=6
et V2=6
.J'ai utilisé le code suivant:
X6 <- data.frame(V2=6)
predict(CopierDataRegression, X6, se.fit=TRUE, interval="confidence", level=0.90)
predict(CopierDataRegression, X6, se.fit=TRUE, interval="prediction", level=0.90)
et j'ai (87.3, 91.9)
et (74.5, 104.8)
qui semble être correct puisque le PI devrait être plus large.
La sortie pour les deux incluait également se.fit = 1.39
qui était identique. Je ne comprends pas ce qu'est cette erreur standard. L'erreur type ne devrait-elle pas être plus grande pour l'IP par rapport à l'EC? Comment trouver ces deux erreurs types différentes dans R?
Les données:
CopierData1 <- structure(list(V1 = c(20L, 60L, 46L, 41L, 12L, 137L, 68L, 89L,
4L, 32L, 144L, 156L, 93L, 36L, 72L, 100L, 105L, 131L, 127L, 57L,
66L, 101L, 109L, 74L, 134L, 112L, 18L, 73L, 111L, 96L, 123L,
90L, 20L, 28L, 3L, 57L, 86L, 132L, 112L, 27L, 131L, 34L, 27L,
61L, 77L), V2 = c(2L, 4L, 3L, 2L, 1L, 10L, 5L, 5L, 1L, 2L, 9L,
10L, 6L, 3L, 4L, 8L, 7L, 8L, 10L, 4L, 5L, 7L, 7L, 5L, 9L, 7L,
2L, 5L, 7L, 6L, 8L, 5L, 2L, 2L, 1L, 4L, 5L, 9L, 7L, 1L, 9L, 2L,
2L, 4L, 5L)), .Names = c("V1", "V2"),
class = "data.frame", row.names = c(NA, -45L))
Lorsque vous spécifiez les arguments interval
et level
, predict.lm
peut renvoyer un intervalle de confiance (IC) ou un intervalle de prédiction (PI). Cette réponse montre comment obtenir des CI et des PI sans définir ces arguments. Il y a deux manières:
predict.lm
;En sachant travailler avec les deux méthodes, vous comprendrez parfaitement la procédure de prévision.
Notez que nous ne couvrirons que le cas type = "response"
(par défaut) pour predict.lm
. La discussion sur type = "terms"
déborde le cadre de cette réponse.
Je rassemble votre code ici pour aider les autres lecteurs à copier, coller et exécuter. Je change également les noms des variables afin qu’elles aient un sens plus clair. De plus, j'élargis la newdat
pour inclure plus d'une ligne, pour montrer que nos calculs sont "vectorisés".
dat <- structure(list(V1 = c(20L, 60L, 46L, 41L, 12L, 137L, 68L, 89L,
4L, 32L, 144L, 156L, 93L, 36L, 72L, 100L, 105L, 131L, 127L, 57L,
66L, 101L, 109L, 74L, 134L, 112L, 18L, 73L, 111L, 96L, 123L,
90L, 20L, 28L, 3L, 57L, 86L, 132L, 112L, 27L, 131L, 34L, 27L,
61L, 77L), V2 = c(2L, 4L, 3L, 2L, 1L, 10L, 5L, 5L, 1L, 2L, 9L,
10L, 6L, 3L, 4L, 8L, 7L, 8L, 10L, 4L, 5L, 7L, 7L, 5L, 9L, 7L,
2L, 5L, 7L, 6L, 8L, 5L, 2L, 2L, 1L, 4L, 5L, 9L, 7L, 1L, 9L, 2L,
2L, 4L, 5L)), .Names = c("V1", "V2"),
class = "data.frame", row.names = c(NA, -45L))
lmObject <- lm(V1 ~ V2, data = dat)
newdat <- data.frame(V2 = c(6, 7))
Ce qui suit est la sortie de predict.lm
, à comparer avec nos calculs manuels ultérieurement.
predict(lmObject, newdat, se.fit = TRUE, interval = "confidence", level = 0.90)
#$fit
# fit lwr upr
#1 89.63133 87.28387 91.9788
#2 104.66658 101.95686 107.3763
#
#$se.fit
# 1 2
#1.396411 1.611900
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508
predict(lmObject, newdat, se.fit = TRUE, interval = "prediction", level = 0.90)
#$fit
# fit lwr upr
#1 89.63133 74.46433 104.7983
#2 104.66658 89.43930 119.8939
#
#$se.fit
# 1 2
#1.396411 1.611900
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508
predict.lm
## use `se.fit = TRUE`
z <- predict(lmObject, newdat, se.fit = TRUE)
#$fit
# 1 2
# 89.63133 104.66658
#
#$se.fit
# 1 2
#1.396411 1.611900
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508
Qu'est-ce que
se.fit
?
z$se.fit
est l'erreur standard de la moyenne prévue z$fit
, utilisée pour construire un CI pour z$fit
. Nous avons également besoin de quantiles de la distribution t avec un degré de liberté z$df
.
alpha <- 0.90 ## 90%
Qt <- c(-1, 1) * qt((1 - alpha) / 2, z$df, lower.tail = FALSE)
#[1] -1.681071 1.681071
## 90% confidence interval
CI <- z$fit + outer(z$se.fit, Qt)
colnames(CI) <- c("lwr", "upr")
CI
# lwr upr
#1 87.28387 91.9788
#2 101.95686 107.3763
Nous voyons que cela est en accord avec predict.lm(, interval = "confidence")
.
Quelle est l'erreur type pour PI?
PI est plus large que CI, car il rend compte de la variance résiduelle:
variance_of_PI = variance_of_CI + variance_of_residual
Notez que ceci est défini au point. Pour une régression linéaire non pondérée (comme dans votre exemple), la variance résiduelle est égale partout (connue sous le nom de homoscédasticité) et correspond à z$residual.scale ^ 2
. Ainsi, l'erreur standard pour PI est
se.PI <- sqrt(z$se.fit ^ 2 + z$residual.scale ^ 2)
# 1 2
#9.022228 9.058082
et PI est construit comme
PI <- z$fit + outer(se.PI, Qt)
colnames(PI) <- c("lwr", "upr")
PI
# lwr upr
#1 74.46433 104.7983
#2 89.43930 119.8939
Nous voyons que cela est en accord avec predict.lm(, interval = "prediction")
.
remarque
Les choses sont plus compliquées si vous avez une régression linéaire en poids, où la variance résiduelle n'est pas égale partout, de sorte que z$residual.scale ^ 2
doit être pondéré. Il est plus facile de construire des PI pour les valeurs ajustées (autrement dit, vous ne définissez pas newdata
lorsque vous utilisez type = "prediction"
dans predict.lm
), car les poids sont connus (vous devez l'avoir fourni via l'argument weight
lorsque vous utilisez lm
). Pour les prédictions hors échantillon (c'est-à-dire que vous passez newdata
à predict.lm
), predict.lm
s'attend à ce que vous lui indiquiez comment la variance résiduelle doit être pondérée. Vous devez utiliser l'argument pred.var
ou weights
dans predict.lm
, sinon vous recevez un avertissement de predict.lm
indiquant des informations insuffisantes pour la construction de PI. Les éléments suivants sont extraits de ?predict.lm
:
The prediction intervals are for a single observation at each case in ‘newdata’ (or by default, the data used for the fit) with error variance(s) ‘pred.var’. This can be a multiple of ‘res.var’, the estimated value of sigma^2: the default is to assume that future observations have the same error variance as those used for fitting. If ‘weights’ is supplied, the inverse of this is used as a scale factor. For a weighted fit, if the prediction is for the original data frame, ‘weights’ defaults to the weights used for the model fit, with a warning since it might not be the intended result. If the fit was weighted and ‘newdata’ is given, the default is to assume constant prediction variance, with a warning.
Notez que la construction de CI n'est pas affectée par le type de régression.
En gros, nous voulons savoir comment obtenir fit
, se.fit
, df
et residual.scale
dans z
.
La moyenne prédite peut être calculée par une multiplication matrice-vecteur Xp %*% b
, où Xp
est la matrice de prédicteur linéaire et b
est le vecteur de coefficient de régression.
Xp <- model.matrix(delete.response(terms(lmObject)), newdat)
b <- coef(lmObject)
yh <- c(Xp %*% b) ## c() reshape the single-column matrix to a vector
#[1] 89.63133 104.66658
Et nous voyons que cela est en accord avec z$fit
. La variance-covariance pour yh
est Xp %*% V %*% t(Xp)
, où V
est la matrice de variance-covariance de b
qui peut être calculée par
V <- vcov(lmObject) ## use `vcov` function in R
# (Intercept) V2
# (Intercept) 7.862086 -1.1927966
# V2 -1.192797 0.2333733
La matrice de variance-covariance complète de yh
n'est pas nécessaire pour calculer l'IC ou l'IP point par point. Nous avons seulement besoin de sa diagonale principale. Donc, au lieu de faire diag(Xp %*% V %*% t(Xp))
, nous pouvons le faire plus efficacement via
var.fit <- rowSums((Xp %*% V) * Xp) ## point-wise variance for predicted mean
# 1 2
#1.949963 2.598222
sqrt(var.fit) ## this agrees with `z$se.fit`
# 1 2
#1.396411 1.611900
Le degré de liberté résiduel est facilement disponible dans le modèle monté:
dof <- df.residual(lmObject)
#[1] 43
Enfin, pour calculer la variance résiduelle, utilisez l’estimateur de Pearson:
sig2 <- c(crossprod(lmObject$residuals)) / dof
# [1] 79.45063
sqrt(sig2) ## this agrees with `z$residual.scale`
#[1] 8.913508
remarque
Notez qu'en cas de régression pondérée, sig2
doit être calculé comme suit:
sig2 <- c(crossprod(sqrt(lmObject$weights) * lmObject$residuals)) / dof
predict.lm
Le code dans "Tout faire à partir de zéro" a été clairement organisé en une fonction lm_predict
dans ce modèle de questions-réponses: modèle linéaire avec lm
: comment obtenir la variance de prédiction de la somme des valeurs prédites .
Je ne sais pas s'il existe un moyen rapide d'extraire l'erreur standard pour l'intervalle de prédiction, mais vous pouvez toujours effectuer une résolution en arrière des intervalles pour le SE (même si ce n'est pas une approche très élégante):
m <- lm(V1 ~ V2, data = d)
newdat <- data.frame(V2=6)
tcrit <- qt(0.95, m$df.residual)
a <- predict(m, newdat, interval="confidence", level=0.90)
cat("CI SE", (a[1, "upr"] - a[1, "fit"]) / tcrit, "\n")
b <- predict(m, newdat, interval="prediction", level=0.90)
cat("PI SE", (b[1, "upr"] - b[1, "fit"]) / tcrit, "\n")
Notez que le CI SE a la même valeur que celle de se.fit
.