三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

用Python和NumPy模拟一个健康预测模型:从保险案例到代码实现

用Python和NumPy模拟一个健康预测模型:从保险案例到代码实现

用Python和NumPy模拟健康预测模型:从保险案例到代码实现

马尔可夫链作为描述随机过程的数学工具,在健康预测领域展现出独特价值。本文将带您用Python实现两状态和三状态的健康预测模型,通过可视化手段直观展示状态转移过程。无论您是保险精算师、医疗数据分析师,还是机器学习工程师,都能从中获得可复用的建模思路。

1. 环境准备与基础概念

在开始编码前,我们需要配置Python环境并理解核心概念。推荐使用Anaconda创建独立环境:

conda create -n markov python=3.9 conda activate markov pip install numpy matplotlib pandas

马尔可夫链的核心特征是无记忆性——下一状态仅取决于当前状态。在健康预测场景中,这意味着明天的健康状况只与今天有关,与历史无关。这种特性使其非常适合建模慢性病的演进过程。

关键术语对照表

数学概念编程实现健康场景对应
状态空间数组维度健康/疾病/死亡
转移概率矩阵二维NumPy数组病情转化几率
初始状态向量一维NumPy数组初始健康分布
n步转移矩阵矩阵幂运算多年后的健康预测

2. 两状态健康模型实现

我们先实现经典的健康-疾病双状态模型。假设年度转移概率如下:

  • 健康保持健康:0.8
  • 健康转为疾病:0.2
  • 疾病恢复健康:0.7
  • 疾病保持疾病:0.3
import numpy as np import matplotlib.pyplot as plt # 定义转移矩阵 P = np.array([[0.8, 0.2], [0.7, 0.3]]) # 三种初始状态 initial_states = { '完全健康': np.array([1, 0]), '完全患病': np.array([0, 1]), '混合状态': np.array([0.75, 0.25]) } # 模拟10年演变 years = 10 results = {} for name, state in initial_states.items(): history = [state] for _ in range(years): state = state @ P # 矩阵乘法更新状态 history.append(state) results[name] = np.array(history)

可视化结果

plt.figure(figsize=(12, 6)) for name, data in results.items(): plt.plot(data[:, 0], label=f'{name} - 健康概率') plt.plot(data[:, 1], '--', label=f'{name} - 疾病概率') plt.xlabel('年数') plt.ylabel('概率') plt.title('两状态健康模型演变') plt.legend() plt.grid(True) plt.show()

运行后会观察到,无论初始状态如何,系统最终都会收敛到稳态分布[0.777..., 0.222...]。这揭示了慢性病的长期管理规律——约78%的时间处于健康状态。

3. 三状态生死模型进阶

更真实的模型需要引入死亡状态。我们扩展为三状态系统:

  • 健康→健康:0.8
  • 健康→疾病:0.18
  • 健康→死亡:0.02
  • 疾病→健康:0.25
  • 疾病→疾病:0.65
  • 疾病→死亡:0.1
  • 死亡→死亡:1.0(吸收态)
# 定义三状态转移矩阵 P_3state = np.array([ [0.8, 0.18, 0.02], [0.25, 0.65, 0.1], [0, 0, 1] ]) # 模拟60年演变 years = 60 initial_states_3 = { '新生儿': np.array([1, 0, 0]), '慢性病患者': np.array([0, 1, 0]), '中年人群': np.array([0.75, 0.25, 0]) } results_3state = {} for name, state in initial_states_3.items(): history = [state.copy()] for _ in range(years): state = state @ P_3state history.append(state.copy()) results_3state[name] = np.array(history)

多维度可视化

fig, axes = plt.subplots(3, 1, figsize=(12, 12)) for idx, (name, data) in enumerate(results_3state.items()): axes[idx].plot(data[:, 0], label='健康') axes[idx].plot(data[:, 1], label='疾病') axes[idx].plot(data[:, 2], label='死亡') axes[idx].set_title(name) axes[idx].legend() axes[idx].grid(True) plt.tight_layout() plt.show()

这个模型清晰展示了吸收态的特性——所有轨迹最终都会收敛到死亡概率100%。通过调整转移概率,保险公司可以评估不同人群的长期风险。

4. 模型优化与实用技巧

实际应用中,我们需要考虑以下增强措施:

4.1 参数估计方法

转移概率通常通过历史数据估计:

# 假设有1000人的年度健康记录 transitions = { (1,1): 650, (1,2): 180, (1,3): 20, (2,1): 250, (2,2): 600, (2,3): 100 } # 计算最大似然估计 P_estimated = np.zeros((3,3)) for (i,j), count in transitions.items(): P_estimated[i-1,j-1] = count P_estimated = P_estimated / P_estimated.sum(axis=1, keepdims=True)

4.2 年龄分层处理

不同年龄段应使用不同转移矩阵:

age_groups = { '20-30': np.array([...]), '30-40': np.array([...]), # ... } def get_age_specific_matrix(age): for group, matrix in age_groups.items(): low, high = map(int, group.split('-')) if low <= age < high: return matrix return default_matrix

4.3 蒙特卡洛模拟

对于复杂场景,可采用随机模拟:

def monte_carlo_simulation(initial_state, P, years): current = initial_state history = [current] for _ in range(years): current = np.random.choice(len(current), p=current @ P) new_state = np.zeros_like(initial_state) new_state[current] = 1 history.append(new_state) return np.array(history)

5. 商业应用案例分析

5.1 保险费率精算

利用模型计算不同人群的长期医疗费用:

# 定义各状态年度医疗成本 costs = np.array([5000, 20000, 0]) # 健康、疾病、死亡 # 计算30年预期总成本 total_cost = sum(state @ costs for state in results_3state['中年人群'][:30])

5.2 健康干预评估

模拟戒烟对健康的影响:

# 吸烟者转移矩阵 P_smoker = np.array([...]) # 戒烟后转移矩阵 P_quitter = np.array([...]) # 比较两种场景的健康概率差异 smoker_health = simulate(P_smoker)[:,0] quitter_health = simulate(P_quitter)[:,0] improvement = quitter_health - smoker_health

5.3 医疗资源规划

预测未来病床需求:

population = 1000000 annual_patients = population * results_3state['新生儿'][:,1] plt.plot(annual_patients) plt.ylabel('预计患病人数') plt.xlabel('年数')
← 返回列表