Simuler une régression linéaire avec une hétéroscédasticité


9

J'essaie de simuler un ensemble de données qui correspond aux données empiriques dont je dispose, mais je ne sais pas comment estimer les erreurs dans les données d'origine. Les données empiriques incluent l'hétéroscédasticité, mais je ne suis pas intéressé à les transformer, mais plutôt à utiliser un modèle linéaire avec un terme d'erreur pour reproduire des simulations des données empiriques.

Par exemple, supposons que j'en ai un ensemble de données empiriques et un modèle:

n=rep(1:100,2)
a=0
b = 1
sigma2 = n^1.3
eps = rnorm(n,mean=0,sd=sqrt(sigma2))
y=a+b*n + eps
mod <- lm(y ~ n)

en utilisant plot(n,y)nous obtenons ce qui suit. entrez la description de l'image ici

Cependant, si j'essaie de simuler les données, simulate(mod)l'hétéroscédasticité est supprimée et non capturée par le modèle.

Je peux utiliser un modèle des moindres carrés généralisés

VMat <- varFixed(~n)
mod2 = gls(y ~ n, weights = VMat)

qui fournit un meilleur ajustement du modèle basé sur AIC, mais je ne sais pas comment simuler des données en utilisant la sortie.

Ma question est de savoir comment créer un modèle qui me permettra de simuler des données correspondant aux données empiriques originales (n et y ci-dessus). Plus précisément, j'ai besoin d'un moyen d'estimer sigma2, l'erreur, en utilisant soit un modèle?


1
Le modèle linéaire ne capturera donc pas l'hétéroskédasticité conditionnelle à moins qu'il n'essaie explicitement de le faire, en utilisant l'une des quelques approches. Les techniques économétriques standard ajustent les erreurs standard sur les paramètres pour tenir compte de l'hétéroscédasticité, mais elles ne la modélisent pas explicitement.
generic_user

Tu as raison. J'essaie d'utiliser un modèle linéaire pour capturer l'hétérogénéité. Je pense que je devrais utiliser un modèle généralisé des moindres carrés. S'il y a d'autres recommandations, je vais les essayer.
user44796

IL Y A UNE ERREUR DANS VOTRE CODE, VOUS DEVEZ UTILISER `lm (y ~ n)`
kjetil b halvorsen

1
Je ne comprends pas votre question, car votre code accomplit exactement ce que vous semblez demander dans son titre: il simule une régression linéaire avec des erreurs hétéroscédastiques. Demandez-vous des méthodes pour estimer une sorte de modèle d'hétéroscédasticité? Si oui, alors vous devez spécifier un modèle!
whuber

J'espère avoir clarifié ma question avec des modifications. Dans la question ci-dessus, n et y représentent les données empiriques. Je souhaite adapter un modèle aux données, puis utiliser le modèle pour générer des données simulées qui correspondent à la moyenne et aux résidus des données d'origine.
user44796

Réponses:


9

Pour simuler des données avec une variance d'erreur variable, vous devez spécifier le processus de génération de données pour la variance d'erreur. Comme cela a été souligné dans les commentaires, vous l'avez fait lorsque vous avez généré vos données d'origine. Si vous avez des données réelles et que vous voulez essayer, il vous suffit d'identifier la fonction qui spécifie comment la variance résiduelle dépend de vos covariables. La façon standard de le faire est d'adapter votre modèle, de vérifier qu'il est raisonnable (autre que l'hétéroscédasticité) et d'économiser les résidus. Ces résidus deviennent la variable Y d'un nouveau modèle. Ci-dessous, je l'ai fait pour votre processus de génération de données. (Je ne vois pas où vous placez la graine aléatoire, donc ce ne seront pas littéralement les mêmes données, mais devraient être similaires, et vous pouvez reproduire la mienne exactement en utilisant ma graine.)

set.seed(568)  # this makes the example exactly reproducible

n      = rep(1:100,2)
a      = 0
b      = 1
sigma2 = n^1.3
eps    = rnorm(n,mean=0,sd=sqrt(sigma2))
y      = a+b*n + eps
mod    = lm(y ~ n)
res    = residuals(mod)

windows()
  layout(matrix(1:2, nrow=2))
  plot(n,y)
  abline(coef(mod), col="red")
  plot(mod, which=3)

entrez la description de l'image ici

Notez que Rle ? Plot.lm vous donnera un tracé (cf. ici ) de la racine carrée des valeurs absolues des résidus, superposée utilement avec un ajustement plus bas, ce qui est exactement ce dont vous avez besoin. (Si vous avez plusieurs covariables, vous voudrez peut-être les évaluer séparément pour chaque covariable.) Il y a le moindre indice d'une courbe, mais cela ressemble à une ligne droite qui fait un bon travail d'ajustement des données. Adaptons donc explicitement ce modèle:

