0
$\begingroup$

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)

enter image description here

$\endgroup$
3
  • $\begingroup$ This looks like something the PyMC package would readily handle, but coding questions are not on topic here. $\endgroup$
    – Galen
    Sep 21, 2022 at 3:34
  • $\begingroup$ @Galen Should I move this question to stackoverflow instead? $\endgroup$
    – jwnz
    Sep 21, 2022 at 3:49
  • $\begingroup$ 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. $\endgroup$ Sep 23, 2022 at 5:12

1 Answer 1

0
$\begingroup$

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)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.