利用熵权法进行数值评分计算——代码实现

1、前情回顾

之前的文章,我们详细介绍了熵权法的具体计算过程(不清楚的读者可点击此处的传送门《利用熵权法进行数值评分计算——算法过程》)。本篇文章我们展示熵权法的主要实现代码(Java版本,实际上Python、GoLang等逻辑是相同的,之后会提供GoLang版本的代码)。

2、具体计算过程

本文的介绍将通过以下示例场景进行:

// 指标数量
int pointNumber = 6;
// 行表示每个参与者的数据,列表示每一个评分指标
double points[][] = new double[][] {{0.0 , 0.0 , 1.0 , 0.0 , 0.0 , 4.0},{1.0 , 2.0 , 0.0 , 0.0 , 0.0 , 3.0},{2.0 , 0.0 , 0.0 , 0.0 , 0.0 , 3.0},{1.0 , 0.0 , 1.0 , 0.0 , 2.0 , 4.0},{3.0 , 0.0 , 0.0 , 0.0 , 1.0 , 4.0},{1.0 , 1.0 , 0.0 , 1.0 , 0.0 , 4.0},{0.0 , 1.0 , 1.0 , 1.0 , 1.0 , 5.0}};
// 如果为true,表示是正向指标;反之则是负向指标
boolean forwards[] = new boolean [] {false , false , false , false , false , true};

从以上代码中我们知道了,评分参与者有7人(或者理解成7个品牌的车、7款电视信号,等等)。评分指标一共有6个,其中除了最后第6个指标外,其余指标都是负向指标。

2.1、首先进行数据标准化

/*** 数据标准化,主要是区分正向因子和负向因子,进行数据标准化,以便进行下一步计算* (这里修正了一下,保证结果不可能出现分母为0的情况)* @param points 原始数据数组* @param index 需要进行标准化的原始数据的索引位置* @param forward 是否是正向因子* @return 返回的标准化之后的数值*/
private static double standard(double points[] , int index , boolean forward) {if(index < 0 || index > points.length - 1) {throw new IllegalArgumentException("错误的参数");}double max = new Max().evaluate(points);double min = new Min().evaluate(points);// 正向指标double result = 0.0;if(forward) {result = (points[index] - min + 1) / (max - min + 1);} else {result = (max - points[index] + 1) / (max - min + 1);}return result;
}// 下面开始进行矩阵的标准化
// 数据标准化后的对应矩阵,存储在这里
double standards[][] = new double[points.length][pointNumber];
// 数据标准化,正向因子和负向因子的标准化要求不一样
for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(points, index);for(int matrixIndex = 0 ; matrixIndex < matrixs.length ; matrixIndex++) {double matrixStandard = standard(matrixs, matrixIndex, forwards[index]);standards[matrixIndex][index] = matrixStandard;}
}

请注意以上代码标段中得到的标准化之后的矩阵standards,后续的计算步骤主要就是使用这个standards矩阵进行。另外注意,为了程序员编码过程的方便,我们在进行每个指标数据标准化前,可以对矩阵的一部分进行翻转,代码片段如下:

/*** 矩阵翻转,矩阵翻转的目的,是确保计算方便* @param matrixs 原始数据矩阵(二维矩阵)* @param index 需要翻转的原始矩阵的索引号* @return*/
private static double[] matrixFlipping(double matrixs[][] , int index) {int matrixLen = matrixs.length;double flips[] = new double[matrixLen];for(int lenIndex = 0 ; lenIndex < matrixLen ; lenIndex++) {flips[lenIndex] = matrixs[lenIndex][index];}return flips;
}

数值矩阵的翻转只是为了保证程序员编写代码的便利性,和计算过程没有任何关系。

2.2、求各评分要素的数值比例

接下来,我们用经过数值标准化的矩阵,带入以下代码片段,进行数值比例的计算:

/*** 求数值比例* @param points* @param index 需要求值的原始数据的索引位置* @return */
private static double relatMatrix(double standards[] , int index) {double sum = new Sum().evaluate(standards);double result = standards[index] / sum;return result;
}// 对数值比例的调用执行,如以下代码片段所示
// 比例化后的数据存储在这里
double proportions[][] = new double[standards.length][pointNumber];
for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(standards, index);for(int matrixIndex = 0 ; matrixIndex < matrixs.length ; matrixIndex++) {double matrixStandard = relatMatrix(matrixs, matrixIndex);proportions[matrixIndex][index] = matrixStandard;}
}

