首页 > 解决方案 > python:带有简单ODE的pyABC-实例str和int之间不支持回溯错误<=

问题描述

我有一个简单的 ODE,其中包含一些未知参数(r、C、mu 和 gamma),它可以预测清洁后表面上细菌的衰变和再生。我有清洗后不同时间点(0h、1h、2h、4h、8h和24h)细菌数量的实验数据。我正在尝试使用 EasyABC 包通过近似贝叶斯计算顺序蒙特卡罗模拟方法来估计参数分布 r、C、d 和 g。

ODE 定义如下: 在此处输入图像描述

实验数据如下所示:

在此处输入图像描述

#前言

from pyabc import (ABCSMC,
                   RV, Distribution,
                   MedianEpsilon,
                   LocalTransition)
from pyabc.visualization import plot_kde_2d, plot_data_callback
import matplotlib.pyplot as plt
import os
import tempfile
import numpy as np
from scipy.integrate import odeint
import math
db_path = ("sqlite:///" +
           os.path.join(tempfile.gettempdir(), "test.db"))

#实验数据

initial_contamination=59 #For ODE
measurement_data = np.array([19,5,5,2,9]) #To compare simulation against
s=[26,2.3,4.67,4.33,4.27] #Standard deviation used in Distance
precision=5000

measurement_times = np.array([0,1,2,4,8,24]) #Hours after cleaning

#定义常微分方程:

def ode_model(contamination,t,r,C,mu,gamma):
    Contamination = contamination;
    return(Contamination*r*(1-Contamination/C)-mu*math.exp(-gamma*t)*Contamination)

def deterministic_run(parameters):#precision,initial_contamination,r,C,mu, gamma):
    precision=5000
    tmax = 24
    time_space = np.linspace(0,tmax,precision+1)
    sim=odeint(ode_model,initial_contamination,time_space,args=(parameters["r"],parameters["C"],parameters["mu"],parameters["gamma"]))
    num_at_1=sim[int(precision*1/50.0)]
    num_at_2=sim[int(precision*2/50.0)]
    num_at_4=sim[int(precision*4/50.0)]
    num_at_8=sim[int(precision*8/50.0)]
    num_at_24=sim[int(precision*24/50.0)]
    return([num_at_1,num_at_2,num_at_4,num_at_8,num_at_24])

#定义先验分布

parameter_prior = Distribution(r=RV("uniform", 0, 4),
                               C=RV("uniform", 6, 15),
                               mu=RV("uniform", 0, 4),
                               gamma=RV("uniform", 0, 4))

parameter_prior.get_parameter_names()

#定义欧几里得距离:

def Distance(x,y,s):

    # computes the Euclidean distance between two lists of the same length

    if len(x) == len(y):

        return math.sqrt(sum([(((x[i]-y[i])/s[i])**2) for i in range(len(x))]))

    else:

        return 'lists not the same length'

#设置ABC-SMC配置

abc = ABCSMC(models=deterministic_run,
             parameter_priors=parameter_prior,
             distance_function=Distance,
             population_size=50,
             transitions=LocalTransition(k_fraction=.3),
             eps=MedianEpsilon(500, median_multiplier=0.7))



abc.new(db_path, {"Contamination": measurement_data})

#运行ABC-SMC

h = abc.run(minimum_epsilon=0.1, max_nr_populations=5)

我得到的错误

类型错误:“str”和“int”的实例之间不支持“<=”

这指的是acceptor.py的第100行

def initialize(self, t: int, get_weighted_distances: Callable[[], pd.DataFrame], distance_function: Distance, x_0: dict): """ 初始化。该方法最初由ABCSMC框架调用,可用于校准接受器到初始统计。默认是什么都不做。

    Parameters
    ----------

    t: int
        The timepoint to initialize the acceptor for.
    get_weighted_distances: Callable[[], pd.DataFrame]
        Returns on demand the distances for initializing the acceptor.
    distance_function: Distance
        Distance object. The acceptor should not modify it, but might
        extract some meta information.
    x_0: dict
        The observed summary statistics.
    """
    pass

但我无法弄清楚它有什么问题。任何想法将不胜感激。

编辑:完整追溯:

runfile('/Users/YYY/Downloads/Beth/Code/pyABC_Cleaning.py', wdir='/Users/YYY/Downloads/Beth/Code')
INFO:Sampler:Parallelizing the sampling on 8 cores.
INFO:History:Start <ABCSMC(id=1, start_time=2020-06-22 09:19:29.808488, end_time=None)>
INFO:ABC:t: 0, eps: 500.
Process Process-1:
Traceback (most recent call last):
Process Process-4:
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
Traceback (most recent call last):
Process Process-2:
Process Process-3:
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
Process Process-5:
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
Process Process-6:
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
Process Process-7:
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
Process Process-8:
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
TypeError: '<=' not supported between instances of 'str' and 'int'
Traceback (most recent call last):
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 37, in work
    new_sim = simulate_one()
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
TypeError: '<=' not supported between instances of 'str' and 'int'
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 598, in simulate_one
    weight_function)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 683, in _evaluate_proposal
    x_0)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/model.py", line 213, in accept
    par=pars)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 306, in __call__
    distance_function, eps, x, x_0, t, par)
  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/acceptor/acceptor.py", line 242, in accept_use_current_time
    accept = d <= eps(t)
TypeError: '<=' not supported between instances of 'str' and 'int'
Traceback (most recent call last):

  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicorebase.py", line 100, in get_if_worker_healthy
    item = queue.get(True, 5)

  File "/Users/YYY/opt/anaconda3/lib/python3.7/multiprocessing/queues.py", line 105, in get
    raise Empty

Empty


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "/Users/YYY/Downloads/Beth/Code/pyABC_Cleaning.py", line 115, in <module>
    h = abc.run(minimum_epsilon=0.1, max_nr_populations=5)

  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/smc.py", line 890, in run
    pop_size, simulate_one, max_eval)

  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/base.py", line 151, in sample_until_n_accepted
    sample = f(self, n, simulate_one, max_eval, all_accepted)

  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicore_evaluation_parallel.py", line 121, in sample_until_n_accepted
    val = get_if_worker_healthy(processes, queue)

  File "/Users/YYY/opt/anaconda3/lib/python3.7/site-packages/pyabc/sampler/multicorebase.py", line 104, in get_if_worker_healthy
    raise ProcessError("At least one worker is dead.")

ProcessError: At least one worker is dead.

标签: python

解决方案


错误来自这一行,是由您的距离函数返回一个字符串引起的。您将距离定义为:

def Distance(x,y,s):
    # computes the Euclidean distance between two lists of the same length
    if len(x) == len(y):
        return math.sqrt(sum([(((x[i]-y[i])/s[i])**2) for i in range(len(x))]))
    else:
        return 'lists not the same length'

所以我猜你最终会遇到这种else情况,返回字符串并用你看到的错误杀死工人。您必须检查xy找出导致它们长度不同的原因。


推荐阅读