目录
1.简介
TOPSIS 法是一种常用的综合评价方法,其能充分利用原始数据的信息, 其结果能精确地反映各评价方案之间的差距。
该方法弥补了层次分析法(AHP)的两个局限:1.评价的决策层不能太多,太多的话n会很大,通常为小于10;2.决策层中指标的数据是已知的,如何高效利用数据。
2.模型
(1)本质
利用已有指标数据,正向标准化,消除量纲影响。在所有的方案中,重新评级得到最优和最劣方案。
(2)步骤
STEP1:正向化指标
由于指标存在以下两种情况:1.极大型指标:即该指标下数据越大,方案决策得分越高;2.极小型指标:即该即该指标下数据越小,方案决策得分越高;3.中间型指标:指标值既不要太大也不要太小,取某特定值最好(如水质量评估 PH 值);4.区间型指标:指标值落在某个区间内最好,例如人的体温在36°~37°这个区间比较好。为了统一数据,消除指标的量纲影响,首先我们正向化指标,即指标全部转换为极大型。
常见的极小型指标转换为极大型指标函数:
可根据不同数据特征选择别的函数(数据全为正,可选择)。
中间型指标转换为极大型指标函数:
区间型指标转换为极大型指标函数:
注:正向化的公式不唯一,大家也可以结合自己的数据进行适当的修改。
STEP2:矩阵标准化
对于n阶方阵,利用下面公式正向化,得到标准化矩阵Z:
注意:标准化的方法有很多种,其主要目的就是去除量纲的影响,存在其他标准化方法,如:;视情况而定。
STEP3:计算得分并归一化
假设n个对象,m个评价指标,其标准矩阵为:
求的每个指标的最大最小值:
定义第i个对象与最大最小值的距离:
其中为第j个指标的权重
得到第i个对象未归一化的得分:
显然,且
越大,对象排名越高。
得分归一化:
注:归一化不会影响实际的排名结果。
3.代码
clear;clc
%% STEP1: LOAD DATA
load data.mat
%% STEP2:POSITIVIZATION
[n,m] = size(X);
disp([num2str(n), ' object, ', num2str(m), ' target'])
flag_pos = input(['1:POSTIVATION, 0:NO \n']);
if flag_pos == 1
index = input('index of colum needed to porcess,s.t.2,3,6colums,input[2,3,6]: \n');
Type = input('INPUT TYPE(1:MINIMAL, 2:MIDDLE, 3:INTERVAL) \n');
X_pos = zeros(n, m);
for i = 1 : size(index,2)
X_pos(:,index(i)) = Positivization(X(:,index(i)),Type(i),index(i));
end
end
%% STEP3: NORMAALIZATION
Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
% disp('Normalized matrix Z = \n');
% disp(Z)
%% STEP4: COMPUTE DISTENCE AND SCORE
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); % unnormalized score
% disp('SCORE: \n')
stand_S = S / sum(S);
[sorted_S,index] = sort(stand_S ,'descend') ;
%%%%%%%%%%%%%%%%%%%%%%%%%%MAIN_FUNCTION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%INPUT :data:kind of colum; i:index that data needed to process
%OUTPUT:data:kind of colum
function [data_posit] = Positivization(x, type, i)
if type == 1 %MINIMAL
% disp([num2str(i), 'colunm is minimal, PROCESSING'] );
data_posit = Min2Max(x); %调用Min2Max函数来正向化
% disp([num2str(i), 'colunm is minimal, COMPLETED'] );
elseif type == 2 %MIDDLE
% disp([num2str(i), 'colunm is middle, PROCESSING'] );
best = input('INPUT BEST VALUE:\n');
data_posit = Mid2Max(x, best);
% disp([num2str(i), 'colunm is middle, COMPLETED'] );
elseif type == 3 %INTERVAL
% disp([num2str(i), 'colunm is interval, PROCESSING'] );
a = input('INPUT UPPER BOUND:\n');
b = input('INPUT LOWER BOUND: \n');
data_posit = Inter2Max(x, a, b);
% disp([num2str(i), 'colunm is interval, COMPLETED'] );
else
disp(num2str(i), 'ERROR!!!\n');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%MAIN_FUNCTION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%SUB_FUNCTION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% MINIMAL SIZE TO MAXIMAL SIZE
function [x_pos] = Min2Max(x)
x_pos = max(x) - x;
% x_pos = 1 ./ x;
end
%% INTERVAL SIZE TO MAXIMAL SIZE
function [x_pos] = Inter2Max(x, a, b)
row = size(x, 1);
M = max([a-min(x),max(x)-b]);
x_pos = zeros(row, 1);
for i = 1: row
if x(i) < a
x_pos(i) = 1-(a-x(i))/M;
elseif x(i) > b
x_pos(i) = 1-(x(i)-b)/M;
else
x_pos(i) = 1;
end
end
end
%% MIDDLE SIZE TO MAXIMAL SIZE
function [x_pos] = Mid2Max(x, best)
M = max(abs(x-best));
x_pos = 1 - abs(x-best) / M;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%SUB_FUNCTION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%