ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

多准则决策分析:从ANP网络分析到TOPSIS排序的建模实践

2026/8/28 20:58:54 拓冰建站 浏览量
多准则决策分析:从ANP网络分析到TOPSIS排序的建模实践 1. 问题拆解与建模思路从“多目标”到“可计算”去年带队做美赛ICM的D题题目是关于联合国可持续发展目标SDGs的优先级排序。这题乍一看很“文科”一堆描述性指标但内核是个典型的多准则决策分析问题。很多队伍一上来就懵要么陷入对17个目标庞杂文本的纠结要么试图找一个“万能公式”硬套。我的思路是先把“优先级”这个模糊概念拆解成几个可以量化的维度。优先级排序本质上是在资源有限、目标间存在复杂关联协同与权衡的约束下寻找一个最优的资源配置或行动序列。所以我们的模型至少要回答三个问题紧迫性哪些目标不立刻解决后果最严重或不可逆影响力推动哪些目标能对其他目标产生最大的正向带动效应杠杆效应可行性以当前或可预见的技术、经济、政治条件哪些目标更容易实现基于这个框架我设计了一个三阶段的混合模型。第一阶段用网络分析法来量化目标间的相互影响关系找出核心枢纽目标。第二阶段结合TOPSIS法引入外部数据如各国发展指数、环境绩效指数等来评估每个目标的紧迫性与基础条件。第三阶段用一个简单的优化模型模拟在资源约束下如何分阶段投入以实现整体效益最大化。整个流程用Python实现从数据爬取、处理、建模到可视化形成闭环。这里的关键在于不要幻想用一个模型解决所有问题。ANP网络分析法擅长处理元素间相互依赖的关系正好用来刻画SDGs之间“牵一发而动全身”的特性。而TOPSIS优劣解距离法则适合在多指标下对方案即SDGs进行排序。两者结合一个看“内在关联”一个看“外在表现”相互校验结论会更稳健。注意美赛ICM题往往没有标准答案评委看重的是建模过程的逻辑性、假设的合理性以及结论的洞察力。清晰阐述你的模型如何对应现实世界的决策逻辑比追求复杂的数学公式更重要。2. 数据基石寻找与构造量化指标没有数据再漂亮的模型也是空中楼阁。SDGs本身有大量的定性描述我们的首要任务就是将其转化为可计算的指标。官方渠道如UN Stats, World Bank, WHO是首选但直接对应17个目标169个具体目标的完美数据集并不存在需要我们自己动手丰衣足食。我们的策略是“代表性指标”法。为每个SDG选取2-3个最具代表性、数据可获得性高的子指标。例如SDG 1无贫困选用“日均生活费用低于1.9美元的人口比例”、“社会保障覆盖率”。SDG 3良好健康与福祉选用“五岁以下儿童死亡率”、“每千人医生数”。SDG 7经济适用的清洁能源选用“可再生能源消费占比”、“通电人口比例”。SDG 13气候行动选用“人均二氧化碳排放量”、“气候变化应对准备指数”。数据来源方面我们主要利用了世界银行的World Development Indicators (WDI)数据库和联合国开发计划署的人类发展报告数据。使用Python的pandas-datareader或wbdata库可以方便地批量获取。对于缺失值我们采用了时间序列插值向前/向后填充和基于相似国家的均值填充法并在论文中明确说明了处理方法及其潜在影响。更重要的是数据标准化。不同指标量纲和极性有的越大越好有的越小越好不同必须统一。我们采用了极差标准化法。对于效益型指标越大越好(x - min) / (max - min)对于成本型指标越小越好(max - x) / (max - min)。这样所有指标值都落在了[0, 1]区间且都是越大越优。import pandas as pd import numpy as np # 假设df是一个DataFrame行是国家/年份列是各个指标 def normalize_data(df, benefit_columns, cost_columns): 标准化数据 :param df: 原始数据DataFrame :param benefit_columns: 效益型指标列名列表 :param cost_columns: 成本型指标列名列表 :return: 标准化后的DataFrame df_normalized df.copy() for col in benefit_columns: if col in df.columns: min_val df[col].min() max_val df[col].max() if max_val ! min_val: df_normalized[col] (df[col] - min_val) / (max_val - min_val) else: df_normalized[col] 0.5 # 处理常数列 for col in cost_columns: if col in df.columns: min_val df[col].min() max_val df[col].max() if max_val ! min_val: df_normalized[col] (max_val - df[col]) / (max_val - min_val) else: df_normalized[col] 0.5 return df_normalized # 示例假设我们有几个指标 # benefit_cols [Renewable_energy_%, Physicians_per_1000] # cost_cols [Child_mortality_rate, CO2_emissions_per_capita] # df_normalized normalize_data(df, benefit_cols, cost_cols)这一步是后续所有分析的基础务必细致。在论文中我们用一个表格清晰列出了每个SDG对应的量化指标、数据来源和处理方法这能极大增强模型的可信度。3. 核心模型一基于网络分析法的关联影响评估SDGs不是一个简单的清单它们之间存在着复杂的相互作用。例如提升教育水平SDG 4会促进性别平等SDG 5也会减少贫困SDG 1。这种网络化的相互依赖关系正是ANP网络分析法的用武之地。我们用它来构建SDGs的影响关系网络并计算每个目标的“中心度”从而识别出哪些目标是撬动整个系统的关键支点。第一步构建直接影响矩阵。我们通过专家问卷模拟和文献综述相结合的方式来判定SDG i对SDG j的影响程度。采用1-9标度法1表示影响极其微弱9表示影响极其强烈。这是一个17x17的矩阵。这里的一个技巧是我们要求判断必须是“非对称”的即A对B的影响程度与B对A的影响程度分别判断。这能更好地捕捉现实中的单向或强弱不对称影响。第二步计算综合影响矩阵。直接影响矩阵只反映了一步影响。在系统中影响会通过其他目标间接传递。我们需要计算综合影响矩阵T X X^2 X^3 ...其中X是标准化后的直接影响矩阵。数学上这等价于求T X * (I - X)^(-1)其中I是单位矩阵。这个矩阵T中的元素t_ij就表示目标i对目标j的直接和间接影响的总和。第三步计算中心度指标。对综合影响矩阵T的行和与列和进行分析影响度D_i sum(t_ij for j in 1...n)。表示目标i对所有其他目标的综合影响程度。值越大说明该目标越像“驱动者”。被影响度R_j sum(t_ij for i in 1...n)。表示目标j受到所有其他目标的综合影响程度。值越大说明该目标越像“结果”。中心度C_i D_i R_i。这是一个非常重要的指标它综合反映了目标i在网络中的活跃程度和重要性。高中心度的目标通常是系统干预的优先候选。import numpy as np import pandas as pd def anp_analysis(direct_influence_matrix): 执行ANP分析计算影响度、被影响度和中心度 :param direct_influence_matrix: 直接影响矩阵numpy array, shape (n, n) :return: 包含各指标结果的DataFrame X direct_influence_matrix.astype(float) n X.shape[0] # 1. 标准化直接影响矩阵行和归一化 row_sums X.sum(axis1, keepdimsTrue) X_norm X / row_sums # 处理全零行 X_norm np.where(np.isnan(X_norm), 0, X_norm) # 2. 计算综合影响矩阵 T X_norm * (I - X_norm)^(-1) I np.eye(n) try: # 使用伪逆增加数值稳定性 T np.linalg.lstsq((I - X_norm), X_norm, rcondNone)[0] # 或者使用求逆但前提是矩阵可逆 # T np.dot(X_norm, np.linalg.inv(I - X_norm)) except np.linalg.LinAlgError: print(矩阵(I - X_norm)可能奇异使用伪逆或添加小扰动) # 添加一个小扰动项确保可逆 T np.dot(X_norm, np.linalg.pinv(I - X_norm 1e-10 * np.eye(n))) # 3. 计算影响度(D)、被影响度(R)和中心度(C) D T.sum(axis1) # 行和 R T.sum(axis0) # 列和 C D R # 4. 整理结果 sdg_labels [fSDG {i1} for i in range(n)] results_df pd.DataFrame({ SDG: sdg_labels, Influence_Degree (D): D, Dependence_Degree (R): R, Centrality (C): C }).sort_values(byCentrality (C), ascendingFalse) return results_df, T # 示例假设我们有一个17x17的直接影响矩阵这里用随机矩阵代替 np.random.seed(42) n_sdgs 17 # 生成一个随机矩阵模拟直接影响关系 direct_matrix np.random.randint(0, 5, size(n_sdgs, n_sdgs)).astype(float) # 将对角线设为0自己对自己无直接影响 np.fill_diagonal(direct_matrix, 0) anp_results, total_influence_matrix anp_analysis(direct_matrix) print(anp_results.head())在我们的分析中SDG 4优质教育、SDG 8体面工作和经济增长、SDG 9产业、创新和基础设施通常表现出很高的中心度。这意味着它们是高度互联的枢纽对这些目标的投资会产生广泛的涟漪效应。这个结论与许多国际研究机构的报告是吻合的为我们的优先级排序提供了坚实的“网络关系”依据。4. 核心模型二基于TOPSIS的综合绩效排序ANP给了我们“内在关联”视角的优先级但它高度依赖于我们构建的影响矩阵的主观判断。为了增加客观性并与现实世界的数据接轨我们引入TOPSIS法。TOPSIS的核心思想很直观优先方案应该离理想解最近离负理想解最远。我们将每个SDG视为一个“方案”用第二阶段收集和标准化的指标数据作为其“属性”。第一步构建加权规范化决策矩阵。我们已经有了标准化后的数据矩阵Vm个国家/地区 * n个指标。现在需要确定每个指标的权重。我们采用了熵权法这是一种客观赋权法根据指标数据的离散程度来确定权重。信息熵越小指标的变异程度越大提供的信息量越多权重也就越大。这避免了主观随意性。第二步确定理想解与负理想解。理想解 A由所有指标在所有方案中的最大值构成。负理想解 A-由所有指标在所有方案中的最小值构成。 因为我们已经标准化且统一为效益型所以理想解就是每个指标列的最大值组成的向量负理想解就是每个指标列的最小值组成的向量。第三步计算距离与贴近度。计算每个SDG在数据上体现为每个国家在该SDG指标上的综合表现我们可以先对国家层面求平均得到一个全球层面的SDG表现向量到理想解和负理想解的欧氏距离D和D-。最后计算贴近度C_i D- / (D D-)。C_i 值介于0和1之间越接近1说明该SDG的综合表现越接近理想状态即基础越好或进展越顺利反之越接近0则说明该SDG距离理想状态越远可能更紧迫或更落后。def entropy_weight(data): 计算指标的熵权 :param data: 标准化后的数据矩阵numpy array, shape (m个样本, n个指标) :return: 权重向量, shape (n,) # 防止log(0) data np.where(data 0, 1e-10, data) # 计算比重 p data / data.sum(axis0, keepdimsTrue) # 计算信息熵 k 1 / np.log(data.shape[0]) e -k * (p * np.log(p)).sum(axis0) # 计算差异系数 d 1 - e # 计算权重 w d / d.sum() return w def topsis(decision_matrix, weightsNone, benefit_attributesNone): 执行TOPSIS评估 :param decision_matrix: 决策矩阵numpy array, shape (m个方案, n个指标) :param weights: 权重向量如果为None则使用熵权法计算 :param benefit_attributes: 效益型指标索引列表如果为None则默认全为效益型 :return: 贴近度得分和排序 m, n decision_matrix.shape if benefit_attributes is None: benefit_attributes list(range(n)) # 1. 数据标准化 (这里假设输入已经是标准化后的效益型数据) # 如果输入是原始数据需要先进行标准化处理如第2部分所述 norm_matrix decision_matrix.copy() # 2. 确定权重 if weights is None: weights entropy_weight(norm_matrix) else: weights np.array(weights) if len(weights) ! n: raise ValueError(权重向量长度与指标数不符) # 3. 构建加权规范化矩阵 weighted_matrix norm_matrix * weights # 4. 确定理想解和负理想解 ideal_best weighted_matrix.max(axis0) ideal_worst weighted_matrix.min(axis0) # 5. 计算距离 # 到理想解的距离 dist_best np.sqrt(((weighted_matrix - ideal_best) ** 2).sum(axis1)) # 到负理想解的距离 dist_worst np.sqrt(((weighted_matrix - ideal_worst) ** 2).sum(axis1)) # 6. 计算贴近度 closeness dist_worst / (dist_best dist_worst 1e-10) # 加一个小数防止除零 return closeness, dist_best, dist_worst, weights # 示例假设我们有17个SDG每个SDG用3个标准化后的指标表示 np.random.seed(123) n_sdgs 17 n_indicators 3 # 生成模拟的标准化数据值在0-1之间 simulated_data np.random.rand(n_sdgs, n_indicators) # 使用TOPSIS计算 closeness_scores, d_plus, d_minus, calculated_weights topsis(simulated_data) sdg_list [fSDG {i1} for i in range(n_sdgs)] topsis_results pd.DataFrame({ SDG: sdg_list, Closeness Score: closeness_scores, Distance to Ideal (D): d_plus, Distance to Worst (D-): d_minus }).sort_values(byCloseness Score, ascendingFalse) print(指标权重:, calculated_weights) print(topsis_results.head())TOPSIS的结果往往显示像SDG 1无贫困、SDG 2零饥饿、SDG 6清洁饮水和卫生设施这类基础生存需求目标其贴近度得分较低即距离理想解远表明在全球范围内这些目标的实现情况相对滞后紧迫性更高。这与ANP得出的“枢纽目标”形成了有趣的对比一个指向“杠杆点”一个指向“短板”。5. 模型融合与动态优先级决策现在我们手上有两份排序清单一份来自ANP的“中心度”排序代表影响力/杠杆效应一份来自TOPSIS的“贴近度”排序代表紧迫性/现状差距。直接平均太粗糙了。我们引入一个动态加权融合模型并在此基础上构建一个简单的资源分配优化模型让优先级服务于决策。第一步构建综合优先级指数。我们定义综合优先级指数P_i α * (1 - C_i_topsis) β * C_i_anp。(1 - C_i_topsis)TOPSIS贴近度的补数。C_i_topsis越小表现越差这个值越大代表紧迫性越高。C_i_anpANP的中心度。值越大代表影响力/杠杆效应越强。α和β是权重满足α β 1。它们反映了决策者更看重“弥补短板”还是“发挥杠杆”。我们可以进行敏感性分析展示不同权重下优先级的变化这本身就是论文的一个亮点。第二步基于优先级的资源分配模拟。假设我们有一个总预算B投入到每个SDG i 都能产生一定的“效益”这个效益与我们的综合优先级指数P_i正相关同时也遵循边际效益递减规律例如可以用对数函数模拟。我们建立一个简单的优化问题 最大化总效益Σ( k * ln(1 r_i * x_i) )其中x_i是分配给目标i的资源r_i是该目标的“效益转化系数”可以与P_i挂钩k是缩放常数约束条件是Σ x_i B且x_i 0。这个模型可以用Python的scipy.optimize库快速求解。通过改变总预算B和权重α, β我们可以生成不同的资源分配方案从而为“优先级”这个概念提供动态的、基于场景的解读。import numpy as np from scipy.optimize import minimize def allocate_resources(priority_scores, total_budget, efficiency_coefsNone): 基于优先级分数进行资源分配优化简化模型 :param priority_scores: 综合优先级指数越高越优先 :param total_budget: 总预算 :param efficiency_coefs: 各目标的效益转化系数如果为None则用priority_scores替代 :return: 最优资源分配方案 n len(priority_scores) if efficiency_coefs is None: efficiency_coefs priority_scores # 简化假设优先级越高资金使用效率也越高 # 定义目标函数最大化总效益假设效益函数为对数形式体现边际递减 def objective(x): # x是分配的资源数组 # 总效益 sum( efficiency_coef * log(1 resource) ) # 加1是为了防止log(0) total_benefit -np.sum(efficiency_coefs * np.log(1 x)) # 取负因为minimize求最小值 return total_benefit # 初始猜测按优先级比例分配 x0 total_budget * priority_scores / priority_scores.sum() # 约束条件总资源不超过预算且每个项目资源非负 constraints ( {type: ineq, fun: lambda x: total_budget - np.sum(x)}, # sum(x) B ) bounds [(0, total_budget) for _ in range(n)] # 每个x_i 0 # 优化求解 result minimize(objective, x0, methodSLSQP, boundsbounds, constraintsconstraints) if result.success: optimal_allocation result.x # 由于数值计算可能和极小我们将其归零 optimal_allocation[optimal_allocation 1e-3] 0 # 重新归一化确保总和等于预算处理数值误差 optimal_allocation optimal_allocation / optimal_allocation.sum() * total_budget return optimal_allocation else: print(优化失败:, result.message) return x0 # 返回初始分配作为后备 # 示例假设我们得到了17个SDG的综合优先级指数 np.random.seed(2023) comprehensive_priority np.random.rand(17) comprehensive_priority comprehensive_priority / comprehensive_priority.sum() * 10 # 放大一些 total_budget 1000 # 总预算1000个单位 optimal_resources allocate_resources(comprehensive_priority, total_budget) allocation_result pd.DataFrame({ SDG: [fSDG {i1} for i in range(17)], Priority Score: comprehensive_priority, Optimal Allocation: optimal_resources }).sort_values(byOptimal Allocation, ascendingFalse) print(allocation_result.head(10))通过这个融合与优化过程我们最终输出的不再是一个简单的排名而是一套决策支持工具。我们可以告诉决策者“如果你更关注解决最紧迫的问题α高那么资源应倾斜于SDG 1, 2, 6如果你更关注投资的长期杠杆效应β高那么应聚焦SDG 4, 8, 9。这是在不同预算水平下的最优分配方案。” 这种动态的、可交互的结论远比一个静态的排行榜更有价值。6. 可视化呈现与论文写作要点建模和编程完成只算成功了一半如何清晰、有力地在25页的论文里呈现出来是另一半挑战。可视化是关键。第一关系网络图。使用networkx和matplotlib或plotly绘制SDGs之间的影响关系网络。节点大小代表中心度颜色代表TOPSIS贴近度用渐变色。边的大小和颜色代表影响强度。这样一张图可以直观展示哪些目标是核心枢纽大节点哪些目标现状堪忧暖色/冷色取决于配色方案。确保图例清晰并在文中对关键节点进行解读。第二优先级雷达图/条形图对比。将ANP中心度、TOPSIS贴近度或1-贴近度、综合优先级指数放在一起比较。可以使用分组条形图让评委一眼看出不同方法排序的异同。雷达图则可以展示某个特定SDG在各个评估维度上的表现。第三敏感性分析热图。展示当权重α和β在0到1之间变化时前5名优先SDG是如何变化的。可以用热图表示X轴是αY轴是排名颜色代表不同的SDG。这能强力证明你的模型是稳健的并且能容纳不同的政策偏好。论文写作上务必注意假设驱动每一个建模选择如为什么用1-9标度、为什么用熵权法都要有合理论述引用相关管理科学或决策理论。模型检验对ANP矩阵进行一致性检验虽然我们模拟数据但要提这个步骤对TOPSIS结果进行鲁棒性分析比如随机扰动指标权重看排名是否稳定。讨论与拓展明确指出模型的局限性如数据质量、主观判断的影响、未考虑的地域差异并提出改进方向如引入模糊理论处理不确定性、分地区建模等。这体现了批判性思维。摘要要精炼用最后写摘要。用三四句话概括问题、方法、核心模型、关键发现和建议。避免在摘要里出现公式和代码。整个代码框架应模块化包含数据获取、清洗、ANP分析、TOPSIS分析、模型融合、优化求解和可视化等多个.py文件或Jupyter Notebook单元。注释要详尽确保评委或任何读者能跟随你的代码逻辑。最终你的论文和代码共同讲述了一个完整、严谨、有洞察力的故事我们如何用一个可计算的框架去逼近“可持续发展目标优先级”这个复杂的决策问题。