MATLAB 之 优劣解距离法(TOPSIS )

一、TOPSIS 简介

  • TOPSIS 是一种常用的综合评价方法,可以充分利用 原始数据 的信息,其结果可以精确地反映各评价方案之间的差距。
  • TOPSIS 是一种逼近于理想解的排序法,该方法只要求各效用函数具有单调递增(或递减)性就行。
  • TOPSIS 是多目标决策分析中一种常用的有效方法,又称为优劣解距离法。
  • TOPSIS 对样本容量没有严格限制,数据计算简单易行,无需数据检验。

二、TOPSIS 步骤

1:将原始矩阵正向化,得到正向化矩阵

1.1 指标类型

指标名称指标特点例子
极大型(效益性)指标越大(多)越好成绩、GDP增速、企业利润
极小型(成本型)指标越小(少)越好费用、坏品率、污染程度
中间型指标越接近某个值越好水质量评估时的PH值
区间型指标落在某个区间最好体温、水中植物性营养物量

1.2 正向化公式

正向化就是将原始数据指标都转化为极大型指标。

符号含义
max一列当中最大的元素
xbest区间最好的值
a区间下限
b区间上限
  • 极小型指标转换为极大型指标:max−x,如果所有的元素均为正数,那么也可以使用:1 / x 。
  • 中间型指标转换为极大型指标:在这里插入图片描述
  • 区间型指标转换为极大型指标:在这里插入图片描述

2. 正向化矩阵标准化

标准化的目的是消除不同指标量纲的影响。
假设有 n 个要评价对象,m个评价指标(已经正向化了)构成的正向化矩阵如下:
在这里插入图片描述
那么,对其标准化的矩阵记为 Z ,Z 当中的每一个元素:
在这里插入图片描述(每一个元素 / 其所在列的元素的平方和的开方)
得到标准化矩阵 Z :
在这里插入图片描述

3. 计算得分并归一化

3.1 方法

在这里插入图片描述

3.2 步骤

  • 定义各个指标的最大值向量与最小值向量
    最大值向量:在这里插入图片描述
    最小值向量:在这里插入图片描述
  • 定义各个对象与最大值、最小值之间的距离
    在这里插入图片描述
  • 计算各个评价对象的分数
    得分:(显然 0 ≤ Si ≤ 1 ,且 Si 越大,Di+越小,即越接近最大值)
    在这里插入图片描述
  • 归一化:每一部分为该部分与所有部分和的比值。归一化的目的是为了让我们的结果更加容易解释。例如将得分归一化后可限制在 0-1 这个区间,对区间内每一个得分,都可以容易的得到起所处的比例位置。
  • 分数最高即为最优方案或对象

三、TOPSIS 模型实现

关于具体实现,需要有一定的数据,这里实现所选用的数据如下:

河流含氧量(ppm)PH值细菌总数(个/mL)植物性营养物量
A4.696.595111.94
B2.037.86196.46
C9.116.31468.91
D8.617.054626.43
E7.136.55023.57
F2.396.773824.62
G7.696.79386.01
H9.36.812731.57
I5.457.62518.46
J6.197.27177.51
K7.937.5396.52
L4.47.281725.3
M7.468.242314.42
N2.015.554726.31
O2.046.42317.91
P7.736.145215.72
Q6.357.582529.46
R8.298.413912.02
S3.547.27543.16
T7.446.26828.41

1. MATLAB 实现

1.1 把数据复制到工作区,并将这个矩阵命名为X

  • 在工作区右键,点击新建(Ctrl+N),输入变量名称为X。
  • 在Excel中复制数据,再回到Excel中右键,点击粘贴Excel数据(Ctrl+Shift+V)。
  • 关掉这个窗口,点击X变量,右键另存为,保存为mat文件(下次就不用复制粘贴了,只需使用load命令即可加载数据)。
  • 注意,代码和数据要放在同一个目录下哦。
clear;clc
load data_water_quality.mat

1.2 判断是否需要正向化

  • 判断是否需要正向化,只有当存在非极大型指标时才需要正向化处理。
