模型拟合与评价 API#

mas.model.PopModel#

class mas.model.PopModel(mod, data=None)#

群体模型。对其可以进行模型拟合与模拟等操作。

此处的“群体模型”一般指代的是用于拟合群体数据的非线性混合效应模型(继承自 Module 的模型)。

参数:

  • mod (AnyModule):模型。

  • data (polars.DataFrame | pandas.DataFrame | EventTable, optional):需要被模型拟合的数据集。默认值为 None

data#

property data#

获取将被模型拟合的数据集。

类型:

DataFrame

inits#

property inits#

获取模型参数及其初值。

类型:

PopParams

fit()#

fit(estimation=FOCEi, cov=True) FitResult#

拟合模型。

参数:

  • estimation (AnyEstimationSettings | Sequence[AnyEstimationSettings], optional):参数估计的算法及其相关设置。当前支持的算法包括 FOCEi (first-order conditional estimation with interaction)与 FO(first-order estimation)。若传入一个序列(Sequence)则将根据传入顺序依次以对应的算法估计参数。默认值为 FOCEi

  • cov (bool, optional):是否计算协方差矩阵。默认值为 True

返回值:

包含参数估计值的模型拟合结果。

返回类型:

FitResult

示例:

使用 FOCEi 算法拟合华法林 PK 模型:

from mas.model import *
from mas.datasets import warfarin
import polars as pl


class WarfarinPk(EvOneCmtLinear):
    def __init__(self):
        super().__init__()
        self.tv_cl = theta(0.134, bounds=(0, None))
        self.tv_v = theta(7.81, bounds=(0, None))
        self.tv_ka = theta(0.571, bounds=(0, None))
        self.tv_alag = theta(0.823, bounds=(0, None))
        self.eta_cl = omega(0.049)
        self.eta_v = omega(0.0802)
        self.eta_ka = omega(0.047)
        self.eta_alag = omega(0.156)
        self.eps_prop = sigma(0.0104)
        self.eps_add = sigma(0.554)

    def pred(self):
        cl = self.tv_cl * exp(self.eta_cl)
        v = self.tv_v * exp(self.eta_v)
        ka = self.tv_ka * exp(self.eta_ka)
        alag = self.tv_alag * exp(self.eta_alag)
        pred_res = self.pred_physio(cl=cl, v=v, ka=ka, alag1=alag, s2=v)
        ipred = pred_res.F
        y = ipred * (1 + self.eps_prop) + self.eps_add
        return y


data = warfarin.filter(pl.col("DVID") != 2)
model = PopModel(data=data, mod=WarfarinPk)
fit_res = model.fit(FOCEi(print=10))
➡️ Since build cache already exists, skip compile
✈️ First Order Conditional Estimation
Using BFGS...
* maxiter = 9999
* xtol = 1e-06
* ftol = 1e-06
* lower_bounds = 
* upper_bounds = 
* log_level = 0
* print = 10
* print_type = 0
* verbose = 1
* p_small = 0.1
* rel_step_size = 0.001

#0    ofv: 347.7917575
x: 1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  1.0000e-01  
Gradients: -10.5092 -8.33744 -96.9252 30.7996 -27.5129 17.5438 -33.1212 -11.5115 43.1845 122.184 

Funcalls: 8
#1    ofv: 252.9367067
x: 1.5161e-01  1.4094e-01  5.7596e-01  -5.1245e-02 2.3511e-01  1.3849e-02  2.6265e-01  1.5653e-01  -1.1206e-01 -5.0000e-01 
Gradients: 58.5006 19.4823 -12.6546 0.438415 -20.9679 14.0305 -33.114 -4.19792 7.4639 42.0374 

Funcalls: 17
#11   ofv: 219.1455368
x: 6.6127e-02  1.1409e-01  1.1175e+00  1.3436e-01  3.6191e-01  -1.8678e-01 1.6618e+00  -3.4381e-02 -4.8288e-02 -1.0445e+00 
Gradients: -12.2346 -8.00718 1.12182 2.07945 -0.317653 -3.44941 4.27612 -2.38963 -2.99215 -5.93228 

