Censored Model with Hurdle Parameter

Thinking about your unobserved failures (you can split the dataset in observed and unobserved failures). The likelihood for unobserved failures is something like:

pm.Mixture(
  "unobserved_failure",
  w=[p_faulty_sensor, 1 - p_faulty_sensor], 
  dist=[
    # If sensor is faulty, we have left censoring
    pm.Censored.dist(dist=time_to_event, lower=df.check_day),    
    # Otherwise, right censoring
    pm.Censored.dist(dist=time_to_event, upper=df.check_day),
  ],
  observed=df.check_day
)

For observed failures it’s just left censoring.

The other thing you want to do is to inform p_faulty_sensor by the number of observed_failures as well. That’s an extra likelihood term of the form:

pm.Binomial("observed_failures", n=n_observed_failures, p=1-p_faulty_sensor, observed=n_observed_failures")

I would have to think a bit more whether you can combine the 3 elements into a single “distribution”. If not, a CustomDist with manual logp may be the more clean implementation.