我是靠谱客的博主 俏皮手链,最近开发中收集的这篇文章主要介绍熵权法计算权重(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版)的全部内容,希望文章能够帮你解决熵权法计算权重(java版)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部