使用 ECDF 手动计算两个样本的 kolmogorov-smirnov
Manually calculate two-sample kolmogorov-smirnov using ECDF
我正在尝试手动计算两个随机样本的 KS 统计量。据我了解,KS 统计量 D 是两个 CDF 之间的最大垂直偏差。但是,手动计算两个 CDF 和 运行 之间的差异 ks.test 来自基础 R 会产生不同的结果。我想知道错误在哪里。
set.seed(123)
a <- rnorm(10000)
b <- rnorm(10000)
### Manual calculation
# function for calculating manually the ecdf
decdf <- function(x, baseline, treatment) ecdf(baseline)(x) - ecdf(treatment)(x)
#Difference between the two CDFs
d <- curve(decdf(x,a,b), from=min(a,b), to=max(a,b))
# getting D
ks <- max(abs(d$y))
#### R-Base calculation
ks.test(a,b)
R-Base D = 0.0109 而人工计算为0.0088。感谢任何解释差异的帮助。
我附上 R-Base 源代码(稍微整理了一下)
n <- length(a)
n.x <- as.double(n)
n.y <- length(b)
n <- n.x * n.y/(n.x + n.y)
w <- c(a, b)
z <- cumsum(ifelse(order(w) <= n.x, 1/n.x, -1/n.y))
STATISTIC <- max(abs(z))
默认情况下,curve
在 from
和 to
之间的 100 个点的细分上计算函数。通过限制为这 100 个点,您可能会错过达到最大差异的值。
相反,评估 ecdf 跳跃的所有点的差异,您一定会捕捉到达到最大差异的值。
set.seed(123)
a <- rnorm(10000)
b <- rnorm(10000)
Fa <- ecdf(a)
Fb <- ecdf(b)
x <- c(a,b) # the points where Fa or Fb jump
max(abs(Fa(x) - Fb(x)))
# [1] 0.0109
我正在尝试手动计算两个随机样本的 KS 统计量。据我了解,KS 统计量 D 是两个 CDF 之间的最大垂直偏差。但是,手动计算两个 CDF 和 运行 之间的差异 ks.test 来自基础 R 会产生不同的结果。我想知道错误在哪里。
set.seed(123)
a <- rnorm(10000)
b <- rnorm(10000)
### Manual calculation
# function for calculating manually the ecdf
decdf <- function(x, baseline, treatment) ecdf(baseline)(x) - ecdf(treatment)(x)
#Difference between the two CDFs
d <- curve(decdf(x,a,b), from=min(a,b), to=max(a,b))
# getting D
ks <- max(abs(d$y))
#### R-Base calculation
ks.test(a,b)
R-Base D = 0.0109 而人工计算为0.0088。感谢任何解释差异的帮助。
我附上 R-Base 源代码(稍微整理了一下)
n <- length(a)
n.x <- as.double(n)
n.y <- length(b)
n <- n.x * n.y/(n.x + n.y)
w <- c(a, b)
z <- cumsum(ifelse(order(w) <= n.x, 1/n.x, -1/n.y))
STATISTIC <- max(abs(z))
默认情况下,curve
在 from
和 to
之间的 100 个点的细分上计算函数。通过限制为这 100 个点,您可能会错过达到最大差异的值。
相反,评估 ecdf 跳跃的所有点的差异,您一定会捕捉到达到最大差异的值。
set.seed(123)
a <- rnorm(10000)
b <- rnorm(10000)
Fa <- ecdf(a)
Fb <- ecdf(b)
x <- c(a,b) # the points where Fa or Fb jump
max(abs(Fa(x) - Fb(x)))
# [1] 0.0109