71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
"""客观赋权:熵权法、CRITIC。
|
||||
|
|
|
|||
|
|
★ `entropy_weights` 是 S 档,建议自己实现。
|
|||
|
|
熵权法是中文建模赛出现频率最高的赋权方法,实现只有 20 行,
|
|||
|
|
但"指标方向、无量纲化、对数 0 处理"三个坑必须理解清楚才能写对。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
__all__ = ["critic_weights", "entropy_weights", "equal_weights"]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def equal_weights(n: int) -> Any:
|
|||
|
|
"""等权,即 `1/n`。作为赋权结果的对照基线,论文里应该报。"""
|
|||
|
|
# TODO(L1)
|
|||
|
|
raise NotImplementedError
|
|||
|
|
|
|||
|
|
|
|||
|
|
def entropy_weights(
|
|||
|
|
X: Any,
|
|||
|
|
benefit_columns: Any = None,
|
|||
|
|
eps: float = 1e-12,
|
|||
|
|
) -> Any:
|
|||
|
|
"""熵权法。
|
|||
|
|
|
|||
|
|
Parameters
|
|||
|
|
----------
|
|||
|
|
X:
|
|||
|
|
决策矩阵,行 = 方案,列 = 指标。**必须已无量纲化且已做正向化**。
|
|||
|
|
benefit_columns:
|
|||
|
|
效益型(越大越好)指标的列名/下标。其余按成本型处理。
|
|||
|
|
`None` 时假设全部是效益型,并在 `message` 里提示——避免静默搞错方向。
|
|||
|
|
|
|||
|
|
Returns
|
|||
|
|
-------
|
|||
|
|
`Result`:`params={"weights": 权重向量}`,
|
|||
|
|
`extras["entropy"]` 是各指标的熵值,
|
|||
|
|
`extras["redundancy"]` 是差异系数 `1 - e`(权重就来自它的归一化)。
|
|||
|
|
|
|||
|
|
Notes
|
|||
|
|
-----
|
|||
|
|
三个必须处理的细节:
|
|||
|
|
1. **方向**:成本型指标要先正向化(`max - x` 或 `1/x`),否则权重完全错。
|
|||
|
|
2. **量纲**:熵权法要求 `x >= 0`,且对量纲敏感——先做 min-max 或向量归一。
|
|||
|
|
3. **零值**:`p·ln(p)` 在 `p=0` 时按 0 处理(极限为 0),不能直接算,否则出 NaN。
|
|||
|
|
|
|||
|
|
熵权法的缺点是**只看数据离散程度,不看指标的实际重要性**。
|
|||
|
|
实践上常和 AHP 做组合赋权:`w = α·w_entropy + (1-α)·w_ahp`。
|
|||
|
|
|
|||
|
|
Examples
|
|||
|
|
--------
|
|||
|
|
>>> import numpy as np
|
|||
|
|
>>> r = entropy_weights(np.array([[1., 2.], [3., 1.], [2., 3.]]))
|
|||
|
|
>>> bool(np.isclose(r.params["weights"].sum(), 1.0))
|
|||
|
|
True
|
|||
|
|
"""
|
|||
|
|
# TODO(L1) ★ S 档:配完整函数卡片
|
|||
|
|
raise NotImplementedError
|
|||
|
|
|
|||
|
|
|
|||
|
|
def critic_weights(X: Any, benefit_columns: Any = None) -> Any:
|
|||
|
|
"""CRITIC 赋权。
|
|||
|
|
|
|||
|
|
与熵权法的区别:熵权法只看"对比强度"(标准差),
|
|||
|
|
CRITIC 还乘上"冲突性"(与其他指标的相关性)。
|
|||
|
|
`C_j = σ_j · Σ_k (1 - r_jk)`,权重 = `C_j / ΣC`。
|
|||
|
|
"""
|
|||
|
|
# TODO(L1)
|
|||
|
|
raise NotImplementedError
|