概述
前言:熵权法,也称为熵决法,客观求权重比,在评价类模型中相对比较简单。根据已知评价对象 指标的数值来确定每个指标所占的权重,在相对数据集合中,以算法的形式剔除主观因素,以客观的方式获取到相关权重。
适用场景:(纯个人经验)
1,每个对象会有几个指标。这几个指标哪个指标所占的权重最大呢?
(指标数相当或相差不大。最好是同类指标在不同源数据下形成的数据集合。)
2,指标数大于2.
一、算法结果展示:
指标1 | 指标1 | 指标1 | 加权平均法 | 熵决法 |
65.00 | 64.71 | 100.00 | 76.57 | 9.360619 |
65.00 | 52.94 | 39.31 | 9.781944 | |
100.00 | 65.00 | 55.00 | 9.781944 | |
65.00 | 100.00 | 55.00 | 9.781944 | |
30.00 | 100.00 | 64.00 | 64.67 | 4.154868 |
64.00 | 100.00 | 54.67 | 9.781944 | |
65.00 | 85.00 | 50.00 | 9.781944 | |
79.79 | 66.00 | 48.60 | 9.781944 | |
40.00 | 99.00 | 46.33 | 9.781944 | |
70.59 | 64.00 | 44.86 | 9.781944 | |
65.00 | 60.00 | 70.00 | 65.00 | 4.11448 |
100.00 | 95.00 | 105.00 | 100.00 | 4.11448 |
二、算法理论
原文链接:https://blog.csdn.net/qq_41686130/article/details/81867400
2.1,数据标准化
假设给定了k个指标,其中。假设对各指标数据标准化后的值为,
那么
2.2,求各指标的信息熵
根据信息论中信息熵的定义,一组数据的信息熵
其中,如果,则定义 。
2.3,确定各指标权重
根据信息熵的计算公式,计算出各个指标的信息熵为 。通过信息熵计算各指标的权重:
2.4,指标缺失(为0)或为负问题
可以使用数据平移法,即所有指标都加上一个平移值x,再参与计算,平移值x不管大小,计算结果一样。
三、java代码
3.1,pom引入
<!-- 集成hutool工具类简便操作 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
3.2,核心类:
import java.util.ArrayList;
import java.util.List;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
public class ShangFactory {
private List<List<Double>> readyList;
private Integer maxNum = 0; // 最大位数
private Double pvg = 100.0; // 平移数值
public ShangFactory(List<List<Double>> dataList) {
getMaxNum(dataList);
readyList = new ArrayList<List<Double>>();
tranData(dataList);
}
public List<Double> listWeight() {
System.err.println("平移标准化:" + readyList);
// 完成数据标准化
List<List<Double>> aveList = orderData(readyList);
System.err.println("数据标准化:" + aveList);
List<Double> shangList = listShang(readyList, aveList);
// 获取信息熵
System.err.println("信息熵:" + shangList);
List<Double> weightList = makeWeight(shangList);
return weightList;
}
// 获取最大位数和平移均值
private void getMaxNum(List<List<Double>> dataList) {
for (List<Double> list : dataList) {
if (list.size() > maxNum) {
maxNum = list.size();
}
double ws = 0.0;
for (Double w : list) {
if (w<pvg) {
pvg=w;
}
ws = ws + w;
}
pvg = pvg + (ws / list.size());
}
pvg = pvg / dataList.size();
}
/**
* 用平移法,补全缺位数据
*
* @param dataList
* @return
*/
private void tranData(List<List<Double>> dataList) {
List<Double> dataNumList;
for (List<Double> list : dataList) {
dataNumList = new ArrayList<Double>();
for (Double weight : list) {
dataNumList.add(weight + pvg);
}
// 补全
for (int i = 0; i < maxNum - list.size(); i++) {
dataNumList.add(pvg);
}
readyList.add(dataNumList);
}
}
/**
* 2.1,数据标准化
* @param dataList
* @return
*/
private List<List<Double>> orderData(List<List<Double>> dataList) {
List<List<Double>> aveList = new ArrayList<List<Double>>();
// 数据归一化处理 (i-min)/(max-min)
List<Double> numList;
List<Double> dataNumList;
double min, diff, temp;
for (int i = 0; i < dataList.size(); i++) {
numList = dataList.get(i);
min = (double) CollUtil.min(numList);
diff = CollUtil.max(numList) - min;
dataNumList = new ArrayList<Double>();
for (int j = 0; j < numList.size(); j++) {
temp = ((double) numList.get(j) - min) / diff;
dataNumList.add(j, temp);
}
aveList.add(dataNumList);
}
return aveList;
}
/**
* 2.2,求各指标的信息熵
* @param dataList
* @param aveList
* @return
*/
private List<Double> listShang(List<List<Double>> dataList, List<List<Double>> aveList) {
List<Double> shangList = new ArrayList<Double>();
for (int i = 0; i < aveList.size(); i++) {
List<Double> aveNumList = aveList.get(i);
double pSum = (double) aveNumList.stream().reduce((x, y) -> (double) x + (double) y).get();
double sum = 0;
for (int j = 0; j < aveList.get(i).size(); j++) {
double p = (double) aveNumList.get(j) / pSum;
if (p != 0) {
sum = sum + p * Math.log(p);
}
}
shangList.add((-1) / Math.log(dataList.get(i).size()) * sum);
}
return shangList;
}
/**
* 2.3,确定各指标权重
* @param shangList
* @return
*/
private static List<Double> makeWeight(List<Double> shangList) {
List<Double> weightList = new ArrayList<Double>();
Double shangSum = shangList.stream().reduce(Double::sum).get();
double weight;
for (int i = 0; i < shangList.size(); i++) {
weight = (1 - shangList.get(i)) / (shangList.size() - shangSum);
weight = weight * 100.0;
// BigDecimal weightDec = NumberUtil.round(weight, 6);
weightList.add(NumberUtil.round(weight, 6).doubleValue());
}
return weightList;
}
}
3.3,测试类
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import cn.hutool.core.util.NumberUtil;
public class ShangTest {
public static void main(String[] args) {
List<List<Double>> dataList = readyData();
ShangFactory shangFactory=new ShangFactory(dataList);
List<Double> weightList = shangFactory.listWeight();
// 获取权重
System.err.println("权重:" + weightList);
for (Double double1 : weightList) {
System.out.println(double1);
}
}
private static List<List<Double>> readyData() {
String dataStr = "[100.0, 83.33, 75.0], [83.33, 72.86, 70.0], [85.0, 66.0, 64.53, 5.0], [99.0, 55.0, 40.0, 17.17], [75.0, 65.53, 52.18], [70.0, 64.53, 33.0, 23.19], [75.0, 70.53, 28.99], [85.0, 83.33], [75.0, 64.53, 28.13], [75.0, 66.53], [75.0, 57.97], [83.33, 25.0], [100.0], [64.53, 34.38], [66.67, 31.25], [66.67, 25.0], [85.71], [83.33], [83.33], [83.33], [75.0], [75.0], [75.0], [75.0], [71.43], [65.53], [65.53], [64.53], [34.38]";
List<List<Double>> dataList = new ArrayList<List<Double>>();
List<String> list = Arrays.asList(dataStr.split("],"));
List<Double> dataNumList;
for (String string : list) {
string = string.replace("[", "");
string = string.replace("]", "");
dataNumList = new ArrayList<Double>();
List<String> numList = Arrays.asList(string.split(","));
for (String numStr : numList) {
dataNumList.add(NumberUtil.parseNumber(numStr.trim()).doubleValue());
}
dataList.add(dataNumList);
}
return dataList;
}
}
测试类中数据集是根据生产环境打印出来,也可以使用excle中导入,方便测试。
最后总结:因场景选择错误,此方法是一个失败案例。但是此方法相当不错。
最后
以上就是俏皮手链为你收集整理的熵权法计算权重(java版)的全部内容,希望文章能够帮你解决熵权法计算权重(java版)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复