Регрессия, когда каждая точка имеет свою собственную неопределенность как по и по

12

Я сделал измерений двух переменных и . Они оба имеют известные неопределенности и связанные с ними. Я хочу найти связь между и . Как мне это сделать?x y σ x σ y x ynxyσxσyxy

РЕДАКТИРОВАТЬ : каждый имеет различные связанные с ним, и то же самое с .σ x , i y ixiσx,iyi


Воспроизводимый R пример:

## pick some real x and y values 
true_x <- 1:100
true_y <- 2*true_x+1

## pick the uncertainty on them
sigma_x <- runif(length(true_x), 1, 10) # 10
sigma_y <- runif(length(true_y), 1, 15) # 15

## perturb both x and y with noise 
noisy_x <- rnorm(length(true_x), true_x, sigma_x)
noisy_y <- rnorm(length(true_y), true_y, sigma_y)

## make a plot 
plot(NA, xlab="x", ylab="y",
    xlim=range(noisy_x-sigma_x, noisy_x+sigma_x), 
    ylim=range(noisy_y-sigma_y, noisy_y+sigma_y))
arrows(noisy_x, noisy_y-sigma_y, 
       noisy_x, noisy_y+sigma_y, 
       length=0, angle=90, code=3, col="darkgray")
arrows(noisy_x-sigma_x, noisy_y,
       noisy_x+sigma_x, noisy_y,
       length=0, angle=90, code=3, col="darkgray")
points(noisy_y ~ noisy_x)

## fit a line 
mdl <- lm(noisy_y ~ noisy_x)
abline(mdl)

## show confidence interval around line 
newXs <- seq(-100, 200, 1)
prd <- predict(mdl, newdata=data.frame(noisy_x=newXs), 
    interval=c('confidence'), level=0.99, type='response')
lines(newXs, prd[,2], col='black', lty=3)
lines(newXs, prd[,3], col='black', lty=3)

линейная регрессия без учета ошибок в переменных

Проблема этого примера в том, что я думаю, что он предполагает отсутствие неопределенности в . Как я могу это исправить?x

rhombidodecahedron
источник
Правда, lmподходит для модели линейной регрессии, то есть модели ожидания относительно , в которой ясно, что является случайным, а считается известным. Чтобы справиться с неопределенностью в вам понадобится другая модель. P ( Y | X ) Y X XYP(Y|X)YXX
сопряженный
1
Для вашего довольно особого случая (одномерного с известным отношением уровней шума для X и Y) регрессия Деминга поможет, например, Demingфункция в R-пакете MethComp .
сопряженный
1
@conjugateprior Спасибо, это выглядит многообещающе. Я задаюсь вопросом: регрессия Деминга все еще работает, если у меня есть различная (но все еще известная) дисперсия на каждом отдельном x и y? т.е. если x - это длины, и я использовал линейки с разной точностью, чтобы получить каждый x
ромбододекаэдр
Я думаю, что, возможно, для решения этой проблемы, когда существуют разные отклонения для каждого измерения, используется метод Йорка. Кто-нибудь знает, есть ли реализация R этого метода?
ромбододекаэдр
1
@rhombidodecahedron Посмотрите, что подходит для "с измеренными ошибками" в моем ответе там: stats.stackexchange.com/questions/174533/… (который был взят из документации пакета deming).
Роланд

Ответы:

9

Пусть истинная линия , заданная углом и значением , будет множествомθ γLθγ

(x,y):cos(θ)x+sin(θ)y=γ.

Расстояние со знаком между любой точкой и этой линией(x,y)

d(x,y;L)=cos(θ)x+sin(θ)yγ.

Позволить дисперсия быть и что из быть , независимость и подразумевает отклонение этого расстоянияσ 2 i y i τ 2 i x i y ixiσi2yiτi2xiyi

Var(d(xi,yi;L))=cos2(θ)σi2+sin2(θ)τi2.

Поэтому давайте найдем и для которых взвешенная сумма квадратов расстояний с обратной дисперсией будет как можно меньше: это будет решение с максимальной вероятностью, если предположить, что ошибки имеют двумерные нормальные распределения. Это требует численного решения, но легко найти несколько шагов Ньютона-Рафсона, начинающихся со значения, предлагаемого обычной подгонкой наименьших квадратов.γθγ

Моделирование показывает, что это решение хорошо даже при небольших объемах данных и относительно больших значениях и . Конечно, вы можете получить стандартные ошибки для параметров обычными способами. Если вас интересует стандартная ошибка положения линии, а также наклона, то вы можете сначала центрировать обе переменные в : это должно устранить почти всю корреляцию между оценками двух параметров.τ i 0σiτi0


Метод работает так хорошо на примере вопроса, что подобранная линия почти неотличима от истинной линии на графике: они находятся в пределах или около того друг от друга повсюду. Вместо этого в этом примере из экспоненциального распределения, а - из экспоненциального распределения с удвоенным масштабом (так что большая часть ошибки имеет место в координате ). Есть только баллов, небольшое количество. Истинные точки расположены на одинаковом расстоянии вдоль линии с интервалом между единицами. Это довольно серьезный тест, потому что потенциальные ошибки заметны по сравнению с диапазоном точек.σ i x n = 8τiσixn=8

