Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

灰色关联分析

灰色关联分析(Grey Relational Analysis, GRA)是灰色系统理论的重要组成部分,由邓聚龙教授于1982年提出。该方法通过比较数据序列的几何形状相似程度来判断因素之间的关联程度,适用于样本量少、信息不完全的“灰色“系统分析。

基本原理

灰色关联分析的核心思想是:根据序列曲线几何形状的相似程度来判断其联系是否紧密。曲线越接近,相应序列之间的关联度就越大。

设系统行为序列(参考序列)为:

\[ X_0 = (x_0(1), x_0(2), \ldots, x_0(n)) \]

相关因素序列(比较序列)为:

\[ X_i = (x_i(1), x_i(2), \ldots, x_i(n)), \quad i = 1, 2, \ldots, m \]

其中 \( n \) 为数据长度(观测时刻数),\( m \) 为比较序列的个数。

分析步骤

  1. 确定参考序列和比较序列
  2. 对原始数据进行无量纲化处理
  3. 计算各比较序列与参考序列的灰色关联系数
  4. 计算灰色关联度
  5. 根据关联度大小进行排序和分析

与传统统计方法的区别

  • 对样本量没有严格要求,少至4个数据点即可分析
  • 不要求数据服从特定的概率分布
  • 计算量较小,不会出现量化结果与定性分析不一致的情况
  • 适用于“小样本、贫信息“的不确定性系统

数据预处理(无量纲化)

由于系统中各因素的物理意义不同,数据的量纲也不一定相同,不便于直接比较。在进行灰色关联分析前,需要对数据进行无量纲化处理。

初值化处理

\[ x_i’(k) = \frac{x_i(k)}{x_i(1)}, \quad k = 1, 2, \ldots, n \]

适用于时间序列数据,但对第一个数据点的依赖性较强。

均值化处理

\[ x_i’(k) = \frac{x_i(k)}{\bar{x}_i}, \quad \bar{x}i = \frac{1}{n}\sum{k=1}^{n} x_i(k) \]

考虑了全部数据的信息,稳定性较好,是最常用的无量纲化方法。

极差标准化(Min-Max归一化)

效益型指标(越大越好):

\[ x_i’(k) = \frac{x_i(k) - \min_k x_i(k)}{\max_k x_i(k) - \min_k x_i(k)} \]

成本型指标(越小越好):

\[ x_i’(k) = \frac{\max_k x_i(k) - x_i(k)}{\max_k x_i(k) - \min_k x_i(k)} \]

方法选择建议

方法适用场景优点缺点
初值化时间序列简单直观依赖首个数据
均值化一般情况稳定性好需计算均值
极差标准化指标评价结果在[0,1]受极端值影响

关联系数与关联度计算

关联系数反映了比较序列与参考序列在各个时刻的关联程度,关联度则是对关联系数的综合度量。

绝对差值计算

\[ \Delta_i(k) = |x_0’(k) - x_i’(k)| \]

确定两级最小差和两级最大差:

\[ \Delta_{\min} = \min_i \min_k \Delta_i(k), \quad \Delta_{\max} = \max_i \max_k \Delta_i(k) \]

关联系数公式

\[ \xi_i(k) = \frac{\Delta_{\min} + \rho \cdot \Delta_{\max}}{\Delta_i(k) + \rho \cdot \Delta_{\max}} \]

其中 \( \rho \in (0, 1] \) 为分辨系数。关联系数满足 \( 0 < \xi_i(k) \leq 1 \)。

关联度计算

等权平均:

\[ r_i = \frac{1}{n}\sum_{k=1}^{n} \xi_i(k) \]

加权平均:

\[ r_i = \sum_{k=1}^{n} w_k \cdot \xi_i(k), \quad \sum_{k=1}^{n} w_k = 1 \]

关联度越大,说明该比较序列与参考序列的变化趋势越一致。

分辨系数选择

分辨系数 \( \rho \) 的取值直接影响关联系数的计算结果和分辨能力。

分辨系数的引入是为了削弱 \( \Delta_{\max} \) 过大导致关联系数失真的问题:

  • \( \rho \) 越小,各关联系数之间的差异越大,分辨能力越强
  • \( \rho \) 越大,各关联系数趋于平均化,分辨能力越弱
  • 一般取 \( \rho = 0.5 \)(邓聚龙教授推荐)

设两个差值 \( \Delta_a < \Delta_b \),其关联系数之比为:

\[ \frac{\xi_a}{\xi_b} = \frac{\Delta_b + \rho \Delta_{\max}}{\Delta_a + \rho \Delta_{\max}} \]

\( \rho \) 减小时比值增大,区分度增强。建议进行敏感性分析:分别取 \( \rho = 0.1, 0.3, 0.5, 0.7, 1.0 \) 计算关联度,观察排序是否稳定。

实际案例分析(完整计算)

以某城市经济发展因素分析为例,展示灰色关联分析的完整计算过程。

问题与数据

分析影响GDP增长的主要因素,选取2018-2022年数据:

