"""客观赋权:熵权法、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