单变量指数霍克斯过程是一个自激点过程,事件到达率为:
在哪里是事件到达时间。
对数似然函数是
可以递归计算:
我可以使用哪些数值方法来查找 MLE?最简单的实用方法是什么?
单变量指数霍克斯过程是一个自激点过程,事件到达率为:
在哪里是事件到达时间。
对数似然函数是
可以递归计算:
我可以使用哪些数值方法来查找 MLE?最简单的实用方法是什么?
Nelder-Mead 单纯形算法似乎运行良好。它由位于https://commons.apache.org/math/的 Apache Commons Math 库用 Java 实现。我还在Point Process Models for Multivariate High-Frequency Irregularly Spaced Data上写了一篇关于 Hawkes 过程的论文。
felix,使用 exp/log 转换似乎可以确保参数的积极性。至于小阿尔法的事情,请在 arxiv.org 上搜索一篇名为“几乎不稳定霍克斯过程的极限定理”的论文
我使用nlopt库解决了这个问题。我发现许多方法很快就收敛了。
你也可以做一个简单的最大化。在 R 中:
neg.loglik <- function(params, data, opt=TRUE) {
mu <- params[1]
alpha <- params[2]
beta <- params[3]
t <- sort(data)
r <- rep(0,length(t))
for(i in 2:length(t)) {
r[i] <- exp(-beta*(t[i]-t[i-1]))*(1+r[i-1])
}
loglik <- -tail(t,1)*mu
loglik <- loglik+alpha/beta*sum(exp(-beta*(tail(t,1)-t))-1)
loglik <- loglik+sum(log(mu+alpha*r))
if(!opt) {
return(list(negloglik=-loglik, mu=mu, alpha=alpha, beta=beta, t=t,
r=r))
}
else {
return(-loglik)
}
}
# insert your values for (mu, alpha, beta) in par
# insert your times for data
opt <- optim(par=c(1,2,3), fn=neg.loglik, data=data)
这是我对“最简单的实用方法是什么?”的解决方案。使用 python,特别是 numpy、scipy 和 tick。
一种修改是我将指数内核设置为 alpha x beta x exp (-beta (t - ti)),以与 tick 定义指数内核的方式一致: https ://x-datainitiative.github.io/tick/modules /生成/tick.hawkes.HawkesExpKern.html#tick.hawkes.HawkesExpKern
我假设读者可能不熟悉 python。
导入相关库:
import numpy as np
from scipy.optimize import minimize
from tick.hawkes import SimuHawkesExpKernels
定义递归函数(上述问题中的 R(i)),它返回一个与事件数相同大小的数组:
def _recursive(timestamps, beta):
r_array = np.zeros(len(timestamps))
for i in range(1, len(timestamps)):
r_array[i] = np.exp(-beta * (timestamps[i] - timestamps[i - 1])) * (1 + r_array[i - 1])
return r_array
定义指定各种参数的对数似然函数:
def log_likelihood(timestamps, mu, alpha, beta, runtime):
r = _recursive(timestamps, beta)
return -runtime * mu + alpha * np.sum(np.exp(-beta * (runtime - timestamps)) - 1) + \
np.sum(np.log(mu + alpha * beta * r))
使用 tick 库(或其他方式)模拟一些 Hawkes 数据:
m = 0.5
a = 0.2
b = 0.3
rt = 1000
simu = SimuHawkesExpKernels([[a]], b, [m], rt, seed=0)
simu.simulate()
t = simu.timestamps[0]
Scipy 的最小化函数可能是标量函数最常见的 Python 优化。它需要一个只有两组参数的函数;那些你想最小化的和那些固定的。有多种可能的最小化方法,我使用默认值 L-BFGS-B 来解决有界问题,并且是准牛顿法。
请注意,我应该首先从蛮力搜索开始,但问题要求最简单的实用方法。我也可以在 mu 和 alpha 上拆分为最小化,然后在 beta 上使用模拟退火,因为对数仅在 mu 和 alpha 上是凸的。
定义要由最小化函数使用的新函数并返回负对数似然:
def crit(params, *args):
mu, alpha, beta = params
timestamps, runtime = args
return -log_likelihood(timestamps, mu, alpha, beta, runtime)
调用最小化函数并将 m、a 和 b 的边界设置为正:
minimize(crit, [m + 0.1, a + 0.1, b+ 0.1], args=(t, rt), bounds=((1e-10, None), (1e-10, None), (1e-10, None),))
它给出了 m,a,b 的估计值:array([0.43835767, 0.25823306, 0.14769243])