Как работает приближение седловой точки?


38

Как работает приближение седловой точки? Для каких проблем это хорошо?
(Не стесняйтесь использовать конкретный пример или примеры в качестве иллюстрации)

Есть ли какие-либо недостатки, трудности, вещи, на которые стоит обратить внимание, или ловушки для неосторожных?

Ответы:


49

Седловое приближение к функции плотности вероятности (она работает аналогично для массовых функций, но я буду говорить здесь только в терминах плотностей) - это удивительно хорошо работающее приближение, которое можно рассматривать как уточнение центральной предельной теоремы. Таким образом, он будет работать только в тех случаях, когда существует центральная предельная теорема, но для этого нужны более строгие предположения.

Начнем с предположения, что функция, порождающая момент, существует и является дважды дифференцируемой. Это подразумевает, в частности, что все моменты существуют. Пусть X - случайная величина с генерирующей момент функцией (mgf)

M(t)=EetX
и cgf (генерирующая функция кумулянта) K(t)=logM(t) (где logобозначает натуральный логарифм). В процессе разработки я буду внимательно следить за Рональдом У. Батлером: «Приближения седловой точки с приложениями» (CUP). Мы разработаем приближение седловой точки, используя приближение Лапласа к некоторому интегралу. Напишите
eK(t)=etxf(x)dx=exp(tx+logf(x))dx=exp(h(t,x))dx
где h(t,x)=txlogf(x) . Теперь мы разложим Тейлораh(t,x) поx рассматриваяt как постоянную. Это дает
h(t,x)=h(t,x0)+h(t,x0)(xx0)+12h(t,x0)(xx0)2+
гдеобозначает дифференцирование поx. Обратите внимание, что
h(t,x)=txlogf(x)h(t,x)=2x2logf(x)>0
(последнее неравенство по предположению, поскольку оно необходимо для работы приближения). Пустьxtбудет решениемh(t,xt)=0. Предположим, что это дает минимум для h(t,x)как функции отx. Используя это разложение в интеграле и забыв прочасть, получим
eK(t)exp(h(t,xt)12h(t,xt)(xxt)2)dx=eh(t,xt)e12h(t,xt)(xxt)2dx
- гауссовский интеграл, дающий
eK(t)eh(t,xt)2πh(t,xt).
Это дает (первый вариант) приближения седловой точки как
(*)f(xt)h(t,xt)2πexp(K(t)txt)
Обратите внимание, что аппроксимация имеет вид экспоненциального семейства.

Теперь нам нужно проделать некоторую работу, чтобы получить это в более полезной форме.

Из мы получаем Дифференцируя это по получаем (по нашим предположениям), образом, связь между и является монотонной, поэтому четко определена. Нам нужно приближение к . Для этого мы получаем решение изh(t,xt)=0

t=xtlogf(xt).
xt
txt=2xt2logf(xt)>0
txtxtxtlogf(xt)(*)
(**)logf(xt)=K(t)txt12log2π2xt2logf(xt).
Предполагая, что последний член, приведенный выше, слабо зависит от , поэтому его производная по приблизительно равна нулю (мы еще вернемся к комментариям по этому поводу), мы получим Тогда до этого приближения мы получим, что так что и должны быть связаны через уравнение который называется уравнением седловой точки. xtxt
logf(xt)xt(K(t)xt)txtt
0t+logf(xt)xt=(K(t)xt)txt
txt
(§)K(t)xt=0,

Что мы упускаем при определении это и что мы можем найти путем неявного дифференцирования уравнения в седловой точке : Результатом является то, что (с точностью до нашего приближения) Собрав все вместе, мы получим окончательное приближение седловой точки плотности как (*)

h(t,xt)=2logf(xt)xt2=xt(logf(xt)xt)=xt(t)=(xtt)1
K(t)=xt
xtt=K(t).
h(t,xt)=1K(t)
f(x)
f(xt)eK(t)txt12πK(t).
Теперь, чтобы использовать это практически, чтобы приблизить плотность в определенной точке , мы решаем уравнение седловой точки для этого чтобы найти .xtxtt

Приближение перевала часто указывается как приближение к плотности среднее на основании н.о.р. наблюдений . Производящая функция кумулянта среднего - это просто , поэтому приближение седловой точки для среднего становится nX1,X2,,XnnK(t)

f(x¯t)=enK(t)ntx¯tn2πK(t)

