TOPSIS算法实战:用Python给河流水质排个名,附完整代码与避坑指南
TOPSIS算法实战用Python给河流水质排个名附完整代码与避坑指南当环保部门拿到一份包含含氧量、PH值、细菌数、水草量等指标的河流水质数据时如何科学评估各条河流的健康状况传统的主观评分方法往往存在偏差而TOPSIS算法提供了一种客观量化的解决方案。本文将手把手带你用Python实现这一过程特别针对PH值等特殊指标的处理给出详细避坑指南。1. 理解TOPSIS算法的核心思想TOPSISTechnique for Order Preference by Similarity to Ideal Solution是一种多准则决策分析方法。它的核心思想很直观理想解假设存在一个所有指标都达到最优值的虚拟方案负理想解假设存在一个所有指标都是最差值的虚拟方案评分原理评估每个实际方案与这两个极端方案的距离距离理想解越近且距离负理想解越远的方案得分越高具体到河流水质评估场景# 伪代码示意 def topsis_score(data): ideal [max(含氧量), 7, min(细菌数), 介于500-1000的水草量] worst [min(含氧量), 偏离7最远的值, max(细菌数), 偏离500-1000最远的水草量] # 计算每个河流与理想解和负理想解的距离 dist_to_ideal 计算距离(河流数据, ideal) dist_to_worst 计算距离(河流数据, worst) return dist_to_worst / (dist_to_ideal dist_to_worst)2. 数据准备与指标类型分析假设我们有以下河流水质数据示例河流含氧量(%)PH值细菌数(个/ml)水草量(株)A河856.81200480B河927.2800750C河787.01500620指标类型分析极大型指标含氧量越大越好中间型指标PH值越接近7越好极小型指标细菌数越小越好区间型指标水草量500-1000为最佳注意在实际应用中指标类型的判断直接影响后续的正向化处理这是最容易出错的第一步。3. 数据正向化处理实战不同类型指标需要不同的正向化方法3.1 极大型指标处理含氧量原始数据已经是极大型无需处理oxygen df[含氧量].values3.2 中间型指标处理PH值PH值的最优值为7使用中间型转换公式def mid_to_max(x, best): m np.max(np.abs(x - best)) return 1 - np.abs(x - best)/m ph df[PH值].values ph_score mid_to_max(ph, best7)3.3 极小型指标处理细菌数使用取反法转换def min_to_max(x): return np.max(x) - x bacteria df[细菌数].values bacteria_score min_to_max(bacteria)3.4 区间型指标处理水草量最佳区间为[500,1000]def interval_to_max(x, a, b): m max(a - np.min(x), np.max(x) - b) score np.zeros_like(x) for i in range(len(x)): if x[i] a: score[i] 1 - (a - x[i])/m elif x[i] b: score[i] 1 - (x[i] - b)/m else: score[i] 1 return score plants df[水草量].values plants_score interval_to_max(plants, 500, 1000)避坑提示区间型指标的正向化最容易出错特别是当数据超出区间范围时的处理逻辑。4. 数据标准化与权重分配4.1 标准化处理消除量纲影响使用向量归一化def normalize(data): return data / np.sqrt(np.sum(data**2)) # 合并所有正向化后的指标 all_scores np.vstack([oxygen, ph_score, bacteria_score, plants_score]).T normalized normalize(all_scores)4.2 权重分配方法可以使用熵权法自动计算权重也可以根据专家经验手动分配。这里展示熵权法实现def entropy_weight(data): p data / np.sum(data, axis0) entropy -np.sum(p * np.log(p 1e-10), axis0) / np.log(len(data)) return (1 - entropy) / np.sum(1 - entropy) weights entropy_weight(normalized)5. TOPSIS核心计算与结果分析5.1 计算理想解与负理想解# 加权后的数据 weighted normalized * weights # 理想解各指标最大值 ideal np.max(weighted, axis0) # 负理想解各指标最小值 worst np.min(weighted, axis0)5.2 计算距离与得分# 欧式距离计算 dist_ideal np.sqrt(np.sum((weighted - ideal)**2, axis1)) dist_worst np.sqrt(np.sum((weighted - worst)**2, axis1)) # 综合得分 score dist_worst / (dist_ideal dist_worst)5.3 结果展示将结果添加到原始数据中df[TOPSIS得分] score df[排名] df[TOPSIS得分].rank(ascendingFalse) print(df.sort_values(排名))典型输出结果示例河流含氧量PH值细菌数水草量TOPSIS得分排名B河927.28007500.6821C河787.015006200.5212A河856.812004800.49736. 完整代码实现与优化建议以下是整合后的完整Python实现基于pandas和numpyimport numpy as np import pandas as pd def topsis_evaluation(df): # 正向化处理 oxygen df[含氧量].values ph df[PH值].values ph_score 1 - np.abs(ph - 7) / np.max(np.abs(ph - 7)) bacteria df[细菌数].values bacteria_score np.max(bacteria) - bacteria plants df[水草量].values a, b 500, 1000 m max(a - np.min(plants), np.max(plants) - b) plants_score np.where(plants a, 1 - (a - plants)/m, np.where(plants b, 1 - (plants - b)/m, 1)) # 标准化 scores np.vstack([oxygen, ph_score, bacteria_score, plants_score]).T normalized scores / np.sqrt(np.sum(scores**2, axis0)) # 熵权法计算权重 p normalized / np.sum(normalized, axis0) entropy -np.sum(p * np.log(p 1e-10), axis0) / np.log(len(normalized)) weights (1 - entropy) / np.sum(1 - entropy) # 加权标准化矩阵 weighted normalized * weights # 理想解与负理想解 ideal np.max(weighted, axis0) worst np.min(weighted, axis0) # 距离计算 dist_ideal np.sqrt(np.sum((weighted - ideal)**2, axis1)) dist_worst np.sqrt(np.sum((weighted - worst)**2, axis1)) # 综合得分 score dist_worst / (dist_ideal dist_worst) # 结果处理 result df.copy() result[TOPSIS得分] score result[排名] result[TOPSIS得分].rank(ascendingFalse) return result.sort_values(排名) # 使用示例 data { 河流: [A河, B河, C河], 含氧量: [85, 92, 78], PH值: [6.8, 7.2, 7.0], 细菌数: [1200, 800, 1500], 水草量: [480, 750, 620] } df pd.DataFrame(data) result topsis_evaluation(df) print(result)优化建议对于大型数据集可以使用numba加速距离计算添加数据有效性检查确保输入数据没有缺失值考虑实现可视化功能直观展示各河流得分情况可以扩展支持自定义权重而不仅限于熵权法7. 常见问题与解决方案在实际应用中我们可能会遇到以下典型问题问题1PH值正好为7时得分不是最高解决方案检查中间型指标的正向化公式实现确保最优值确实映射到最高分1。问题2所有河流得分非常接近难以区分优劣可能原因指标权重分配不合理或者数据本身区分度不大。解决方案重新考虑权重分配方法增加更多评价指标检查数据是否存在异常值问题3区间型指标边界值处理异常示例场景当水草量正好等于500或1000时得分异常。解决方案在区间边界条件判断时使用闭区间plants_score np.where(plants a, 1 - (a - plants)/m, np.where(plants b, 1 - (plants - b)/m, 1))问题4熵权法给出的权重不符合实际认知示例可能计算出细菌数的权重远高于其他指标。解决方案检查数据标准化是否正确考虑使用层次分析法等主观赋权法替代可以设置权重上下限在实际项目中TOPSIS算法往往需要与其他方法结合使用。例如可以先使用熵权法计算客观权重再结合专家打分确定最终权重这样既能反映数据特性又能融入领域知识。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2462625.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!