Funcalls: 109
#21   ofv: 218.0048506
x: 8.5522e-02  1.2083e-01  9.4660e-01  8.7388e-02  3.6554e-01  -1.5218e-01 1.4398e+00  1.1196e-01  -6.5216e-02 -9.5924e-01 
Gradients: -0.424662 -0.426146 -0.204735 -0.723757 -0.0638195 -0.0733563 -0.0561034 -0.0253637 0.0186558 -0.117254 

Funcalls: 223
converged = True
n_iter = 24
x_opt = 8.6125e-02  1.2129e-01  9.6338e-01  1.0150e-01  3.6619e-01  -1.5174e-01 1.4491e+00  9.8515e-02  -6.5824e-02 -9.5708e-01 
f_opt = 217.9974604
fun_calls = 266

Computing Covariance...
Covariance computation succeed
fit_res

Estimation Summary

OFVConvergedTotal IterationsCompilation TimeEstimation TimeCovariance Time
217.997True ✅240:00:00.20:00:01.250:00:01.66

Parameter Estimation

ParameterEstimateShrinkage(%)RSE(%)
Theta
tv_cl0.1325.218
tv_v7.9784.075
tv_ka1.35431.919
tv_alag0.82419.057
Omega(SD)
eta_cl0.2890.00014.186
eta_v0.2203.99313.348
eta_ka0.83550.45319.177
eta_alag0.39459.24528.372
Sigma(SD)
eps_prop0.08614.95214.144
eps_add0.25915.63523.639

支持的算法设置#

设置

功能

print: int = 1

print 次迭代打印一次迭代历史详情。

verbose: Literal["silent", "info", "debug", "trace"] = "info"

输出详尽等级。若为 "info" 则正常打印迭代历史与其他输出信息。若为 "silent" 则不进行任何打印。

minimize_method: Literal["nm", "powell", "bobyqa", "lbfgs", "newuoa", "bfgs"] = "lbfgs"

最小化方法。

maxiter: int = 9999

最大迭代次数。

xtol: float = 1e-6

相对参数收敛界值。

ftol: float = 1e-6

相对目标函数收敛界值。

cov_method: Literal["r", "s", "rs"] = "rs"

协方差估算方法。

map_minimizer: Literal["nm", "powell", "bobyqa", "lbfgs", "newuoa", "bfgs"] = "lbfgs"

eta 参数最小化方法(仅适用于 FOCEi 算法)。

cov_minimizer: Literal["nm", "powell", "bobyqa", "lbfgs", "newuoa", "bfgs"] = "lbfgs"

协方差最小化方法(仅适用于 FOCEi 算法)。

extra: dict[str, str | int | float | bool] = dict()

各最小化方法额外设置选项

支持的各最小化方法额外设置选项#

lbfgs#

设置

功能

lbfgs_rank: int = 20

用于方向计算(direction calculation)的迭代次数。

use_approx_eigen_scaling: bool = False

使用近似特征值(approximate eigenvalue scaling)。

ls_interp_type: int = 2

用于近似目标函数的多项式的次数。

min_ls_step_size: float = 1e-9

最小线搜索(line search)步长。

gtol: float = 1e-10

相对梯度收敛界值。

num_method: int = 1

数值微分(numerical differentiation)方法。 若为 0 则使用中心(central)差分;若为 1 则使用前向(forward)差分;若为 2 则使用 Ridders 方法。

rel_step: float = 1e-3

数值微分方法相对步长(relative step size)。

BObyQA 与 NEWUOA#

设置

功能

initial_trust_region_radius: float = 0.01

初始信赖域(trust region)大小。

final_trust_region_radius: float = 1e-6

最终信赖域大小。

Nelder-Mead#

设置

功能

alpha: float = 1.0

反射(reflection)系数。

beta: float = 0.5

扩展(contraction)系数

gamma: float = 2.0

收缩(expansion)参数。

delta: float = 0.5

