Modello lineare in cui i dati hanno incertezza, usando R


9

Diciamo che ho dei dati con qualche incertezza. Per esempio:

X  Y
1  10±4
2  50±3
3  80±7
4  105±1
5  120±9

La natura dell'incertezza potrebbe essere la ripetizione di misurazioni o esperimenti, o l'incertezza dello strumento di misurazione, ad esempio.

Vorrei adattarci ad una curva usando R, qualcosa che normalmente farei lm. Tuttavia, ciò non tiene conto dell'incertezza nei dati quando mi dà l'incertezza nei coefficienti di adattamento e, di conseguenza, negli intervalli di previsione. Guardando la documentazione, la lmpagina ha questo:

... i pesi possono essere usati per indicare che osservazioni diverse hanno varianze diverse ...

Quindi mi fa pensare che forse questo ha qualcosa a che fare con esso. Conosco la teoria di farlo manualmente, ma mi chiedevo se fosse possibile farlo con la lmfunzione. In caso contrario, c'è qualche altra funzione (o pacchetto) in grado di farlo?

MODIFICARE

Vedendo alcuni dei commenti, ecco alcuni chiarimenti. Prendi questo esempio:

x <- 1:10
y <- c(131.4,227.1,245,331.2,386.9,464.9,476.3,512.2,510.8,532.9)
mod <- lm(y ~ x + I(x^2))
summary(mod)

Mi da:

Residuals:
    Min      1Q  Median      3Q     Max 
-32.536  -8.022   0.087   7.666  26.358 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  39.8050    22.3210   1.783  0.11773    
x            92.0311     9.3222   9.872 2.33e-05 ***
I(x^2)       -4.2625     0.8259  -5.161  0.00131 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Residual standard error: 18.98 on 7 degrees of freedom
Multiple R-squared:  0.986, Adjusted R-squared:  0.982 
F-statistic: 246.7 on 2 and 7 DF,  p-value: 3.237e-07

Quindi sostanzialmente i miei coefficienti sono a = 39,8 ± 22,3, b = 92,0 ± 9,3, c = -4,3 ± 0,8. Ora diciamo che per ogni punto dati, l'errore è 20. Userò weights = rep(20,10)nella lmchiamata e ottengo questo invece:

Residual standard error: 84.87 on 7 degrees of freedom

ma gli errori std sui coefficienti non cambiano.

Manualmente, so come farlo calcolando la matrice di covarianza usando l'algebra di matrice e inserendo i pesi / errori e ricavando gli intervalli di confidenza usando quello. Quindi esiste un modo per farlo nella funzione lm stessa o in qualsiasi altra funzione?


Se si conosce la distribuzione dei dati, è possibile eseguirne il bootstrap utilizzando il bootpacchetto in R. Successivamente è possibile eseguire una regressione lineare sul set di dati con bootstrap.
Ferdi,

lmutilizzerà le varianze normalizzate come pesi e quindi presupporrà che il modello sia statisticamente valido per stimare l'incertezza dei parametri. Se ritieni che non sia così (barre di errore troppo piccole o troppo grandi), non dovresti fidarti di alcuna stima dell'incertezza.
Pascal,

Risposte:


14

Questo tipo di modello è in realtà molto più comune in alcuni rami della scienza (es. Fisica) e ingegneria rispetto alla regressione lineare "normale". Quindi, in strumenti di fisica come ROOT, fare questo tipo di adattamento è banale, mentre la regressione lineare non è implementata nativamente! I fisici tendono a chiamarlo solo un "adattamento" o un adattamento minimizzante chi-quadrato.

σ

Lie12(yi(axi+b)σ)2
log(L)=constant12σ2i(yi(axi+b))2
σ
LαΠe-12(y-(un'X+B)σio)2
log(L)=conStun'nt-12Σ(yio-(un'Xio+B)σio)2
1/σio2log(L)

F=mun'F=mun'+εlmσ2lm

Sono pesi e l'errore standard

Ci sono un paio di possibili soluzioni fornite nelle risposte lì. In particolare, una risposta anonima suggerisce l'utilizzo

vcov(mod)/summary(mod)$sigma^2

lmσ

MODIFICARE

