北太天元学习38-TOPSIS法选购手机
在北太天元学习20中,我们学习了一种多准则决策的方法,称为层次分析法。今天, 我们将学习另一种应用广泛的多准则决策的方法,称为TOPSIS方法。 TOPSIS 是 Technique for Order Preference by Similarity to an Ideal Solution 的缩写,可以翻译为"通过与理想解相似性进行偏好排序的技术"。 由Hwang和Yoon(1981)开发的TOPSIS方法是继Saaty(1980)的层次分析法(AHP)之后第二广泛使用和流行的多准则决策方法。这是因为它简单易用,可以应用于由多标准和多被选择品组成的问题。
首先,我们把下面的表格称为决策矩阵, 如
指标1 指标2 ....
备选1 10 0.3
备选2 8 0.7
...
它是一个表,每一个行对应一个备选方案, 每一列对应一个指标.
我还是以一个例子简单讲讲如何使用TOPSIS方法给 不同的备选 进行评分排序。 假设你想买一部手机,根据RAM、内存、显示屏大小、电池和价格分析了5部手机。

最后,你看到这么多指标后感到困惑(乱花渐欲迷人眼),不知道如何决定你应该购买哪部手机。TOPSIS是一种根据给定指标的权重和影响来分配排名的方法。

权重是指应考虑给定指标的程度(所有指标的默认权重=1)。 就像你希望RAM比其他指标更重一样,所以RAM的权重可以取成2,而其他指标可以是1。我们也可以先用层次分析法给出各个指标的权重, 参考北太天元学习20。
每个指标的影响是可能是积极的也可能是消极的。就像你希望电池尽可能大(效益型指标, 极大型指标), RAM 和 Memory 你也希望越大越好,因此也是极大型指标; 但手机的价格尽可能低(成本性指标, 极小型指标), 还有屏幕你既不希望太大也不希望太小,
最好在5-6英寸之间(区间型指标),那么我们怎么根据上表的数据来对这5个手机进行排序?
我们就用北太天元,首先在北太天元输入图中的决策矩阵
>> x = [ 8 128 5 2400 800 ;
8 256 5.5 3000 1500 ;
16 256 6 3200 3000 ;
32 512 10 3200 10000 ;
8 256 4 3000 2000 ];
步骤1: 数据预处理
1.1 数据正向化处理
在处理数据时,有些指标的数据越大越好,有些则是越小越好,有些又是某段区间最好。我们可以对其进行“正向化处理”,使指标都可以像考试分数那样,越大越好。
对于极小型指标j, 这一列的元素是 x_{ij}, i=1,...n; 我们可以用下面的一段北太天元的代码来对第j列做变换,把这一列的指标转化成极大型
>> j = 5; % 第5列是价格,是极小型指标
>> xj = x(:,j); % 取到决策矩阵的第j列
>> maxj = max(xj); % 取得 xj 的最大值
>> yj = maxj - xj; % yj 是成了极大型指标
>> x(:,j) = yj; % 把原来的决策矩阵的第j列 修改为 yj
经过这个操作, 决策矩阵变成了

对于区间型指标j, 这一列的元素是 x_{ij},j = 1,...n; 如果其最佳区间是[lb,ub],我们还是令 xj = x(:,j), 然后取 xj 的元素的最大值 和最小值 max_xj, min_xj, 假设 max_xj > ub 和 min_xj < lb 至少有一个成立( 不然,这一列的指标对区分备选是没有用处的,可以剔除这一列), 此时 取 M = max( [max_xj - ub, lb - min_xj ] ), 可以证明 M > 0. 然后我们使用下面的分段函数作为变换函数, 直接用北太天元的代码来写
>> j = 3; % 第3列是屏幕尺寸指标,是区间型
>> xj = x(:,j)
>> max_xj = max(xj);
>> min_xj = min(xj);
>> lb = 5; % 我们考虑的是第3列所给的屏幕尺寸指标,最佳范围是[5,6]
>> ub = 6;
>> M = max ( [ max_xj - ub, lb - min_xj]);
>> if M <=0
x(:,j) == 1;
else
fh = @(t) ( t < lb ) .* (1 - (lb-t)/M) + (t>=lb & t <=ub) ...
+ (t > ub ) .* (1 - (t-ub)/M);
yj = fh(xj);
x(:,j) = yj;
end
经过这一步, 第三列第3列也转成了极大型,决策矩阵现在变成了

