未记录事实核验 · 状态:现行内容

记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。

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()

⚠️ 使用注意事项

🚫 常见错误

  1. 盲目假设正态分布:许多实际数据并不服从正态分布
  2. 忽略数据特征:不考虑数据的界限、偏态等特征
  3. 参数估计不当:使用不合适的参数估计方法
  4. 样本量不足:小样本下分布检验不可靠

💡 最佳实践建议

  1. 数据探索:

    • 绘制直方图和Q-Q图
    • 计算偏度和峰度
    • 检查异常值和界限
  2. 分布检验:

    • 使用多种拟合优度检验
    • 结合可视化方法判断
    • 考虑业务背景和理论基础
  3. 模型选择:

    • 优先考虑理论依据
    • 比较多个候选分布
    • 交叉验证模型性能

🔗 相关知识

#统计学 #数据分布 #概率分布 #Python