R 中的 3 维预测限制
3 dimension prediction limit in R
设一个数据集有3个变量(这里是正态且独立但它们可以相关)
data = data.frame(x1 = rnorm(10000),
x2 = rnorm(10000),
x3 = rnorm(10000))
我想获得 x1、x2 和 x3 的最窄范围,以便 95% 的观察值落在所有三个范围内。
到目前为止我有下面的代码。
is.between <- function(x, a, b){
x <= max(c(a, b)) & x >= min(c(a, b))
}
getlims <- function(lims, x1, x2, x3){
abs(mean(
is.between(x1, lims[1], lims[2]) &
is.between(x2, lims[3], lims[4]) &
is.between(x3, lims[5], lims[6])
) - 0.95)
}
optim(initial_values, getlims, x1=x1,x2=x2,x3=x3)
其中 lims[1,2] 是 x1 的范围,lims[3,4] 是 x2 的范围,lims[5,6] 是 x3 的范围。
它提供的限制包含我观察的 95%,但不保证它会是较小体积的 lims[1,2]*lims[3,4]*lims[5,6]。
我觉得这其实是离散优化中的一个问题。它以三个维度给出,我将其重新表述为两个维度以获得更好的可视化效果,它可以立即扩展到更多维度。
让我们尝试将其作为具有约束的非线性优化问题来解决。
set.seed(1009)
N <- 1000
x <- rnorm(N); y <- rnorm(N)
还需要这些坐标的 0.05 和 0.95 分位数。
q1 <- quantile(x, 0.05); q2 <- quantile(x, 0.95)
q3 <- quantile(y, 0.05); q4 <- quantile(y, 0.95)
我们定义了两个函数,fmin
要最小化的函数,fbnd
定义约束的函数。即我们要求fbnd(x) >= 0
,这样表示至少95%的点在矩形内。
fmin <- function(p) (p[2]-p[1]) * (p[4]-p[3])
fbnd <- function(p) {
c(0.05 - sum(x < p[1] | x > p[2] | y < p[3] | y > p[4]) / N,
q1 - p[1], p[2] - q2,
q3 - p[3], p[4] - q4 )
}
作为起点,我们可以采用 x 和 y 坐标的范围。
start <- c(range(x), range(y))
优化求解器必须最小化具有非线性约束的函数。程序包 nloptr 中的 auglag
例程是候选求解器。
S <- nloptr::auglag(start, fn=fmin, hin=fbnd)
S$par; S$value
# [1] -2.301263 2.308038 -2.079166 2.130744
# [1] 19.40474
我们可以通过将矩形边界移动到下一个较高或较低的 x-resp 来改进解决方案。 y 坐标。这是必要的步骤,因为 objective 函数是局部常量。
r <- S$par
r[1] <- min(x[x >= r[1]]); r[2] <- max(x[x <= r[2]])
r[3] <- min(y[y >= r[3]]); r[4] <- max(y[y <= r[4]])
r
# [1] -2.299467 2.281395 -2.079166 2.127260
我们可以看到,矩形外有50个点,面积为19.26905。
(r[2]-r[1]) * (r[4]-r[3]) # 19.26905
sum(x < r[1] | x > r[2] | y < r[3] | y > r[4]) # 50
解仍然可以是局部最小值。幸运的是,objective 函数也是局部单调的,因此通常不会发生这种情况。当然,可以通过应用全局求解器来验证解决方案。
设一个数据集有3个变量(这里是正态且独立但它们可以相关)
data = data.frame(x1 = rnorm(10000),
x2 = rnorm(10000),
x3 = rnorm(10000))
我想获得 x1、x2 和 x3 的最窄范围,以便 95% 的观察值落在所有三个范围内。
到目前为止我有下面的代码。
is.between <- function(x, a, b){
x <= max(c(a, b)) & x >= min(c(a, b))
}
getlims <- function(lims, x1, x2, x3){
abs(mean(
is.between(x1, lims[1], lims[2]) &
is.between(x2, lims[3], lims[4]) &
is.between(x3, lims[5], lims[6])
) - 0.95)
}
optim(initial_values, getlims, x1=x1,x2=x2,x3=x3)
其中 lims[1,2] 是 x1 的范围,lims[3,4] 是 x2 的范围,lims[5,6] 是 x3 的范围。
它提供的限制包含我观察的 95%,但不保证它会是较小体积的 lims[1,2]*lims[3,4]*lims[5,6]。
我觉得这其实是离散优化中的一个问题。它以三个维度给出,我将其重新表述为两个维度以获得更好的可视化效果,它可以立即扩展到更多维度。
让我们尝试将其作为具有约束的非线性优化问题来解决。
set.seed(1009)
N <- 1000
x <- rnorm(N); y <- rnorm(N)
还需要这些坐标的 0.05 和 0.95 分位数。
q1 <- quantile(x, 0.05); q2 <- quantile(x, 0.95)
q3 <- quantile(y, 0.05); q4 <- quantile(y, 0.95)
我们定义了两个函数,fmin
要最小化的函数,fbnd
定义约束的函数。即我们要求fbnd(x) >= 0
,这样表示至少95%的点在矩形内。
fmin <- function(p) (p[2]-p[1]) * (p[4]-p[3])
fbnd <- function(p) {
c(0.05 - sum(x < p[1] | x > p[2] | y < p[3] | y > p[4]) / N,
q1 - p[1], p[2] - q2,
q3 - p[3], p[4] - q4 )
}
作为起点,我们可以采用 x 和 y 坐标的范围。
start <- c(range(x), range(y))
优化求解器必须最小化具有非线性约束的函数。程序包 nloptr 中的 auglag
例程是候选求解器。
S <- nloptr::auglag(start, fn=fmin, hin=fbnd)
S$par; S$value
# [1] -2.301263 2.308038 -2.079166 2.130744
# [1] 19.40474
我们可以通过将矩形边界移动到下一个较高或较低的 x-resp 来改进解决方案。 y 坐标。这是必要的步骤,因为 objective 函数是局部常量。
r <- S$par
r[1] <- min(x[x >= r[1]]); r[2] <- max(x[x <= r[2]])
r[3] <- min(y[y >= r[3]]); r[4] <- max(y[y <= r[4]])
r
# [1] -2.299467 2.281395 -2.079166 2.127260
我们可以看到,矩形外有50个点,面积为19.26905。
(r[2]-r[1]) * (r[4]-r[3]) # 19.26905
sum(x < r[1] | x > r[2] | y < r[3] | y > r[4]) # 50
解仍然可以是局部最小值。幸运的是,objective 函数也是局部单调的,因此通常不会发生这种情况。当然,可以通过应用全局求解器来验证解决方案。