Censoring model / Observing on Delta

Hi all,

I’m quite new to pyro and I was trying to build a simple generative toy model for sales of a specific product in a store over a certain period of time (assuming time-invariant demand), assuming the store has limited storage capacity for that product, but the amount of stock on each day is unknown.

To give you some context on the code below, I modeled this in the following way:
The demand of the product on each day is drawn from a Poisson distribution.
The amount of items that the store has on stock on each day is drawn from a uniform Categorical distribution with a maximum value of 20 (assuming this is the maximum storage capacity of the store).
The actual sales are then the minimum over demand and stocks (you cannot sell more than you have on stock). I modeled this as a Delta(min(demand, stocks)).
Even though the actual amount of stock on each day is unknown, I have additional information that could guide the model:
The time at which the last item was sold on each day (0: right at the beginning of the day, 1: right at the end of the day) is known (the last_sold_time).
Assuming sales happen with constant rate throughout the day, this can be modeled by a Beta distribution.

Here is the model:

def model(obs_sales, obs_lst):
    mu = pyro.sample("mu", dist.LogNormal(0., 2.))
    with pyro.plate("obs", obs_sales.size(0)):
        demand = pyro.sample("demand", dist.Poisson(mu))
        stocks = pyro.sample("stocks", dist.Categorical(probs=torch.ones(20) / 20.).to(torch.float)
        sales = pyro.sample("sales", dist.Delta(torch.min(demand, stocks)), obs=obs_sales)
        lost_sales = demand - sales
        mask = sales > 0
        last_sold_time = pyro.sample("last_sold_time", dist.Beta(sales + ~mask, lost_sales + 1).mask(mask), obs=obs_lst)
        
    return mu, stocks, demand, sales, last_sold_time

The problem with this model is, that I observe from a Delta distribution, which seems to not be supported as I found out using google and this forum.
During inference (SVI), I get a ValueError: The parameter concentration has invalid values, and a %debug reveals, that the conditioning on Delta indeed does not do what I expcted it to do (observations and output of the sample statement are not the same).

So my question is:
Is there a recommended way to re-express / re-parameterize my model, to avoid conditioning on the Delta?
Or do I make an obvious mistake?

Thank you in advance, to anyone who lends me her/his time!
(Oh and just as a sidenote: Having a tool like pyro, that let’s me think this might be possible at all in such a straightforward way, is really awesome!)

Hi @trahflow,

General I would handle censored data by reparameterizing to use the cdf; since PyTorch.distributions does not implement Poisson.cdf() you’d need to implement that by hand (it is easy). Also SVI doesn’t work well for discrete random variables unless you enumerate them. I would recommend enumerating the stocks random variable.