请注意以上代码片段中的proportions矩阵,求得的数值比例值就存储在这里,并且后续继续基于此矩阵进行计算。

2.3、求对数

求对数的方法如下代码片段所示:

// 求对数
double lnMatrixs[][] = new double[standards.length][pointNumber];
for(int index = 0 ; index < proportions.length ; index++) {double matrixItems[] = proportions[index];for(int matrixIndex = 0 ; matrixIndex < matrixItems.length ; matrixIndex++) {double lnResult = matrixItems[matrixIndex] * Math.log(matrixItems[matrixIndex]);lnMatrixs[index][matrixIndex] = lnResult;}
}

注意,以上求对数的过程引入了Java原生的求对数计算工具。另外,求得的对数值,被放置在lnMatrixs这个数值矩阵中。

2.4、求每一个评分要素的熵值


/*** 计算某一个数组的熵值* @param matrixs* @return*/
private static double entropyMatrix(double matrixs[]) {double result = (-1 * 1 / Math.log(matrixs.length)) * (new Sum().evaluate(matrixs));return result;
}// 计算熵值的代码如下所示
// 其中n表示参与评分的数据条数
double entropys[] = new double[pointNumber];
for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(lnMatrixs, index);double entropy = entropyMatrix(matrixs);entropys[index] = entropy;
}
// 根据熵求权值
double entropyWeights[] = new double[pointNumber];
for(int index = 0 ; index < pointNumber ; index++) {double weight = relatMatrix(entropys, index);entropyWeights[index] = weight;
}

注意以上代码片段中,除了调用了求每个要素熵值的matrixFlipping方法外,还调用了求数值比例的relatMatrix方法。这是因为熵值也要进行占比计算。

2.5、计算基准得分和使用者能看懂的百分制得分

现在开始计算基准得分,并基于基准得分计算得到百分制得分。

// 基于熵权进行每一个评分参与者的基准得分
double benchScores[] = new double[standards.length];
for(int index = 0 ; index < standards.length ; index++) {double standardItems[] = standards[index];double result = 0d;for(int weightIndex = 0 ; weightIndex < entropyWeights.length ; weightIndex++) {result += standardItems[weightIndex] * entropyWeights[weightIndex];}benchScores[index] = result;
}// 转换成百分数
Double percentageScores[] = new Double[standards.length];
for(int index = 0 ; index < standards.length ; index++) {percentageScores[index] = percentageScores(benchScores, index);
}
System.out.println("percentageScores = " + StringUtils.join(percentageScores, " | "));/*** 转换为100分制* @param benchScores* @param index 要将哪一个基准数转换为100分制* @return*/
private static double percentageScores(double benchScores[] , int index) {int len = benchScores.length;Double maxScore = new Max().evaluate(benchScores);Double maxScaleScore = new BigDecimal(maxScore.toString()).setScale(2, RoundingMode.UP).doubleValue();Double total = (100 * len) / (maxScaleScore * len) * benchScores[index];return new BigDecimal(total.toString()).setScale(2, RoundingMode.HALF_UP).doubleValue();
}

以下是针对最原始评分项,经过熵权法评分后的计算结果:

percentageScores = 98.99 | 84.68 | 92.72 | 81.45 | 87.93 | 87.78 | 82.91

以上计算结果中,第一个参与者的百分制得分是98.99;第二个参与者的百分制得分是84.68;以此类推。

3、总结说明

这里我们给出完整的代码片段,有需要的读者可直接复制粘贴

