I have some count data for user-interaction over the past 365 days. I have reason to believe that several events have occurred which change the rate at which users are interacting. The model is as follow:
Assumptions
- Daily count data is (locally) drawn from a Poisson distribution with parameter
lambda
- There are between
0
andn<365
structural changes, i.e.lambda
changes - These changes can occur at any time during the 365 day period
Desired Answers
- How many times did a likely structural change occur?
- When did these changes happen?
I would like to instantiate this model with tensorflow_probability
. The model described near the end of this chapter seems like a good starting place. However the number of structural changes is hard-coded to 1. How can I expand this model to handle an unknown number of changes?
EDIT
This is a modified version of the code mentioned above. It allows for an arbitrary number of switchpoints. Inspired by Dave Moore's answer below, I've allowed tau
to have "out-of-bounds" elements by multiplying by 2. Stylistically, I'm concerned about the computation for indices
, as I think it's a bit confusing to understand what is happening. However, I can't think of a better way to do it. Functionally, I'm worried about the effect that the out-of-bounds values may have on the log probability.
def joint_log_prob(count_data, taus, lambdas, max_switches):
rate = np.array(1./count_data_.mean(), np.float32)
lambdas_prior = tfd.Exponential(rate)
taus_prior = tfd.Uniform()
A = tf.gather(
taus * ndays,
indices=tf.stack([tf.fill([ndays], i) for i in range(max_switches-1)])
)
B = tf.to_float(tf.range(ndays))
indices = tf.reduce_sum(tf.to_int32(tf.less(A, B)), axis=0)
lambda_ = tf.gather(lambdas, indices)
count_data_prior = tfd.Poisson(lambda_)
return (
tf.reduce_sum(count_data_prior.log_prob(count_data))
+ tf.reduce_sum(taus_prior.log_prob(taus))
+ tf.reduce_sum(lambdas_prior.log_prob(lambdas))
)
You're exactly right that models with an random number of latent variables are tricky to write in most existing tools, including TFP, because they require the shape of the inference computation to change dynamically during inference: the set of things to infer is itself one of the quantities you're doing inference over. That doesn't (easily) fit into standard computation graph frameworks.
The usual solution is to rewrite the model to use a fixed number of variables. For example, if you think there will be at most 20 structural changes, you could write a model with 20 changepoints, where some are allowed to be 'dummy' changepoints (e.g., occurring outside the length of the observed signal), so that only a subset are actually active.
A related approach is to treat the structural uncertainty as a problem of Bayesian model selection: instead of fitting a model with uncertain structure, you consider several models, each with different number of variables, and compare them using the marginal likelihood.
Unfortunately I don't know of any concrete examples applying these approaches specifically to changepoint models -- maybe others will have better references?