回退(shrinkage)系数。

adaptive: bool = True

是否使用自适应(adaptive)参数。

simulate()#

simulate(data=None, param=None, seed=1234) SimulationResult#

运行模型模拟。

参数:

  • data (DataFrame | EventTable, optional):用于模拟的数据集。若为 None 则使用模型将要拟合的数据集(即在创建 PopModel 时指定的 data)。支持使用 EventTable。默认值为 None

  • params (AnyPopParams, optional):用于模拟的参数值。若为 None 则使用模型中的参数初值。默认值为 None

  • seed (int, optional):随机种子。默认值为 1234

返回值:

包含模拟数据集的模拟结果。

返回类型:

SimulationResult

示例:

模拟华法林的 PK 场景

sim_res = model.simulate(data)
sim_res.output
shape: (288, 22)
IDTIMEAMTDVDVIDMDVWTAGESEXDOSEEVIDCMTSS_IPRED__PRED__Y_alagclipredkavy
i64f64f64f64i64i64f64i64i64f64i64i64i64f64f64f64f64f64f64f64f64f64
00.0100.0null0166.7501100.011null0.00.0-0.3803761.0256040.1805160.00.7649267.788145-0.380376
00.5null0.01066.7501100.002null0.00.0-0.238971.0256040.1805160.00.7649267.788145-0.23897
01.0null1.91066.7501100.002null0.01.228928-0.4392781.0256040.1805160.00.7649267.788145-0.439278
02.0null3.31066.7501100.002null6.6616216.1958576.3634831.0256040.1805166.6616210.7649267.7881456.363483
03.0null6.61066.7501100.002null9.7246068.9083868.1207541.0256040.1805169.7246060.7649267.7881458.120754
3236.0null7.71062.021193.002null6.3831426.7137285.1267280.6275270.1005036.3831420.4309410.6765415.126728
3248.0null6.91062.021193.002null5.7013325.4644555.6054460.6275270.1005035.7013320.4309410.6765415.605446
3272.0null4.41062.021193.002null4.5484113.6200394.5530910.6275270.1005034.5484110.4309410.6765414.553091
3296.0null3.51062.021193.002null3.6286332.3981683.9507450.6275270.1005033.6286330.4309410.6765413.950745
32120.0null2.51062.021193.002null2.8948521.5887143.6056010.6275270.1005032.8948520.4309410.6765413.605601

to_nonmem()#

to_nonmem(dir, control_filename=None, data_filename=None) None#

将模型翻译为 NONMEM 控制文件代码。

参数:

  • dir (PathLike):翻译结果输出路径

  • control_filename (str, optional):输出的控制文件文件名。若为 None 则采用 模型类名.mod 的命名形式。默认值为 None

  • data_filename (str, optional):输出的数据集文件文件名。若为 None 则采用 模型类名.csv 的命名形式。默认值为 None

mas.model.EstimationResult#

class mas.model.EstimationResult#

模型参数估计结果。

ofv#

property ofv#

当前参数估计结果对应的目标函数值。

类型:

float

estimates#

property estimates#

模型参数估计结果。

类型:

PopParams

converged#

property converged#

目标函数最小化过程中参数估计是否收敛。

类型:

bool

n_iter#

property n_iter#

迭代次数。

类型:

int

est_time#

property est_time#

参数估计耗时。

类型:

timedelta

mas.model.FitResult#

class mas.model.FitResult#

模型拟合结果。

ofv#

property ofv

所有最小化过程结束后参数估计结果对应的目标函数值。

类型:

float

estimates#

property estimates

所有最小化过程结束后得到的参数估计值。

类型:

PopParams

converged#

property converged

所有最小化过程结束后参数估计是否收敛。

类型:

bool

n_iter#

property n_iter

所有最小化过程的总迭代次数。

类型:

int

inits#

property inits

模型参数初值。

类型:

PopParams

est_sequence#

property est_sequence

各最小化过程的参数估计结果。

类型:

list[EstimationResult]

iterations#

property iterations

