TOPSIS方法
TOPSIS方法其实是一种打分的方法,当数据已知时,可以对多个不同的考虑因素进行综合评价,最后对每一个项目打出总评价分
(1)不考虑权重的TOPSIS方法
1.对原始矩阵进行正向化
-
首先给出常见的四种指标:
-
为了处理方便,每一次都要将指标转化为极大型指标(正向化)。
-
下面给出不同的指标的正向化的方法(假设数据中的任意一列为 X X X):
① ① ①对极小型指标的正向化
x i ~ = max x i − x i \widetilde{x_i}=\max_{x_i}-x_i xi =ximax−xi
例如对细菌总数:
② ② ②对中间型指标的正向化
假设要接近的中间值为 m i d mid mid
M = max i { ∣ x i − m i d ∣ } M=\max_i\{|x_i-mid|\} M=imax{
∣xi−mid∣}
x i ~ = 1 − ∣ x i − m i d ∣ M \widetilde{x_i}=1-\dfrac{|x_i-mid|}{M} xi
=1−M∣xi−mid∣
例如对PH值:
③ ③ ③对区间型指标的正向化
假设要接近的区间值为 [ l e f t , r i g h t ] [left,right] [left,right]
M = max { l e f t − m i n ( x i ) , m a x ( x i ) − r i g h t } M=\max\{left-min(x_i),max(x_i)-right\} M=max{
left−min(xi),max(xi)−right}
x i ~ = { 1 − l e f t − x i M x i < l e f t 1 l e f t < x i < r i g h t 1 − x i − r i g h t M x i > r i g h t \widetilde{x_i}=\left\{ \begin{aligned} & 1-\dfrac{left-x_i}{M} &x_i<left\\ & 1 &left<x_i<right\\ & 1-\dfrac{x_i-right}{M}&x_i>right \end{aligned} \right. xi
=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧1−Mleft−xi11−Mxi−rightxi<leftleft<xi<rightxi>right
例如对植物性营养含量:
2.正向化矩阵标准化
-
标准化的目的是为了消除量纲的影响
-
对 m m m个要评价的对象,各有 n n n各评价指标,完成正向化后的矩阵
[ x 11 x 12 ⋯ x 1 n x 21 x 22 ⋯ x 2 n ⋮ ⋮ ⋱ ⋮ x m 1 x m 2 ⋯ x m n ] \left[ \begin{matrix} x_{11} & x_{12} & \dotsb & x_{1n}\\ x_{21} & x_{22} & \dotsb & x_{2n}\\ \vdots & \vdots& \ddots & \vdots \\ x_{m1} & x_{m2} & \dotsb & x_{mn} \\ \end{matrix} \right] ⎣⎢⎢⎢⎡x11x21⋮xm1x12x22⋮xm2⋯⋯⋱⋯x1nx2n⋮xmn⎦⎥⎥⎥⎤
标准化的公式为 x i j ~ = x i j ∑ i = 1 m x i j 2 ( j = 1 ⋯ n ) \widetilde{x_{ij}}=\dfrac{x_{ij}}{\sqrt{\displaystyle \sum_{i=1}^mx_{ij}^2}}(j=1\dotsb n) xij =i=1∑mxij2xij(j=1⋯n)也就是 每 一 个 元 素 其 所 在 列 的 所 有 元 素 的 平 方 和 \dfrac{每一个元素}{ \displaystyle\sqrt{ 其所在列的所有元素的平方和 }} 其所在列的所有元素的平方和每一个元素
3.计算得分并归一化
-
对于已经标准化完成的矩阵:
Z = [ z 11 z 12 ⋯ z 1 n z 21 z 22 ⋯ z 2 n ⋮ ⋮ ⋱ ⋮ z m 1 z m 2 ⋯ z m n ] Z= \left[ \begin{matrix} z_{11} & z_{12} & \dotsb & z_{1n}\\ z_{21} & z_{22} & \dotsb & z_{2n}\\ \vdots & \vdots& \ddots & \vdots \\ z_{m1} & z_{m2} & \dotsb & z_{mn} \\ \end{matrix} \right] Z=⎣⎢⎢⎢⎡z11z21⋮zm1z12z22⋮zm2⋯⋯⋱⋯z1nz2n⋮zmn⎦⎥⎥⎥⎤ -
凑出最小值和最大值
最大值 Z + = { Z 1 + , Z 2 + ⋯ , Z n + } = { m a x { z 11 , z 21 , ⋯ , z m 1 } , m a x { z 12 , z 22 , ⋯ , z m 2 } , ⋯ , m a x { z 1 n , z 2 n , ⋯ , z m n } } Z^+=\{Z^+_1,Z^+_2\dotsb,Z^+_n\}=\{ max\{z_{11},z_{21},\dotsb,z_{m1}\},max\{z_{12},z_{22},\dotsb,z_{m2}\},\dotsb ,max\{z_{1n},z_{2n},\dotsb,z_{mn}\}\} Z+={ Z1+,Z2+⋯,Zn+}={ max{ z11,z21,⋯,zm1},max{ z12,z22,⋯,zm2},⋯,max{ z1n,z2n,⋯,zmn}}是一个 1 × n 1\times n 1×n的行向量,每一列的取值都是 Z Z Z中那一列的最大值。最小值 Z + = { Z 1 − , Z 2 − ⋯ , Z n − } = { m i n { z 11 , z 21 , ⋯ , z m 1 } , m i n { z 12 , z 22 , ⋯ , z m 2 } , ⋯ , m i n { z 1 n , z 2 n , ⋯ , z m n } } Z^+=\{Z^-_1,Z^-_2\dotsb,Z^-_n\}=\{ min\{z_{11},z_{21},\dotsb,z_{m1}\},min\{z_{12},z_{22},\dotsb,z_{m2}\},\dotsb ,min\{z_{1n},z_{2n},\dotsb,z_{mn}\}\} Z+={ Z1−,Z2−⋯,Zn−}={ min{ z11,z21,⋯,zm1},min{ z12,z22,⋯,zm2},⋯,min{ z1n,z2n,⋯,zmn}}是一个 1 × n 1\times n 1×n的行向量,每一列的取值都是 Z Z Z中那一列的最小值。
-
计算每一个评价对象到 Z + Z^+ Z+和 Z − Z^- Z−的距离:
-
D i + = ∑ j = 1 n ( Z j + − z i j ) 2 D_i^+=\sqrt{\displaystyle\sum_{j=1}^n (Z_j^+-z_{ij})^2} Di+=j=1∑n(Zj+−zij)2
D i − = ∑ j = 1 n ( Z j − − z i j ) 2 D_i^-=\sqrt{\displaystyle\sum_{j=1}^n (Z_j^--z_{ij})^2} Di−=j=1∑n(Zj−−zij)2
S i = D i − D i − + D i + S_i=\dfrac{D_i^-}{D_i^-+D_i^+} Si=Di−+Di+Di− S i ∈ ( 0 , 1 ) S_i\in(0,1) Si∈(0,1)并且由于进行了正向化的处理, S i S_i Si越大表明 D i + D_i^+ Di+越小,也就是该评价对象与 Z + Z^+ Z+越接近。
求出距离矩阵
S = [ S 1 S 2 ⋮ S m ] S= \left[ \begin{matrix} S_1 \\ S_2 \\ \vdots \\ S_m\\ \end{matrix} \right] S=⎣⎢⎢⎢⎡S1S2⋮Sm⎦⎥⎥⎥⎤ -
对 S S S进行归一化处理。
(2)考虑权重的TOPSIS方法
-
使用层次分析法先计算出每一个指标的权重。
W = ( w 1 , w 2 , ⋯ , w n ) W=(w_1,w_2,\dotsb,w_n) W=(w1,w2,⋯,wn) -
在计算 D i + D_i^+ Di+与 D i − D_i^- Di−的时候将每一个因素权重乘进去就行了。
D i + = ∑ j = 1 n ( Z j + − z i j ) 2 w j D_i^+=\sqrt{\displaystyle\sum_{j=1}^n (Z_j^+-z_{ij})^2w_j} Di+=j=1∑n(Zj+−zij)2wj
D i − = ∑ j = 1 n ( Z j − − z i j ) 2 w j D_i^-=\sqrt{\displaystyle\sum_{j=1}^n (Z_j^--z_{ij})^2w_j} Di−=j=1∑n(Zj−−zij)2wj
(3)matlab代码
- 主函数
%%
%导入数据
%这里database.mat应当存储一个矩阵,weight.mat应当存储一个行向量
load('database.mat');
[r,c]=size(X);
judge=input('是否需要加权处理,需要输入1,不需要输入0\n');
if judge==1
load('weight.mat');
end
%%
%进行正向化处理
Need_Handle=input('请输入需要正向化处理的列[c_1,c_2。。。]\n');
Kind=input('请输入这些列的指标[k_1,k_2。。。],极小型为1,中间型为2,区间型为3\n');
for i=1:size(Need_Handle,2)
X(:,Need_Handle(1,i))=Positive(Need_Handle(1,i),Kind(1,i),X(:,Need_Handle(1,i)));
end
%%
%正向化矩阵标准化
Norm=(sum(X.^2)).^0.5;
Norm=repmat(Norm,size(X,1),1);
X=X./Norm;
%%
%进行距离的计算
Dmax=zeros(r,1);
Dmin=zeros(r,1);
S=zeros(r,1);
Zmax=max(X);
Zmin=min(X);
if judge==0
for i=1:r
Dmax(i,1)=(sum((Zmax-X(i,:)).^2)).^0.5;
Dmin(i,1)=(sum((Zmin-X(i,:)).^2)).^0.5;
end
elseif judge==1
for i=1:r
Dmax(i,1)=(sum((Zmax-X(i,:).*weight).^2)).^0.5;
Dmin(i,1)=(sum((Zmin-X(i,:).*weight).^2)).^0.5;
end
end
S=Dmin./(Dmax+Dmin);
S=S/sum(S);
%%
%对结果进行排序
[value,index]=sort(S)
- 用到的Positive函数
function X_Col=Positive(Need_Handle_Index,Kind_Index,Need_Handle_Col)
if Kind_Index==1
M=repmat(max(Need_Handle_Col),size(Need_Handle_Col,1),1);
X_Col=M-Need_Handle_Col;
elseif Kind_Index==2
best=input(['第',num2str(Need_Handle_Index),'列为中间型,请输入其best值\n']);
Best_Vector=repmat(best,size(Need_Handle_Col,1),1);
Max_Length=max(abs(Best_Vector-Need_Handle_Col));
Length=abs(Best_Vector-Need_Handle_Col);
M=repmat(Max_Length,size(Need_Handle_Col,1),1);
X_Col=ones(size(Need_Handle_Col,1),1)-Length./M;
elseif Kind_Index==3
X_Col_copy=zeros(size(Need_Handle_Col,1),1);
range=input(['第',num2str(Need_Handle_Index),'列为中间型,请输入其区间[left,right]值\n']);
Max_Length=max([max(Need_Handle_Col)-range(1,2),range(1,1)-min(Need_Handle_Index)]);
for i=1:size(Need_Handle_Col,1)
if Need_Handle_Col(i,1)>=range(1,1)&&Need_Handle_Col(i,1)<=range(1,2)
X_Col_copy(i,1)=1;
elseif Need_Handle_Col(i,1)<range(1,1)
X_Col_copy(i,1)=1-(range(1,1)-Need_Handle_Col(i,1))/Max_Length;
else
X_Col_copy(i,1)=1-(Need_Handle_Col(i,1)-range(1,2))/Max_Length;
end
end
X_Col=X_Col_copy;
end