фигура

Истинная линия показана синим пунктиром. Вдоль него исходные точки изображены в виде полых кружков. Серые стрелки соединяют их с наблюдаемыми точками, нанесенными в виде сплошных черных дисков. Решение нарисовано как сплошная красная линия. Несмотря на наличие больших отклонений между наблюдаемыми и фактическими значениями, решение замечательно близко к правильной линии в этой области.

#
# Generate data.
#
theta <- c(1, -2, 3) # The line is theta %*% c(x,y,-1) == 0
theta[-3] <- theta[-3]/sqrt(crossprod(theta[-3]))
n <- 8
set.seed(17)
sigma <- rexp(n, 1/2)
tau <- rexp(n, 1)
u <- 1:n
xy.0 <- t(outer(c(-theta[2], theta[1]), 0:(n-1)) + c(theta[3]/theta[1], 0))
xy <- xy.0 + cbind(rnorm(n, sd=sigma), rnorm(n, sd=tau))
#
# Fit a line.
#
x <- xy[, 1]
y <- xy[, 2]
f <- function(phi) { # Negative log likelihood, up to an additive constant
  a <- phi[1]
  gamma <- phi[2]
  sum((x*cos(a) + y*sin(a) - gamma)^2 / ((sigma*cos(a))^2 + (tau*sin(a))^2))/2
}
fit <- lm(y ~ x) # Yields starting estimates
slope <- coef(fit)[2]
theta.0 <- atan2(1, -slope)
gamma.0 <- coef(fit)[1] / sqrt(1 + slope^2)
sol <- nlm(f,c(theta.0, gamma.0))
#
# Plot the data and the fit.
#
theta.hat <- sol$estimate[1] %% (2*pi)
gamma.hat <- sol$estimate[2]
plot(rbind(xy.0, xy), type="n", xlab="x", ylab="y")
invisible(sapply(1:n, function(i) 
  arrows(xy.0[i,1], xy.0[i,2], xy[i,1], xy[i,2], 
         length=0.15, angle=20, col="Gray")))
points(xy.0)
points(xy, pch=16)
abline(c(theta[3] / theta[2], -theta[1]/theta[2]), col="Blue", lwd=2, lty=3)
abline(c(gamma.hat / sin(theta.hat), -1/tan(theta.hat)), col="Red", lwd=2)
Whuber
источник
+1. Насколько я понимаю, это отвечает и на этот старый вопрос Q: stats.stackexchange.com/questions/178727 ? Мы должны закрыть его как дубликат.
говорит амеба: восстановите Монику
Кроме того, согласно моему комментарию к ответу в этой теме, похоже, что demingфункция также может обрабатывать переменные ошибки. Вероятно, это должно привести к приступу, очень похожему на ваш.
говорит амеба: восстанови Монику
Интересно, имеет ли смысл обсуждение, если вы поменяете местами 2 абзаца выше и ниже рисунка?
gung - Восстановить Монику
3
Этим утром мне напомнил (один избиратель), что этот вопрос задавался и отвечал несколькими способами, с рабочим кодом, несколько лет назад на сайте Mathematica SE .
whuber
У этого решения есть имя? и, возможно, ресурс для дальнейшего чтения (помимо сайта Mathematica SE, я имею в виду)?
JustGettinStarted
0

Оптимизация максимального правдоподобия для случая неопределенности в x и y была рассмотрена York (2004). Вот код R для его функции.

"YorkFit", написанный Риком Вером, 2011, переведенный на R Рэйчел Чанг

Универсальная процедура для нахождения наилучшей прямой подгонки к данным с переменными, коррелированными ошибками, включая ошибки и оценки достоверности подгонки, по формуле. (13) of York 2004, Американский журнал физики, который в свою очередь был основан на York 1969, Earth and Planetary Sciences Letters.

YorkFit <- функция (X, Y, Xstd, Ystd, Ri = 0, b0 = 0, printCoefs = 0, makeLine = 0, eps = 1e-7)

X, Y, Xstd, Ystd: волны, содержащие точки X, точки Y и их стандартные отклонения

ВНИМАНИЕ: Xstd и Ystd не могут быть равны нулю, так как это приведет к тому, что Xw или Yw будут равны NaN. Вместо этого используйте очень маленькое значение.

Ri: коэффициенты корреляции для ошибок X и Y - длина 1 или длина X и Y

b0: грубое начальное предположение для наклона (может быть получено из стандартного подбора по методу наименьших квадратов без ошибок)

printCoefs: установить равным 1 для отображения результатов в окне команд

makeLine: установить равным 1, чтобы сгенерировать волну Y для линии соответствия

Возвращает матрицу с перехватом и наклоном плюс их неопределенности

Если исходное предположение для b0 не предусмотрено, просто используйте OLS, если (b0 == 0) {b0 = lm (Y ~ X) $ коэффициенты [2]}

tol = abs(b0)*eps #the fit will stop iterating when the slope converges to within this value

a, b: окончательный перехват и наклон a.err, b.err: оценочные неопределенности в пересечении и наклоне

# 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)
 }
Стивен Вофси
источник
Также обратите внимание, что пакет R IsoplotR включает функцию york (), которая дает те же результаты, что и код YorkFit.
Стивен Вофси