MEMR模型复现介绍:最大熵-最小残差权重法的Julia通用实现

一、这次复现的是什么模型?

这次整理的不是 DEA,而是一类很典型、也很实用的综合评价赋权模型

MEMR(Maximum Entropy Minimum Residual)模型,也就是“最大熵—最小残差”权重法。

它的核心目标很直接:

  • 一方面,希望各指标的权重分配不要过于极端,尽量保留“均衡性”;
  • 另一方面,又希望加权后的综合评价结果,能够尽量贴近各个原始指标的信息结构。

换句话说,这个模型不是只追求“权重分散”,也不是只追求“拟合误差最小”,而是想在两者之间找到一个更合理的平衡点。

这正是 MEMR 这个名字的含义:

  • Maximum Entropy:权重分布尽量有更高的信息熵;
  • Minimum Residual:综合评价指数与原始指标之间的残差尽量小。

二、MEMR模型到底在解决什么问题?

在多指标综合评价里,一个绕不开的问题就是:

每个指标到底应该给多大权重?

如果直接等权,做法简单,但往往太粗; 如果完全依赖主观赋权,又容易受专家判断影响。

MEMR 的思路比较有意思,它试图用一个优化模型同时回答两个问题:

1)权重能不能尽量客观、均衡?

这部分由来体现。

如果某一个指标权重特别大、其他指标特别小,那么权重分布就会很“尖”,信息熵偏低; 如果权重分布更均衡,熵就更高。

2)综合得分能不能尽量代表原始数据?

这部分由残差来体现。

模型会先构造综合评价指数:

[ y = Xw ]

其中:

  • (X) 是标准化后的指标矩阵;
  • (w) 是各指标权重;
  • (y) 是每个地区(或样本)的综合评价指数 CEI。

然后再看每个指标与综合指数之间的偏离程度,并把它总结成残差 ()。

所以,MEMR 其实是在做这样一件事:

在“权重尽量均衡”和“综合指标尽量贴近原始信息”之间,求一个最优折中。


三、这次 Julia 代码里是怎么实现的?

这次的 memr_reproduce.jl 不只是把论文公式抄了一遍,而是已经整理成了一个可复用的通用版脚本

从代码结构看,主线非常清晰,大致分为下面几步。

第一步:集中配置参数

程序最前面用了一个 CONFIG 配置块,统一管理:

  • 输入数据文件路径;
  • 输出目录;
  • 随机种子;
  • 最大迭代次数;
  • 学习率;
  • 多起点重启次数;
  • 标准化方式;
  • 论文参考权重、熵、残差等校验值。

这一步的意义很大,因为它把“模型逻辑”和“实验参数”拆开了。

以后如果要换数据、换输出目录,甚至换成别的案例,不需要去改核心算法,优先改配置即可。

第二步:从 CSV 读取原始数据

程序通过 read_csv_dataset()data/table2_raw.csv 读取:

  • 地区名称;
  • 指标名称;
  • 各地区的原始指标值。

这意味着当前版本已经不依赖硬编码数据,而是真正做成了一个“输入文件驱动”的复现脚本。

第三步:做最小-最大标准化

代码里当前采用的是:

Min-Max 标准化

即把每个指标压缩到 0~1 区间。

这样做的原因很简单:MEMR 模型的残差和熵计算,默认是建立在可比尺度上的。若各指标量纲差异太大,直接做优化会让结果失真。

第四步:定义 MEMR 的核心量

程序中对应了论文的几个核心公式:

  1. 综合评价指数 CEIy = X * w
  2. 残差 ():衡量综合结果与原始指标之间的偏离
  3. 信息熵 (E)

[ E = -w_j _2(w_j) ]

  1. 目标函数

[ ^E ]

这也是这篇代码最关键的一点:

它不是分别去优化“熵”和“残差”,而是直接把两者组合进同一个目标函数。


四、优化过程是怎么做的?

这次 Julia 程序没有依赖复杂的外部求解器,而是采用了:

Adam + 多起点重启(multi-start)

具体思路是:

  • 先用 softmax 把无约束参数映射成和为 1 的非负权重;
  • 再通过中心差分近似梯度;
  • 用 Adam 迭代更新参数;
  • 最后从多个随机初始点中,选择目标函数值最好的那一组权重。

这么做的好处有两个:

1)避免直接处理“权重和为1、且非负”的约束难题

因为 softmax 天生就满足:

  • 每个权重非负;
  • 所有权重之和等于 1。

所以优化器实际上是在无约束空间里搜索,代码会更干净。

2)降低陷入局部最优的风险

由于目标函数并不是一个特别简单的凸函数,如果只从单一起点出发,可能停在局部较优解。

多起点重启就是为了尽量提高结果稳定性。

从最终结果看,这个策略是成功的,因为程序已经把论文主结果复现到非常高的精度。