各次迭代的参数估计结果。

类型:

list[IterationResults]

compile_time#

property compile_time

模型编译耗时。

类型:

timedelta

est_time#

property est_time

参数估计耗时。

类型:

timedelta

cov_time#

property cov_time

协方差估计耗时。

类型:

timedelta | None

elapsed_time#

property elapsed_time

模型拟合所花费的总耗时。

类型:

timedelta

output#

property output

包含观测值、群体预测值、个体预测值与个体参数值(以最后一次最小化过程的结果为准)的数据集。

类型:

DataFrame

covariance#

property covariance

协方差估计结果。

类型:

CovResult

summary()#

summary() None

打印模型拟合结果摘要。

compute()#

compute(residuals=None) DataFrame

计算群体预测值(population predictions)、个体预测值(individual predictions)与残差(residuals)。

参数:

  • residuals (list[Literal["CWRES", "WRES", "CWRESI", "WRESI", "CIWRES", "IWRES", "CIWRESI", "IWRESI"]], optional):需要计算的残差类型。如果为 None 则跳过残差计算。默认值为 None

返回值:

包含指定计算内容的 DataFrame

返回类型:

DataFrame

ebe()#

ebe() DataFrame

计算 eta 参数的经验贝叶斯估计。

返回值:

包含各个个体经验贝叶斯估计值的 DataFrame

返回类型:

DataFrame

eta_shr()#

eta_shr(method='sd', ebv=False) DataFrame

计算 eta 参数的收缩量。

eta 参数收缩量公式

若为标准差形式,计算公式如下:

\[ shr = [1 - \frac{SD(eta(j))}{\sqrt{omega(j, j)}}] \times 100\% \]

若为方差形式,计算公式如下:

\[ shr = [1 - \frac{Var(eta(j))}{\sqrt{omega(j, j)}}] \times 100\% \]

其中,eta(j) 为第 j 个 eta 参数的个体经验贝叶斯估计值。

参数:

  • method (Literal["sd", "var"], optional):计算收缩量的方法。使用标准差形式("sd")或方差形式("var")。默认值为 "sd"。计算公式可见:eta 参数收缩量公式

  • ebv (bool, optional):是否计算平均经验贝叶斯方差。默认值为 False

返回值:

eta 参数收缩量的数据框。

返回类型:

DataFrame

示例:

fit_res.eta_shr("sd")
shape: (1, 4)
eta_cleta_veta_kaeta_alag
f64f64f64f64
1.0000e-100.0399340.504530.592446

eps_shr()#

eps_shr(method='sd') DataFrame

计算 eps 参数的收缩量。

eps 参数收缩量公式

若为标准差形式,计算公式如下:

\[ shr = [1 - SD(IWRES)] \times 100\% \]

若为方差形式,计算公式如下:

\[ shr = [1 - Var(IWRES)] \times 100\% \]

其中,IWRES 为个体加权残差(individual weighted residual)。

参数:

  • method (Literal["sd", "var"], optional):计算收缩量的方法。使用标准差形式("sd")或方差形式("var")。默认值为 "sd"。计算公式可见:eps 参数收缩量公式

返回值:

eps 参数收缩量的数据框。

返回类型:

DataFrame

plot_gof()#

plot_gof(self, filter=None, idv_name=None, dv_name=None, wres='CWRES', iwres='CIWRES') Plot#

绘制模型拟合优度图(goodness of fit)。

参数:

  • filter (Expr, optional): 筛选条件,对于部分数据进行 gof 绘制。默认值为 None

  • idv_name (str, optional):因变量名。若为 None,则自动推断。默认值为 None

  • dv_name (str, optional):自变量名。若为 None,则自动推断。默认值为 None

  • wres (Literal["CWRES", "CWRESI", "WRES", "WRESI"], optional):需要计算的加权残差类型(weighted residuals)。默认值为 "CWRES"

  • iwres (Literal["CIWRES", "CIWRESI", "IWRES", "IWRESI"], optional):需要计算的个体加权残差类型(individual weighted residual)。默认值为 "CIWRES"

