# 生成灵活性轴:从1到10的100个等间距点
flexibility_range = np.linspace(1, 10, 100) # 模型灵活性连续变化
# 构建偏差-方差理论曲线
bias_squared = 20 / flexibility_range # 偏差平方随灵活性增加而衰减(反比例)
variance_component = 0.8 * (flexibility_range - 1)**1.8 # 方差随灵活性增加而按幂律膨胀
irreducible_error = 2.0 # 不可约误差为常数
total_test_mse = bias_squared + variance_component + irreducible_error # 总测试MSE = 三部分之和
# 创建偏差-方差权衡图
fig, ax_bv = plt.subplots(figsize=(10, 6)) # 创建画布
ax_bv.plot(flexibility_range, bias_squared, color='#DC2626', linewidth=2, label='偏差² (Bias²)') # 偏差曲线
ax_bv.plot(flexibility_range, variance_component, color='#2563EB', linewidth=2, label='方差 (Variance)') # 方差曲线
ax_bv.axhline(y=irreducible_error, color='#94A3B8', linestyle='--', label='不可约误差 Var(ε)') # 噪声底线
ax_bv.plot(flexibility_range, total_test_mse, color='#1E293B', linewidth=3, label='总测试 MSE') # 总误差曲线
# 标注最优点
optimal_idx = np.argmin(total_test_mse) # 找到U型曲线最低点索引
ax_bv.plot(flexibility_range[optimal_idx], total_test_mse[optimal_idx], 'o', color='gold', markersize=12, markeredgecolor='black') # 金色圆点标记最优
ax_bv.annotate('最优拟合点', xy=(flexibility_range[optimal_idx], total_test_mse[optimal_idx]),
xytext=(flexibility_range[optimal_idx]+1, total_test_mse[optimal_idx]+4),
arrowprops=dict(facecolor='black', shrink=0.05), fontsize=11, fontweight='bold') # 箭头标注
ax_bv.set_xlabel('模型灵活性 →', fontsize=12) # X轴标签
ax_bv.set_ylabel('误差 →', fontsize=12) # Y轴标签
ax_bv.set_ylim(0, 25) # Y轴范围
ax_bv.legend(fontsize=11) # 显示图例
ax_bv.grid(True, alpha=0.3) # 添加网格
plt.tight_layout() # 调整布局
plt.show() # 显示图表