Se stai facendo questo genere di cose molto si potrebbe considerare l'utilizzo ROOT(che sembra fare questo in modo nativo, mentre lme glmnon). Ecco un breve esempio di come eseguire questa operazione ROOT. Prima di tutto, ROOTpuò essere utilizzato tramite C ++ o Python, ed è un enorme download e installazione. Puoi provarlo nel browser usando un notebook Jupiter, seguendo il link qui , scegliendo "Binder" a destra e "Python" a sinistra.

import ROOT
from array import array
import math
x = range(1,11)
xerrs = [0]*10
y = [131.4,227.1,245,331.2,386.9,464.9,476.3,512.2,510.8,532.9]
yerrs = [math.sqrt(i) for i in y]
graph = ROOT.TGraphErrors(len(x),array('d',x),array('d',y),array('d',xerrs),array('d',yerrs))
graph.Fit("pol2","S")
c = ROOT.TCanvas("test","test",800,600)
graph.Draw("AP")
c.Draw()

y

Welcome to JupyROOT 6.07/03

****************************************
Minimizer is Linear
Chi2                      =       8.2817
NDf                       =            7
p0                        =      46.6629   +/-   16.0838     
p1                        =       88.194   +/-   8.09565     
p2                        =     -3.91398   +/-   0.78028    

e viene prodotta una bella trama:

quadfit

Xlm

SECONDA MODIFICA

L'altra risposta della stessa domanda precedente di @Wolfgang offre una soluzione ancora migliore: lo rmastrumento del metaforpacchetto (inizialmente ho interpretato il testo in quella risposta per indicare che non ha calcolato l'intercettazione, ma non è così). Prendendo le varianze nelle misure y per essere semplicemente y:

> rma(y~x+I(x^2),y,method="FE")

Fixed-Effects with Moderators Model (k = 10)

Test for Residual Heterogeneity: 
QE(df = 7) = 8.2817, p-val = 0.3084

Test of Moderators (coefficient(s) 2,3): 
QM(df = 2) = 659.4641, p-val < .0001

Model Results:

         estimate       se     zval    pval    ci.lb     ci.ub     
intrcpt   46.6629  16.0838   2.9012  0.0037  15.1393   78.1866   **
x         88.1940   8.0956  10.8940  <.0001  72.3268  104.0612  ***
I(x^2)    -3.9140   0.7803  -5.0161  <.0001  -5.4433   -2.3847  ***

---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Questo è sicuramente il miglior strumento R puro per questo tipo di regressione che ho trovato.


Penso che sia fondamentalmente sbagliato annullare il ridimensionamento lm. In questo caso, le statistiche di convalida, come il chi-quadrato, verranno disattivate. Se la dispersione dei tuoi residui non corrisponde alle tue barre di errore, qualcosa non va nel modello statistico (o la scelta del modello o le barre di errore o l'ipotesi normale ...). In entrambi i casi, le incertezze dei parametri saranno inaffidabili !!!
Pascal,

@PascalPERNOT Non ci ho pensato; Penserò ai tuoi commenti. Ad essere sincero, concordo in senso generale sul fatto che penso che la soluzione migliore sia utilizzare la fisica o il software di ingegneria garantiti per risolvere correttamente questo problema, piuttosto che hackerare lmper ottenere l'output corretto. (Se qualcuno è curioso, mostrerò come farlo in ROOT).
jwimberley,

1
Un potenziale vantaggio dell'approccio dello statistico al problema è che consente di raggruppare le stime di varianza tra osservazioni a diversi livelli. Se la varianza sottostante è costante o ha una relazione definita con le misurazioni come nei processi di Poisson, l'analisi sarà in genere migliorata rispetto a quanto si ottiene dall'assunto (tipicamente non realistico) che la varianza misurata per ciascun punto di dati sia corretta e quindi ingiustamente ponderata alcuni punti dati. Nei dati del PO, immagino che l'assunzione della varianza costante potrebbe essere migliore.
EdM

1
σσ2

1
C'è una buona discussione di questi problemi nel capitolo 8 di Andreon, S. e Weaver, B. (2015) Metodi bayesiani per le scienze fisiche. Springer. springer.com/us/book/9783319152868
Tony Ladson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.