// 熵权法相关代码——可直接执行
public class EwmTest {public static void main(String[] args) {// 指标数量int pointNumber = 6;// 行表示每个参与者的数据,列表示每一个评分指标double points[][] = new double[][] {{0.0 , 0.0 , 1.0 , 0.0 , 0.0 , 4.0},{1.0 , 2.0 , 0.0 , 0.0 , 0.0 , 3.0},{2.0 , 0.0 , 0.0 , 0.0 , 0.0 , 3.0},{1.0 , 0.0 , 1.0 , 0.0 , 2.0 , 4.0},{3.0 , 0.0 , 0.0 , 0.0 , 1.0 , 4.0},{1.0 , 1.0 , 0.0 , 1.0 , 0.0 , 4.0},{0.0 , 1.0 , 1.0 , 1.0 , 1.0 , 5.0}};// 如果为true,表示是正向指标;反之则是负向指标boolean forwards[] = new boolean [] {false , false , false , false , false , true};// 数据标准化后的对应矩阵,存储在这里double standards[][] = new double[points.length][pointNumber];// 数据标准化,正向因子和负向因子的标准化要求不一样for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(points, index);for(int matrixIndex = 0 ; matrixIndex < matrixs.length ; matrixIndex++) {double matrixStandard = standard(matrixs, matrixIndex, forwards[index]);standards[matrixIndex][index] = matrixStandard;}}// 接着求各列的数值比例,比例化后的数据存储在这里double proportions[][] = new double[standards.length][pointNumber];for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(standards, index);for(int matrixIndex = 0 ; matrixIndex < matrixs.length ; matrixIndex++) {double matrixStandard = relatMatrix(matrixs, matrixIndex);proportions[matrixIndex][index] = matrixStandard;}}// 求对数double lnMatrixs[][] = new double[standards.length][pointNumber];for(int index = 0 ; index < proportions.length ; index++) {double matrixItems[] = proportions[index];for(int matrixIndex = 0 ; matrixIndex < matrixItems.length ; matrixIndex++) {double lnResult = matrixItems[matrixIndex] * Math.log(matrixItems[matrixIndex]);lnMatrixs[index][matrixIndex] = lnResult;}}// 计算熵值,其中n表示参与评分的数据条数double entropys[] = new double[pointNumber];for(int index = 0 ; index < pointNumber ; index++) {double matrixs[] = matrixFlipping(lnMatrixs, index);double entropy = entropyMatrix(matrixs);entropys[index] = entropy;}// 根据熵求权值double entropyWeights[] = new double[pointNumber];for(int index = 0 ; index < pointNumber ; index++) {double weight = relatMatrix(entropys, index);entropyWeights[index] = weight;}// 基于熵权进行每一个评分参与者的基准得分double benchScores[] = new double[standards.length];for(int index = 0 ; index < standards.length ; index++) {double standardItems[] = standards[index];double result = 0d;for(int weightIndex = 0 ; weightIndex < entropyWeights.length ; weightIndex++) {result += standardItems[weightIndex] * entropyWeights[weightIndex];}benchScores[index] = result;}// 转换成百分数Double percentageScores[] = new Double[standards.length];for(int index = 0 ; index < standards.length ; index++) {percentageScores[index] = percentageScores(benchScores, index);}System.out.println("percentageScores = " + StringUtils.join(percentageScores, " | "));}/*** 转换为100分制* @param benchScores* @param index 要将哪一个基准数转换为100分制* @return*/private static double percentageScores(double benchScores[] , int index) {int len = benchScores.length;Double maxScore = new Max().evaluate(benchScores);Double maxScaleScore = new BigDecimal(maxScore.toString()).setScale(2, RoundingMode.UP).doubleValue();Double total = (100 * len) / (maxScaleScore * len) * benchScores[index];return new BigDecimal(total.toString()).setScale(2, RoundingMode.HALF_UP).doubleValue();}/*** 计算某一个数组的熵值* @param matrixs* @return*/private static double entropyMatrix(double matrixs[]) {double result = (-1 * 1 / Math.log(matrixs.length)) * (new Sum().evaluate(matrixs));return result;}/*** 求数值比例比例* @param points* @param index 需要求值的原始数据的索引位置* @return */private static double relatMatrix(double standards[] , int index) {double sum = new Sum().evaluate(standards);double result = standards[index] / sum;return result;}/*** 矩阵翻转,矩阵翻转的目的,是确保计算方便* @param matrixs 原始数据矩阵(二维矩阵)* @param index 需要翻转的原始矩阵的索引号* @return*/private static double[] matrixFlipping(double matrixs[][] , int index) {int matrixLen = matrixs.length;double flips[] = new double[matrixLen];for(int lenIndex = 0 ; lenIndex < matrixLen ; lenIndex++) {flips[lenIndex] = matrixs[lenIndex][index];}return flips;}/*** 数据标准化,主要是区分正向因子和负向因子,进行数据标准化,以便进行下一步计算(这里修正了一下,导致结果不可能为0)* @param points 原始数据数组* @param index 需要进行标准化的原始数据的索引位置* @param forward 是否是正向因子* @return 返回的标准化之后的数值*/private static double standard(double points[] , int index , boolean forward) {if(index < 0 || index > points.length - 1) {throw new IllegalArgumentException("错误的参数");}double max = new Max().evaluate(points);double min = new Min().evaluate(points);// 正向指标double result = 0.0;if(forward) {result = (points[index] - min + 1) / (max - min + 1);} else {result = (max - points[index] + 1) / (max - min + 1);}return result;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147622.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Vivado的.v文件被误分类到Non-module Files中[filemgmt 20-2001] Source scanning failed

报错 所有新创建的Design Sources被分类到Non-module Files中 两条报错 1、[filemgmt 20-2001] Source scanning failed (launch error) while processing fileset “sources_1” due to unrecoverable syntax error or design hierarchy issues. Recovering last known analys…

STM32(十七):I2C通信外设

I2C外设 STM32内部集成了硬件I2C收发电路&#xff08;USART是串口通信的硬件收发电路&#xff09;&#xff0c;可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能&#xff0c;减轻CPU的负担。 支持多主机模型&#xff08;可变多主机&#xff…

python基础(二) 包和import

包的创建 文件创建命令 在 Django 中&#xff0c;python manage.py startapp first_app 这一行命令的作用是创建一个新的应用&#xff08;app&#xff09;&#xff0c;名为 first_app。在 Django 项目中&#xff0c;"app" 是实现某些功能模块的单独部分&#xff0c…

詹妮弗洛佩兹25年发9张专辑3张是关于阿弗莱克的,爱恨情仇之深可见一斑!新专辑已定时间表!

詹妮弗洛佩兹25年共发9张专辑&#xff0c;有3张是关于本阿弗莱克的 内部人爆詹妮弗洛佩兹已定制作与本阿弗莱克的“心碎”专辑时间表 虽然詹妮弗洛佩兹最近的专辑《This Is Me…Now》以失败告终&#xff0c;但她可能已经准备好重返音乐工作室。但这一次&#xff0c;她将推出一…

校园美食地图:Spring Boot实现的探索与分享平台

第1章 绪 论 1.1课题背景 2021年处于信息高速发展的大背景之下。在今天&#xff0c;缺少手机和电脑几乎已经成为不可能的事情&#xff0c;人们生活中已经难以离开手机和电脑。针对增加的成本管理和操作,商家非常有必要建立自己的网上校园周边美食探索及分享平台&#xff0c;这既…

【Java】Java开发全攻略:从环境搭建到高效编程

文章目录 前言&#xff1a;1. JDK组成2. 配置JDK的环境变量3. 选择开发工具3.1 使用文本编辑器 命令行3.2 Java的跨平台原理3.3 IntelliJ IDEA 开发工具3.3.1 IDEA 创建 Java项目的代码结构3.3.2 使用IDEA开发第一个Java程序的步骤3.3.2 IDEA安装AI编程插件3.3.3 IDEA常用快捷…

【CSS in Depth 2 精译_033】5.4 Grid 网格布局的显式网格与隐式网格(中)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

pytorch的动态计算图机制

pytorch的动态计算图机制 一&#xff0c;动态计算图简介 Pytorch的计算图由节点和边组成&#xff0c;节点表示张量或者Function&#xff0c;边表示张量和Function之间的依赖关系。 Pytorch中的计算图是动态图。这里的动态主要有两重含义。 第一层含义是&#xff1a;计算图的…

Swin Transformer—使用平移窗口的分层视觉转换器结构

Swin Transformer解读 论文题目&#xff1a;Swin Transformer: Hierarchical Vision Transformer using Shifted Windows. 官方代码地址&#xff1a;https://github.com/microsoft/Swin-Transformer. 引言与概括 ICCV2021的最佳论文作者是来自微软亚洲研究院。 SwinTransforme…

基础实践:使用JQuery Ajax调用Servlet

前言 本博客介绍最简单的JQuery&#xff08;原生JS的封装库&#xff09;使用Ajax发送请求&#xff0c;并通过对应的servlet响应数据&#xff0c;并在页面显示&#xff0c;并且servlet响应的数据来自MySQL数据库。 实现需求&#xff1a;在前端页面的输入框中输入要注册的用户名&…

依赖库查看工具Dependencies

依赖库查看工具&#xff1a;Dependencies Dependencies 是一款 Windows 平台下的静态分析工具&#xff0c;用来分析可执行文件&#xff08;EXE、DLL 等&#xff09;所依赖的动态链接库&#xff08;DLL&#xff09;。它可以帮助开发者和系统管理员快速查找程序在运行时可能缺少的…

【机器学习】--- 决策树与随机森林

文章目录 决策树与随机森林的改进&#xff1a;全面解析与深度优化目录1. 决策树的基本原理2. 决策树的缺陷及改进方法2.1 剪枝技术2.2 树的深度控制2.3 特征选择的优化 3. 随机森林的基本原理4. 随机森林的缺陷及改进方法4.1 特征重要性改进4.2 树的集成方法优化4.3 随机森林的…

论文浅尝 | KAM-CoT: 利用知识图谱进行知识增强的多模态链式推理(AAAI2024)

笔记整理&#xff1a;沈小力&#xff0c;东南大学硕士&#xff0c;研究方向为多模态大预言模型、知识图谱 论文链接&#xff1a;https://arxiv.org/abs/2401.12863 发表会议&#xff1a;AAAI2024 1. 动机 本文探索了知识图谱在扩展大语言模型的多模态能力的效果&#xff0c;提出…

在jupyter notebook中取消代理服务器的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

使用GPU 加速 Polars:高效解决大规模数据问题

Polars 最近新开发了一个可以支持 GPU 加速计算的执行引擎。这个引擎可以对超过 100GB 的数据进行交互式操作能。本文将详细讨论 Polars 中DF的概念、GPU 加速如何与 Polars DF协同工作&#xff0c;以及使用新的 CUDA 驱动执行引擎可能带来的性能提升。 Polars 核心概念 Polar…

go libreoffice word 转pdf

一、main.go 关键代码 完整代码 package mainimport ("fmt""github.com/jmoiron/sqlx""github.com/tealeg/xlsx""log""os/exec""path/filepath" ) import _ "github.com/go-sql-driver/mysql"import &q…

多态与绑定例题

答案&#xff1a; B D C 知识点&#xff1a; 多态是相同方法不同的表现&#xff0c;分为重写和重载 重写体现在父类与子类不同表现&#xff0c;主要表现为子类重现父类的方法 重载体现在同一个类中的不同表现 绑定分为动态绑定和静态绑定 动态绑定是在运行时 静态绑定是…

java23发布啦

2024年9月java23发布啦&#xff01;&#xff01;! JDK 23 提供了12 项增强功能&#xff0c;这些功能足以保证其自己的JDK 增强提案 - JEP &#xff0c;其中包括 8 项预览功能和 1 项孵化器功能。它们涵盖了对 Java 语言、API、性能和 JDK 中包含的工具的改进。除了 Java 平台上…

《独孤九剑》游戏源码(客户端+服务端+数据库+游戏全套源码)大小2.38G

《独孤九剑》游戏源码&#xff08;客户端服务端数据库游戏全套源码&#xff09;大小2.38G ​ 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【源码】《独孤九剑》游戏源码&#xff08;客户端服务端数据库游戏全套源码&#xff09;大小2.38G 链接: https://pan.baidu.co…

走在时代前沿:让ChatGPT成为你的职场超级助手

在当今快节奏的工作环境中&#xff0c;时间和效率是宝贵的资源。人工智能&#xff08;AI&#xff09;&#xff0c;尤其是自然语言处理技术的进步&#xff0c;为我们提供了强大的工具来优化工作流程。ChatGPT&#xff08;Generative Pre-trained Transformer&#xff09;就是其中…