ICB-DCM / pyABC

distributed, likelihood-free inference
https://pyabc.rtfd.io
BSD 3-Clause "New" or "Revised" License
204 stars 44 forks source link

How to deal with "covariance is not symmetric positive-semidefinite" ? #641

Closed Ookra closed 1 week ago

Ookra commented 2 weeks ago

When I choose only one set of parameters from Distribution by pyabc RV, I find it works, the paramters can be accepted by my rule, and the error can be successfully calculated. However, when I try to use ABCSMC to choose more sets of parameters, it will break down, cou not calculate the next one. I don't know why, please help me. Thank you very much!

%%%%%%%%%%%%%%%%%%%%%%%%%%% Debug log %%%%%%%%%%%%%%%%%%%%%%%%%%%

ABC INFO: t: 0, eps: 5.00000000e+02.
ABC INFO: Accepted: 50 / 50 = 1.0000e+00, ESS: 5.0000e+01.
ABC INFO: t: 1, eps: 0.00000000e+00.
D:\Anaconda\envs\pyabcc\lib\site-packages\pyabc\transition\multivariatenormal.py:109: **RuntimeWarning: covariance is not symmetric positive-semidefinite.**
  perturbed = sample + np.random.multivariate_normal(
ABC WARNING: Unusually many (model, parameter) samples have prior density zero. **The transition might be inappropriate.**

%%%%%%%%%%%%%%%%%%%%%%%%%%% My parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%

parameter_priors = Distribution(
    n0=RV("uniform", 1e2, 1e5),
    w0=RV("uniform", 0, 1e1),
    rs=RV("uniform", 0.01 * 24, 0.04 * 24),
    m=RV("uniform", 10 ** 5, 10 ** 9),  
    qes=RV("uniform", 1.1 * 10 ** (-7), 1.1 * 10 ** (-7)),
    K=RV("uniform", 10 ** 6, 10 ** 9),
    rhoo=RV("uniform", 4.17 * 10 ** (-13), 3.09 * 10 ** (-5)),
    epsilon=RV("uniform", 1, 50),
    u4=RV("uniform", 0.01, 0.303)
)

%%%%%%%%%%%%%%%%%%%%%%%%%%% My transitions %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%% Kernel 1 %%%%%%%%%%%%%%%

abc = ABCSMC(
    models=model,
    parameter_priors=parameter_priors,
    distance_function=distance,
    population_size=20,
    transitions=LocalTransition(k_fraction=0.3),
    eps=MedianEpsilon(500, median_multiplier=0.7),
)

abc.new(db_path)
h = abc.run(minimum_epsilon=0.5, max_nr_populations=3)

%%%%%%%%%%%%%%%%%% Kernel 2 %%%%%%%%%%%%%%%%%

from pyabc.transition import MultivariateNormalTransition

abc = ABCSMC(
    models=model,
    parameter_priors=parameter_priors,
    distance_function=distance,
    population_size=20,  
    transitions=MultivariateNormalTransition(),  
    eps=MedianEpsilon(500, median_multiplier=0.7),
)

abc.new(db_path)
h = abc.run(minimum_epsilon=0.5, max_nr_populations=3)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

arrjon commented 2 weeks ago

Do you get the same error, when using a different transition kernel?

Your parameters are on very different scales, which makes it difficult to find a good new set of parameters. Try log-transforming them in your prior and then handling them correctly in the model.

Ookra commented 2 weeks ago

Do you get the same error, when using a different transition kernel?

Your parameters are on very different scales, which makes it difficult to find a good new set of parameters. Try log-transforming them in your prior and then handling them correctly in the model.

Okay, I will try. Thank you so much!!!

arrjon commented 2 weeks ago

any news? hopefully, we can close the issue! :)

Ookra commented 1 week ago

any news? hopefully, we can close the issue! :) Thank you very much for your help! I tried selecting parameters before log-transforming, and it works for most parameters, especially when the sample size is large. Thank you again! : )

ABC.History INFO: Start <ABCSMC id=209, start_time=2024-11-06 11:48:07> ABC INFO: t: 0, eps: 5.00000000e+02. ABC INFO: Accepted: 30 / 30 = 1.0000e+00, ESS: 3.0000e+01. ABC INFO: t: 1, eps: 0.00000000e+00. ABC INFO: Accepted: 30 / 30 = 1.0000e+00, ESS: 1.9135e+00. ABC INFO: Stop: Minimum epsilon. ABC.History INFO: Done <ABCSMC id=209, duration=0:00:11.321198, end_time=2024-11-06 11:48:18>