PyMC中是否实施了Hawkes流程?

时间:2016-02-05 09:32:48

标签: python statistics pymc mcmc stochastic-process

我想使用Hawkes流程来建模一些数据。我无法找到PyMC是否支持Hawkes进程。更具体地说,我希望用霍克斯过程观察变量,并在其参数上学习后验。

如果它不存在,那么我可以用某种方式在PyMC中定义它,例如@deminministic等。??

1 个答案:

答案 0 :(得分:0)

距离您提出问题已有很长时间了,但是我今天已经在PyMC上进行了研究,所以我认为我应该与其他可能遇到相同问题的人分享我的实施要点。我们将推断霍克斯过程的参数λ和α。我将不讨论时间尺度参数β,而是将其作为练习供读者使用。

首先让我们生成一些数据:

def hawkes_intensity(mu, alpha, points, t):
    p = np.array(points)
    p = p[p <= t]
    p = np.exp(p - t)
    return mu + alpha * np.sum(p)


def simulate_hawkes(mu, alpha, window):
    t = 0
    points = []
    lambdas = []
    while t < window:
        m = hawkes_intensity(mu, alpha, points, t)
        s = np.random.exponential(scale=1/m)
        ratio = hawkes_intensity(mu, alpha, points, t + s)

        t = t + s
        if t < window:
            points.append(t)
            lambdas.append(ratio)
        else:
            break
    points = np.sort(np.array(points, dtype=np.float32))
    lambdas = np.array(lambdas, dtype=np.float32)
    return points, lambdas


# parameters
window = 1000
mu = 8
alpha = 0.25
points, lambdas = simulate_hawkes(mu, alpha, window)
num_points = len(points)

我们刚刚使用一些我从那里改编的函数生成了一些时间点:https://nbviewer.jupyter.org/github/MatthewDaws/PointProcesses/blob/master/Temporal%20points%20processes.ipynb

现在,诀窍是创建一个大小为(num_points,num_points)的矩阵,其中包含第i个点与所有其他点的时间距离。因此,矩阵的(i,j)点是将第i个点与第j个点分开的时间间隔。该矩阵将用于计算霍克斯过程指数的和。自我激励的部分。创建此矩阵以及指数和的方法有些棘手。我建议您自己检查每一行,以便查看它们的作用。

tile = np.tile(points, num_points).reshape(num_points, num_points)
tile = np.clip(points[:, None] - tile, 0, np.inf)
tile = np.tril(np.exp(-tile), k=-1)
Σ = np.sum(tile, axis=1)[:-1]  # this is our self-exciting sum term

我们有一些点,并且我们有一个包含激励项之和的矩阵。 Hawkes过程的两个连续事件之间的持续时间遵循参数λ=λ0+ ∑激发的指数分布。这就是我们要建模的东西,但是首先我们必须计算所生成数据的两个连续点之间的持续时间。

interval = points[1:] - points[:-1]

我们现在可以进行推断了:

with pm.Model() as model:
    λ = pm.Exponential("λ", 1)
    α = pm.Uniform("α", 0, 1)

    lam = pm.Deterministic("lam", λ + α * Σ)
    interarrival = pm.Exponential(
        "interarrival", lam, observed=interval)


    trace = pm.sample(2000, tune=4000)
    pm.plot_posterior(trace, var_names=["λ", "α"])
    plt.show()

    print(np.mean(trace["λ"]))
    print(np.mean(trace["α"]))
  

7.829   0.284

注意:如果您有许多数据点,则tile矩阵会变得很大。