超越总收入差距:用Dagum基尼分解洞察区域发展不均衡的Python实战指南

当面对一组区域经济数据时,我们常常会问:这些差异究竟来自哪里?是同一区域内不同县市的贫富悬殊,还是不同区域之间的整体落差?传统基尼系数虽然能告诉我们"差距有多大",却无法揭示"差距从何而来"。这正是Dagum基尼分解方法的用武之地——它像一台精密的CT扫描仪,能清晰呈现经济差距的内在结构。

1. 理解Dagum基尼分解的核心价值

在区域经济分析中,单纯知道"某省基尼系数为0.4"远远不够。政策制定者需要明确:是该优先解决省内发达县与落后县的差距(组内不平等),还是应该重点协调不同地市之间的整体发展水平(组间不平等)?Dagum方法通过三个关键指标给出了量化答案:

  • 组内差距(G_w) :反映同一分组内部的不平等程度。例如同一地级市内各县区的发展差异。
  • 组间净值差距(G_nb) :衡量不同分组之间的平均发展水平差异。例如苏南与苏北地区的整体经济差距。
  • 超变密度(G_t) :捕捉分组间分布重叠带来的影响,解释那些"富县中的穷区域"和"穷县中的富区域"现象。

这三个指标的独特之处在于它们的 可加性 ——三者之和正好等于总体基尼系数。这意味着我们可以精确量化每种差距对总不平等的贡献比例。例如某省分析结果可能显示:

指标 数值 贡献率
G_w 0.15 37.5%
G_nb 0.20 50.0%
G_t 0.05 12.5%
总计 0.40 100%

这样的分解结果直接指明:该省的发展不平衡主要源于地区间的整体差距(G_nb占50%),而非单个地区内部的差异。这对资源配置决策具有直接指导意义。

2. 数据准备与预处理实战

2.1 构建分析数据集

理想的数据结构应该包含三个维度:区域分组标识、观测单位(如县区)和经济发展指标(如人均GDP)。以下是一个模拟数据创建的Python示例:

import pandas as pd
import numpy as np

# 模拟生成某省3个地市下辖县区的人均GDP数据
np.random.seed(2023)

data = []
for city in ['A市', 'B市', 'C市']:
    # 每个地市有5-8个县区
    n_counties = np.random.randint(5, 9)
    
    # 根据地市整体水平设置基准值
    if city == 'A市': base = 80000  # 发达地区
    elif city == 'B市': base = 50000  # 中等地区
    else: base = 30000  # 欠发达地区
    
    # 生成各县区数据,考虑组内差异
    for i in range(n_counties):
        gdp = base * np.random.uniform(0.7, 1.3)  # 上下浮动30%
        data.append({'city': city, 'county': f'{city}县区{i+1}', 'pc_gdp': gdp})

df = pd.DataFrame(data)
print(df.head(8))

2.2 数据质量检查

在进行分析前,必须进行四项关键检查:

  1. 缺失值检测 df.isnull().sum()
  2. 异常值识别 :通过箱线图或3σ原则排查
  3. 分组平衡性 :各组观测单位数量不宜差异过大
  4. 指标合理性 :如人均GDP是否在可信区间

提示:对于存在极端值的情况,建议同时分析原始数据和经Winsorize处理后的数据,比较结果稳定性。

3. Dagum分解的Python实现详解

3.1 核心算法实现

以下是完整的Dagum基尼分解函数实现,包含详细的注释说明:

def dagum_gini_decomposition(df, group_col, value_col):
    """
    执行Dagum基尼系数分解
    参数:
        df: 包含分组和数值的DataFrame
        group_col: 分组列名
        value_col: 待分析数值列名
    返回:
        包含G, G_w, G_nb, G_t及各组间指标的字典
    """
    import numpy as np
    from itertools import combinations, product
    
    groups = df[group_col].unique()
    group_data = {g: df[df[group_col]==g][value_col].values for g in groups}
    n = len(df)
    y_mean = df[value_col].mean()
    
    # 计算总体基尼系数
    def _gini(a, b):
        diffs = np.abs(np.subtract.outer(a, b))
        return diffs.sum() / (2 * len(a) * len(b) * (a.mean() + b.mean()))
    
    G = _gini(df[value_col].values, df[value_col].values)
    
    # 计算各组统计量
    stats = {}
    for g in groups:
        data = group_data[g]
        stats[g] = {
            'p_j': len(data)/n,  # 组内单位数占比
            's_j': len(data)*data.mean()/(n*y_mean),  # 组内收入份额
            'mean': data.mean()
        }
    
    # 按均值降序排列组别
    sorted_groups = sorted(groups, key=lambda g: -stats[g]['mean'])
    
    # 计算组内差距G_w
    G_w = sum(_gini(group_data[g], group_data[g]) * stats[g]['p_j'] * stats[g]['s_j'] 
              for g in groups)
    
    # 计算组间贡献
    G_nb, G_t = 0, 0
    D_jh = {}  # 储存组间影响系数
    
    for j, h in combinations(sorted_groups, 2):
        data_j = group_data[j]
        data_h = group_data[h]
        
        # 计算D_jh影响系数
        diff_jh = np.subtract.outer(data_j, data_h)
        M_jh = np.where(diff_jh > 0, diff_jh, 0).mean()
        N_jh = np.where(diff_jh < 0, -diff_jh, 0).mean()
        D_jh[(j,h)] = (M_jh - N_jh) / (M_jh + N_jh) if (M_jh + N_jh) > 0 else 0
        
        # 计算组间贡献
        cross_gini = _gini(data_j, data_h)
        weight = stats[j]['p_j']*stats[h]['s_j'] + stats[h]['p_j']*stats[j]['s_j']
        
        G_nb += cross_gini * D_jh[(j,h)] * weight
        G_t += cross_gini * (1 - D_jh[(j,h)]) * weight
    
    return {
        'G_total': G,
        'G_within': G_w,
        'G_net_between': G_nb,
        'G_transvariation': G_t,
        'D_jh': D_jh,
        'components_share': {
            'within_share': G_w/G,
            'between_share': G_nb/G,
            'transvar_share': G_t/G
        }
    }