五、这次复现结果怎么样?

output/summary.csvoutput/weights.csvoutput/ranking.csv 来看,这次 MEMR 复现已经属于高质量对齐

1. 目标函数、残差、熵都与论文高度一致

当前程序输出的核心结果是:

  • log(Objective) = -13.2752
  • Residual σ = 0.011634
  • Entropy E = 2.980594
  • F-value = 4.3394
  • p-value = 0.0002
  • Optimization Index = 11.2347%

与论文对照值相比:

  • log(Objective) 完全一致;
  • 残差差异约为 0.000001
  • 熵差异约为 0.000001
  • F 值和优化指数也只存在极小的数值误差。

这说明当前脚本已经不是“差不多对上”,而是已经到了:

核心统计量与论文主表基本一致。

2. 各指标权重与论文 Table 3 基本逐项对齐

当前 8 个指标的结果分别为:

  • Food:0.117108
  • Clothing:0.103886
  • Housing:0.118592
  • HA:0.157953
  • TC:0.161194
  • EM:0.109561
  • HC:0.107163
  • Others:0.124543

与论文权重相比,差异都非常小,基本都在万分位附近。

其中权重相对较高的指标包括:

  • TC(0.161194)
  • HA(0.157953)

这意味着在当前样本与模型设定下,这两类消费支出对综合评价指数的影响更大。

3. 综合评价排名也已经完整输出

程序最终给出了 31 个地区的 CEI 和排名。

排名前几位分别是:

  1. Shanghai:0.978237
  2. Beijing:0.726384
  3. Zhejiang:0.714589
  4. Jiangsu:0.452920
  5. Fujian:0.331306

这份结果与论文主案例的结论是一致的,也说明当前 MEMR 程序已经不仅能“算权重”,还能把完整的综合评价链条跑通。


六、这次复现除了“跑通”,还有什么价值?

1. 从“论文复现脚本”升级成“可复用程序”

很多复现项目的问题在于:

  • 数据写死;
  • 参数写死;
  • 输出只在终端里;
  • 别人拿过去几乎没法复用。

这次 MEMR 代码已经明显不是这种状态了。

它实现了:

  • 从 CSV 读取数据;
  • 自动生成标准化结果、权重、排名、摘要表;
  • 还预留了 Bootstrap 统计输出结构。

这就使它更接近一个可以直接继续扩展的研究工具。

2. 结果解释链条比较完整

这次输出的不只是“最终权重”,还有:

  • 标准化数据;
  • 目标函数;
  • 残差;
  • 熵;
  • F 检验;
  • 优化指数;
  • 地区排名。

这意味着我们不是只拿到一个结论,而是可以追溯:

这个结论是怎么来的,它与论文差在哪,为什么可以认为复现成功。

3. 为后续扩展留了接口

当前代码中已经补进了 Bootstrap 相关框架,包括:

  • 抽样函数;
  • 权重与熵的分布统计;
  • 95% 置信区间输出结构。

也就是说,这套程序已经不只是“复现论文最小闭环”,而是在往“完整科研复现模板”靠近。


七、这篇 MEMR 代码最值得关注的细节是什么?

如果从复现者角度看,我觉得有三个细节特别值得注意。

1. 等权模型 RSS 的定义必须和 MEMR 保持一致

代码里专门强调了 rss_equal_weight() 的写法,这是非常关键的。

因为如果 EW 的残差定义和 MEMR 模型不在同一口径下,后面的:

  • ANOVA
  • F-value
  • Optimization Index

都会对不上论文。

这类地方往往不是“大公式错了”,而是细节口径不统一,结果就会偏很多。

2. 使用 softmax 很适合这类权重优化

综合评价模型里,权重优化经常带有“非负 + 和为1”的约束。

如果直接在约束条件下写数值优化,往往比较麻烦。

而 softmax 的好处是,它天然把无约束参数变成合法权重,因此非常适合这类模型。

3. Bootstrap 虽然耗时,但对论文风格结果很重要

当前代码已经支持按论文表结构输出 Bootstrap 统计量。

这件事很重要,因为很多时候:

论文里真正体现“结果稳不稳”的,不只是单次权重,而是权重分布、标准差和区间估计。

如果后续把 1000 次 Bootstrap 稳定跑完,这套复现的完整度会再上一个台阶。


八、复现小结

这次 MEMR 复现最核心的一条主线,可以概括成一句话:

用最大熵保证权重分布不过度偏斜,用最小残差保证综合指标尽量保留原始信息,然后在两者之间找到一个最优平衡。

从 Julia 实现结果来看,目前代码已经可以实现:

  • 数据从文件读取;
  • 模型按论文公式实现;
  • 优化过程稳定;
  • 结果与论文高度一致;
  • 输出结构适合继续交付与扩展。

如果需要,请联系微信canglang12002 任公子