说明:对含年份、城市、指标的面板数据使用熵值法为各指标进行客观赋权,从而得出各城市的综合得分。本文对基于面板数据的熵值法公式做出解释并给出MATLAB代码实现。


公式理解1

  • Step1:指标选取。设有 r r r个年份, n n n个城市, m m m个指标,则 X θ i j \mathrm{X}_{θij} Xθij表示第 θ θ θ年,第 i i i个地级市,第 j j j个指标的值。

  • Step2:指标标准化处理。由于不同的指标具有不同的量纲和单位,因此需要进行标准化处理。

    正向指标(数值越大越好)标准化: X θ i j ′ = X θ i j − X m i n X m a x − X m i n \mathrm{X}^{\prime} _{\theta \mathrm{ij}}=\frac{\mathrm{X} _{\theta \mathrm{ij}}-\mathrm{X_{min}}}{\mathrm{X_{max}}-\mathrm{X_{min}}} Xθij=XmaxXminXθijXmin ;负向指标(数值越小越好)标准化: X θ i j ′ = X m a x − X θ i j X m a x − X m i n \mathrm{X}^{\prime} _{\theta \mathrm{ij}}=\frac{\mathrm{X_{max}}-\mathrm{X} _{\theta \mathrm{ij}}}{\mathrm{X_{max}}-\mathrm{X_{min}}} Xθij=XmaxXminXmaxXθij

    其中, X m a x \mathrm{X_{max}} Xmax X m i n \mathrm{X_{min}} Xmin表示第 j j j个指标在第 i i i个城市 r r r个年份中的最大、最小值,即取每个指标全部年份的最大、最小值。指标标准化处理后, X θ i j ′ \mathrm{X}^{\prime} _{\theta \mathrm{ij}} Xθij的取值范围为 [ 0 , 1 ] [0,1] [0,1],表示 X θ i j ′ \mathrm{X}^{\prime} _{\theta \mathrm{ij}} Xθij n n n个城市 r r r个年份中的相对大小。

    注意 X m a x \mathrm{X_{max}} Xmax X m i n \mathrm{X_{min}} Xmin不能是当年的最大、最小值,而是所有年份中的。若是当年的最大最小值,那么每年指标数值相近,不利于后续分析

  • Step3:非负平移。 X θ i j ′ = X θ i j ′ + 0.001 \mathrm{X}^{\prime} _{\theta \mathrm{ij}}=\mathrm{X}^{\prime} _{\theta \mathrm{ij}}+0.001 Xθij=Xθij+0.001

    标准化后,可能会对小于等于0的数字取对数,从而产生null值或nan。一般采用非负平移,即对所有数据加上很小的数。

  • Step4:计算权重: Y θ i j = X θ i j ′ / ∑ θ r ∑ i n X θ i j ′ \mathrm{Y}_{\theta \mathrm{ij}}=\mathrm{X}_{\theta \mathrm{ij}}^{\prime} / \sum\limits_{\theta}^r \sum\limits_{\mathrm{i}}^n \mathrm{X}^{\prime} _{\theta \mathrm{ij}} Yθij=Xθij/θrinXθij

  • Step5:计算熵值: S j = − k ∑ θ r ∑ i n ( Y θ i j ln ⁡ ( Y θ i j ) ) , k = 1 / l n ( r n ) \mathrm{S}_{\mathrm{j}}=-\mathrm{k} \sum\limits_{\theta}^r \sum\limits_{\mathrm{i}}^n (\mathrm{Y}_{\theta \mathrm{ij}} \ln \left(\mathrm{Y}_{\theta \mathrm{ij}}\right)), \mathrm{k}=1 / \mathrm{ln}(\mathrm{rn}) Sj=kθrin(Yθijln(Yθij)),k=1/ln(rn)

  • Step6:计算差异系数。第 j j j项指标的差异系数 : E j = 1 − S j \mathrm{E}_{\mathrm{j}}=1-\mathrm{S}_{\mathrm{j}} Ej=1Sj

  • Step7:计算第 j j j指标的权重: W j = E j / ∑ j m E j \mathrm{W}_{\mathrm{j}}=\mathrm{E}_{\mathrm{j}} / \sum\limits_{\mathrm{j}}^m \mathrm{E}_{\mathrm{j}} Wj=Ej/jmEj

  • Step8:计算每个城市每个年份下的综合得分。指标权重与标准化后的指标值乘积: H θ i = ∑ j m ( W j ( X θ i j ′ ) T ) \mathrm{H}_{\theta \mathrm{i}}=\sum\limits_{\mathrm{j}}^m \left(\mathrm{W}_{\mathrm{j}} (\mathrm{X}_{\theta \mathrm{ij}}^{\prime}\right)^\mathrm{T}) Hθi=jm(Wj(Xθij)T)

代码实现

输入与输出

data.xlsx输入的数据文件,指标数据排列如下。
在这里插入图片描述
输出结果为各个指标的权重各年度各城市的综合指数


MATLAB实现

仅供测试用数据:https://download.csdn.net/download/what_how_why2020/84855240