示例:

fit_res.plot_gof()

plot_predictions()#

plot_predictions(self, filter=None, idv_name=None, dv_name=None, wres='CWRES', iwres='CIWRES') Plot#

绘制个体拟合图(个体预测值/群体预测值 vs. 实测值)。

参数:

  • filter (Expr, optional): 筛选条件,对于部分数据进行个体拟合图绘制。默认值为 None

  • idv_name (str, optional):因变量名。若为 None,则自动推断。默认值为 None

  • dv_name (str, optional):自变量名。若为 None,则自动推断。默认值为 None

  • wres (Literal["CWRES", "CWRESI", "WRES", "WRESI"], optional):需要计算的加权残差类型(weighted residuals)。默认值为 "CWRES"

  • iwres (Literal["CIWRES", "CIWRESI", "IWRES", "IWRESI"], optional):需要计算的个体加权残差类型(individual weighted residual)。默认值为 "CIWRES"

示例:

fit_res.plot_predictions(filter=pl.col("SEX") == 0)

plot_iterations()#

plot_iterations(self) Plot#

绘制迭代历史图(目标函数值与各模型参数估计值在迭代间的变动情况)。

示例:

fit_res.plot_iterations().with_x_grid(visible=True).with_y_grid(visible=True)

vpc()#

vpc(n_sample=1000, seed=1234, ci_level=0.95, percentile_level=0.95, auto_bin=True, min_points_in_each_bin=10, linear_interpolation=True, *, dv_name=None, idv_name=None) VpcResult#

运行模型可视化预测检验(visual predictive check)。

参数:

  • n_sample (int, optional):抽样次数。默认值为 1000

  • seed (int, optional):随机种子号。默认值为 1234

  • ci_level (float, optional):模拟数据百分位数的置信水平。默认值为 0.95

  • percentile_level (float, optional):模拟数据与实测值的百分位数水平。默认值为 0.95,即取 2.5% 与 97.5% 分位数。

  • auto_bin (bool | int | tuple[int, int], optional):分箱(binning)方法。默认值为 True。具体方法如下:

    • 若为 True,则使用自动分箱方法。

    • 若为 False,则视每一个观测时间点为一个分箱。

    • 若为 int,则视分箱数目为 int,将基于此数目计算每个箱体的范围。

    • 若为 tuple[int, int],则视箱体的范围为 tuple[int, int],将基于此范围计算最终的分箱数目。

  • min_points_in_each_bin (int, optional):每个分箱中需包含的最少观测点数目。默认值为 10

  • linear_interpolation (bool, optional):是否进行线性化。默认值为 True

  • idv_name (str, optional):因变量名。若为 None,则自动推断。默认值为 None

  • dv_name (str, optional):自变量名。若为 None,则自动推断。默认值为 None

返回值:

包含 VPC 图、置信区间数据、模拟数据等相关内容的检验结果。

返回类型:

VpcResult

示例:

vpc_res = fit_res.vpc(linear_interpolation=False)
vpc_res.plot()
[VPC] Preparing data...
[VPC] Running simulation...
Running Auto-bin...
Bin search ended, result is 10
Auto-bin completed, finally use 10 bins.

bootstrap()#

bootstrap(n_sample=1000, seed=1234, level=0.95) BootstrapResult#

运行自举法(bootstrap)。

参数:

  • n_sample (int, optional):抽样次数。默认值为 1000

  • seed (int, optional):随机种子号。默认值为 1234

  • level (float, optional):参数估计值的置信水平。默认值为 0.95

返回值:

包含估算成功率与抽样数据等相关内容的检验结果。

返回类型:

BootstrapResult

scm()#

scm(config) ScmResultCollection#

利用 SCM 法(stepwise covariate modeling)进行协变量筛选。

参数:

  • config (ScmConfig | typing.Callable[[], ScmConfig]):SCM 配置。可详见 ScmConfig

返回值:

SCM 运行结果汇总。

返回类型:

ScmResultCollection