Giter Site home page Giter Site logo

hawkesbook's Introduction

hawkesbook Python package for Hawkes Process inference, simulation, etc.

This package implements inference, simulation, and other related method for Hawkes processes and some mutually-exciting Hawkes processes. It is meant to accompany The Elements of Hawkes Processes written by Patrick J. Laub, Young Lee, and Thomas Taimre. To install simply run pip install hawkesbook.

The main design goal for this package was simplicity and readability. Unicode characters are used to match the mathematics to the code as much as possible. For example, the Hawkes process conditional intensity (in LaTeX notation) is

\lambda^\ast(t) = \lambda + \sum_{t_i \in \mathcal{H}_t} \mu(t - t_i)

and this is rendered in Python as

def hawkes_intensity(t, 鈩媉t, 饾泬):
    , , _ = 饾泬
    位耍 = 
    for t_i in 鈩媉t:
        位耍 += (t - t_i)
    return 位耍

Some functions are JIT-compiled to C and parallelised with numba so the computational performance is not completely neglected. Everything that can be numpy-vectorised has been.

Our main dependencies are numba, numpy, and scipy (for the minimize function).

As an example, in the book we have a case study which fits various Hawkes process to the arrival times of earthquakes. The code for the fitting and analysis of that data is like:

import hawkesbook as hawkes

import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
from statsmodels.graphics.gofplots import qqplot

# Load data to fit
quakes = pd.read_csv("japanese-earthquakes.csv")
quakes.index = pd.to_datetime(quakes.Day.astype(str) + "/" + quakes.Month.astype(str) + "/" + quakes.Year.astype(str) + " " + quakes.Time, dayfirst=True)
quakes.sort_index(inplace=True)

# Calculate each arrival as a (fractional) number of days since the
# beginning of the observation period
timeToQuake = quakes.index - pd.Timestamp("1/1/1973")
ts = np.array(timeToQuake.total_seconds() / 60 / 60 / 24)

# Calculate the length of the observation period
obsPeriod = pd.Timestamp("31/12/2020") - pd.Timestamp("1/1/1973")
T = obsPeriod.days

# Calculate the maximum likelihood estimate for the Hawkes process
# with an exponentially decaying intensity
饾泬_exp_mle = hawkes.exp_mle(ts, T)
print("Exp Hawkes MLE fit: ", 饾泬_exp_mle)

# Calculate the EM estimate or the same type of Hawkes process
饾泬_exp_em = hawkes.exp_em(ts, T, iters=100)
print("Exp Hawkes EM fit: ", 饾泬_exp_mle)

# Get the likelihoods of each fit to find the better one
ll_mle = hawkes.exp_log_likelihood(ts, T, 饾泬_exp_mle)
ll_em = hawkes.exp_log_likelihood(ts, T, 饾泬_exp_em)

if ll_mle > ll_em:
	print("MLE was a better fit than EM in this case")
	饾泬_exp = 饾泬_exp_mle
	ll_exp = ll_mle
else:
	print("EM was a better fit than MLE in this case")
	饾泬_exp = 饾泬_exp_em
	ll_exp = ll_em

# Fit instead the Hawkes with a power-law decay
饾泬_pl = hawkes.power_mle(ts, T)
ll_pl = hawkes.power_log_likelihood(ts, T, 饾泬_pl)

# Compare the BICs
BIC_exp = 3 * np.log(len(ts)) - 2 * ll_exp
BIC_pl = 4 * np.log(len(ts)) - 2 * ll_pl
if BIC_exp < BIC_pl:
	print(f"The exponentially-decaying Hawkes was the better fit with BIC={BIC_exp:.2f}.")
	print(f"The power-law Hawkes had BIC={BIC_pl:.2f}.")
else:
	print(f"The power-law Hawkes was the better fit with BIC={BIC_pl:.2f}.")
	print(f"The exponentially-decaying Hawkes had BIC={BIC_exp:.2f}.")

# Create a Q-Q plot for the exponential-decay fit by
# first transforming the points to a unit-rate Poisson
# process as outlined by the random time change theorem
tsShifted = hawkes.exp_hawkes_compensators(ts, 饾泬_exp)
iat = np.diff(np.insert(tsShifted, 0, 0))
qqplot(iat, dist=stats.expon, fit=False, line="45")
plt.show()

hawkesbook's People

Contributors

pat-laub avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    馃枛 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 馃搳馃搱馃帀

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google 鉂わ笍 Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.