熵权法计算权重(java版)
前言:熵權法,也稱為熵決法,客觀求權重比,在評價類模型中相對比較簡單。根據已知評價對象 指標的數值來確定每個指標所占的權重,在相對數據集合中,以算法的形式剔除主觀因素,以客觀的方式獲取到相關權重。
適用場景:(純個人經驗)
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版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vector_capl
- 下一篇: ORA-00257