Давайте посмотрим на первый пример. Что мы получим, если попытаться приблизить стандартную нормальную плотность mgf: так что поэтому уравнение седловой точки и приближение седловой точки дает так что в этом случае приближение является точным.

f(x)=12πe12x2
M(t)=exp(12t2)
K(t)=12t2K(t)=tK(t)=1
t=xt
f(xt)e12t2txt12π1=12πe12xt2

Давайте посмотрим на совсем другое приложение: начальную загрузку в области преобразования, мы можем выполнить загрузку аналитически, используя приближение седловой точки к загрузочному распределению среднего!

Предположим, у нас есть распределенные по некоторой плотности (в смоделированном примере мы будем использовать единичное экспоненциальное распределение). Из выборки мы вычисляем эмпирическую функцию, генерирующую моменты, а затем эмпирическую cgf . Нам нужно эмпирическое значение mgf для среднего значения, которое является и эмпирическое значение cgf для среднего значения который мы используем для построения седлового приближения. Ниже приведен код R (версия 3.2.3 R): X1,X2,,Xnf

M^(t)=1ni=1netxi
K^(t)=logM^(t)log(M^(t/n)n)
K^X¯(t)=nlogM^(t/n)

set.seed(1234)
x  <-  rexp(10)

require(Deriv)   ### From CRAN
drule[["sexpmean"]]   <-  alist(t=sexpmean1(t))  # adding diff rules to 
                                                 # Deriv
drule[["sexpmean1"]]  <-  alist(t=sexpmean2(t))

###

make_ecgf_mean  <-   function(x)   {
    n  <-  length(x)
    sexpmean  <-  function(t) mean(exp(t*x))
    sexpmean1 <-  function(t) mean(x*exp(t*x))
    sexpmean2 <-  function(t) mean(x*x*exp(t*x))
    emgf  <-  function(t) sexpmean(t)
    ecgf  <-   function(t)  n * log( emgf(t/n) )
    ecgf1 <-   Deriv(ecgf)
    ecgf2 <-   Deriv(ecgf1)
    return( list(ecgf=Vectorize(ecgf),
                 ecgf1=Vectorize(ecgf1),
                 ecgf2 =Vectorize(ecgf2) )    )
}

### Now we need a function solving the saddlepoint equation and constructing
### the approximation:
###

make_spa <-  function(cumgenfun_list) {
    K  <- cumgenfun_list[[1]]
    K1 <- cumgenfun_list[[2]]
    K2 <- cumgenfun_list[[3]]
    # local function for solving the speq:
    solve_speq  <-  function(x) {
          # Returns saddle point!
          uniroot(function(s) K1(s)-x,lower=-100,
                  upper = 100, 
                  extendInt = "yes")$root
}
    # Function finding fhat for one specific x:
    fhat0  <- function(x) {
        # Solve saddlepoint equation:
        s  <-  solve_speq(x)
        # Calculating saddlepoint density value:
        (1/sqrt(2*pi*K2(s)))*exp(K(s)-s*x)
    }
    # Returning a vectorized version:
    return(Vectorize(fhat0))
} #end make_fhat

(Я пытался написать это как общий код, который можно легко модифицировать для других cgfs, но код все еще не очень надежен ...)

Затем мы используем это для выборки из десяти независимых наблюдений из единичного экспоненциального распределения. Мы делаем обычную непараметрическую начальную загрузку «вручную», строим итоговую гистограмму начальной загрузки для среднего значения и выводим приближение седловой точки:

> ECGF  <- make_ecgf_mean(x)
> fhat  <-  make_spa(ECGF)
> fhat
function (x) 
{
    args <- lapply(as.list(match.call())[-1L], eval, parent.frame())
    names <- if (is.null(names(args))) 
        character(length(args))
    else names(args)
    dovec <- names %in% vectorize.args
    do.call("mapply", c(FUN = FUN, args[dovec], MoreArgs = list(args[!dovec]), 
        SIMPLIFY = SIMPLIFY, USE.NAMES = USE.NAMES))
}
<environment: 0x4e5a598>
> boots  <-  replicate(10000, mean(sample(x, length(x), replace=TRUE)), simplify=TRUE)
> boots  <-  replicate(10000, mean(sample(x, length(x), replace=TRUE)), simplify=TRUE)
> hist(boots, prob=TRUE)
> plot(fhat, from=0.001, to=2, col="red", add=TRUE)

Предоставление полученного участка:

седловая аппроксимация распределения начальной загрузки

Аппроксимация кажется довольно хорошей!