经过这样的操作,我们得到的决策矩阵,每一列都可以看成极大型指标了。 我们可以把这一步叫做矩阵的正向化,也就是每一个指标都是越大越好。
步骤2:计算归一化矩阵和加权归一化矩阵。
矩阵的第1列是RAM, 数值在8-32之间(单位是M字节),第3列是电池容量, 数值在2400-3200之间(单位是毫安时), 如果使用原始数据会使得MEMORY指标的贡献值远大于RAM指标的贡献值。因此,我们 把所有的列的数据都归一化到一个相同的范围内,这个步骤叫做标准化(或者归一化),目的是消除不同的数据指标量纲的影响。
有很多标准化的方法,我们可以采用下面的方法:
>> [m,n] = size(x); % m是x的行数,n 是x的列数
>> for j = 1:n
x(:,j) = x(:,j) / norm( x(:,j) ); % 把x的第j列做了放缩,放缩后2范数是1
end
上面的北太天元代码,也可以用下面一行来代替
>> x = x ./ vecnorm(x);
归一化后的矩阵是

然后再乘以权重, 例如 w=[2 1 1 1 1]
>> w = [ 2 1 1 1 1];
>> x = x .* w;
得到的加权归一化的矩阵是

步骤3: 确定正理想解和负理想解
经过了正向化处理和标准化处理的评分矩阵x,里面的数据全部是极大型数据。 我们就可以从中取出理想最优解和最劣解。因此我们取出每个指标,即每一列中最大的数,构成理想最优解向量,即
>> s_p = max(x); % 对每一列取最大值 得到正理想解(positive ideal solution)

同理,取每一列中最小的数计算理想最劣解向量:
>> s_n = min(x); % 对每一列取最小值 得到负理想解(negative ideal solution)

步骤4: 计算各对象到正理想解与负理想解的距离
在得到理想最优解和理想最劣解的基础上就能计算每个备选的评分了。
>> d_p = vecnorm(x-s_p, 2, 2); %距离正理想解的距离

>> d_n = vecnorm(x-s_n, 2, 2); %距离负理想解的距离

步骤5: 计算综合评价指数
>> score = d_n ./ ( d_p + d_n); %计算分数
>> [sf,ind]=sort(score, 'descend') %求排序结果

上面计算出的各个手机的得分表明得分最高的是第4个手机,它的指标列在第4行,得分最低的是第5个手机,它的指标列在第5行。 第4个手机是10000元,是最贵的,怎么得分最高呢? 第五个手机看着还行,怎么得分最低呢?咋一看, 这是不合理的,但是想想我们开始把RAM的权重定成2,其它都是1,第4个手机的RAM最大,第5个手机的RAM最小, 仔细想想还是合理的,如果我们觉得不合理,还是要重新调整权重。还是欢迎大家看看北太学习20的层次分析法确定 权重的方法,再重新确定权重试试看。
下面是完整代码:
x = [ 8 128 5 2400 800 ;
8 256 5.5 3000 1500 ;
16 256 6 3200 3000 ;
32 512 10 3200 10000 ;
8 256 4 3000 2000 ];
j = 5; % 第5列是价格,是极小型指标
xj = x(:,j); % 取到决策矩阵的第j列
maxj = max(xj); % 取得 xj 的最大值
yj = maxj - xj; % yj 是成了极大型指标
x(:,j) = yj; % 把原来的决策矩阵的第j列 修改为 yj
j = 3; % 第3列是屏幕尺寸指标,是区间型
xj = x(:,j);
max_xj = max(xj);
min_xj = min(xj);
lb = 5; % 我们考虑的是第3列所给的屏幕尺寸指标,最佳范围是[5,6]
ub = 6;
M = max ( [ max_xj - ub, lb - min_xj]);
if M <=0
x(:,j) == 1;
else
fh = @(t) ( t < lb ) .* (1 - (lb-t)/M) + (t>=lb & t <=ub) ...
+ (t > ub ) .* (1 - (t-ub)/M);
yj = fh(xj);
x(:,j) = yj;
end
x = x ./ vecnorm(x); % 归一化
w = [ 2 1 1 1 1];
x = x .* w; % 加权归一化
s_p = max(x); % 对每一列取最大值 得到正理想解(positive ideal solution)
s_n = min(x); % 对每一列取最小值 得到负理想解(negative ideal solution)
d_p = norm(x-s_p, 2, 2); %距离正理想解的距离
d_n = norm(x-s_n, 2, 2); %距离负理想解的距离
score = d_n ./ ( d_p + d_n); %计算分数
[sf,ind]=sort(score, 'descend') %求排序结果