IMMC2020:熵权TOPSIS
笔记整理来自清风老师的数学建模课程:TOPSIS教程
目录
6.4 计算得分并归一化(计算与最大值的距离和最小值的距离,并算出得分)
1. 层次分析法的局限性(主观求权重方法)
层次分析法真正的核心是判断矩阵的填写,但是判断矩阵受人为因素比较大,所以最后计算得出的权重也比较主观。如果在有数据的情况下最好不要使用层次分析法。
(1)评价的决策层不能太多,太多的话n会很大,判断矩阵和一致性差异可能会很大。(可能会通过不了一致性检验)
(2)如果决策层中指标的数据是已知的,那么我们如何利用这些数据来使得评价更加准确呢?
可以分析数据内在的特征就行评价。(熵权法、TOPSIS法)
2. TOPSIS法引入
2.1 一个指标的情况
小明同宿舍共有四名同学,他们第一学期的高数成绩如下表所示:
请你为这四名同学进行评分,该评分能合理的描述其高数成绩的高低。
(注:这里要求的评分可以类比于上一讲层次分析法中要求的那个权重)
修正后的排名表示数字越大越好,评分用排名的得分/总得分
可以随便修改成绩,只要保证排名不变,那么评分就不会改变!
【矛盾】评分没变说明结果有问题,说明这种评分方式不能够全部反应原始数据的全部信息。
想法1:把数都减去一个最小值。结果通过与(max-min)相处,将数字变为【0,1】之间的数。
将数归一化:
需要说明的问题:如果用下面这种方法,虽然结果更加精确,能够反应更多的原始信息;比如60分时,我们得到的结果是0.6,而不是0。但是需要知道理论的最大值和最小值。
但是大多数情况下,我们是无法知道理论的最大值与最小值的,只能得到1组数据中的最大值与最小值,所以常用的评分方法是上一种。
为什么不用上面表格这个理论最大值最小值的公式:
2.2 2个指标的情况
新增加了一个指标,现在要综合评价四位同学,并为他们进行评分。
成绩是越高(大)越好,这样的指标称为极大型指标(效益型指标)。
与他人争吵的次数越少(越小)越好,这样的指标称为极小型指标(成本型指标)。
在进行分析的时候我们需要将指标统一为一个类型,一般都转为极大型指标。
2.2.1 指标正向化
将所有的指标转化为极大型称为指标正向化(最常用)
可以在excel中进行计算。比如折扣需要正向化处理。
2.2.2 指标标准化处理
只有一个指标的时候不需要消除量纲的影响,但是2个指标及以上呢?
由于成绩和争吵次数的量纲不同(单位不同),所以需要消除指标对不同量纲的影响。
为了消去不同指标量纲的影响,需要对已经正向化的矩阵进行标准化处理。
可以发现标准化后不会影响到指标的相对大小。
matlab代码:B = repmat(A,m,n):将矩阵A复制m×n块,即把A作为B的元素,B由m×n个A平铺而成。
X = [89 1; 60 3; 74 2; 99 0]
[n,m] = size(X)
X./repmat(sum(X.*X).^0.5,n,1)
代码分解:
X.*X
得到
sum(X.*X)
得到
sum(X.*X).^0.5
得到
由于矩阵(点除)除法的运算需要行列一致。
repmat(sum(X.*X).^0.5,n,1)
X./repmat(sum(X.*X).^0.5,n,1)
得到
所以:
2.2.3 计算得分
计算多个指标的得分时,可以类别只有一个指标时的得分。
先求出每一列的最大值最小值,再求每个元素与最大值(最小值)的距离(欧式距离)。最后求得分即可。(和只有一个指标时的解法一样)
2.2.4 实例计算
代码:
X = [89,1; 60,3; 74,2;99,0]%已经正向化后的矩阵
[n,m] = size(X)
Z = X./repmat(sum(X.*X) .^ 0.5,n,1)%标准化
D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5; % D+ 与最大值的距离向量
D_N = sum([(Z - repmat(min(Z),n,1)) .^ 2 ],2) .^ 0.5; % D- 与最小值的距离向量
S = D_N ./ (D_P+D_N); % 未归一化的得分
D+代码分解:D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5; % D+ 与最大值的距离向量
max(Z)%求出Z矩阵中每列的最大值。
repmat(max(Z),n,1)%将max(Z)矩阵复制n次
(Z - repmat(max(Z),n,1))%得到每一行的数与最大值的差
(Z - repmat(max(Z),n,1)) .^ 2%得到每行中的每个数与其最大值差的平方
sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2)%得到(Z - repmat(max(Z),n,1)) .^ 2 ]矩阵每一行的和 后面不加2默认是求每一列的和。
sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5 %将 sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) 的结果开根号
最后求得的结果就是D+的结果。
结果如下:
3. TOPSIS简介
C.L.Hwang 和 K.Yoon 于1981年首次提出 TOPSIS (Technique for Order Preference by Similarity to an Ideal Solution),可翻译为逼近理想解排序法,国内常简称为优劣解距离法。
TOPSIS 法是一种常用的综合评价方法,能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。
基本过程为:(1)将原始数据矩阵统一指标类型(一般正向化处理)得到正向化的矩阵;
(2)再对正向化的矩阵进行标准化处理以消除各指标量纲的影响;
(3)并找到有限方案中的最优方案和最劣方案;
(4)然后分别计算各评价对象与最优方案和最劣方案间的距离;
(5)获得各评价对象与最优方案的相对接近程度,以此作为评价优劣的依据。
该方法对数据分布及样本含量没有严格限制,数据计算简单易行。
4. TOPSIS法步骤
4.1 将原始矩阵正向化(可以在Excel中完成)
4.1.1 极小型指标转换为极大型指标
4.1.2 中间型指标转换为极大型指标
化简后的结果尽量在[0,1]之间。并且越靠近于最优值(这里为7)越接近于1.
4.1.3 区间型指标转换为极大型指标
4.2 正向化矩阵标准化
标准化的目的是消除不同指标量纲的影响
4.3 计算得分并归一化
5. 例题:评价水质情况
代码知识点:
(1)将EXCEL中的数据导入到Matlab,并另存为mat文件,下次可直接load Matlab中函数的编写和调用
(2)magic(n)幻方矩阵
(3)sort函数
(4)zeros和ones函数
6. 代码讲解
6.1 将数据导入到MATLAB中
第一步:Ctrl+C复制Excel中的数据
第二步:在工作区新建一个空白的数据文件(.mat),命名为data_water.
第三步:双击data_water,将数据按住Ctrl+v粘贴到里面即可。
第四步:右击数据文件,另存为.mat文件,下次使用时可以直接用load导入数据。
代码:
load data_water.mat
然后可以将数据表的文件名改成X(短一些,好写代码)
6.2 判断指标是否正向化
第一步:判断是否需要正向化,只有当存在非极大型指标时才需要正向化处理。
[n,m] = size(X);
disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标'])
Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0: ']);
这里采用矩阵的形式拼接字符。
第二步:如果需要正向化处理,输入1.
if Judge == 1
Position = input('请输入需要正向化处理的指标所在的列,例如第2、3、6三列需要处理,那么你需要输入[2,3,6]: '); %[2,3,6]
disp('请输入需要处理的这些列的指标类型(1:极小型, 2:中间型, 3:区间型) ')
Type = input('例如:第2列是极小型,第3列是区间型,第6列是中间型,就输入[1,3,2]: '); %[2,1,3]
% 注意,Position和Type是两个同维度的行向量
for i = 1 : size(Position,2) %这里需要对这些列分别处理,因此我们需要知道一共要处理的次数,即循环的次数
X(:,Position(i)) = Positivization(X(:,Position(i)),Type(i),Position(i));
% Positivization是我们自己定义的函数,其作用是进行正向化,其一共接收三个参数
% 第一个参数是要正向化处理的那一列向量 X(:,Position(i)) 回顾上一讲的知识,X(:,n)表示取第n列的全部元素
% 第二个参数是对应的这一列的指标类型(1:极小型, 2:中间型, 3:区间型)
% 第三个参数是告诉函数我们正在处理的是原始矩阵中的哪一列
% 该函数有一个返回值,它返回正向化之后的指标,我们可以将其直接赋值给我们原始要处理的那一列向量
end
disp('正向化后的矩阵 X = ')
disp(X)
end
可以得到正向化后的矩阵为:
4.69 | 0.717241379 | 3 | 1 |
2.03 | 0.406896552 | 35 | 0.694036301 |
9.11 | 0.524137931 | 8 | 0.905790838 |
8.61 | 0.965517241 | 8 | 0.444252377 |
7.13 | 0.655172414 | 4 | 0.691443388 |
2.39 | 0.84137931 | 16 | 0.600691443 |
7.69 | 0.855172414 | 16 | 0.65514261 |
9.3 | 0.868965517 | 27 | 0 |
5.45 | 0.572413793 | 49 | 1 |
6.19 | 0.813793103 | 37 | 0.784788245 |
7.93 | 0.634482759 | 45 | 0.699222126 |
4.4 | 0.806896552 | 37 | 0.541918755 |
7.46 | 0.144827586 | 31 | 1 |
2.01 | 0 | 7 | 0.454624028 |
2.04 | 0.586206897 | 31 | 1 |
7.73 | 0.406896552 | 2 | 1 |
6.35 | 0.6 | 29 | 0.182368194 |
8.29 | 0.027586207 | 15 | 1 |
3.54 | 0.813793103 | 0 | 0.408815903 |
7.44 | 0.489655172 | 46 | 0.273120138 |
6.2.1 极小型指标正向化
function [posit_x] = Min2Max(x)
posit_x = max(x) - x;
%posit_x = 1 ./ x; %如果x全部都大于0,也可以这样正向化
end
6.2.3 中间型指标正向化
function [posit_x] = Mid2Max(x,best)
M = max(abs(x-best));
posit_x = 1 - abs(x-best) / M;
end
6.2.4 区间型指标正向化
function [posit_x] = Inter2Max(x,a,b)
r_x = size(x,1); % row of x
M = max([a-min(x),max(x)-b]);
posit_x = zeros(r_x,1); %zeros函数用法: zeros(3) zeros(3,1) ones(3)
% 初始化posit_x全为0 初始化的目的是节省处理时间
for i = 1: r_x
if x(i) < a
posit_x(i) = 1-(a-x(i))/M;
elseif x(i) > b
posit_x(i) = 1-(x(i)-b)/M;
else
posit_x(i) = 1;
end
end
end
6.2.5 指标正向化处理
% function [输出变量] = 函数名称(输入变量)
% 函数的中间部分都是函数体
% 函数的最后要用end结尾
% 输出变量和输入变量可以有多个,用逗号隔开
% function [a,b,c]=test(d,e,f)
% a=d+e;
% b=e+f;
% c=f+d;
% end
% 自定义的函数要单独放在一个m文件中,不可以直接放在主函数里面(和其他大多数语言不同)
function [posit_x] = Positivization(x,type,i)
% 输入变量有三个:
% x:需要正向化处理的指标对应的原始列向量
% type: 指标的类型(1:极小型, 2:中间型, 3:区间型)
% i: 正在处理的是原始矩阵中的哪一列
% 输出变量posit_x表示:正向化后的列向量
if type == 1 %极小型
disp(['第' num2str(i) '列是极小型,正在正向化'] )
posit_x = Min2Max(x); %调用Min2Max函数来正向化
disp(['第' num2str(i) '列极小型正向化处理完成'] )
disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~')
elseif type == 2 %中间型
disp(['第' num2str(i) '列是中间型'] )
best = input('请输入最佳的那一个值: ');
posit_x = Mid2Max(x,best);
disp(['第' num2str(i) '列中间型正向化处理完成'] )
disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~')
elseif type == 3 %区间型
disp(['第' num2str(i) '列是区间型'] )
a = input('请输入区间的下界: ');
b = input('请输入区间的上界: ');
posit_x = Inter2Max(x,a,b);
disp(['第' num2str(i) '列区间型正向化处理完成'] )
disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~')
else
disp('没有这种类型的指标,请检查Type向量中是否有除了1、2、3之外的其他值')
end
end
6.3 对正向化后的矩阵进行标准化
Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 Z = ')
disp(Z)
可以得到标准化后的矩阵为:
0.162185916 | 0.248255278 | 0.024544035 | 0.306457563 |
0.070199874 | 0.140837129 | 0.286347071 | 0.212692674 |
0.315034904 | 0.181417319 | 0.065450759 | 0.277586453 |
0.297744294 | 0.334189798 | 0.065450759 | 0.136144501 |
0.24656409 | 0.226771648 | 0.03272538 | 0.211898056 |
0.082649113 | 0.291222538 | 0.130901518 | 0.184086436 |
0.265929573 | 0.295996678 | 0.130901518 | 0.200773408 |
0.321605335 | 0.300770818 | 0.220896312 | 0 |
0.188467643 | 0.198126809 | 0.4008859 | 0.306457563 |
0.214057745 | 0.281674258 | 0.302709761 | 0.240504293 |
0.274229065 | 0.219610438 | 0.36816052 | 0.214281909 |
0.152157363 | 0.279287188 | 0.302709761 | 0.166075101 |
0.257975892 | 0.05012847 | 0.253621692 | 0.306457563 |
0.06950825 | 0 | 0.057269414 | 0.139322972 |
0.070545686 | 0.202900949 | 0.253621692 | 0.306457563 |
0.267312822 | 0.140837129 | 0.01636269 | 0.306457563 |
0.21959074 | 0.207675088 | 0.237259002 | 0.055888112 |
0.286678304 | 0.00954828 | 0.122720173 | 0.306457563 |
0.122417515 | 0.281674258 | 0 | 0.125284726 |
0.257284268 | 0.169481969 | 0.376341865 | 0.083699732 |
6.4 计算得分并归一化(计算与最大值的距离和最小值的距离,并算出得分)
D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5; % D+ 与最大值的距离向量
D_N = sum([(Z - repmat(min(Z),n,1)) .^ 2 ],2) .^ 0.5; % D- 与最小值的距离向量
S = D_N ./ (D_P+D_N); % 未归一化的得分
disp('最后的得分为:')
stand_S = S / sum(S)%归一化后的得分
%[sorted_S,index] = sort(stand_S ,'descend')
排序(可以在Excel中完成),可以看出河流K的得分最高,排名最高。
河流 | D+ | D- | Stand_S(归一化后得分) | 排名 |
K | 0.1579 | 0.5212 | 0.0702 | 1 |
J | 0.1683 | 0.4997 | 0.0684 | 2 |
I | 0.1904 | 0.5550 | 0.0681 | 3 |
L | 0.2471 | 0.4517 | 0.0591 | 4 |
T | 0.2855 | 0.4611 | 0.0565 | 5 |
G | 0.2977 | 0.4285 | 0.0539 | 6 |
O | 0.3193 | 0.4466 | 0.0533 | 7 |
M | 0.3262 | 0.4430 | 0.0527 | 8 |
H | 0.3570 | 0.4503 | 0.0510 | 9 |
D | 0.3770 | 0.4320 | 0.0488 | 10 |
C | 0.3698 | 0.4178 | 0.0485 | 11 |
B | 0.3500 | 0.3835 | 0.0478 | 12 |
Q | 0.3405 | 0.3537 | 0.0466 | 13 |
A | 0.4177 | 0.4059 | 0.0451 | 14 |
F | 0.3832 | 0.3688 | 0.0448 | 15 |
R | 0.4289 | 0.3953 | 0.0438 | 16 |
P | 0.4338 | 0.3913 | 0.0434 | 17 |
E | 0.4021 | 0.3588 | 0.0431 | 18 |
S | 0.4858 | 0.3128 | 0.0358 | 19 |
N | 0.5668 | 0.1506 | 0.0192 | 20 |
7. 模型拓展