年份GDP(\(X_0\))固定资产投资(\(X_1\))社消零售(\(X_2\))进出口(\(X_3\))财政支出(\(X_4\))
2018320014501680920580
2019348016201820980640
2020335015801750850720
20213720175019501050780
20224100192021501200850

步骤一:均值化处理

各序列均值:\( \bar{x}_0=3570 \), \( \bar{x}_1=1664 \), \( \bar{x}_2=1870 \), \( \bar{x}_3=1000 \), \( \bar{x}_4=714 \)

年份\(X_0’\)\(X_1’\)\(X_2’\)\(X_3’\)\(X_4’\)
20180.89640.87140.89840.92000.8123
20190.97480.97360.97330.98000.8964
20200.93840.94950.93580.85001.0084
20211.04201.05171.04281.05001.0924
20221.14851.15381.14971.20001.1905

步骤二:计算绝对差值

年份\(\Delta_1(k)\)\(\Delta_2(k)\)\(\Delta_3(k)\)\(\Delta_4(k)\)
20180.02500.00200.02360.0841
20190.00120.00150.00520.0784
20200.01110.00260.08840.0700
20210.00970.00080.00800.0504
20220.00530.00120.05150.0420

步骤三:确定极值

\[ \Delta_{\min} = 0.0008, \quad \Delta_{\max} = 0.0884 \]

步骤四:计算关联系数(\(\rho=0.5\))

\[ \xi_i(k) = \frac{0.0008 + 0.5 \times 0.0884}{\Delta_i(k) + 0.5 \times 0.0884} = \frac{0.0450}{\Delta_i(k) + 0.0442} \]

年份\(\xi_1(k)\)\(\xi_2(k)\)\(\xi_3(k)\)\(\xi_4(k)\)
20180.65030.97410.66400.3509
20190.99120.98360.91310.3672
20200.81370.96030.33750.3864
20210.83540.99110.85270.4716
20220.90910.98680.46990.5218

步骤五:计算关联度

\[ r_1 = \frac{1}{5}(0.6503 + 0.9912 + 0.8137 + 0.8354 + 0.9091) = 0.8399 \]

\[ r_2 = \frac{1}{5}(0.9741 + 0.9836 + 0.9603 + 0.9911 + 0.9868) = 0.9792 \]

\[ r_3 = \frac{1}{5}(0.6640 + 0.9131 + 0.3375 + 0.8527 + 0.4699) = 0.6474 \]

\[ r_4 = \frac{1}{5}(0.3509 + 0.3672 + 0.3864 + 0.4716 + 0.5218) = 0.4196 \]

结论

关联度排序:\( r_2 > r_1 > r_3 > r_4 \),即社会消费品零售总额 > 固定资产投资 > 进出口总额 > 财政支出。内需消费是推动该城市经济增长的最主要因素,固定资产投资次之。

Python代码实现

以下提供灰色关联分析的完整Python实现,包括数据预处理、关联度计算和可视化。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


def grey_relational_analysis(reference, comparisons, rho=0.5, method='mean'):
    """
    灰色关联分析

    Parameters
    ----------
    reference : array-like, shape (n,)
        参考序列
    comparisons : array-like, shape (m, n)
        比较序列
    rho : float
        分辨系数, 取值范围(0, 1]
    method : str
        无量纲化方法: 'mean', 'initial', 'minmax'

    Returns
    -------
    dict : 关联系数矩阵、关联度、排序结果
    """
    reference = np.array(reference, dtype=float)
    comparisons = np.array(comparisons, dtype=float)
    if comparisons.ndim == 1:
        comparisons = comparisons.reshape(1, -1)

    m, n = comparisons.shape
    assert len(reference) == n, "参考序列与比较序列长度不一致"
    assert 0 < rho <= 1, "分辨系数rho必须在(0, 1]范围内"

    # 无量纲化
    all_data = np.vstack([reference.reshape(1, -1), comparisons])
    if method == 'mean':
        all_data = all_data / all_data.mean(axis=1, keepdims=True)
    elif method == 'initial':
        all_data = all_data / all_data[:, 0:1]
    elif method == 'minmax':
        mins = all_data.min(axis=1, keepdims=True)
        maxs = all_data.max(axis=1, keepdims=True)
        ranges = maxs - mins
        ranges[ranges == 0] = 1
        all_data = (all_data - mins) / ranges
    else:
        raise ValueError(f"不支持的方法: {method}")

    ref_norm = all_data[0]
    comp_norm = all_data[1:]

    # 绝对差值矩阵
    delta = np.abs(comp_norm - ref_norm)
    delta_min = delta.min()
    delta_max = delta.max()

    # 关联系数
    xi = (delta_min + rho * delta_max) / (delta + rho * delta_max)

    # 关联度
    r = xi.mean(axis=1)
    order = np.argsort(-r)

    return {
        'delta': delta,
        'delta_min': delta_min,
        'delta_max': delta_max,
        'xi': xi,
        'grey_relational_grade': r,
        'order': order
    }