Мы могли бы получить еще лучшее приближение, интегрировав приближение седловой точки и масштабирование:

> integrate(fhat, lower=0.1, upper=2)
1.026476 with absolute error < 9.7e-07

Теперь кумулятивная функция распределения, основанная на этом приближении, может быть найдена путем численного интегрирования, но для этого также можно сделать прямое приближение седловой точки. Но это для другого поста, этого достаточно долго.

Наконец, некоторые комментарии остались вне разработки выше. В мы сделали приближение, по существу игнорируя третий член. Почему мы можем это сделать? Одно наблюдение состоит в том, что для нормальной функции плотности оставленный член ничего не дает, поэтому приближение является точным. Итак, поскольку седловая аппроксимация является уточнением центральной предельной теоремы, мы немного приблизились к нормали, поэтому это должно хорошо работать. Можно также посмотреть на конкретные примеры. Глядя на приближение седловой точки к распределению Пуассона, глядя на этот пропущенный третий член, в этом случае он становится тригамма-функцией, которая действительно довольно плоская, когда аргумент не близок к нулю.(**)

Наконец, почему имя? Название происходит от альтернативного происхождения, используя методы комплексного анализа. Позже мы можем рассмотреть это, но в другом посте!


4
То, что у вас есть, великолепно. Развитие там очень ясно.
Glen_b

1
kjetil Я попытался исправить четыре маленьких опечатки 1. « В разработке я буду следовать « 2. », необходимой для работы аппроксимации » 3. « Что мы пропустили сейчас » 4. « Неявное дифференцирование точки перегиба », но при этом оно похоже, я нарушил одно из ваших уравнений - я понятия не имею, как, поскольку я ничего не менял, кроме этих текстовых элементов (как вы можете видеть из истории редактирования). Я бы откатил назад, но так как я не могу объяснить, как исправление этих ошибок вызвало проблему, я не хочу вызывать дальнейшие проблемы. Мои извенения.

1
Возможно, в коде редактирования есть ошибка mathJax или ошибка, которая приводит к этой проблеме.
Glen_b

1
@Christoph Hanck: Чтобы получить аппроксимацию с некоторым значением , вы решаете уравнение точки чтобы найти . xt(§)t
kjetil b halvorsen

2
Возможно, стоит отметить, что при использовании эмпирического cgf результирующее приближение седловой точки не определено вне выпуклой оболочки данных. См. Feuerverger (1989) «Об эмпирическом приближении седловой точки». Так должно быть и в приведенном выше примере начальной загрузки.
Маттео Фазиоло,

15

Здесь я подробно остановлюсь на ответе kjetil и остановлюсь на тех ситуациях, когда функция генерации кумулянта (CGF) неизвестна, но ее можно оценить по данным , где . Самая простая оценка CGF - это, вероятно, оценка Дэвисона и Хинкли (1988) который используется в примере начальной загрузки kjetil. Недостатком этой оценки является то, что полученное уравнение седловой точки может быть решено, только если , точка, в которой мы хотим оценить плотность седловой точки, попадает в выпуклую оболочку .x1,,xnxRd

K^(λ)=1ni=1neλTxi,
K^(λ)=y,
yx1,,xn

Wong (1992) и Fasiolo et al. (2016) решили эту проблему, предложив две альтернативные оценки CGF, сконструированные таким образом, чтобы уравнение седловой точки могло быть решено для любого . Решение Fasiolo et al. (2016), называемый расширенным Эмпирическим СЭП по Седловой точке, реализован в пакете esaddle R, и здесь я привожу несколько примеров.y

В качестве простого одномерного примера рассмотрите возможность использования ESA для аппроксимации плотности .Gamma(2,1)

library("devtools")
install_github("mfasiolo/esaddle")
library("esaddle")

########## Simulating data
x <- rgamma(1000, 2, 1)

# Fixing tuning parameter of ESA
decay <-  0.05

# Evaluating ESA at several point
xSeq <- seq(-2, 8, length.out = 200)
tmp <- dsaddle(y = xSeq, X = x, decay = decay, log = TRUE)

# Plotting true density, ESA and normal approximation
plot(xSeq, exp(tmp$llk), type = 'l', ylab = "Density", xlab = "x")
lines(xSeq, dgamma(xSeq, 2, 1), col = 3)
lines(xSeq, dnorm(xSeq, mean(x), sd(x)), col = 2)
suppressWarnings( rug(x) )
legend("topright", c("ESA", "Truth", "Gaussian"), col = c(1, 3, 2), lty = 1)

