使用泰勒展开估计比率的标准偏差

时间:2016-02-08 22:26:05

标签: r estimation taylor-series

我有兴趣构建一个R函数,我可以用它来测试泰勒级数近似的极限。我知道我正在做的事情是有限的,但这正是我希望调查的那些限制。

我有两个正态分布的随机变量xyx的平均值为7,标准差(sd)为1. y的平均值为5,sd为4.

me.x <- 4; sd.x <- 1
me.y <- 5; sd.y <- 4

我知道如何估算y/x的平均比率,就像这样

# E(y/x) = E(y)/E(x) - Cov(y,x)/E(x)^2 + Var(x)*E(y)/E(x)^3
me.y/me.x - 0/me.x^2 + sd.x*me.y/me.x^3
[1] 1.328125

但我仍然坚持如何估算比率的标准差?我意识到我必须使用泰勒扩展,但不是如何使用它。

我做了一个简单的模拟

 x <- rnorm(10^4, mean = 4, sd = 1);  y <- rnorm(10^4, mean = 5, sd = 4)
 sd(y/x)
 [1] 2.027593
 mean(y/x)[1]
 1.362142

3 个答案:

答案 0 :(得分:5)

完成了对两位高斯比例的PDF的分析表达式 作者:David Hinkley(见Wikipedia)。因此我们可以计算所有动量,均值等等。我输入它并且显然它没有有限的第二动量,因此它没有有限的标准偏差。注意,我把你的Y gaussian表示为我的X,你的X表示为我的Y(公式假定为X / Y)。我的比率的平均值非常接近你从模拟得到的,但最后的积分是无限的,抱歉。您可以采样越来越多的值,但是从采样std.dev开始增长,正如@ G.Grothendieck所指出的那样

library(ggplot2)

m.x <- 5; s.x <- 4
m.y <- 4; s.y <- 1

a <- function(x) {
    sqrt( (x/s.x)^2 + (1.0/s.y)^2 )
}

b <- function(x) {
    (m.x*x)/s.x^2 + m.y/s.y^2
}

c <- (m.x/s.x)^2 + (m.y/s.y)^2

d <- function(x) {
    u <- b(x)^2 - c*a(x)^2
    l <- 2.0*a(x)^2
    exp( u / l )
}

# PDF for the ratio of the two different gaussians
PDF <- function(x) {
    r <- b(x)/a(x)
    q <- pnorm(r) - pnorm(-r)

    (r*d(x)/a(x)^2) * (1.0/(sqrt(2.0*pi)*s.x*s.y)) * q + exp(-0.5*c)/(pi*s.x*s.y*a(x)^2)
}

# normalization
nn <- integrate(PDF, -Inf, Inf)
nn <- nn[["value"]]

# plot PDF
p <- ggplot(data = data.frame(x = 0), mapping = aes(x = x))
p <- p + stat_function(fun = function(x) PDF(x)/nn) + xlim(-2.0, 6.0)
print(p)

# first momentum
m1 <- integrate(function(x) x*PDF(x), -Inf, Inf)
m1 <- m1[["value"]]

# mean
print(m1/nn)

# some sampling
set.seed(32345)
n <- 10^7L
x <- rnorm(n, mean = m.x, sd = s.x); y <- rnorm(n, mean = m.y, sd = s.y)
print(mean(x/y))
print(sd(x/y))

# second momentum - Infinite!
m2 <- integrate(function(x) x*x*PDF(x), -Inf, Inf)

因此,不可能测试std.dev的任何泰勒展开。

答案 1 :(得分:3)

考虑到@ G.Grothendieck提出的注意事项:独立 X和Y变量的产品和商的有用助记符是

CV^2(X/Y) = CV^2(X*Y) = CV^2(X) + CV^2(Y)

其中CV是变异系数(sd(X)/mean(X)),因此CV^2Var/mean^2。换句话说

Var(Y/X)/(m(Y/X))^2 = Var(X)/m(X)^2 + Var(Y)/m(Y)^2

或重新排列

sd(Y/X) = sqrt[ Var(X)*m(Y/X)^2/m(X)^2 + Var(Y)*m(Y/X)^2/m(Y)^2 ]

