You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在lmfit拟合疾病传播模型时让单参数分组变化其余全局拟合?

用lmfit实现全局统一参数+分组独立参数的拟合方案

嗨,我来帮你搞定这个lmfit的分组参数拟合问题!你要的是让指数参数在所有数据组里统一拟合,而缩放因子按不同组(不同年份/毒株)独立调整对吧?刚好lmfit的参数系统天生适合处理这种“部分共享、部分独立”的拟合需求,我给你一步步拆解,附上手把手的代码示例:

1. 先明确你的模型结构

假设你的疾病传播模型是类似这样的形式(你可以根据自己的实际模型调整):

def transmission_model(t, k, scale):
    # k是全局统一的指数参数(传播速率相关)
    # scale是每组独立的缩放因子(不同毒株/年份的传播能力差异)
    return scale * np.exp(k * t)

2. 构造带分组标识的数据集

不管你用真实数据还是模拟数据,关键是要给每个数据点打上组标签,比如用一个数组groups来标记每个t/y属于哪一组(比如0、1、2代表不同年份):

import numpy as np
from lmfit import Parameters, minimize

# 模拟3组数据,每组对应不同的scale,但k相同
np.random.seed(42)
k_true = 0.2
scales_true = [10, 25, 15]

t_groups = []
y_groups = []
groups = []
for i, scale in enumerate(scales_true):
    t = np.linspace(0, 10, 20)
    y = scale * np.exp(k_true * t) + np.random.normal(0, 2, size=len(t))
    t_groups.extend(t)
    y_groups.extend(y)
    groups.extend([i]*len(t))  # 给每个数据点打组标签

t_data = np.array(t_groups)
y_data = np.array(y_groups)
groups = np.array(groups)

3. 创建参数集合:全局参数+分组参数

这里的核心是:

  • 全局参数k只定义一个,所有组共享
  • 每个组对应一个独立的scale参数,比如scale_0、scale_1、scale_2
params = Parameters()
# 添加全局统一的指数参数k,给个初始值
params.add('k', value=0.1, min=0, max=1)

# 给每个组添加独立的scale参数,用循环自动生成(组多的时候特别方便)
unique_groups = np.unique(groups)
for group_id in unique_groups:
    params.add(f'scale_{group_id}', value=5, min=1, max=50)

4. 定义带分组逻辑的残差函数

在残差函数里,我们要根据每个数据点的组标签,找到对应的scale参数,然后代入模型计算残差:

def residual(params, t, y, groups):
    k = params['k'].value
    res = []
    for t_val, y_val, group_id in zip(t, y, groups):
        # 根据组id获取对应的scale参数
        scale = params[f'scale_{group_id}'].value
        y_pred = transmission_model(t_val, k, scale)
        res.append(y_val - y_pred)
    return np.array(res)

5. 执行拟合并查看结果

# 调用minimize进行拟合
result = minimize(residual, params, args=(t_data, y_data, groups))

# 打印拟合结果
print(result.fit_report())

额外技巧:简化残差计算(避免循环)

如果你的数据集很大,用循环可能有点慢,可以用向量化的方式处理,效率更高:

def residual_vectorized(params, t, y, groups):
    k = params['k'].value
    # 先把每个组的scale值映射成和t/y长度一致的数组
    scale_vals = np.array([params[f'scale_{g}'].value for g in groups])
    y_pred = scale_vals * np.exp(k * t)
    return y - y_pred

这样拟合出来的结果里,k会是所有组共用的最优值,而每个scale_*参数对应各自组的最优缩放因子,完全符合你要的“指数统一、缩放因子分组变化”的需求!

内容的提问来源于stack exchange,提问作者Lorcán

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:03:36