龙空技术网

熵权法计算权重(java版)

冬山兄 87

前言:

而今同学们对“权重算法”大体比较关切,同学们都需要分析一些“权重算法”的相关文章。那么小编在网上汇集了一些有关“权重算法””的相关文章,希望兄弟们能喜欢,姐妹们快快来了解一下吧!

前言:熵权法,也称为熵决法,客观求权重比,在评价类模型中相对比较简单。根据已知评价对象 指标的数值来确定每个指标所占的权重,在相对数据集合中,以算法的形式剔除主观因素,以客观的方式获取到相关权重。

适用场景:(纯个人经验)

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

二、算法理论

原文链接:

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中导入,方便测试。

最后总结:因场景选择错误,此方法是一个失败案例。但是此方法相当不错。

标签: #权重算法