A otimização de probabilidade máxima para o caso de incertezas em xey foi abordada por York (2004). Aqui está o código R para sua função.
"YorkFit", escrito por Rick Wehr, 2011, traduzido para R por Rachel Chang
Rotina universal para encontrar o melhor ajuste de linha reta para dados com erros variáveis e correlatos, incluindo estimativas de erro e qualidade do ajuste, seguindo a Eq. (13) de York 2004, American Journal of Physics, que foi baseado em York 1969, Earth and Planetary Sciences Letters
YorkFit <- função (X, Y, Xstd, Ystd, Ri = 0, b0 = 0, printCoefs = 0, makeLine = 0, eps = 1e-7)
X, Y, Xstd, Ystd: ondas contendo pontos X, pontos Y e seus desvios padrão
AVISO: Xstd e Ystd não podem ser zero, pois isso fará com que Xw ou Yw seja NaN. Use um valor muito pequeno.
Ri: coeficientes de correlação para erros X e Y - comprimento 1 ou comprimento de X e Y
b0: estimativa inicial aproximada da inclinação (pode ser obtida de um ajuste de mínimos quadrados padrão sem erros)
printCoefs: defina igual a 1 para exibir os resultados na janela de comando
makeLine: defina igual a 1 para gerar uma onda Y para a linha de ajuste
Retorna uma matriz com a interceptação e a inclinação mais suas incertezas
Se nenhuma estimativa inicial para b0 for fornecida, use OLS se (b0 == 0) {b0 = lm (Y ~ X) $ coeficientes [2]}
tol = abs(b0)*eps #the fit will stop iterating when the slope converges to within this value
a, b: interceptação final e inclinação a.err, b.err: incertezas estimadas em interceptação e inclinação
# WAVE DEFINITIONS #
Xw = 1/(Xstd^2) #X weights
Yw = 1/(Ystd^2) #Y weights
# ITERATIVE CALCULATION OF SLOPE AND INTERCEPT #
b = b0
b.diff = tol + 1
while(b.diff>tol)
{
b.old = b
alpha.i = sqrt(Xw*Yw)
Wi = (Xw*Yw)/((b^2)*Yw + Xw - 2*b*Ri*alpha.i)
WiX = Wi*X
WiY = Wi*Y
sumWiX = sum(WiX, na.rm = TRUE)
sumWiY = sum(WiY, na.rm = TRUE)
sumWi = sum(Wi, na.rm = TRUE)
Xbar = sumWiX/sumWi
Ybar = sumWiY/sumWi
Ui = X - Xbar
Vi = Y - Ybar
Bi = Wi*((Ui/Yw) + (b*Vi/Xw) - (b*Ui+Vi)*Ri/alpha.i)
wTOPint = Bi*Wi*Vi
wBOTint = Bi*Wi*Ui
sumTOP = sum(wTOPint, na.rm=TRUE)
sumBOT = sum(wBOTint, na.rm=TRUE)
b = sumTOP/sumBOT
b.diff = abs(b-b.old)
}
a = Ybar - b*Xbar
wYorkFitCoefs = c(a,b)
# ERROR CALCULATION #
Xadj = Xbar + Bi
WiXadj = Wi*Xadj
sumWiXadj = sum(WiXadj, na.rm=TRUE)
Xadjbar = sumWiXadj/sumWi
Uadj = Xadj - Xadjbar
wErrorTerm = Wi*Uadj*Uadj
errorSum = sum(wErrorTerm, na.rm=TRUE)
b.err = sqrt(1/errorSum)
a.err = sqrt((1/sumWi) + (Xadjbar^2)*(b.err^2))
wYorkFitErrors = c(a.err,b.err)
# GOODNESS OF FIT CALCULATION #
lgth = length(X)
wSint = Wi*(Y - b*X - a)^2
sumSint = sum(wSint, na.rm=TRUE)
wYorkGOF = c(sumSint/(lgth-2),sqrt(2/(lgth-2))) #GOF (should equal 1 if assumptions are valid), #standard error in GOF
# OPTIONAL OUTPUTS #
if(printCoefs==1)
{
print(paste("intercept = ", a, " +/- ", a.err, sep=""))
print(paste("slope = ", b, " +/- ", b.err, sep=""))
}
if(makeLine==1)
{
wYorkFitLine = a + b*X
}
ans=rbind(c(a,a.err),c(b, b.err)); dimnames(ans)=list(c("Int","Slope"),c("Value","Sigma"))
return(ans)
}
lm
se encaixa em um modelo de regressão linear, ou seja: um modelo da expectativa de em relação a P ( Y | X ) , no qual Y é claramente aleatório e X é considerado conhecido. Para lidar com a incerteza em X, você precisará de um modelo diferente.