# Predict user's next login time

I am trying to implement a model to predict the next time a user will login to some system. The only data I have is the user ID and the login time.

The distribution for the time between each users' logins (in seconds) is exponential. I'm struggling to implement a model that one could use to predict the next n $$\Delta_t$$.

There was a very similar question previously asked, and The answer was to model the data as such:

$$(\Delta_t)i∼$$Exponential$$(\lambda_i)$$ $$i=1…N$$

$$λi∼P(λ)$$

Where the Exponential distribution is paramatarised by $$\lambda$$ and the $$P$$ is the distribution for $$\lambda_i$$ which are gamma distributed.

I'm strugging to understand how I would implement this in Python using numpy or scipy for example. I'm very familiar with training machine learning models using scikit-Learn or PyTorch, but how would I implement the model above?

Given the data below, where do I go next?

time_between_logins = scipy.stats.expon.rvs(450, 80000, 1000)


• This looks like something the PyMC package would readily handle, but coding questions are not on topic here. Sep 21, 2022 at 3:34
• @Galen Should I move this question to stackoverflow instead?
– jwnz
Sep 21, 2022 at 3:49
• The resulting distribution from the inter-login times $\Delta_{t,i}$ is a Pareto distribution, see e.g. math.stackexchange.com/questions/646852/…. Therefore you can use any function that allows you to fit a Pareto distribution, or you can do it yourself by maximum likelihood. Sep 23, 2022 at 5:12

I have managed to get an implementation that works for my purposes.

Below is a snippet of how I implemented just the model definition in NumPyro. You can also find a Gist of the full working and runnable code here.

def model(user_ids, time_deltas=None):

n_users = len(set(user_ids))

with numpyro.plate("user_plate", n_users):
gamma_dist = dist.Gamma(concentration, gamma_rate)
scaledGamma = dist.TransformedDistribution(
gamma_dist,
transforms=dist.transforms.AffineTransform(
loc,
scale,
domain=dist.transforms.constraints.positive))
_r = numpyro.sample("rate", scaledGamma)

rate = _r[user_ids]

with numpyro.plate("data", len(time_deltas)):
exp = dist.Exponential(1 / rate)
numpyro.sample("obs", exp, obs=time_deltas)