def sensitivity_analysis(reference, comparisons, rho_values=None, method='mean'):
    """分辨系数敏感性分析"""
    if rho_values is None:
        rho_values = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

    results = {}
    for rho in rho_values:
        res = grey_relational_analysis(reference, comparisons, rho, method)
        results[f'rho={rho}'] = res['grey_relational_grade']

    df = pd.DataFrame(results)
    df.index = [f'X{i+1}' for i in range(len(comparisons))]
    return df


def plot_grey_relational(result, labels=None):
    """可视化关联分析结果"""
    r = result['grey_relational_grade']
    m = len(r)
    if labels is None:
        labels = [f'X{i+1}' for i in range(m)]

    fig, axes = plt.subplots(1, 2, figsize=(14, 5))

    # 关联度柱状图
    colors = plt.cm.RdYlGn(r / r.max())
    bars = axes[0].bar(labels, r, color=colors, edgecolor='black', alpha=0.8)
    axes[0].set_ylabel('关联度')
    axes[0].set_ylim(0, 1.1)
    axes[0].axhline(y=r.mean(), color='red', linestyle='--',
                    label=f'平均: {r.mean():.4f}')
    axes[0].legend()
    for bar, val in zip(bars, r):
        axes[0].text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.02,
                     f'{val:.4f}', ha='center', fontsize=9)

    # 关联系数热力图
    xi = result['xi']
    im = axes[1].imshow(xi, cmap='YlOrRd', aspect='auto', vmin=0, vmax=1)
    axes[1].set_yticks(range(m))
    axes[1].set_yticklabels(labels)
    axes[1].set_xticks(range(xi.shape[1]))
    axes[1].set_xticklabels([f'k={k+1}' for k in range(xi.shape[1])])
    for i in range(m):
        for j in range(xi.shape[1]):
            axes[1].text(j, i, f'{xi[i,j]:.3f}', ha='center', va='center',
                         fontsize=8)
    plt.colorbar(im, ax=axes[1])
    plt.tight_layout()
    plt.savefig('grey_relational_analysis.png', dpi=150, bbox_inches='tight')
    plt.show()


# ============ 案例运行 ============
if __name__ == '__main__':
    gdp = [3200, 3480, 3350, 3720, 4100]
    comparisons = np.array([
        [1450, 1620, 1580, 1750, 1920],  # 固定资产投资
        [1680, 1820, 1750, 1950, 2150],  # 社消零售
        [920, 980, 850, 1050, 1200],     # 进出口
        [580, 640, 720, 780, 850]        # 财政支出
    ])
    labels = ['固定资产投资', '社消零售总额', '进出口总额', '财政支出']

    result = grey_relational_analysis(gdp, comparisons, rho=0.5, method='mean')

    print("灰色关联分析结果")
    print(f"两级最小差: {result['delta_min']:.4f}")
    print(f"两级最大差: {result['delta_max']:.4f}")
    print("\n关联度:")
    for label, grade in zip(labels, result['grey_relational_grade']):
        print(f"  {label}: {grade:.4f}")
    print(f"\n排序: {' > '.join(labels[i] for i in result['order'])}")

    # 敏感性分析
    print("\n敏感性分析:")
    sa = sensitivity_analysis(gdp, comparisons)
    sa.index = labels
    print(sa.round(4))

    plot_grey_relational(result, labels)

应用注意事项与局限性

灰色关联分析虽然适用范围广、计算简便,但在实际应用中仍需注意若干关键问题。

应用注意事项

数据质量:序列长度建议至少4个数据点;各序列长度必须一致;应避免明显异常值;缺失值需先行插补。

无量纲化一致性:同一分析中所有序列必须采用同一种方法;建议对比多种方法的结果验证稳健性。

参考序列选择:参考序列直接影响结论,必须具有明确实际意义;多目标评价中可采用“理想序列“作为参考。

结果解释:关联度反映的是序列间“形状相似性“,而非因果关系;高关联度不等同于因果效应;应结合专业知识验证结论。

局限性

  1. 缺乏统计检验:无法判断关联度差异是否具有统计学显著性
  2. 方向性问题:传统方法不区分正相关和负相关
  3. 参数主观性:分辨系数选取缺乏理论最优解
  4. 非线性关系:对非线性关系的捕捉能力有限
  5. 动态性不足:静态方法难以反映变量间的滞后效应
  6. 可比性问题:不同研究中的关联度值不具有横向可比性

改进方向与方法组合

应用场景推荐方法
小样本因素分析灰色关联分析
大样本相关分析Pearson/Spearman相关
因果推断回归分析/结构方程
综合评价排序灰色关联-TOPSIS
权重确定灰色关联+熵权法

建模竞赛建议

  1. 明确说明选择灰色关联分析的理由(样本量小、数据不完全等)
  2. 详细展示无量纲化过程和分辨系数选取依据
  3. 进行敏感性分析以增强结果可信度
  4. 与至少一种其他方法交叉验证
  5. 结合问题背景对结果进行合理解释