未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适合学习峰度与超额峰度计算、模拟分布比较、Bootstrap、峰度检验及滑窗监控的实现,不是已校准的投资或生产决策工具。当前类型可视化和分析工具包仍根据峰度输出“尖峭/平坦”“厚尾/薄尾”等标签,不能据此确定峰顶形状或指定阈值处的尾部概率;两处检验输出的“接受正态峰度假设”应理解为未拒绝,不能视为证实零假设或正态性。df=3、df=4的t分布没有有限总体四阶矩,相关有限样本峰度及Bootstrap区间不能作为有限总体峰度的稳定估计;df=5示例的Bootstrap区间也没有覆盖率保证。金融资产、工艺名称及风险等级仅为模拟设定,峰度排序和示例建议不能证明资产安全、配置合理、过程稳定或精度不足,非正态过程的Cp/Cpk不能直接解释为正态尾部风险或能力等级。滑窗阈值和质量监控控制限未提供误报率校准,监控状态仅表示示例规则的判定结果。代码依赖首段导入,应按正文顺序使用;本次仅作全文结构审阅,未运行代码或进行外部事实核验。
📈 峰度(Kurtosis)
abstract 📋 本节概览
- 🎯 学习目标:掌握峰度的概念、计算和实际应用
- 📚 前置知识:描述性统计|描述性统计 | 正态分布|正态分布 | 偏度|偏度
- ⏱️ 预计用时:8分钟
🤔 什么是峰度?
note 📖 **峰度的定义**
峰度是标准化四阶中心矩,在方差非零且四阶中心矩有限时定义,反映标准化偏差的四次方的平均大小,对极端值十分敏感;它不能单独确定峰顶尖峭程度、正态性或某个阈值处的尾部概率。
数学表达式: $$\text{Kurtosis} = \frac{E[(X-\mu)^4]}{\sigma^4} = \frac{\mu_4}{\sigma^4}$$
其中:
- $\mu_4$ 是四阶中心矩
- $\sigma$ 是标准差
- $E[·]$ 表示期望值
超额峰度(Excess Kurtosis): $$\text{Excess Kurtosis} = \text{Kurtosis} - 3$$
峰度值的含义:
- 峰度 = 3(超额峰度 = 0):与正态分布的峰度相同(mesokurtic),不意味着分布正态
- 峰度 > 3(超额峰度 > 0):高峰度(leptokurtic),标准化四阶矩高于正态参考值
- 峰度 < 3(超额峰度 < 0):低峰度(platykurtic),标准化四阶矩低于正态参考值
这些分类不能单独确定峰顶形状或任意指定阈值处的尾部概率。
生活例子:
- 股票收益率:通常具有高峰度,极端收益比正态分布更频繁
- 测量误差:可能呈现低峰度,误差分布相对均匀
- 考试成绩:成绩集中并不必然意味着高峰度;若多数成绩集中而少数成绩远离均值,可能出现较高峰度,需按实际分布计算。
- 身高体重:接近正态峰度
📊 峰度的类型与特征
1. 三种峰度类型
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
def plot_kurtosis_types():
"""展示不同类型的峰度"""
fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2, 3, figsize=(18, 12))
np.random.seed(42)
# 1. 正态峰度 (mesokurtic) - 峰度 = 3
normal_data = np.random.normal(0, 1, 5000)
normal_kurt = stats.kurtosis(normal_data, fisher=False) # 原始峰度
normal_excess_kurt = stats.kurtosis(normal_data, fisher=True) # 超额峰度
ax1.hist(normal_data, bins=50, density=True, alpha=0.7, color='blue', edgecolor='black')
ax1.set_title(f'正态峰度 (Mesokurtic)\n峰度 = {normal_kurt:.2f}, 超额峰度 = {normal_excess_kurt:.2f}')
ax1.set_ylabel('密度')
ax1.grid(True, alpha=0.3)
# 叠加理论正态分布
x_range = np.linspace(-4, 4, 1000)
ax1.plot(x_range, stats.norm.pdf(x_range, 0, 1), 'r-', linewidth=2, label='理论正态分布')
ax1.legend()
# 2. 高峰度 (leptokurtic) - 峰度 > 3
# 使用t分布(自由度较小)模拟高峰度
high_kurt_data = stats.t.rvs(df=3, size=5000) # t分布,df=3
high_kurt = stats.kurtosis(high_kurt_data, fisher=False)
high_excess_kurt = stats.kurtosis(high_kurt_data, fisher=True)
ax2.hist(high_kurt_data, bins=50, density=True, alpha=0.7, color='red',
edgecolor='black', range=(-5, 5))
ax2.set_title(f'高峰度 (Leptokurtic)\n峰度 = {high_kurt:.2f}, 超额峰度 = {high_excess_kurt:.2f}')
ax2.grid(True, alpha=0.3)
# 对比正态分布
ax2.plot(x_range, stats.norm.pdf(x_range, 0, 1), 'b--', alpha=0.7,
linewidth=2, label='正态分布对比')
ax2.legend()
# 3. 低峰度 (platykurtic) - 峰度 < 3
# 使用均匀分布模拟低峰度
low_kurt_data = np.random.uniform(-2, 2, 5000)
low_kurt = stats.kurtosis(low_kurt_data, fisher=False)
low_excess_kurt = stats.kurtosis(low_kurt_data, fisher=True)
ax3.hist(low_kurt_data, bins=50, density=True, alpha=0.7, color='green', edgecolor='black')
ax3.set_title(f'低峰度 (Platykurtic)\n峰度 = {low_kurt:.2f}, 超额峰度 = {low_excess_kurt:.2f}')
ax3.grid(True, alpha=0.3)
# 对比正态分布
x_uniform = np.linspace(-2.5, 2.5, 1000)
ax3.plot(x_uniform, stats.norm.pdf(x_uniform, 0, 1.15), 'b--', alpha=0.7,
linewidth=2, label='调整的正态分布')
ax3.legend()
# 4-6. 尾部对比图(对数尺度)
datasets = [
("正态分布", normal_data, 'blue'),
("高峰度分布", high_kurt_data, 'red'),
("低峰度分布", low_kurt_data, 'green')
]
axes_bottom = [ax4, ax5, ax6]
for i, (name, data, color) in enumerate(datasets):
# 使用完整样本的绝对值排序,避免截断尾部;此处比较原始尺度
abs_data = np.sort(np.abs(data))
n = len(abs_data)
tail_prob = (n - np.searchsorted(abs_data, abs_data, side='right')) / n
# 绘制经验双尾概率(保留概率大于1e-4的点)
tail_mask = tail_prob > 1e-4
if np.sum(tail_mask) > 10: # 确保有足够的点
axes_bottom[i].semilogy(abs_data[tail_mask], tail_prob[tail_mask],
'o-', color=color, markersize=3, alpha=0.7, label=name)
# 对比理论正态分布的尾部
x_tail = np.linspace(0, 4, 100)
normal_tail = 2 * (1 - stats.norm.cdf(x_tail)) # 双尾概率
axes_bottom[i].semilogy(x_tail, normal_tail, 'k--', alpha=0.7,
linewidth=2, label='正态分布理论值')
axes_bottom[i].set_xlabel('|x|')
axes_bottom[i].set_ylabel('P(|X| > x)')
axes_bottom[i].set_title(f'{name} - 尾部概率')
axes_bottom[i].legend()
axes_bottom[i].grid(True, alpha=0.3)
axes_bottom[i].set_ylim(1e-4, 1)
plt.tight_layout()
plt.show()
# 数值比较
print("峰度类型数值对比:")
print("=" * 50)
datasets_analysis = [
("正态分布", normal_data),
("高峰度分布 (t分布, df=3)", high_kurt_data),
("低峰度分布 (均匀分布)", low_kurt_data)
]
print(f"{'分布类型':<25} {'峰度':<8} {'超额峰度':<10} {'特征描述':<20}")
print("-" * 70)
for name, data in datasets_analysis:
kurt_val = stats.kurtosis(data, fisher=False)
excess_kurt = stats.kurtosis(data, fisher=True)
if abs(excess_kurt) < 0.5:
description = "峰度接近正态参考值,不代表分布正态"
elif excess_kurt > 2:
description = "高度尖峭,厚尾"
elif excess_kurt > 0:
description = "轻度尖峭,较厚尾"
elif excess_kurt < -1:
description = "高度平坦,薄尾"
else:
description = "轻度平坦,较薄尾"
print(f"{name:<25} {kurt_val:<8.2f} {excess_kurt:<10.2f} {description:<20}")
# 尾部风险分析
print(f"\n尾部风险对比 (|x| > 2的概率):")
print("-" * 35)
for name, data in datasets_analysis:
tail_prob = np.mean(np.abs(data) > 2)
theoretical_normal_tail = 2 * (1 - stats.norm.cdf(2)) # 理论正态分布
print(f"{name:<25}: {tail_prob:.4f} (正态分布: {theoretical_normal_tail:.4f})")
plot_kurtosis_types()
2. 峰度的计算方法
def calculate_kurtosis_methods():
"""演示峰度的不同计算方法"""
np.random.seed(42)
# 生成高峰度数据 (t分布)
data = stats.t.rvs(df=5, size=1000)
print("峰度的计算方法:")
print("=" * 40)
# 1. 手动计算 - 第四中心矩方法
n = len(data)
mean = np.mean(data)
std = np.std(data, ddof=0) # 与第四中心矩及SciPy默认bias=True使用一致的矩估计口径
# 第四中心矩
fourth_moment = np.mean((data - mean)**4)
kurt_manual = fourth_moment / (std**4)
excess_kurt_manual = kurt_manual - 3
print(f"1. 手动计算(第四中心矩法):")
print(f" 均值: {mean:.4f}")
print(f" 标准差: {std:.4f}")
print(f" 第四中心矩: {fourth_moment:.4f}")
print(f" 峰度: {kurt_manual:.4f}")
print(f" 超额峰度: {excess_kurt_manual:.4f}")
# 2. scipy.stats 计算(两种定义)
# Fisher定义(超额峰度)
fisher_kurt = stats.kurtosis(data, fisher=True)
# Pearson定义(原始峰度)
pearson_kurt = stats.kurtosis(data, fisher=False)
print(f"\n2. SciPy统计函数:")
print(f" Fisher定义(超额峰度): {fisher_kurt:.4f}")
print(f" Pearson定义(原始峰度): {pearson_kurt:.4f}")
print(f" 验证关系: {pearson_kurt:.4f} = {fisher_kurt:.4f} + 3")
# 3. 矩估计vs样本估计
# 使用不同的标准化方法
kurt_biased = stats.kurtosis(data, fisher=True, bias=True)
kurt_unbiased = stats.kurtosis(data, fisher=True, bias=False)
print(f"\n3. 偏差修正:")
print(f" 有偏估计: {kurt_biased:.4f}")
print(f" 偏差修正估计(非任意分布下严格无偏): {kurt_unbiased:.4f}")
# 4. 峰度的置信区间(Bootstrap方法)
n_bootstrap = 1000
bootstrap_kurts = []
for _ in range(n_bootstrap):
bootstrap_sample = np.random.choice(data, size=len(data), replace=True)
bootstrap_kurts.append(stats.kurtosis(bootstrap_sample, fisher=True))
kurt_ci_lower = np.percentile(bootstrap_kurts, 2.5)
kurt_ci_upper = np.percentile(bootstrap_kurts, 97.5)
print(f"\n4. 超额峰度的95%置信区间 (Bootstrap):")
print(f" [{kurt_ci_lower:.4f}, {kurt_ci_upper:.4f}]")
# 5. 峰度的稳健性分析
print(f"\n5. 峰度对异常值的敏感性:")
# 原始数据
original_kurt = stats.kurtosis(data, fisher=True)
# 添加异常值
outlier_data = np.append(data, [10, -10]) # 添加两个极端值
outlier_kurt = stats.kurtosis(outlier_data, fisher=True)
print(f" 原始数据峰度: {original_kurt:.4f}")
print(f" 添加异常值后: {outlier_kurt:.4f}")
print(f" 变化幅度: {outlier_kurt - original_kurt:.4f}")
# 6. 样本量对峰度估计的影响
print(f"\n6. 样本量对峰度估计的影响:")
# 真实分布参数
true_data = stats.t.rvs(df=5, size=10000)
true_kurt = 6.0 # t分布df=5的理论超额峰度;true_data仅为重复抽样所用的有限模拟样本池
sample_sizes = [50, 100, 500, 1000, 5000]
print(f" 真实超额峰度: {true_kurt:.4f}")
print(" 样本量 -> 平均估计超额峰度 (固定模拟样本池内不放回重复抽样的标准差)")
for size in sample_sizes:
sample_kurts = []
for _ in range(100): # 100次重复采样
sample = np.random.choice(true_data, size=size, replace=False)
sample_kurts.append(stats.kurtosis(sample, fisher=True))
mean_kurt = np.mean(sample_kurts)
std_kurt = np.std(sample_kurts, ddof=1)
print(f" {size:4d} -> {mean_kurt:.4f} ({std_kurt:.4f})")
# 7. 不同分布的理论峰度
print(f"\n7. 常见分布的理论峰度:")
theoretical_kurtosis = {
"正态分布": 0, # 超额峰度
"均匀分布": -1.2,
"指数分布": 6,
"拉普拉斯分布": 3,
"t分布(df=3)": float('inf') if 3 <= 4 else 6/(3-4), # df=3时峰度无穷
"t分布(df=5)": 6/(5-4) if 5 > 4 else float('inf')
}
for dist_name, theoretical_val in theoretical_kurtosis.items():
if dist_name == "t分布(df=5)":
theoretical_val = 6 # df=5时的超额峰度
print(f" {dist_name}: {theoretical_val}")
calculate_kurtosis_methods()
💻 Python实现
1. 峰度分析工具包
def kurtosis_analysis_toolkit():
"""峰度分析的完整工具包"""
def analyze_kurtosis(data, name="数据"):
"""分析数据的峰度"""
# 基本统计量
mean_val = np.mean(data)
std_val = np.std(data, ddof=1)
kurt_val = stats.kurtosis(data, fisher=False) # 原始峰度
excess_kurt = stats.kurtosis(data, fisher=True) # 超额峰度
# 峰度解释
if abs(excess_kurt) < 0.5:
kurt_desc = "接近正态峰度"
color = 'blue'
elif excess_kurt > 2:
kurt_desc = "高度尖峭分布"
color = 'red'
elif excess_kurt > 0:
kurt_desc = "中度尖峭分布"
color = 'orange'
elif excess_kurt < -1:
kurt_desc = "高度平坦分布"
color = 'lightgreen'
else:
kurt_desc = "中度平坦分布"
color = 'green'
# 尾部风险评估
tail_2sigma = np.mean(np.abs(data - mean_val) > 2 * std_val)
normal_tail_2sigma = 2 * (1 - stats.norm.cdf(2))
tail_risk_ratio = tail_2sigma / normal_tail_2sigma if normal_tail_2sigma > 0 else 1
print(f"{name}峰度分析:")
print("-" * 30)
print(f"样本量: {len(data)}")
print(f"均值: {mean_val:.4f}")
print(f"标准差: {std_val:.4f}")
print(f"峰度: {kurt_val:.4f}")
print(f"超额峰度: {excess_kurt:.4f}")
print(f"峰度类型: {kurt_desc}")
print(f"2σ外概率: {tail_2sigma:.4f} (正态分布: {normal_tail_2sigma:.4f})")
print(f"尾部风险倍数: {tail_risk_ratio:.2f}x")
return {
'mean': mean_val,
'std': std_val,
'kurtosis': kurt_val,
'excess_kurtosis': excess_kurt,
'description': kurt_desc,
'color': color,
'tail_risk_ratio': tail_risk_ratio
}
def plot_kurtosis_analysis(data, name="数据", ax=None):
"""绘制峰度分析图"""
if ax is None:
fig, ax = plt.subplots(1, 1, figsize=(10, 6))
# 分析峰度
result = analyze_kurtosis(data, name)
# 绘制直方图
ax.hist(data, bins=50, density=True, alpha=0.7,
color=result['color'], edgecolor='black')
# 叠加正态分布对比
x_range = np.linspace(data.min(), data.max(), 100)
normal_fit = stats.norm.pdf(x_range, result['mean'], result['std'])
ax.plot(x_range, normal_fit, 'k--', linewidth=2, alpha=0.8,
label='正态分布拟合')
# 标注统计量
ax.axvline(result['mean'], color='red', linestyle='-',
linewidth=2, label=f"均值 = {result['mean']:.2f}")
# 标注±2σ范围
ax.axvline(result['mean'] - 2*result['std'], color='orange',
linestyle=':', linewidth=1, alpha=0.7, label='±2σ')
ax.axvline(result['mean'] + 2*result['std'], color='orange',
linestyle=':', linewidth=1, alpha=0.7)
ax.set_title(f'{name} - {result["description"]}\n' +
f'超额峰度 = {result["excess_kurtosis"]:.3f}, ' +
f'尾部风险 = {result["tail_risk_ratio"]:.1f}x')
ax.set_xlabel('值')
ax.set_ylabel('密度')
ax.legend()
ax.grid(True, alpha=0.3)
return result
def compare_tail_behavior(datasets):
"""比较不同数据集的尾部行为"""
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
colors = plt.cm.Set1(np.linspace(0, 1, len(datasets)))
for i, (name, data, color) in enumerate(zip(datasets.keys(), datasets.values(), colors)):
# 标准化数据
standardized = (data - np.mean(data)) / np.std(data, ddof=1)
# 计算经验分布
sorted_abs = np.sort(np.abs(standardized))
n = len(sorted_abs)
survival_prob = (n - np.searchsorted(sorted_abs, sorted_abs, side='right')) / n
# Q-Q图 vs 正态分布
theoretical_quantiles = stats.norm.ppf((np.arange(1, len(data) + 1) - 0.5) / len(data))
sample_quantiles = np.sort(standardized)
ax1.scatter(theoretical_quantiles, sample_quantiles, alpha=0.6,
color=color, s=10, label=name)
# 尾部概率图
mask = survival_prob > 1e-4
if np.sum(mask) > 10:
ax2.semilogy(sorted_abs[mask], survival_prob[mask],
'o-', color=color, markersize=3, alpha=0.7, label=name)
# Q-Q图设置
ax1.plot([-4, 4], [-4, 4], 'k--', alpha=0.5, label='理论直线')
ax1.set_xlabel('理论分位数')
ax1.set_ylabel('样本分位数')
ax1.set_title('Q-Q图 vs 标准正态分布')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 尾部概率图设置
x_theory = np.linspace(0, 4, 100)
normal_tail = 2 * (1 - stats.norm.cdf(x_theory))
ax2.semilogy(x_theory, normal_tail, 'k--', linewidth=2,
alpha=0.7, label='标准正态分布')
ax2.set_xlabel('|标准化值|')
ax2.set_ylabel('P(|X| > x)')
ax2.set_title('尾部概率对比')
ax2.legend()
ax2.grid(True, alpha=0.3)
ax2.set_ylim(1e-4, 1)
plt.tight_layout()
plt.show()
# 演示工具包应用
print("峰度分析工具包演示:")
print("=" * 50)
# 生成不同峰度的示例数据
np.random.seed(42)
datasets = {
"正态分布": np.random.normal(0, 1, 2000),
"t分布(df=3)": stats.t.rvs(df=3, size=2000),
"均匀分布": np.random.uniform(-2, 2, 2000),
"拉普拉斯分布": stats.laplace.rvs(size=2000),
"混合分布": np.concatenate([
np.random.normal(0, 0.5, 1600), # 主体分布
np.random.normal(0, 3, 400) # 厚尾分量
])
}
# 分析每个数据集
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
axes = axes.flatten()
results = {}
for i, (name, data) in enumerate(datasets.items()):
if i < len(axes):
print(f"\n{i+1}. {name}:")
result = plot_kurtosis_analysis(data, name, axes[i])
results[name] = result
# 删除多余的子图
if len(datasets) < len(axes):
fig.delaxes(axes[-1])
plt.tight_layout()
plt.show()
# 峰度对比总结
print(f"\n峰度对比总结:")
print("=" * 60)
print(f"{'分布类型':<15} {'峰度':<8} {'超额峰度':<10} {'尾部风险':<10} {'类型描述':<15}")
print("-" * 60)
for name, result in results.items():
print(f"{name:<15} {result['kurtosis']:<8.2f} {result['excess_kurtosis']:<10.2f} " +
f"{result['tail_risk_ratio']:<10.1f}x {result['description']:<15}")
# 尾部行为对比
print(f"\n绘制尾部行为对比图...")
compare_tail_behavior(datasets)
return analyze_kurtosis, plot_kurtosis_analysis
# 使用工具包
analyze_func, plot_func = kurtosis_analysis_toolkit()
2. 峰度检验
def kurtosis_tests():
"""峰度的统计检验方法"""
print("峰度统计检验:")
print("=" * 40)
# 生成测试数据
np.random.seed(42)
test_datasets = {
"正态分布": np.random.normal(0, 1, 500),
"高峰度分布": stats.t.rvs(df=4, size=500),
"低峰度分布": np.random.uniform(-2, 2, 500),
"拉普拉斯分布": stats.laplace.rvs(size=500)
}
for name, data in test_datasets.items():
print(f"\n{name}:")
print("-" * 20)
# 计算峰度
kurt_val = stats.kurtosis(data, fisher=True) # 超额峰度
n = len(data)
print(f"样本超额峰度: {kurt_val:.4f}")
# 1. 超额峰度的大样本Z近似(不是D'Agostino变换检验)
# 在正态总体零假设下使用偏差修正的超额峰度及其标准误。
# 该检验只利用峰度信息,不能识别所有非正态分布。
corrected_kurt = stats.kurtosis(data, fisher=True, bias=False)
se_kurt = np.sqrt(24 * n * (n - 1)**2 / ((n - 3) * (n - 2) * (n + 3) * (n + 5)))
z_kurt = corrected_kurt / se_kurt
p_value_kurt = 2 * stats.norm.sf(abs(z_kurt))
print(f"超额峰度的大样本Z近似:")
print(f" 检验统计量 Z = {z_kurt:.4f}")
print(f" p值 = {p_value_kurt:.4f}")
if p_value_kurt < 0.05:
print(f" 结论: 拒绝正态峰度假设 (p < 0.05)")
else:
print(f" 结论: 接受正态峰度假设 (p ≥ 0.05)")
# 2. Jarque-Bera检验 (偏度和峰度的联合检验)
jb_stat, jb_pvalue = stats.jarque_bera(data)
print(f"Jarque-Bera检验:")
print(f" JB统计量 = {jb_stat:.4f}")
print(f" p值 = {jb_pvalue:.4f}")
if jb_pvalue < 0.05:
print(f" 结论: 拒绝正态性假设 (p < 0.05)")
else:
print(f" 结论: 未拒绝正态性假设 (p ≥ 0.05),不代表已证明正态性")
# 3. Anscombe-Glynn峰度检验
# 更准确的峰度正态性检验
def anscombe_glynn_test(data):
# 使用SciPy的峰度检验实现,避免不完整的手写变换
result = stats.kurtosistest(data)
return result.statistic, result.pvalue
if n > 20: # Anscombe-Glynn检验需要足够大的样本
ag_stat, ag_pvalue = anscombe_glynn_test(data)
print(f"Anscombe-Glynn峰度检验:")
print(f" AG统计量 = {ag_stat:.4f}")
print(f" p值 = {ag_pvalue:.4f}")
if ag_pvalue < 0.05:
print(f" 结论: 拒绝正态峰度假设 (p < 0.05)")
else:
print(f" 结论: 接受正态峰度假设 (p ≥ 0.05)")
# 4. 峰度的置信区间
# 使用bootstrap方法
n_bootstrap = 1000
bootstrap_kurts = []
for _ in range(n_bootstrap):
bootstrap_sample = np.random.choice(data, size=len(data), replace=True)
bootstrap_kurts.append(stats.kurtosis(bootstrap_sample, fisher=True))
ci_lower = np.percentile(bootstrap_kurts, 2.5)
ci_upper = np.percentile(bootstrap_kurts, 97.5)
print(f"超额峰度95%置信区间: [{ci_lower:.4f}, {ci_upper:.4f}]")
# 判断是否包含0(正态性)
if ci_lower <= 0 <= ci_upper:
print(f" 置信区间包含0,尚不能排除超额峰度为0;这不等于证明分布正态")
else:
print(f" 置信区间不包含0,支持非正态峰度")
kurtosis_tests()
🎯 实际应用场景
1. 金融风险管理
def financial_kurtosis_analysis():
"""金融市场的峰度分析"""
np.random.seed(42)
print("金融市场峰度风险分析:")
print("=" * 40)
# 模拟不同类型金融资产的收益率
trading_days = 252 * 2 # 两年的交易数据
# 不同资产的收益率特征
assets = {
"政府债券": {
"returns": np.random.normal(0.0003, 0.005, trading_days), # 低风险,接近正态
"description": "低风险资产"
},
"大盘股票": {
"returns": stats.t.rvs(df=6, loc=0.0005, scale=0.015, size=trading_days), # 中等峰度
"description": "传统股票资产"
},
"小盘股票": {
"returns": stats.t.rvs(df=4, loc=0.001, scale=0.025, size=trading_days), # 高峰度
"description": "高风险股票"
},
"加密货币": {
"returns": np.concatenate([
np.random.normal(0.002, 0.03, int(trading_days * 0.8)), # 正常时期
np.random.normal(0, 0.15, int(trading_days * 0.2)) # 高波动时期
]), # 极高峰度
"description": "极高风险资产"
}
}
# 分析每个资产
analysis_results = {}
for asset_name, asset_info in assets.items():
returns = asset_info["returns"] * 100 # 转换为百分比
# 基本统计
mean_return = np.mean(returns)
std_return = np.std(returns, ddof=1)
skew_return = stats.skew(returns)
kurt_return = stats.kurtosis(returns, fisher=False)
excess_kurt = stats.kurtosis(returns, fisher=True)
# 风险指标
var_95 = np.percentile(returns, 5) # 95% VaR
var_99 = np.percentile(returns, 1) # 99% VaR
# 尾部风险分析
tail_5pct = np.mean(returns < var_95) # 实际5%尾部概率
extreme_loss_3sigma = np.mean(returns < mean_return - 3 * std_return)
normal_extreme_prob = stats.norm.cdf(-3) # 理论正态分布的-3σ概率
# 峰度的风险含义
if excess_kurt > 3:
risk_interpretation = "极端收益频发,黑天鹅风险高"
elif excess_kurt > 1:
risk_interpretation = "尾部风险显著,需要额外风险管理"
elif excess_kurt > 0:
risk_interpretation = "轻度尾部风险,可接受"
else:
risk_interpretation = "尾部风险低于正态分布"
analysis_results[asset_name] = {
'returns': returns,
'mean': mean_return,
'std': std_return,
'skewness': skew_return,
'kurtosis': kurt_return,
'excess_kurtosis': excess_kurt,
'var_95': var_95,
'var_99': var_99,
'tail_risk_ratio': extreme_loss_3sigma / normal_extreme_prob if normal_extreme_prob > 0 else 1,
'risk_interpretation': risk_interpretation,
'description': asset_info["description"]
}
print(f"\n{asset_name} ({asset_info['description']}):")
print(f" 年化收益率: {mean_return * 252:.2f}%")
print(f" 年化波动率: {std_return * np.sqrt(252):.2f}%")
print(f" 偏度: {skew_return:.4f}")
print(f" 峰度: {kurt_return:.4f}")
print(f" 超额峰度: {excess_kurt:.4f}")
print(f" 95% VaR: {var_95:.2f}%")
print(f" 99% VaR: {var_99:.2f}%")
print(f" 极端损失倍数: {extreme_loss_3sigma / normal_extreme_prob:.1f}x")
print(f" 风险特征: {risk_interpretation}")
# 可视化对比
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
# 收益率分布对比
for asset_name, result in analysis_results.items():
returns = result['returns']
ax1.hist(returns, bins=50, alpha=0.6, density=True,
label=f"{asset_name} (超额峰度={result['excess_kurtosis']:.1f})")
ax1.set_xlabel('日收益率 (%)')
ax1.set_ylabel('密度')
ax1.set_title('收益率分布对比')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.set_xlim(-10, 10) # 限制x轴范围以便观察
# 峰度 vs 尾部风险
excess_kurts = [result['excess_kurtosis'] for result in analysis_results.values()]
tail_risks = [result['tail_risk_ratio'] for result in analysis_results.values()]
asset_names = list(analysis_results.keys())
ax2.scatter(excess_kurts, tail_risks, s=100, alpha=0.7)
for i, name in enumerate(asset_names):
ax2.annotate(name, (excess_kurts[i], tail_risks[i]),
xytext=(5, 5), textcoords='offset points', fontsize=9)
ax2.set_xlabel('超额峰度')
ax2.set_ylabel('极端损失风险倍数')
ax2.set_title('峰度 vs 尾部风险关系')
ax2.grid(True, alpha=0.3)
# VaR对比
var_95_values = [result['var_95'] for result in analysis_results.values()]
var_99_values = [result['var_99'] for result in analysis_results.values()]
x_pos = np.arange(len(asset_names))
width = 0.35
ax3.bar(x_pos - width/2, np.abs(var_95_values), width,
label='95% VaR', alpha=0.7, color='orange')
ax3.bar(x_pos + width/2, np.abs(var_99_values), width,
label='99% VaR', alpha=0.7, color='red')
ax3.set_xlabel('资产类型')
ax3.set_ylabel('VaR (绝对值, %)')
ax3.set_title('不同资产的VaR对比')
ax3.set_xticks(x_pos)
ax3.set_xticklabels(asset_names, rotation=45)
ax3.legend()
ax3.grid(True, alpha=0.3)
# 尾部概率对比
for asset_name, result in analysis_results.items():
returns = result['returns']
standardized = (returns - result['mean']) / result['std']
# 计算尾部概率
abs_returns = np.abs(standardized)
sorted_abs = np.sort(abs_returns)
n = len(sorted_abs)
survival = (n - np.searchsorted(sorted_abs, sorted_abs, side='right')) / n
# 只绘制尾部
mask = survival > 1e-3
if np.sum(mask) > 10:
ax4.semilogy(sorted_abs[mask], survival[mask],
'o-', markersize=2, alpha=0.7, label=asset_name)
# 理论正态分布
x_theory = np.linspace(0, 4, 100)
normal_tail = 2 * (1 - stats.norm.cdf(x_theory))
ax4.semilogy(x_theory, normal_tail, 'k--', linewidth=2,
alpha=0.7, label='理论正态分布')
ax4.set_xlabel('|标准化收益率|')
ax4.set_ylabel('P(|X| > x)')
ax4.set_title('尾部概率对比')
ax4.legend()
ax4.grid(True, alpha=0.3)
ax4.set_ylim(1e-3, 1)
plt.tight_layout()
plt.show()
# 风险管理建议
print(f"\n基于峰度的风险管理建议:")
print("=" * 40)
for asset_name, result in analysis_results.items():
excess_kurt = result['excess_kurtosis']
print(f"\n{asset_name}:")
if excess_kurt > 3:
print(" 🚨 极高峰度风险:")
print(" - 使用更保守的VaR估计")
print(" - 考虑期权对冲策略")
print(" - 降低仓位集中度")
print(" - 实施动态风险管理")
elif excess_kurt > 1:
print(" ⚠️ 高峰度风险:")
print(" - 调整风险模型参数")
print(" - 增加压力测试频率")
print(" - 考虑尾部风险对冲")
elif excess_kurt > 0:
print(" ✅ 中等峰度风险:")
print(" - 维持标准风险管理")
print(" - 定期监控峰度变化")
else:
print(" 📈 低峰度资产:")
print(" - 低峰度不足以支持正态假设,需结合分布诊断与尾部评估")
print(" - 是否适合作为组合稳定器,需结合波动、相关性、流动性及损失风险评估,不能仅凭低峰度判断")
# 组合构建建议
print(f"\n投资组合构建建议:")
print("-" * 25)
# 按峰度排序
sorted_assets = sorted(analysis_results.items(),
key=lambda x: x[1]['excess_kurtosis'])
print("峰度从低到高排序:")
for asset_name, result in sorted_assets:
excess_kurt = result['excess_kurtosis']
print(f" {asset_name}: 超额峰度 = {excess_kurt:.2f}")
print(f"\n建议配置策略:")
print(" 模拟配置假设:将低峰度资产(本例标签为政府债券、大盘股)作为保守型候选;峰度本身不能支持实际配置比例或风险等级")
print(" 平衡型: 混合配置,控制组合整体峰度")
print(" 激进型: 可接受高峰度,但需要严格风险控制")
financial_kurtosis_analysis()
2. 质量控制应用
def manufacturing_kurtosis_analysis():
"""制造业中的峰度质量分析"""
np.random.seed(42)
print("制造业峰度质量分析:")
print("=" * 40)
# 模拟不同生产过程的质量数据
n_samples = 1000
production_processes = {
"标准工艺": {
"data": np.random.normal(100, 1.5, n_samples), # 标准正态过程
"description": "稳定的标准化生产工艺"
},
"自动化生产": {
"data": np.random.uniform(98.5, 101.5, n_samples), # 低峰度,均匀分布
"description": "高度自动化,变异均匀"
},
"手工调整": {
"data": np.concatenate([
np.random.normal(100, 0.8, int(n_samples * 0.8)), # 大部分精确
np.random.normal(100, 3, int(n_samples * 0.2)) # 少数偏差大
]), # 高峰度,混合分布
"description": "人工调整,大多精确但偶有偏差"
},
"设备老化": {
"data": stats.t.rvs(df=3, loc=100, scale=2, size=n_samples), # 高峰度t分布
"description": "设备磨损,性能不稳定"
}
}
# 质量规格
target = 100
usl = 105 # 上规格限
lsl = 95 # 下规格限
print(f"质量规格: 目标值 = {target}, 规格范围 = [{lsl}, {usl}]")
# 分析每个生产过程
process_results = {}
for process_name, process_info in production_processes.items():
data = process_info["data"]
# 基本统计
mean_val = np.mean(data)
std_val = np.std(data, ddof=1)
skew_val = stats.skew(data)
kurt_val = stats.kurtosis(data, fisher=False)
excess_kurt = stats.kurtosis(data, fisher=True)
# 过程能力分析
cp = (usl - lsl) / (6 * std_val) # 过程能力
cpk = min((usl - mean_val) / (3 * std_val),
(mean_val - lsl) / (3 * std_val)) # 过程能力指数
# 合格率
conforming = np.sum((data >= lsl) & (data <= usl))
conformance_rate = conforming / len(data)
# 基于峰度的质量风险评估
# 计算超出±3σ的实际概率
extreme_count = np.sum(np.abs(data - mean_val) > 3 * std_val)
actual_extreme_rate = extreme_count / len(data)
theoretical_extreme_rate = 2 * (1 - stats.norm.cdf(3)) # 理论正态概率
# 峰度对质量的影响分析
if excess_kurt > 2:
quality_impact = "高峰度:极值频发,需要严格监控"
risk_level = "高"
elif excess_kurt > 0.5:
quality_impact = "中等峰度:存在异常值风险"
risk_level = "中"
elif excess_kurt > -0.5:
quality_impact = "峰度接近正态参考值:过程稳定性仍需时序监控判断"
risk_level = "低"
else:
quality_impact = "低峰度:不能据此判断精度,需结合偏差、变异与规格限评估"
risk_level = "中"
process_results[process_name] = {
'data': data,
'mean': mean_val,
'std': std_val,
'skewness': skew_val,
'kurtosis': kurt_val,
'excess_kurtosis': excess_kurt,
'cp': cp,
'cpk': cpk,
'conformance_rate': conformance_rate,
'actual_extreme_rate': actual_extreme_rate,
'extreme_risk_ratio': actual_extreme_rate / theoretical_extreme_rate if theoretical_extreme_rate > 0 else 1,
'quality_impact': quality_impact,
'risk_level': risk_level,
'description': process_info["description"]
}
print(f"\n{process_name} ({process_info['description']}):")
print(f" 均值: {mean_val:.2f}")
print(f" 标准差: {std_val:.2f}")
print(f" 峰度: {kurt_val:.3f}")
print(f" 超额峰度: {excess_kurt:.3f}")
print(f" Cp: {cp:.3f}")
print(f" Cpk: {cpk:.3f}")
print(f" 合格率: {conformance_rate:.1%}")
print(f" 极值率: {actual_extreme_rate:.1%} (理论: {theoretical_extreme_rate:.1%})")
print(f" 极值风险倍数: {actual_extreme_rate / theoretical_extreme_rate:.1f}x")
print(f" 质量影响: {quality_impact}")
print(f" 风险等级: {risk_level}")
# 可视化质量分析
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
# 质量分布对比
colors = plt.cm.Set2(np.linspace(0, 1, len(process_results)))
for i, (process_name, result) in enumerate(process_results.items()):
data = result['data']
ax1.hist(data, bins=40, alpha=0.6, density=True,
color=colors[i], label=f"{process_name} (超额峰度={result['excess_kurtosis']:.1f})")
# 添加规格限
ax1.axvline(lsl, color='red', linestyle='--', linewidth=2, label='规格限')
ax1.axvline(usl, color='red', linestyle='--', linewidth=2)
ax1.axvline(target, color='green', linestyle='-', linewidth=2, label='目标值')
ax1.set_xlabel('测量值')
ax1.set_ylabel('密度')
ax1.set_title('生产过程质量分布对比')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 峰度 vs 过程能力
excess_kurts = [result['excess_kurtosis'] for result in process_results.values()]
cpk_values = [result['cpk'] for result in process_results.values()]
process_names = list(process_results.keys())
ax2.scatter(excess_kurts, cpk_values, s=100, alpha=0.7, c=colors)
for i, name in enumerate(process_names):
ax2.annotate(name, (excess_kurts[i], cpk_values[i]),
xytext=(5, 5), textcoords='offset points', fontsize=9)
ax2.axhline(y=1.33, color='green', linestyle='--', alpha=0.7, label='优秀水平')
ax2.axhline(y=1.0, color='orange', linestyle='--', alpha=0.7, label='可接受水平')
ax2.set_xlabel('超额峰度')
ax2.set_ylabel('过程能力指数 (Cpk)')
ax2.set_title('峰度 vs 过程能力关系')
ax2.legend()
ax2.grid(True, alpha=0.3)
# 极值风险对比
extreme_risks = [result['extreme_risk_ratio'] for result in process_results.values()]
ax3.bar(process_names, extreme_risks, alpha=0.7, color=colors)
ax3.axhline(y=1, color='red', linestyle='--', alpha=0.7, label='理论正态水平')
ax3.set_ylabel('极值风险倍数')
ax3.set_title('各过程极值风险对比')
ax3.tick_params(axis='x', rotation=45)
ax3.legend()
ax3.grid(True, alpha=0.3)
# 在柱子上显示数值
for i, risk in enumerate(extreme_risks):
ax3.text(i, risk + 0.1, f'{risk:.1f}x', ha='center', va='bottom')
# 合格率 vs 峰度
conformance_rates = [result['conformance_rate'] * 100 for result in process_results.values()]
ax4.scatter(excess_kurts, conformance_rates, s=100, alpha=0.7, c=colors)
for i, name in enumerate(process_names):
ax4.annotate(name, (excess_kurts[i], conformance_rates[i]),
xytext=(5, 5), textcoords='offset points', fontsize=9)
ax4.set_xlabel('超额峰度')
ax4.set_ylabel('合格率 (%)')
ax4.set_title('峰度 vs 合格率关系')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 改进建议
print(f"\n基于峰度的过程改进建议:")
print("=" * 40)
for process_name, result in process_results.items():
excess_kurt = result['excess_kurtosis']
cpk = result['cpk']
print(f"\n{process_name}:")
if excess_kurt > 2 and cpk < 1.33:
print(" 🚨 高峰度低能力:")
print(" - 立即调查极值产生原因")
print(" - 实施更严格的过程控制")
print(" - 考虑更换设备或工艺")
print(" - 增加实时监控频率")
elif excess_kurt > 1:
print(" ⚠️ 中高峰度:")
print(" - 分析异常值产生机制")
print(" - 优化操作标准化程度")
print(" - 加强操作员培训")
elif excess_kurt < -1:
print(" 📊 低峰度分析:")
print(" - 检查测量系统精度")
print(" - 评估过程变异来源")
print(" - 考虑提高过程精度")
else:
print(" ✅ 峰度正常:")
print(" - 维持当前过程控制")
print(" - 继续监控峰度趋势")
# 基于Cpk的补充建议
if cpk < 1.0:
print(" - Cpk偏低,需要提高过程能力")
elif cpk > 1.33:
print(" - Cpk优秀,过程能力充足")
# 监控策略建议
print(f"\n峰度监控策略:")
print("-" * 20)
print("1. 建立峰度控制图,设定±2σ控制限")
print("2. 当超额峰度 > 1.5时触发调查")
print("3. 结合Cpk和峰度进行过程评估")
print("4. 定期进行峰度趋势分析")
print("5. 针对高峰度过程制定专项改进计划")
manufacturing_kurtosis_analysis()
🛠️ 实用技巧
1. 峰度异常检测系统
def kurtosis_anomaly_detection():
"""基于峰度的异常检测系统"""
class KurtosisAnomalyDetector:
def __init__(self, window_size=100, threshold=1.5):
self.window_size = window_size
self.threshold = threshold
self.data_buffer = []
self.kurtosis_history = []
self.anomalies = []
self.baseline_kurtosis = None
def add_data(self, new_data):
"""添加新数据并检测异常"""
if isinstance(new_data, (list, np.ndarray)):
self.data_buffer.extend(new_data)
else:
self.data_buffer.append(new_data)
# 保持缓冲区大小
if len(self.data_buffer) > self.window_size * 2:
self.data_buffer = self.data_buffer[-self.window_size:]
# 计算当前峰度
if len(self.data_buffer) >= self.window_size:
current_data = self.data_buffer[-self.window_size:]
current_kurtosis = stats.kurtosis(current_data, fisher=True)
self.kurtosis_history.append(current_kurtosis)
# 设定基线(前10个窗口的平均峰度)
if self.baseline_kurtosis is None and len(self.kurtosis_history) >= 10:
self.baseline_kurtosis = np.mean(self.kurtosis_history[:10])
# 检测异常
if self.baseline_kurtosis is not None:
self._detect_anomaly(current_kurtosis)
return current_kurtosis
return None
def _detect_anomaly(self, current_kurtosis):
"""检测峰度异常"""
deviation = abs(current_kurtosis - self.baseline_kurtosis)
if deviation > self.threshold:
anomaly_type = self._classify_anomaly(current_kurtosis)
self.anomalies.append({
'timestamp': len(self.kurtosis_history),
'kurtosis': current_kurtosis,
'baseline': self.baseline_kurtosis,
'deviation': deviation,
'type': anomaly_type,
'severity': self._get_severity(deviation)
})
def _classify_anomaly(self, kurtosis):
"""分类异常类型"""
if kurtosis > self.baseline_kurtosis + self.threshold:
return "峰度激增"
else:
return "峰度降低"
def _get_severity(self, deviation):
"""获取异常严重程度"""
if deviation > 3 * self.threshold:
return "严重"
elif deviation > 2 * self.threshold:
return "中等"
else:
return "轻微"
def get_current_status(self):
"""获取当前状态"""
if not self.kurtosis_history:
return "无数据"
if self.baseline_kurtosis is None:
return "基线未建立,尚未进行异常判定"
if not self.anomalies:
return "正常"
latest_anomaly = self.anomalies[-1]
if latest_anomaly['timestamp'] == len(self.kurtosis_history):
return f"异常: {latest_anomaly['type']} ({latest_anomaly['severity']})"
else:
return "已恢复"
def plot_monitoring(self):
"""绘制监控图表"""
if len(self.kurtosis_history) < 2:
print("数据不足,无法绘图")
return
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12))
# 峰度时间序列
timestamps = range(len(self.kurtosis_history))
ax1.plot(timestamps, self.kurtosis_history, 'b-', linewidth=2, label='峰度')
if self.baseline_kurtosis is not None:
ax1.axhline(y=self.baseline_kurtosis, color='green', linestyle='-',
alpha=0.7, label=f'基线 = {self.baseline_kurtosis:.3f}')
ax1.axhline(y=self.baseline_kurtosis + self.threshold, color='orange',
linestyle='--', alpha=0.7, label=f'警戒线 ±{self.threshold}')
ax1.axhline(y=self.baseline_kurtosis - self.threshold, color='orange',
linestyle='--', alpha=0.7)
# 标记异常点
for anomaly in self.anomalies:
color = {'轻微': 'yellow', '中等': 'orange', '严重': 'red'}[anomaly['severity']]
ax1.scatter(anomaly['timestamp'] - 1, anomaly['kurtosis'],
color=color, s=100, marker='X', alpha=0.8,
label=f"{anomaly['type']} ({anomaly['severity']})")
ax1.set_title('峰度监控时间序列')
ax1.set_xlabel('时间窗口')
ax1.set_ylabel('超额峰度')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 异常偏差程度
if self.anomalies:
anomaly_times = [a['timestamp'] - 1 for a in self.anomalies]
deviations = [a['deviation'] for a in self.anomalies]
colors = [{'轻微': 'yellow', '中等': 'orange', '严重': 'red'}[a['severity']]
for a in self.anomalies]
ax2.bar(anomaly_times, deviations, color=colors, alpha=0.7)
ax2.axhline(y=self.threshold, color='red', linestyle='--',
alpha=0.7, label=f'阈值 = {self.threshold}')
ax2.set_title('异常偏差程度')
ax2.set_xlabel('时间窗口')
ax2.set_ylabel('偏差幅度')
ax2.legend()
ax2.grid(True, alpha=0.3)
# 当前数据分布
if len(self.data_buffer) >= self.window_size:
current_data = self.data_buffer[-self.window_size:]
ax3.hist(current_data, bins=30, density=True, alpha=0.7,
color='skyblue', edgecolor='black')
current_kurtosis = stats.kurtosis(current_data, fisher=True)
ax3.text(0.02, 0.98, f'当前超额峰度: {current_kurtosis:.3f}',
transform=ax3.transAxes, verticalalignment='top',
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.8))
ax3.set_title(f'当前数据分布 (最近{self.window_size}个点)')
ax3.set_xlabel('数值')
ax3.set_ylabel('密度')
ax3.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
def generate_report(self):
"""生成监控报告"""
print("峰度异常检测报告")
print("=" * 30)
print(f"监控窗口大小: {self.window_size}")
print(f"异常阈值: {self.threshold}")
print(f"基线峰度: {self.baseline_kurtosis:.4f}" if self.baseline_kurtosis is not None else "基线未建立")
print(f"当前状态: {self.get_current_status()}")
print(f"监控周期数: {len(self.kurtosis_history)}")
print(f"检测到异常: {len(self.anomalies)}次")
if self.anomalies:
print(f"\n异常详情:")
for i, anomaly in enumerate(self.anomalies[-5:], 1): # 显示最近5次异常
print(f" {i}. 时间窗口{anomaly['timestamp']}: {anomaly['type']}")
print(f" 峰度: {anomaly['kurtosis']:.4f} (偏差: {anomaly['deviation']:.4f})")
print(f" 严重程度: {anomaly['severity']}")
# 演示异常检测系统
print("峰度异常检测系统演示:")
print("=" * 40)
# 创建检测器
detector = KurtosisAnomalyDetector(window_size=50, threshold=1.0)
np.random.seed(42)
# 阶段1: 正常数据(基线建立)
print("阶段1: 建立基线...")
normal_data = np.random.normal(0, 1, 500)
for data_point in normal_data:
detector.add_data(data_point)
print(f"基线峰度: {detector.baseline_kurtosis:.4f}")
# 阶段2: 峰度异常(高峰度)
print("\n阶段2: 注入高峰度数据...")
high_kurt_data = stats.t.rvs(df=3, size=100)
for data_point in high_kurt_data:
detector.add_data(data_point)
print(f"当前状态: {detector.get_current_status()}")
# 阶段3: 峰度异常(低峰度)
print("\n阶段3: 注入低峰度数据...")
low_kurt_data = np.random.uniform(-2, 2, 100)
for data_point in low_kurt_data:
detector.add_data(data_point)
print(f"当前状态: {detector.get_current_status()}")
# 阶段4: 恢复正常
print("\n阶段4: 恢复正常数据...")
recovery_data = np.random.normal(0, 1, 100)
for data_point in recovery_data:
detector.add_data(data_point)
print(f"当前状态: {detector.get_current_status()}")
# 生成报告和图表
detector.generate_report()
detector.plot_monitoring()
kurtosis_anomaly_detection()
🔗 相关知识
#统计学 #峰度 #描述性统计 #分布形状 #尖峭程度 #基础