[n,m] = size(X);
disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标']) 
Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0:  ']);
  • 如果需要正向化处理,输入1。
if Judge == 1
    Position = input('请输入需要正向化处理的指标所在的列,例如第236三列需要处理,那么你需要输入[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
  • 可以得到正向化后的矩阵为:
含氧量(ppm)PH值细菌总数(个/mL)植物性营养物量
4.690.71724137931
2.030.406896552350.694036301
9.110.52413793180.905790838
8.610.96551724180.444252377
7.130.65517241440.691443388
2.390.84137931160.600691443
7.690.855172414160.65514261
9.30.868965517270
5.450.572413793491
6.190.813793103370.784788245
7.930.634482759450.699222126
4.40.806896552370.541918755
7.460.144827586311
2.01070.454624028
2.040.586206897311
7.730.40689655221
6.350.6290.182368194
8.290.027586207151
3.540.81379310300.408815903
7.440.489655172460.273120138
1.2.1 极小型指标正向化
function [posit_x] = Min2Max(x)
    posit_x = max(x) - x;
     %posit_x = 1 ./ x;    %如果x全部都大于0,也可以这样正向化
end
1.2.2 中间型指标正向化
function [posit_x] = Mid2Max(x,best)
    M = max(abs(x-best));
    posit_x = 1 - abs(x-best) / M;
end
1.2.3 区间型指标正向化
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
1.2.4 指标正向化处理
% 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向量中是否有除了123之外的其他值')
    end
end 

1.3 对正向化后的矩阵进行标准化

Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 Z = ')
disp(Z)
  • 标准化后的矩阵为:
含氧量(ppm)PH值细菌总数(个/mL)植物性营养物量
0.1621859160.2482552780.0245440350.306457563
0.0701998740.1408371290.2863470710.212692674
0.3150349040.1814173190.0654507590.277586453
0.2977442940.3341897980.0654507590.136144501
0.246564090.2267716480、032725380.211898056
0.0826491130.2912225380.1309015180.184086436
0.2659295730.2959966780.1309015180.200773408
0.3216053350.3007708180.2208963120
0.1884676430.1981268090.40088590.306457563
0.2140577450.2816742580.3027097610.240504293
0.2742290650.2196104380.368160520.214281909
0.1521573630.2792871880.3027097610.166075101
0.2579758920.050128470.2536216920.306457563
0.0695082500.0572694140.139322972
0.0705456860.2029009490.2536216920.306457563
0.2673128220.1408371290.016362690.306457563
0.219590740.2076750880.2372590020.055888112
0.2866783040.009548280.1227201730.306457563
0.1224175150.28167425800.125284726
0.2572842680.1694819690.3763418650.083699732

1.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')
  • 得分排名情况:
河流D+D-Stand_S(归一化后得分)排名
K0.15790.52120.07021
J0.16830.49970.06842
I0.19040.55500.06813
L0.24710.45170.05914
T0.28550.46110.05655
G0.29770.42850.05396
O0.31930.44660.05337
M0.32620.44300.05278
H0.35700.45030.05109
D0.37700.43200.048810
C0.36980.41780.048511
B0.35000.38350.047812
Q0.34050.35370.046613
A0.41770.40590.045114
F0.38320.36880.044815
R0.42890.39530.043816
P0.43380.39130.043417
E0.40210.35880.043118
S0.48580.31280.035819
N0.56680.15060.019220

四、TOPSIS 模型优缺点

1. TOPSIS 法的优点

  • 避免了数据的主观性,不需要目标函数,不用通过检验,而且能够很好的刻画多个影响指标的综合影响力度。
  • 对于数据分布及样本量、指标多少无严格限制,既适于小样本资料,也适于多评价单元、多指标的大系统,较为灵活、方便。

2. TOPSIS 法的缺点

  • 需要的每个指标的数据,对应的量化指标选取会有一定难度。
  • 不确定指标的选取个数为多少适宜,才能够去很好刻画指标的影响力度。
  • 必须有两个以上的研究对象才可以进行使用

五、TOPSIS 模型优化

在 TOPSIS 当中,默认了各个评价指标所占的权重相同,但在实际的评价过程当中由于各种主观客观因素的影响,导致每一个评价指标所占的权重是有差异的。因此,对于 TOPSIS 模型的优化,可以从合理调整个评价指标所占权重入手。

1. 主观权重——层次分析法(AHP)

在此处只是简单介绍,详细介绍有时间的话会补充

  • 层次分析法是一个较为主观的评价方法,其在赋权得到权重向量时,主观因素占比很大。
  • 首先,分析系统中各因素之间的关系,建立系统的递阶层次结构。
  • 其次,对于同一层次的个元素关于上一层次中某一准则的重要性两两比较,构造两两比较矩阵(判断矩阵)。
  • 然后,由判断矩阵计算被比较元素对于该准则的相对权重,并进行 一致性检验(检验通过权重才能用)。
  • 最后,填充权重矩阵,根据矩阵计算得分,得出结果。
  • 权重矩阵填充方法
标度含义
1表示两个因素相比,具有同样重要性
3表示两个因素相比,一个因素比另一个因素稍微重要
5表示两个因素相比,一个因素比另一个因素明显重要
7表示两个因素相比,一个因素比另一个因素强烈重要
9表示两个因素相比,一个因素比另一个因素极端重要
2、4、6、8上述两相邻判断的中值
倒数A和B相比如果标度为3,那么B和A相比就是1/3
  • 判断矩阵实际情况下都是专家填的,但是很多时候大都是我们自己填的,最好有一些理论的依据支撑。
  • 判断矩阵当中,a[i][j] 表示:与指标 j 相比,i 的重要程度。

1.1 权重求解方法

(1) 算术平均法求权重
  • 将判断矩阵按照列归一化。
  • 将归一化的列相加(按行求和)。
  • 将相加后得到的向量中的每个元素除以 n 即可得到权重向量。
    在这里插入图片描述
(2) 几何平均法求权重
  • 将A的元素按照行相乘得到一个新的列向量。
  • 将新的向量的每个分量开n次方。
  • 对该列向量进行归一化即可得到权重向量。
    在这里插入图片描述
(3) 特征值法求权重

一致矩阵有一个特征值为 n,其余特征值均为 0。另外,我们很容易可以得到,特征值为 n 时,对应的特征向量刚好为:
在这里插入图片描述
在实际过程中建议综合三种方法求得的权重得到一个综合的权重向量更具有说服力。

2. 客观权重——熵权法

  • 熵权法就是根据一项指标的变化程度来分配权重的。
  • 第一步:判断输入的矩阵中是否存在负数,如果有则要重新标准化到非负区间(后面计算概率时需要保证每一个元素为非负数)。
  • 第二步:计算第 j 项指标下第 i 个样本所占的比重,并将其看作相对熵计算中用到的概率。
  • 第三步:计算每个指标的信息熵,并计算信息效用值,并归一化得到每个指标的熵权。

(1) 第一步

  • 假设有 n 个要评价的对象,m 个评价指标(已经正向化了)构成的正向化矩阵如下:
    在这里插入图片描述
  • 设标准化矩阵为 Z ,Z 中元素记为 zij
    在这里插入图片描述
  • 判断 Z 矩阵中是否存在着负数,如果存在的话,需要对 X 使用另一种标准化方法对矩阵 X 进行一次标准化得到 Z 矩阵,其标准化的公式为:在这里插入图片描述
  • 这样可以保证 zij 在 [0,1] 区间,没有负数。

(2) 第二步

  • 假设有 n 个要评价的对象,m 个评价指标,且经过了上一步处理得到的非负矩阵为:在这里插入图片描述
  • 计算概率矩阵 P ,其中 P 中每一个元素 Pij 的计算公式如下:
  • 在这里插入图片描述
  • 保证每一列的加和为 1 ,即每个指标所对应的概率和为 1 。

(3) 第三步

  • 对于第 j 个指标而言,其信息嫡的计算公式为:
    在这里插入图片描述

3. 优化结果

在各个对象与最大值、最小值之间的距离公式转变为:在这里插入图片描述

  • 16
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚心求知的熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值