3.2 结果可视化解读

分解结果的直观呈现至关重要。以下是使用matplotlib创建雷达图的示例:

def plot_dagum_results(result):
    import matplotlib.pyplot as plt
    import numpy as np
    
    labels = ['组内差距(G_w)', '组间净值差距(G_nb)', '超变密度(G_t)']
    values = [result['G_within'], result['G_net_between'], result['G_transvariation']]
    shares = [result['components_share']['within_share'],
              result['components_share']['between_share'],
              result['components_share']['transvar_share']]
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5), subplot_kw={'polar': True})
    
    # 绝对值雷达图
    angles = np.linspace(0, 2*np.pi, len(labels), endpoint=False)
    values += values[:1]
    angles = np.concatenate((angles, [angles[0]]))
    ax1.plot(angles, values, 'o-', linewidth=2)
    ax1.fill(angles, values, alpha=0.25)
    ax1.set_xticks(angles[:-1])
    ax1.set_xticklabels(labels)
    ax1.set_title('Dagum分解绝对值(G={:.3f})'.format(result['G_total']), y=1.1)
    
    # 相对贡献雷达图
    shares = np.array(shares) * 100
    shares = np.concatenate((shares, [shares[0]]))
    ax2.plot(angles, shares, 'o-', linewidth=2)
    ax2.fill(angles, shares, alpha=0.25)
    ax2.set_xticks(angles[:-1])
    ax2.set_xticklabels(labels)
    ax2.set_title('各成分贡献比例(%)', y=1.1)
    
    plt.tight_layout()
    plt.show()

4. 从数据到决策:深度解读与应用建议

4.1 典型结果场景分析

假设我们对某省三大经济带进行分析,得到以下结果:

总基尼系数: 0.42
- 组内差距(G_w): 0.15 (35.7%)
- 组间净值差距(G_nb): 0.22 (52.4%) 
- 超变密度(G_t): 0.05 (11.9%)

这显示该省的发展不平衡主要源于经济带之间的整体差距(G_nb占52.4%)。进一步分析组间影响系数D_jh:

对比组 D_jh值
经济带A vs 经济带B 0.82
经济带A vs 经济带C 0.91
经济带B vs 经济带C 0.68

高D_jh值(接近1)表明经济带之间存在明显的层级差异,特别是A与C之间。这提示政策应优先考虑:

  1. 跨区域基础设施投资 :加强经济带之间的交通网络
  2. 产业协同规划 :避免重复建设,形成互补产业链
  3. 人才流动机制 :促进发达地区人才向欠发达地区流动

4.2 不同场景下的分析策略

根据G_w、G_nb的相对重要性,可采取不同的分析视角:

场景一:高G_w主导(组内差异大)

  • 关注点:同一地市内县区发展不平衡
  • 对策建议:
    • 优化县域经济结构
    • 加强市域内财政转移支付
    • 建立县域协同发展机制

场景二:高G_nb主导(组间差异大)

  • 关注点:区域整体发展落差
  • 对策建议:
    • 制定区域性发展战略
    • 设立专项发展基金
    • 推动跨区域合作项目

场景三:高G_t显著(重叠影响大)

  • 关注点:发展水平的非均匀分布
  • 对策建议:
    • 精准识别"发展洼地"
    • 实施靶向扶持政策
    • 建立跨区域帮扶机制

5. 方法局限性与进阶技巧

5.1 注意事项与常见问题

在实际应用中,我们需要注意以下关键点:

  • 分组合理性 :组别划分需要基于实质性的社会经济特征(如地理分区、产业类型),而非随意分组
  • 数据尺度效应 :分析县域差距和使用乡镇级数据可能得出不同结论,需明确研究尺度
  • 时间维度分析 :建议进行多年份追踪,观察各成分的变化趋势

注意:当某些分组样本量过小时(如少于5个观测单位),相应的分解结果可能不够稳定,建议合并相关分组或谨慎解释。

5.2 方法扩展与交叉验证

为增强分析深度,可以结合其他方法:

  1. 空间自相关分析 :检验地区差距是否存在空间集聚性

    from esda.moran import Moran
    w = ... # 空间权重矩阵
    moran = Moran(df[value_col], w)
    print(f"Moran's I: {moran.I:.3f}, p-value: {moran.p_sim:.4f}")
    
  2. 分位数回归 :考察不同发展水平地区的影响因素差异

  3. 动态分解分析 :将基尼系数变化分解为各成分的贡献

下表对比了几种常见的不平等分析方法:

方法 优势 局限 适用场景
Dagum分解 区分组内/组间来源 需要明确分组 区域政策评估
Theil指数 可逐层分解 对低端敏感 多层次结构分析
变异系数 计算简单 缺乏分解能力 快速评估
空间基尼 考虑地理因素 计算复杂 区域集群研究

在实际研究中,建议先用基尼系数评估总体不平等程度,再通过Dagum分解识别主要矛盾来源,最后结合空间分析或回归方法探究深层原因。这种组合策略能提供更全面、更有操作性的分析结果。

更多推荐