res.mod = lm(sqrt(abs(res))~fitted(mod))
summary(res.mod)
# Call:
# lm(formula = sqrt(abs(res)) ~ fitted(mod))
# 
# Residuals:
#     Min      1Q  Median      3Q     Max 
# -3.3912 -0.7640  0.0794  0.8764  3.2726 
# 
# Coefficients:
#             Estimate Std. Error t value Pr(>|t|)    
# (Intercept) 1.669571   0.181361   9.206  < 2e-16 ***
# fitted(mod) 0.023558   0.003157   7.461 2.64e-12 ***
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# 
# Residual standard error: 1.285 on 198 degrees of freedom
# Multiple R-squared:  0.2195,  Adjusted R-squared:  0.2155 
# F-statistic: 55.67 on 1 and 198 DF,  p-value: 2.641e-12
windows()
  layout(matrix(1:4, nrow=2, ncol=2, byrow=TRUE))
  plot(res.mod, which=1)
  plot(res.mod, which=2)
  plot(res.mod, which=3)
  plot(res.mod, which=5)

entrez la description de l'image ici

Nous n'avons pas à nous inquiéter du fait que la variance résiduelle semble également augmenter dans le graphique de localisation de l'échelle pour ce modèle - cela doit essentiellement se produire. Il y a à nouveau le moindre indice d'une courbe, nous pouvons donc essayer d'ajuster un terme au carré et voir si cela aide (mais cela ne fonctionne pas):

res.mod2 = lm(sqrt(abs(res))~poly(fitted(mod), 2))
summary(res.mod2)
# output omitted
anova(res.mod, res.mod2)
# Analysis of Variance Table
# 
# Model 1: sqrt(abs(res)) ~ fitted(mod)
# Model 2: sqrt(abs(res)) ~ poly(fitted(mod), 2)
#   Res.Df    RSS Df Sum of Sq     F Pr(>F)
# 1    198 326.87                          
# 2    197 326.85  1  0.011564 0.007 0.9336

Si nous en sommes satisfaits, nous pouvons désormais utiliser ce processus comme module complémentaire pour simuler des données.

set.seed(4396)  # this makes the example exactly reproducible
x = n
expected.y = coef(mod)[1] + coef(mod)[2]*x
sim.errors = rnorm(length(x), mean=0,
                   sd=(coef(res.mod)[1] + coef(res.mod)[2]*expected.y)^2)
observed.y = expected.y + sim.errors

Notez que ce processus n'est pas plus garanti pour trouver le véritable processus de génération de données que toute autre méthode statistique. Vous avez utilisé une fonction non linéaire pour générer les SD d'erreur, et nous l'avons approximée avec une fonction linéaire. Si vous connaissez réellement le véritable processus de génération de données a priori (comme dans ce cas, parce que vous avez simulé les données d'origine), vous pourriez aussi bien l'utiliser. Vous pouvez décider si l'approximation ici est suffisante pour vos besoins. Cependant, nous ne connaissons généralement pas le véritable processus de génération de données et, sur la base du rasoir d'Occam, nous utilisons la fonction la plus simple qui correspond adéquatement aux données que nous avons fournies, la quantité d'informations disponibles. Vous pouvez également essayer des splines ou des approches plus sophistiquées si vous préférez. Les distributions bivariées me semblent raisonnablement similaires,

entrez la description de l'image ici


C'était en fait une conclusion à laquelle je commençais à arriver, mais je n'aurais jamais pu arriver à une réponse aussi élégante.
user44796

5

Vous devez modéliser l'hétéroskédasticité. Une approche est via le package R (CRAN) dglm, modèle linéaire généralisé de dispersion. Il s'agit d'une extension de glm qui, en plus de l'habituel glm, s'adapte à un deuxième glm pour la dispersion des résidus du premier glm. Je n'ai aucune expérience avec de tels modèles, mais ils semblent prometteurs ... Voici du code:

n <- rep(1:100,2)
a <- 0
b <- 1
sigma2 <- n^1.3
eps <- rnorm(n,mean=0,sd=sqrt(sigma2))
y <- a+b*n + eps
mod <- lm(y ~ n)

library(dglm)  ### double glm's

mod2   <-  dglm(y ~ n, ~ n, gaussian,ykeep=TRUE,xkeep=TRUE,zkeep=TRUE)
### This uses log link for the dispersion part, should also try identity link ..

y2 <-  simulate(mod2)

plot(n, y2$sim_1)

mod3  <-  dglm(y ~ n, ~ n, gaussian, dlink="identity", ykeep=TRUE,xkeep=TRUE,zkeep=TRUE)  ### This do not work because it leads to negative weights!

Le tracé simulé est illustré ci-dessous:

entrez la description de l'image ici

L'intrigue ressemble à la simulation qui a utilisé la variance estimée, mais je ne suis pas sûr, car la fonction simulate () n'a pas de méthodes pour dglm ...

(Une autre possibilité à examiner est d'utiliser le Rpackage gamlss, qui utilise une autre approche pour modéliser la variance en fonction des covariables.)


1
le double modèle linéaire généralisé semble modéliser adéquatement les données originales. Je ne suis pas certain de la façon dont l'erreur résiduelle est modélisée à l'aide de Predict (). Je vais devoir examiner cela.
user44796
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.