以下代码测试于MATLAB 2020b

clear, clc;

%% 读取数据
% 以下两种读取数据的方式任选其一即可

% 方式一,推荐,MATLAB 2013b及以上版本
% data是表结构
data = readtable('data.xlsx', 'PreserveVariableNames', true);
% 读取data.xlsx表格中数据,需包含所有年份的所有指标。
% 「修改」:“3:11”为第3列至11列数据
data1 = data(:, 3:11);
% 转成矩阵,以便使用max等函数
data1 = table2array(data1);


% 方式二
% 「修改」参数依次是:文件名、工作簿名、单元格位置名
data1 = xlsread('data.xlsx', 'sheet', 'C2:K97');

%% 标准化
max_indicator = max(data1);  % 每个指标的最大值
min_indicator = min(data1);  % 每个指标的最小值
diff_indicator = max_indicator - min_indicator;  % 差值

% 正负指标矩阵。0表示正指标归一化;1表示负指标归一化
% 「修改」:根据实际数据的正负指标情况,对向量 Indicator_Type 做出修改
Indicator_Type = [0 0 1 0 1 0 0 0 0];  

[data1_line, data1_column] = size(data1);

for i = 1:data1_line
    for j = 1:data1_column
        if Indicator_Type(j) == 0
            % 正指标归一化
            normal_result(i,j) = (data1(i,j) - min_indicator(j)) / diff_indicator(j);
        else
            % 负指标归一化
            normal_result(i,j) = (max_indicator(j) - data1(i,j)) / diff_indicator(j);
        end
    end
end  

% 非负平移,对所有数值都加上0.001
normal_result = normal_result + 0.001

%% 计算权重
sum_column = sum(normal_result);
for j = 1:data1_column
    for i = 1:data1_line
        Y(i, j) = normal_result(i, j)/sum_column(j)
    end
end


%% 计算熵值
year_num = 6;  % 「修改」年份数
city_num = 16;  % 「修改」城市数
k = 1 / log(year_num*city_num);

for j = 1:data1_column
    for i = 1:data1_line
        temp_a(i, j) = Y(i, j).*log(Y(i, j));
    end
end

S = -k * sum(temp_a)

%% 计算第j项指标的差异系数
E = ones(1, data1_column) - S;

%% 计算第j项指标权重
sum_E = sum(E);
for j = 1:data1_column
    W(j) = E(j)/sum_E;
end

%% 计算综合得分
H = W*normal_result';
% 生成city_num个行、year_num个列的矩阵,final_result(city_num, year_num)表示某城市在某年的综合水平
final_result = reshape(H', city_num, year_num);

advance

获取各年度各城市在每个一级指标下的综合得分2:。暂无简单的代码实现思路,推荐使用Excel


说明:上图中“步骤3 两矩阵相乘”表述错误,不是矩阵相乘,本意是将每个指标的权重依次乘上每年每个城市的标准化后的指标数据

可能遇到的问题

以下为博主编写熵值法代码过程中遇到的问题,现已解决,可供读者参考。

  1. MatLab错误使用sum数据类型无效。第一个参数必须为数值或逻辑值。3
    报错原因:sum函数的参数类型需为矩阵,而非,使用readtable()函数导入数据时,返回值的数据类型为表table
    解决方法:若是使用readtable()函数所导致的此问题,使用table2array()转换数据类型即可
  2. MatLab数据中有NaN4
    报错原因:数据中本身含有NaN;分数计算中分母为0
    解决方法:检查数据和计算过程
  3. 某一个指标原始数据没有NaN,但在运行中出现NaN,导致权重变量W全是NaN。
    可能是数据异常值的原因

读者反馈的问题

因博主学识尚浅,存在一些问题不能解答,故将评论区中未解决的问题置于此处,希望有读者能提供解决思路或方法。更新于2022年5月21日

问1:xmax是指第i个城市所有年份最大值还是所有年份所有城市的最大值呢
答1:在写本文的时候,我理解的是第i个城市所有年份的最大值,即对比第i个城市历年数据变化。但在此刻我想,如果xmax是所有年份所有城市的最大值也是合理的,那样数据就有统一的上下限,直观可见每个城市每个年份在每个指标下的差异。究竟哪种方式更合理,暂时我也无法给出确定的答复

问2:请问为什么输出的权重都等于0.8多,几个指标加起来不等于1?
答2:暂时未知原因


参考资料:


  1. 杨丽与孙之淳, 基于熵值法的西部新型城镇化发展水平测评. 经济问题, 2015(03): 第115-119页. ↩︎

  2. 马茹,罗晖,王宏伟,王铁成.中国区域经济高质量发展评价指标体系及测度研究[J].中国软科学,2019(07):60-67. ↩︎

  3. matlab错误使用 sum 数据类型无效。第一个参数必须为数值或逻辑值。解决方法_岁月不负人的博客-CSDN博客 ↩︎

  4. 为什么Matlab运行的结果是NaN呢,急盼解答 – MATLAB中文论坛 (ilovematlab.cn) ↩︎

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