占比越多权重越低 怎么计算(权重占比计算公式)
前言:熵权法,也称为熵决法,客观求权重比,在评价类模型中相对比较简单。根据已知评价对象 指标的数值来确定每个指标所占的权重,在相对数据集合中,以算法的形式剔除主观因素,以客观的方式获取到相关权重。
适用场景:(纯个人经验)
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中导入,方便测试。
最后总结:因场景选择错误,此方法是一个失败案例。但是此方法相当不错。
如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。