Files
MCM-ICM_Toolkit/src/mcm_toolkit/decision/weighting.py
T
guzhujushi 5319589dfd chore: 初始化 MCM/ICM Toolkit 仓库骨架
审查并精简 ChatGPT 的建库建议后落地的第一版骨架,只定接口不写实现。

- 建议审查:14 个包 → 7 个;约 250 个函数 → 约 40 个;5 个 Result 类 → 1 个
  (docs/01-suggestion-review.md)
- docs/:架构、路线图(含永久不做清单)、环境、Git 工作流、函数卡片模板
- src/mcm_toolkit/:core / data / stats / models / solve / decision / viz
  共 23 个模块,均为签名 + docstring + NotImplementedError
- tests/:9 个文件,其中 test_api_surface.py 已通过(20 passed)
- examples/ problems/ notebooks/ figures/ tables/ 骨架
- pyproject.toml(核心依赖 4 个 + 6 组 extras)、environment.yml
- scripts/:setup-venv.ps1(ASCII + LF)、setup-conda.ps1、doctor.ps1
- 环境:.venv(system-site-packages)与 conda 环境 mcm-toolkit 均已建好,
  数值栈版本与 base 完全对齐(numpy 2.4.6 / scipy 1.18.1 / pandas 3.0.6,MKL 后端)
2026-10-01 17:43:48 +08:00

72 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""客观赋权:熵权法、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