Issue Running VPC

Hello,

I am trying to run a VPC with a fitted model and continue to run into an error with my quantiles. The lower bounds are dropping into the negatives towards the tail-end of my data and I can’t figure out how to trouble shoot.
This is my current code for it:
vpc_result = vpc(
mydataframe;
samples = 100,
qreg_method = :IP,
observations = [:dv],
quantiles = (0.1, 0.5, 0.9),
level = 0.95,
prediction_correction = false,
covariates = [:time],
smooth = true
)
Any feedback is greatly appreciated, thank you!

Hi Emily,

Make sure you have gone through the VPC tutorial - Visual Predictive Checks for Continuous Data Models

It looks like you are running a Visual Predictive Check (VPC) in Pumas and noticing that the lower quantile (e.g., 10th percentile) drops into negative values at later time points, which is not physiologically plausible for your data (e.g., concentrations). This is a common issue, especially when using an additive error model or when the model does not fit the data well at low concentrations. It really depends a lot on the error model that you are using.

Here are some steps and considerations to help you troubleshoot and improve your VPC:

1. Check Your Error Model

If your model uses an additive error structure, it can predict negative concentrations, especially at low values. This is a well-known limitation of additive error models. If your data are concentrations (which cannot be negative), a proportional or combined error model is usually more appropriate.

Example:

# In your model definition, use a proportional or combined error model

@derived begin
    dv ~ @. Normal(μ, sqrt(σ_add^2 + (μ * σ_prop)^2))
end

Or, if you only want proportional error:

@derived begin
    dv ~ @. Normal(mu, mu * σ_prop)
end

2. Inspect the Model Fit

A poor model fit, especially at the tail end of your data (e.g., late time points), can cause the simulated quantiles to be too low or negative. Check your model diagnostics and consider whether the structural model or parameter estimates need refinement.

3. Consider Prediction Correction

If your study design is heterogeneous (e.g., different doses, covariates), using prediction_correction = true can help normalize the data and simulated values, making the VPC more robust to design differences.

Example:

vpc_result = vpc(
    myfitobj;
    samples = 500,
    observations = [:dv],
    quantiles = (0.1, 0.5, 0.9),
    level = 0.95,
    prediction_correction = true,  # Try enabling this
 
)

Note: You cannot use stratify_by and prediction_correction together. This may be allowed in later versions

4. Adjust the Bandwidth

The bandwidth parameter controls the smoothing of quantile regression. If the bandwidth is too small, the quantile lines may be too wiggly and sensitive to outliers; if too large, they may be overly smoothed and not reflect the data well. Try adjusting the bandwidth (default is 2.0 for continuous VPCs).

Example:

vpc_result = vpc(
    myfitobj;
    samples = 500,
    observations = [:dv],
    quantiles = (0.1, 0.5, 0.9),
    level = 0.95,
    prediction_correction = false,
    bandwidth = 2.5  # Try increasing or decreasing this value
)

5. Check for Data Issues

  • Are there outliers or unphysiological values in your data?
  • Are there very few observations at late time points, making quantile estimation unstable?

6. Plot and Interpret

After running the VPC, use vpc_plot to visualize the results:

using Pumas, AlgebraOfGraphics, CairoMakie

plt = vpc_plot(vpc_result)

Summary Table

Issue Solution/Check
Negative quantiles Use proportional/combined error model
Poor fit at late times Refine model, check parameter estimates
Outliers/unstable quantiles Adjust bandwidth, clean data
Heterogeneous design Try prediction correction

If you try these suggestions and still see negative quantiles, please provide more details about your model structure and error model.

2 Likes

Hi Vijay,

Thank you for your quick response! I followed your suggestions, but I’m still seeing negative quantiles in the VPC output. To provide better context, here are some details about my model:

Error model: dv ~ @. Normal(cp, sqrt(σ_add^2 + (σ_prop * cp)^2))

My model includes an oral lead-in followed by a long-acting injectable. The observed dataset used for model fitting includes five injections and the extended tail phase.

I noticed the tutorial includes a section on plotting Time After Dose, and I’m wondering if filtering the data by time might improve the VPC. Specifically, the negative quantiles appear toward the tail end of the time period. Would it be more appropriate to generate separate VPCs for the injection and tail phases rather than combining them in a single plot?

Thank you!

Em

Would it be more appropriate to generate separate VPCs for the injection and tail phases rather than combining them in a single plot?

No, I don’t think you should do that. One thing that you can do is to change this error model slightly

dv ~ @. Normal(cp, sqrt(σ_add^2 + (σ_prop * abs(cp))^2)) # notice the `abs()`

Try using this both for fitting and then the vpc call and let us know what happens.

Further, since you said it is over 5 doses, you may want to try covariates = [:tad] in the vpc call so that the plot show concentration vs time after most recent dose rather than time since first dose.

2 Likes

After adjusting the error model to

dv ~ @. Normal(cp, sqrt(σ_add^2 + (σ_prop * abs(cp))^2))

and updating the vpc as shown:

vpc_result = vpc(
  han_tail_model_fit;
  samples = 100,
  observations = [:dv],
  quantiles = (0.1, 0.5, 0.9),
  level = 0.95,
  prediction_correction = true,
  covariates = [:tad],
  bandwidth = 3,
  smooth = true)

I am still getting negative values - for instance, the tenth percentile values at the end of the tail look like this:

            τ     tad      lower        middle      upper
   6 │     0.1   5544.0  -0.298716    -0.200965   -0.10568
   7 │     0.1   7392.0  -0.322153    -0.231757   -0.147717
   8 │     0.1   9408.0  -0.354302    -0.238082   -0.142191

Thank you again for your support!!!

1 Like

Update:

The TAD was a helpful addition to the VPC. However, the negative quantiles persisted after adjustment to the error model. I am trying to figure out if the problem lies within the model or the VPC function itself.

I created a minimal cap (vpc_tad_df.lower .= max.(vpc_tad_df.lower, 0.05), so I could visualize it. The VPC with the set minimum is attached below.

Any insight would be helpful. Thank you and I look forward to hearing your thoughts!

1 Like

Sorry for the late response, Emily. Can you tell me what is the final estimate of your error model parameters, the proportional and additive parts?

I think it’s not super surprising that your values could be negative with an additive or a combined error model. You are assuming that your observations follow a central tendency of cp and then there is gaussian noise of sqrt(σ_add^2 + (σ_prop *abs(cp))^2). Of course, if cp is close to 0 the last part goes to zero as well, but you will always have positive probability of negative quantities, even small sigma_add.