未记录事实核验 · 状态:现行内容
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适用于常见分布形态学习、模拟绘图和所列候选模型的描述性比较,不是业务数据分布成立的证明或完整的推断检验流程。同一样本估参后输出的普通KS p值不能按通常的显著性含义解释,正式推断需采用适用的参数估计校正或重抽样校准;“最佳拟合”仅表示所列候选中KS距离最小,不保证模型充分适合数据。分布选择树及转化量、呼叫量、收入和故障间隔等案例只提供候选方向,实际使用须检查支持域、独立性、成功概率、事件率等相应假设。各代码段依赖前文导入,应按顺序使用。本次仅作全文结构审阅,未执行代码或开展外部事实核验。
📊 数据分布类型(Data Distribution Types)
abstract 📋 本节概览
- 🎯 学习目标:掌握常见数据分布类型的特征、应用场景和Python实现
- 📚 前置知识:数据类型|数据类型 | 描述性统计|描述性统计 | 概率的基本概念|概率的基本概念
- ⏱️ 预计用时:15分钟
🎯 核心概念
note 📖 **什么是数据分布?**
数据分布描述了数据在不同取值上的分布规律和概率特征,是统计分析和建模的基础。
为什么理解分布类型很重要?
- 方法选择:不同分布需要不同的统计方法
- 模型假设:许多统计方法对数据分布有假设要求
- 数据理解:分布特征反映数据的内在规律
- 预测建模:选择合适的概率模型进行预测
📈 连续分布详解
1. 🔔 正态分布(Normal Distribution)
特征:钟形对称,均值=中位数=众数
数学特性:
- 参数:μ(均值)和σ(标准差)
- 记号:N(μ, σ²)
- 概率密度函数:f(x) = (1/σ√2π)e^(-½((x-μ)/σ)²)
应用场景:
- 测量误差、身高体重等自然现象
- 中心极限定理的基础
- 大多数参数统计方法的假设
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
def normal_distribution_demo():
"""正态分布详解与应用"""
print("=== 正态分布分析 ===")
# 不同参数的正态分布
x = np.linspace(-10, 10, 1000)
distributions = [
{"μ": 0, "σ": 1, "label": "标准正态分布 N(0,1)", "color": "blue"},
{"μ": 0, "σ": 2, "label": "N(0,4)", "color": "red"},
{"μ": 2, "σ": 1, "label": "N(2,1)", "color": "green"},
{"μ": -1, "σ": 0.5, "label": "N(-1,0.25)", "color": "orange"}
]
plt.figure(figsize=(15, 10))
# 概率密度函数对比
plt.subplot(2, 2, 1)
for dist in distributions:
y = stats.norm.pdf(x, dist["μ"], dist["σ"])
plt.plot(x, y, color=dist["color"], label=dist["label"], linewidth=2)
plt.title('正态分布概率密度函数')
plt.xlabel('x值')
plt.ylabel('概率密度')
plt.legend()
plt.grid(True, alpha=0.3)
# 累积分布函数
plt.subplot(2, 2, 2)
for dist in distributions:
y = stats.norm.cdf(x, dist["μ"], dist["σ"])
plt.plot(x, y, color=dist["color"], label=dist["label"], linewidth=2)
plt.title('正态分布累积分布函数')
plt.xlabel('x值')
plt.ylabel('累积概率')
plt.legend()
plt.grid(True, alpha=0.3)
# 实际数据示例:学生身高
np.random.seed(42)
heights = np.random.normal(170, 8, 1000) # 假设身高均值170cm,标准差8cm
plt.subplot(2, 2, 3)
plt.hist(heights, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')
# 拟合正态分布
mu, sigma = stats.norm.fit(heights)
x_fit = np.linspace(heights.min(), heights.max(), 100)
plt.plot(x_fit, stats.norm.pdf(x_fit, mu, sigma), 'r-', linewidth=2,
label=f'拟合正态分布\nμ={mu:.1f}, σ={sigma:.1f}')
plt.title('学生身高分布示例')
plt.xlabel('身高 (cm)')
plt.ylabel('概率密度')
plt.legend()
# 正态性检验
shapiro_stat, shapiro_p = stats.shapiro(heights[:50]) # 样本量限制
kstest_stat, kstest_p = stats.kstest(heights, 'norm', args=(mu, sigma))
plt.subplot(2, 2, 4)
stats.probplot(heights, dist="norm", plot=plt)
plt.title(f'Q-Q图正态性检验\nShapiro p={shapiro_p:.4f}\nKS p={kstest_p:.4f}')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 68-95-99.7规则验证
print(f"\n正态分布68-95-99.7规则验证:")
print(f"数据均值: {mu:.2f}, 标准差: {sigma:.2f}")
within_1sigma = np.sum(np.abs(heights - mu) <= sigma) / len(heights)
within_2sigma = np.sum(np.abs(heights - mu) <= 2*sigma) / len(heights)
within_3sigma = np.sum(np.abs(heights - mu) <= 3*sigma) / len(heights)
print(f"1σ范围内数据比例: {within_1sigma:.1%} (理论68%)")
print(f"2σ范围内数据比例: {within_2sigma:.1%} (理论95%)")
print(f"3σ范围内数据比例: {within_3sigma:.1%} (理论99.7%)")
return heights, mu, sigma
# 执行正态分布分析
height_data, mean_h, std_h = normal_distribution_demo()
2. 📈 偏态分布(Skewed Distribution)
特征:分布不对称,有明显的偏向
类型:
- 右偏(正偏):通常表现为右侧长尾;某些常见单峰右偏分布呈现均值>中位数>众数,但这一顺序不是通用判定条件
- 左偏(负偏):通常表现为左侧长尾;某些常见单峰左偏分布呈现均值<中位数<众数,但这一顺序不是通用判定条件
def skewed_distribution_demo():
"""偏态分布分析"""
print("=== 偏态分布分析 ===")
np.random.seed(42)
# 生成不同偏态的数据
normal_data = np.random.normal(50, 10, 1000)
right_skewed = np.random.exponential(2, 1000) # 右偏分布
left_skewed = 100 - np.random.exponential(2, 1000) # 左偏分布
datasets = {
'对称分布(正态)': normal_data,
'右偏分布(指数)': right_skewed,
'左偏分布': left_skewed
}
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
for i, (name, data) in enumerate(datasets.items()):
# 计算统计量
mean_val = np.mean(data)
median_val = np.median(data)
skewness = stats.skew(data)
kurtosis = stats.kurtosis(data)
print(f"\n{name}:")
print(f" 均值: {mean_val:.2f}")
print(f" 中位数: {median_val:.2f}")
print(f" 偏度: {skewness:.2f}")
print(f" 峰度: {kurtosis:.2f}")
# 分布图
axes[0, i].hist(data, bins=30, density=True, alpha=0.7,
color=['blue', 'red', 'green'][i], edgecolor='black')
axes[0, i].axvline(mean_val, color='red', linestyle='--', linewidth=2, label=f'均值: {mean_val:.1f}')
axes[0, i].axvline(median_val, color='green', linestyle='--', linewidth=2, label=f'中位数: {median_val:.1f}')
axes[0, i].set_title(f'{name}\n偏度: {skewness:.2f}')
axes[0, i].legend()
axes[0, i].grid(True, alpha=0.3)
# 箱线图
axes[1, i].boxplot(data, vert=True)
axes[1, i].set_title(f'{name}\n箱线图')
axes[1, i].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 实际业务场景
print(f"\n=== 偏态分布的业务应用 ===")
# 收入分布(典型右偏)
income_data = np.random.lognormal(10, 0.5, 1000)
print(f"收入分布示例(对数正态分布):")
print(f" 均值: {np.mean(income_data):.0f}")
print(f" 中位数: {np.median(income_data):.0f}")
print(f" 偏度: {stats.skew(income_data):.2f}")
print(f" 解释: 少数高收入者拉高了平均值,中位数更能代表典型收入水平")
return datasets
# 执行偏态分布分析
skewed_data = skewed_distribution_demo()
3. 📊 其他重要连续分布
def other_continuous_distributions():
"""其他重要连续分布"""
print("=== 其他重要连续分布 ===")
x = np.linspace(0, 10, 1000)
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 1. 指数分布
lambda_param = 1.5
y_exp = stats.expon.pdf(x, scale=1/lambda_param)
axes[0, 0].plot(x, y_exp, 'b-', linewidth=2, label=f'λ={lambda_param}')
axes[0, 0].set_title('指数分布\n(等待时间、生存分析)')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)
# 2. 对数正态分布
y_lognorm = stats.lognorm.pdf(x, s=0.5, scale=np.exp(1))
axes[0, 1].plot(x, y_lognorm, 'r-', linewidth=2, label='σ=0.5, μ=1')
axes[0, 1].set_title('对数正态分布\n(收入、股价)')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)
# 3. 伽马分布
y_gamma = stats.gamma.pdf(x, a=2, scale=1)
axes[0, 2].plot(x, y_gamma, 'g-', linewidth=2, label='α=2, β=1')
axes[0, 2].set_title('伽马分布\n(等待时间、降雨量)')
axes[0, 2].legend()
axes[0, 2].grid(True, alpha=0.3)
# 4. 贝塔分布
x_beta = np.linspace(0, 1, 1000)
y_beta = stats.beta.pdf(x_beta, a=2, b=5)
axes[1, 0].plot(x_beta, y_beta, 'm-', linewidth=2, label='α=2, β=5')
axes[1, 0].set_title('贝塔分布\n(比例、概率)')
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)
# 5. 韦伯分布
y_weibull = stats.weibull_min.pdf(x, c=1.5, scale=2)
axes[1, 1].plot(x, y_weibull, 'c-', linewidth=2, label='k=1.5, λ=2')
axes[1, 1].set_title('韦伯分布\n(可靠性分析)')
axes[1, 1].legend()
axes[1, 1].grid(True, alpha=0.3)
# 6. 卡方分布
x_chi2 = np.linspace(0, 15, 1000)
for df in [1, 3, 5]:
y_chi2 = stats.chi2.pdf(x_chi2, df)
axes[1, 2].plot(x_chi2, y_chi2, linewidth=2, label=f'df={df}')
axes[1, 2].set_title('卡方分布\n(方差检验)')
axes[1, 2].legend()
axes[1, 2].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 分布应用场景总结
applications = {
'指数分布': '客户服务等待时间、设备故障间隔时间',
'对数正态分布': '收入分布、股价变动、网站访问时长',
'伽马分布': '降雨量、保险理赔金额',
'贝塔分布': '成功率、市场份额、项目完成度',
'韦伯分布': '产品寿命、可靠性分析',
'卡方分布': '方差检验、拟合优度检验'
}
print(f"\n各分布的典型应用场景:")
for dist, app in applications.items():
print(f" {dist}: {app}")
# 执行其他连续分布分析
other_continuous_distributions()
🎯 离散分布详解
1. 🎲 常见离散分布
def discrete_distributions_demo():
"""离散分布详解"""
print("=== 离散分布分析 ===")
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 1. 二项分布
n, p = 20, 0.3
x_binom = np.arange(0, n+1)
y_binom = stats.binom.pmf(x_binom, n, p)
axes[0, 0].bar(x_binom, y_binom, alpha=0.7, color='blue')
axes[0, 0].set_title(f'二项分布 B({n},{p})\n质量检验、营销转化')
axes[0, 0].set_xlabel('成功次数')
axes[0, 0].set_ylabel('概率')
axes[0, 0].grid(True, alpha=0.3)
# 2. 泊松分布
lambda_param = 3
x_poisson = np.arange(0, 15)
y_poisson = stats.poisson.pmf(x_poisson, lambda_param)
axes[0, 1].bar(x_poisson, y_poisson, alpha=0.7, color='red')
axes[0, 1].set_title(f'泊松分布 P({lambda_param})\n网站访问量、呼叫中心')
axes[0, 1].set_xlabel('事件发生次数')
axes[0, 1].set_ylabel('概率')
axes[0, 1].grid(True, alpha=0.3)
# 3. 几何分布
p_geom = 0.2
x_geom = np.arange(1, 21)
y_geom = stats.geom.pmf(x_geom, p_geom)
axes[0, 2].bar(x_geom, y_geom, alpha=0.7, color='green')
axes[0, 2].set_title(f'几何分布 Geom({p_geom})\n首次成功试验次数')
axes[0, 2].set_xlabel('试验次数')
axes[0, 2].set_ylabel('概率')
axes[0, 2].grid(True, alpha=0.3)
# 4. 负二项分布
r, p_nb = 5, 0.3
x_nb = np.arange(0, 25)
y_nb = stats.nbinom.pmf(x_nb, r, p_nb)
axes[1, 0].bar(x_nb, y_nb, alpha=0.7, color='orange')
axes[1, 0].set_title(f'负二项分布 NB({r},{p_nb})\n过离散计数数据')
axes[1, 0].set_xlabel('失败次数')
axes[1, 0].set_ylabel('概率')
axes[1, 0].grid(True, alpha=0.3)
# 5. 超几何分布
N, K, n_hyper = 50, 15, 10
x_hyper = np.arange(0, min(K, n_hyper)+1)
y_hyper = stats.hypergeom.pmf(x_hyper, N, K, n_hyper)
axes[1, 1].bar(x_hyper, y_hyper, alpha=0.7, color='purple')
axes[1, 1].set_title(f'超几何分布\n无放回抽样')
axes[1, 1].set_xlabel('成功次数')
axes[1, 1].set_ylabel('概率')
axes[1, 1].grid(True, alpha=0.3)
# 6. 多项分布示例(绘制一个类别的边际分布)
n_multi, p_multi = 20, [0.3, 0.4, 0.3]
x_multi = np.arange(0, n_multi+1)
# 第一个类别的边际分布是二项分布
y_multi = stats.binom.pmf(x_multi, n_multi, p_multi[0])
axes[1, 2].bar(x_multi, y_multi, alpha=0.7, color='brown')
axes[1, 2].set_title('多项分布(第一类)\n市场份额分析')
axes[1, 2].set_xlabel('第一类数量')
axes[1, 2].set_ylabel('概率')
axes[1, 2].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 实际业务应用示例
print(f"\n=== 离散分布业务应用示例 ===")
# 1. 网站转化率分析(二项分布)
visitors = 1000
conversion_rate = 0.05
conversions = np.random.binomial(visitors, conversion_rate, 100)
print(f"网站转化分析(二项分布):")
print(f" 访客数: {visitors}, 转化率: {conversion_rate:.1%}")
print(f" 100天转化量均值: {np.mean(conversions):.1f}")
print(f" 标准差: {np.std(conversions):.1f}")
# 2. 客服呼叫量分析(泊松分布)
avg_calls_per_hour = 15
hourly_calls = np.random.poisson(avg_calls_per_hour, 100)
print(f"\n客服呼叫量分析(泊松分布):")
print(f" 平均每小时呼叫: {avg_calls_per_hour}次")
print(f" 100小时呼叫量均值: {np.mean(hourly_calls):.1f}")
print(f" 标准差: {np.std(hourly_calls):.1f}")
return {
'conversions': conversions,
'calls': hourly_calls
}
# 执行离散分布分析
discrete_data = discrete_distributions_demo()
🔄 分布之间的关系
def distribution_relationships():
"""展示分布之间的关系"""
print("=== 分布关系分析 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 二项分布趋向正态分布
n_values = [10, 30, 100]
p = 0.3
x_range = np.arange(0, 100)
for n in n_values:
if n <= 30:
x = np.arange(0, n+1)
y = stats.binom.pmf(x, n, p)
axes[0, 0].plot(x, y, 'o-', label=f'二项分布 n={n}', alpha=0.7)
# 正态近似
mu, sigma = n*p, np.sqrt(n*p*(1-p))
x_norm = np.linspace(max(0, mu-4*sigma), min(n, mu+4*sigma), 100)
y_norm = stats.norm.pdf(x_norm, mu, sigma)
axes[0, 0].plot(x_norm, y_norm, '--', label=f'正态近似 n={n}', alpha=0.7)
axes[0, 0].set_title('二项分布的正态近似\n(中心极限定理)')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)
# 2. 泊松分布趋向正态分布
lambda_values = [1, 5, 20]
for lam in lambda_values:
x = np.arange(0, lam + 4*np.sqrt(lam))
y = stats.poisson.pmf(x, lam)
axes[0, 1].plot(x, y, 'o-', label=f'泊松分布 λ={lam}', alpha=0.7)
# 正态近似(当λ较大时)
if lam >= 5:
x_norm = np.linspace(max(0, lam-4*np.sqrt(lam)), lam+4*np.sqrt(lam), 100)
y_norm = stats.norm.pdf(x_norm, lam, np.sqrt(lam))
axes[0, 1].plot(x_norm, y_norm, '--', label=f'正态近似 λ={lam}', alpha=0.7)
axes[0, 1].set_title('泊松分布的正态近似')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)
# 3. 二项分布趋向泊松分布
n_values = [20, 100, 500]
p_values = [0.1, 0.02, 0.004] # 保持np≈2
for n, p in zip(n_values, p_values):
x = np.arange(0, 15)
y_binom = stats.binom.pmf(x, n, p)
axes[1, 0].plot(x, y_binom, 'o-', label=f'二项 n={n}, p={p}', alpha=0.7)
# 泊松近似
lambda_approx = 2 # np的极限
y_poisson = stats.poisson.pmf(x, lambda_approx)
axes[1, 0].plot(x, y_poisson, 's--', label=f'泊松近似 λ={lambda_approx}', alpha=0.8)
axes[1, 0].set_title('二项分布的泊松近似\n(n大p小时)')
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)
# 4. 对数正态分布与正态分布关系
mu, sigma = 0, 0.5
x_lognorm = np.linspace(0.1, 5, 1000)
y_lognorm = stats.lognorm.pdf(x_lognorm, sigma, scale=np.exp(mu))
axes[1, 1].plot(x_lognorm, y_lognorm, 'b-', linewidth=2, label='对数正态分布')
# 对应的正态分布(取对数后)
x_norm = np.linspace(-3, 3, 1000)
y_norm = stats.norm.pdf(x_norm, mu, sigma)
ax_twin = axes[1, 1].twinx()
ax_twin.plot(x_norm, y_norm, 'r--', linewidth=2, label='对应正态分布')
ax_twin.set_ylabel('正态分布密度', color='red')
axes[1, 1].set_title('对数正态分布与正态分布关系')
axes[1, 1].set_ylabel('对数正态分布密度', color='blue')
axes[1, 1].legend(loc='upper right')
ax_twin.legend(loc='upper left')
axes[1, 1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print(f"\n重要的分布关系:")
print(f"1. 二项分布 → 正态分布 (n大时)")
print(f"2. 二项分布 → 泊松分布 (n大p小时)")
print(f"3. 泊松分布 → 正态分布 (λ大时)")
print(f"4. 正态随机变量经exp变换得到对数正态随机变量;标准对数正态随机变量经ln变换得到正态随机变量")
print(f"5. 多个独立正态分布的和 → 正态分布")
# 执行分布关系分析
distribution_relationships()
🎯 分布选择指南
📋 分布选择决策树
def distribution_selection_guide():
"""分布选择指南"""
print("=== 数据分布选择指南 ===")
decision_tree = {
"数据类型": {
"连续数据": {
"对称分布": "正态分布等候选;对称性本身不能确定正态分布",
"右偏分布": "对数正态分布、指数分布",
"左偏分布": "若数据有界且可缩放至[0,1],可考虑适当参数的贝塔分布;左偏本身不足以确定分布",
"有界数据[0,1]": "贝塔分布",
"非负数据": "伽马分布、韦伯分布",
"等待时间": "指数分布、韦伯分布"
},
"离散数据": {
"成功/失败次数": "二项分布",
"稀有事件计数": "泊松分布",
"首次成功": "几何分布",
"过离散计数": "负二项分布",
"无放回抽样": "超几何分布",
"多类别计数": "多项分布"
}
},
"业务场景": {
"质量控制": "正态分布、控制图",
"营销转化": "二项分布、贝塔分布",
"客户到达": "泊松分布、指数分布",
"收入分析": "对数正态分布",
"生存分析": "韦伯分布、指数分布",
"A/B测试": "正态分布、二项分布"
}
}
for category, subcategories in decision_tree.items():
print(f"\n{category}:")
if isinstance(subcategories, dict):
for subcat, distributions in subcategories.items():
print(f" {subcat}:")
if isinstance(distributions, dict):
for condition, dist in distributions.items():
print(f" {condition}: {dist}")
else:
print(f" 推荐: {distributions}")
# 实际应用案例
print(f"\n=== 实际应用案例 ===")
cases = [
{
"场景": "电商网站转化率分析",
"数据": "1000次访问,50次购买",
"分布": "二项分布 B(1000, 0.05)",
"分析": "计算转化率置信区间"
},
{
"场景": "客服中心呼叫量预测",
"数据": "每小时平均12次呼叫",
"分布": "泊松分布 P(12)",
"分析": "预测峰值呼叫量,安排人力"
},
{
"场景": "员工薪资分布",
"数据": "右偏分布,少数高薪",
"分布": "对数正态分布",
"分析": "使用中位数而非均值"
},
{
"场景": "产品故障率分析",
"数据": "故障间隔时间",
"分布": "指数分布",
"分析": "计算可靠性指标"
}
]
for case in cases:
print(f"\n场景: {case['场景']}")
print(f" 数据特征: {case['数据']}")
print(f" 适用分布: {case['分布']}")
print(f" 分析重点: {case['分析']}")
# 执行分布选择指南
distribution_selection_guide()
🧪 分布拟合与检验
def distribution_fitting_demo():
"""分布拟合与检验"""
print("=== 分布拟合与检验 ===")
# 生成示例数据
np.random.seed(42)
# 1. 明显正态分布的数据
normal_sample = np.random.normal(100, 15, 1000)
# 2. 右偏分布数据
skewed_sample = np.random.exponential(2, 1000)
# 3. 混合数据
mixed_sample = np.concatenate([
np.random.normal(80, 10, 700),
np.random.normal(120, 8, 300)
])
datasets = {
'正态分布样本': normal_sample,
'指数分布样本': skewed_sample,
'混合分布样本': mixed_sample
}
fig, axes = plt.subplots(3, 3, figsize=(18, 15))
for i, (name, data) in enumerate(datasets.items()):
# 原始数据分布
axes[i, 0].hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')
axes[i, 0].set_title(f'{name}\n原始数据')
axes[i, 0].grid(True, alpha=0.3)
# 尝试不同分布拟合
distributions = [
('正态分布', stats.norm),
('指数分布', stats.expon),
('对数正态分布', stats.lognorm)
]
best_fit = None
best_ks_stat = float('inf')
for dist_name, distribution in distributions:
try:
# 参数估计
if distribution == stats.expon:
params = distribution.fit(data, floc=0)
else:
params = distribution.fit(data)
# KS检验
ks_stat, ks_p = stats.kstest(data, distribution.cdf, args=params)
if ks_stat < best_ks_stat:
best_ks_stat = ks_stat
best_fit = (dist_name, distribution, params, ks_p)
# 绘制拟合分布
x_fit = np.linspace(data.min(), data.max(), 100)
y_fit = distribution.pdf(x_fit, *params)
axes[i, 1].plot(x_fit, y_fit, linewidth=2, label=f'{dist_name} (KS p={ks_p:.3f})')
except:
continue
axes[i, 1].hist(data, bins=30, density=True, alpha=0.5, color='lightgray')
axes[i, 1].set_title(f'{name}\n分布拟合对比')
axes[i, 1].legend()
axes[i, 1].grid(True, alpha=0.3)
# Q-Q图(使用最佳拟合)
if best_fit:
dist_name, distribution, params, ks_p = best_fit
if distribution == stats.lognorm:
# 对数正态分布的Q-Q图
shifted_data = data - params[1] # 减去拟合的loc参数
log_data = np.log(shifted_data[shifted_data > 0])
stats.probplot(log_data, dist="norm", plot=axes[i, 2])
axes[i, 2].set_title(f'{name}\n最佳拟合: {dist_name}')
else:
stats.probplot(data, dist=distribution, sparams=params, plot=axes[i, 2])
axes[i, 2].set_title(f'{name}\n最佳拟合: {dist_name}')
axes[i, 2].grid(True, alpha=0.3)
print(f"\n{name}分布拟合结果:")
if best_fit:
print(f" 最佳拟合分布: {best_fit[0]}")
print(f" KS统计量: {best_ks_stat:.4f}")
print(f" p值: {best_fit[3]:.4f}")
print(f" 拟合参数: {best_fit[2]}")
# 正态性检验
shapiro_stat, shapiro_p = stats.shapiro(data[:5000] if len(data) > 5000 else data)
jarque_stat, jarque_p = stats.jarque_bera(data)
print(f" 正态性检验:")
print(f" Shapiro-Wilk p值: {shapiro_p:.4f}")
print(f" Jarque-Bera p值: {jarque_p:.4f}")
plt.tight_layout()
plt.show()
return datasets
# 执行分布拟合与检验
fitted_data = distribution_fitting_demo()
⚠️ 使用注意事项
🚫 常见错误
- 盲目假设正态分布:许多实际数据并不服从正态分布
- 忽略数据特征:不考虑数据的界限、偏态等特征
- 参数估计不当:使用不合适的参数估计方法
- 样本量不足:小样本下分布检验不可靠
💡 最佳实践建议
-
数据探索:
- 绘制直方图和Q-Q图
- 计算偏度和峰度
- 检查异常值和界限
-
分布检验:
- 使用多种拟合优度检验
- 结合可视化方法判断
- 考虑业务背景和理论基础
-
模型选择:
- 优先考虑理论依据
- 比较多个候选分布
- 交叉验证模型性能
🔗 相关知识
#统计学 #数据分布 #概率分布 #Python