前言:熵权法,也称为熵决法,客观求权重比,在评价类模型中相对比较简单。根据已知评价对象 指标的数值来确定每个指标所占的权重,在相对数据集合中,以算法的形式剔除主观因素,以客观的方式获取到相关权重。
适用场景:(纯个人经验)
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引入
1
2
3
4
5
6
7
8
9
10
11<!-- 集成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,核心类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136import 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,测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import 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版)内容请搜索靠谱客的其他文章。
发表评论 取消回复