Это подходит

введите описание изображения здесь

Глядя на ковер, становится ясно, что мы оценили плотность ESA за пределами диапазона данных. Более сложным примером является следующий искривленный двумерный гауссов.

# Function that evaluates the true density
dwarp <- function(x, alpha) {
  d <- length(alpha) + 1
  lik <- dnorm(x[ , 1], log = TRUE)
  tmp <- x[ , 1]^2
  for(ii in 2:d)
    lik <- lik + dnorm(x[ , ii] - alpha[ii-1]*tmp, log = TRUE)
  lik
}

# Function that simulates from true distribution
rwarp <- function(n = 1, alpha) {
  d <- length(alpha) + 1
  z <- matrix(rnorm(n*d), n, d)
  tmp <- z[ , 1]^2
  for(ii in 2:d) z[ , ii] <- z[ , ii] + alpha[ii-1]*tmp
  z
}

set.seed(64141)
# Creating 2d grid
m <- 50
expansion <- 1
x1 <- seq(-2, 3, length=m)* expansion; 
x2 <- seq(-3, 3, length=m) * expansion
x <- expand.grid(x1, x2) 

# Evaluating true density on grid
alpha <- 1
dw <- dwarp(x, alpha = alpha)

# Simulate random variables
X <- rwarp(1000, alpha = alpha)

# Evaluating ESA density
dwa <- dsaddle(as.matrix(x), X, decay = 0.1, log = FALSE)$llk

# Plotting true density
par(mfrow = c(1, 2))
plot(X, pch=".", col=1, ylim = c(min(x2), max(x2)), xlim = c(min(x1), max(x1)),
     main = "True density", xlab = expression(X[1]), ylab = expression(X[2]))
contour(x1, x2, matrix(dw, m, m), levels = quantile(as.vector(dw), seq(0.8, 0.995, length.out = 10)), col=2, add=T)

# Plotting ESA density
plot(X, pch=".",col=2, ylim = c(min(x2), max(x2)), xlim = c(min(x1), max(x1)),
     main = "ESA density", xlab = expression(X[1]), ylab = expression(X[2]))
contour(x1, x2, matrix(dwa, m, m), levels = quantile(as.vector(dwa), seq(0.8, 0.995, length.out = 10)), col=2, add=T)

введите описание изображения здесь

Подгонка довольно хорошая.


9

Благодаря замечательному ответу Кжетила я сам пытаюсь привести небольшой пример, который я хотел бы обсудить, потому что он, кажется, поднимает важный вопрос:

Рассмотрим . и его производные могут быть найдены здесь и воспроизведены в функциях в коде ниже. χ2(m)K(t)

x <- seq(0.01,20,by=.1)
m <- 5

K  <- function(t,m) -1/2*m*log(1-2*t)
K1 <- function(t,m) m/(1-2*t)
K2 <- function(t,m) 2*m/(1-2*t)^2

saddlepointapproximation <- function(x) {
  t <- .5-m/(2*x)
  exp( K(t,m)-t*x )*sqrt( 1/(2*pi*K2(t,m)) )
}
plot( x, saddlepointapproximation(x), type="l", col="salmon", lwd=2)
lines(x, dchisq(x,df=m), col="lightgreen", lwd=2)

Это производит

введите описание изображения здесь

Это, очевидно, приводит к приближению, которое дает качественные характеристики правильной плотности, но, как подтверждается в комментарии Кжетила, не является правильной плотностью, так как она выше точной плотности везде. Изменение масштаба аппроксимации следующим образом дает почти ничтожную ошибку аппроксимации, представленную ниже.

scalingconstant <- integrate(saddlepointapproximation, x[1], x[length(x)])$value

approximationerror_unscaled <- dchisq(x,df=m) - saddlepointapproximation(x)
approximationerror_scaled   <- dchisq(x,df=m) - saddlepointapproximation(x) /
                                                    scalingconstant

plot( x, approximationerror_unscaled, type="l", col="salmon", lwd=2)
lines(x, approximationerror_scaled,             col="blue",   lwd=2)

введите описание изображения здесь


1
Это особенность, приближение седловой точки не нужно интегрировать в одно, но оно часто близко. Это может быть изменено путем численного интегрирования.
kjetil b halvorsen

Это может быть более показательным, чтобы построить относительную ошибку!
kjetil b halvorsen

approximationerror_unscaled/approximationerror_scaledОказывается, парить около 25.90798
Кристоф Ханк
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.