我有兴趣构建一个R函数,我可以用它来测试泰勒级数近似的极限。我知道我正在做的事情是有限的,但这正是我希望调查的那些限制。
我有两个正态分布的随机变量x
和y
。 x
的平均值为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
答案 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^2
为Var/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
所有用于计算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)