各ポイントに


12

Iが行わn 2つの変数の測定値をxy。どちらも不確実性が知られているσx及びσyそれらに関連します。と関係を見つけたい。どうすればできますか?xy

編集:各には異なる関連付けられており、でも同じです。xiσ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


確かに、lmの期待のモデル:線形回帰でモデル、フィットに関して、P Y | X 、ここで明確にYをYP(Y|X)Yはランダムであり、は既知であると見なされます。Xの不確実性に対処するには、別のモデルが必要になります。XX
共役

1
かなり特殊なケース(XとYの既知のノイズレベル比を持つ単変量)の場合、デミング回帰はトリックを行いDemingます(RパッケージMethCompの関数など)
共役

1
@conjugatepriorありがとう、これは有望に見えます。私は疑問に思っています:個々のxとyに異なる(しかしまだ知られている)分散がある場合、デミング回帰はまだ機能しますか?すなわち、xが長さであり、各xを取得するために異なる精度の定規を使用した場合
菱形十六面体

おそらく、測定ごとに異なる分散がある場合にそれを解決する方法は、ヨークの方法を使用していると思います。このメソッドのR実装があるかどうかを誰かが知っていますか?
菱形十二面体

1
@rhombidodecahedronそこに私の答えに収まる「測定誤差あり」を参照してください。 stats.stackexchange.com/questions/174533/…(パッケージデミングのドキュメントから取られました)。
ローランド

回答:


9

本当の行をしましょう 角度 θと値 γで与えられる Lを集合とするLθγ

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

任意の点とこの線の間の符号付き距離は(x,y)

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

分散させることがσ 2 IとのことY iはであるτ 2 Iの、独立Xxiσi2yiτi2及び Y iは、この距離の変動がある意味しますxiyi

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

したがって、2乗距離の逆分散加重和が可能な限り小さいγを見つけましょう。誤差が2変量正規分布を持っていると仮定すると、最尤解になります。これには数値解が必要ですが、通常の最小二乗近似によって示唆された値で始まるいくつかのニュートンラプソンステップを見つけるのは簡単です。θγ

シミュレーションは、この解決策でも少量のデータとの比較的大きな値とよくあるお勧めτσi。もちろん、通常の方法でパラメーターの標準エラーを取得できます。傾きだけでなく、ラインの位置の標準誤差に関心がある場合は、最初に両方の変数を 0にセンタリングすることをお勧めします。これにより、2つのパラメーターの推定値間のほとんどすべての相関が除去されます。τi0


この方法は問題の例で非常にうまく機能し、近似線はプロットの真の線とほとんど区別できます。それらはどこでも互いに1ユニット以内にあります。代わりに、この例では指数分布からIID描かれσ iは二倍規模で指数分布からIID描かれている(そうエラーのほとんどは傾向があることで発生する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)

+1。私の知る限り、これはこの古いQ:stats.stackexchange.com/questions/178727?複製として閉じます。
アメーバは、モニカーを復活させる

また、そのスレッドの答えに対する私のコメントによれば、deming関数は変数エラーも処理できるようです。それはおそらくあなたと非常によく似たフィットをもたらすはずです。
アメーバは、モニカーを復活させる

図の上と下の2つの段落の位置を入れ替えると、議論の流れがより意味をなさないのだろうか?
GUNG -復活モニカ

3
今朝(投票者によって)数年前にMathematica SEのサイトで、この質問が複数の方法で、実際のコードを使って尋ねられ、回答されたことを思い出しました
whuber

このソリューションには名前がありますか?おそらくさらに読むためのリソース(Mathematica SEサイト以外の意味)?
JustGettinStarted

0

xとyに不確実性がある場合の最尤最適化は、ヨーク(2004)によって対処されています。これが彼の関数のRコードです。

「ヨークフィット」、リック・ウェール、2011年作成、レイチェル・チャン著Rに翻訳

誤差および適合度の推定値を含む変数、相関誤差を含むデータに最適な直線近似を見つけるための汎用ルーチン (13)2004年ヨーク、American Journal of Physics、1969年ヨーク、地球惑星科学レターに順番に基づいた

YorkFit <-function(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の初期推定値が提供されない場合、(b0 == 0){b0 = lm(Y〜X)$ coefficients [2]}の場合にOLSを使用します。

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コードと同じ結果が得られることに注意してください。
スティーブンウォフシー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.