对于平均值远离零的随机变量,这是一个合理的近似值。

set.seed(101)
y <- rnorm(1000,mean=5)
x <- rnorm(1000,mean=10)
myx <- mean(y/x)
sqrt(var(x)*myx^2/mean(x)^2 + var(y)*myx^2/mean(y)^2)  ## 0.110412
sd(y/x)  ## 0.1122373

使用你的例子是相当糟糕的,因为Y的CV接近1 - 我最初认为它看起来不错,但现在我看到它有偏见以及没有很好地捕捉变化(我也插入平均值和SD的预期值而不是它们的模拟值,但对于如此大的样本应该是误差的一小部分。)

me.x <- 4; sd.x <- 1
me.y <- 5; sd.y <- 4
myx <- me.y/me.x - 0/me.x^2 + sd.x*me.y/me.x^3
x <- rnorm(1e4,me.x,sd.x); y <- rnorm(1e4,me.y,sd.y)
c(myx,mean(y/x))
sdyx <- sqrt(sd.x^2*myx^2/me.x^2 + sd.y^2*myx^2/me.y^2)
c(sdyx,sd(y/x))    
## 1.113172 1.197855

rvals <- replicate(1000,
    sd(rnorm(1e4,me.y,sd.y)/rnorm(1e4,me.x,sd.x)))
hist(log(rvals),col="gray",breaks=100)
abline(v=log(sdyx),col="red",lwd=2)
min(rvals)  ## 1.182698

enter image description here

所有用于计算Y / X方差的预制delta方法方法都使用Y / X的点估计(即m(Y / X)= mY / mX),而不是上面使用的二阶近似。构建均值和方差的高阶形式应该是直截了当的,如果可能乏味(计算机代数系统可能有帮助......)

mvec <- c(x = me.x, y = me.y)
V <- diag(c(sd.x, sd.y)^2)
car::deltaMethod(mvec, "y/x", V)
##     Estimate       SE
## y/x     1.25 1.047691

library(emdbook)
sqrt(deltavar(y/x,meanval=mvec,Sigma=V)) ## 1.047691

sqrt(sd.x^2*(me.y/me.x)^2/me.x^2 + sd.y^2*(me.y/me.x)^2/me.y^2)  ## 1.047691

为了它的价值,我在@ SeverinPappadeux的答案中获取了代码并将其转换为函数gratio(mx,my,sx,sy)。对于Cauchy案例(gratio(0,0,1,1)),它会混淆并报告均值为0(应该是NA /发散),但是正确地将差异/标准差报告为发散。对于由OP(gratio(5,4,4,1))指定的参数,它给出均值= 1.352176,sd = NA如上所述。对于我在上面尝试的第一个参数(gratio(10,5,1,1)),它给出了均值= 0.5051581,sd = 0.1141726。

这些数值实验强烈告诉我,高斯人有时的比例有明确定义的方差,但我不知道何时(Math StackOverflow或CrossValidated的另一个问题的时间?)< / p>

答案 2 :(得分:2)

这种近似不太可能有用,因为分布可能没有有限的标准偏差。看看它有多不稳定:

set.seed(123)
n <- 10^6
X <- rnorm(n, me.x, sd.x)
Y <- rnorm(n, me.y, sd.y)

sd(head(Y/X, 10^3))
## [1] 1.151261

sd(head(Y/X, 10^4))
## [1] 1.298028

sd(head(Y/X, 10^5))
## [1] 1.527188

sd(Y/X)
## [1] 1.863168

对比当我们用普通随机变量尝试相同的事情时会发生什么:

sd(head(Y, 10^3))
## [1] 3.928038

sd(head(Y, 10^4))
## [1] 3.986802

sd(head(Y, 10^5))
## [1] 3.984113

sd(Y)
## [1] 3.999024

注意:如果您处于不同的情况,例如分母有紧凑的支持,那么你可以这样做:

library(car)

m <- c(x = me.x, y = me.y)
v <- diag(c(sd.x, sd.y)^2)
deltaMethod(m, "y/x", v)