一、数据正向化


将数据中评价需要使用的极小性指标,中间型指标,区间型指标正向为极大型指标,具体方法如下:

极小型指标正向化公式:

\hat{x}_i=\max -x_i  或

 \hat{x}_i=\frac{1}{x_i}

中间型指标正向化公式:先求出与设定中间值x_{\text {best }}(最佳值)相差最远的值作为M

 M=\max \left\{\left|x_i-x_{\text {best }}\right|\right\}

之后正向化:

\hat{x}_i=1-\frac{x_i-x_{\text {best }}}{M}

区间型指标正向化公式:设置最佳区间[a,b],计算M

M=\max \left\{a-\min \left\{x_i\right\}, \max \left\{x_i\right\}-b\right\}

之后正向化:

\hat{x}_i= \begin{cases}1-\frac{a-x_i}{M}, & x_i<a \\ 1, & a<x_i<b \\ 1-\frac{x_i-b}{M}, & x_i>b\end{cases}

二、标准化

采用公式:

z_{i j}=\frac{x_{i j}}{\sqrt{\sum_{i=1}^n x_{i j}^2}}

即每个元素除以所在列元素平方和的开方,得到标准化后的矩阵Z

三、求出最优解与最劣解


计算每个方案与其最优解最劣解的距离

选出每列中的最大值组成向量作为最优解

z^{+}=\left[z_1^{+}, z_2^{+}, \ldots, z_m^{+}\right]=\left[\max \left\{z_{11}, z_{21}, \ldots, z_{n 1}\right\}, \max \left\{z_{12}, z_{22}, \ldots, z_{n 2}\right\}, \ldots, \max \left\{z_{1 m}, z_{2 m}, \ldots, z_{n m}\right\}\right]

选出每列中的最小值组成向量作为最劣解

z^{-}=\left[z_1^{-}, z_2^{-}, \ldots, z_m^{-}\right]=\left[\min \left\{z_{11}, z_{21}, \ldots, z_{n 1}\right\}, \min \left\{z_{12}, z_{22}, \ldots, z_{n 2}\right\}, \ldots, \min \left\{z_{1 m}, z_{2 m}, \ldots, z_{m m}\right\}\right]


四、得出结果并排序
根据最优解与最劣解算出得分并排序

计算公式:对于每一个方案(样例)计算与最优解的距离

d_i^{+}=\sqrt{\sum_{j=1}^m\left(z_j^{+}-z_{i j}\right)^2}

计算与最劣解的距离

d_i^{-}=\sqrt{\sum_{j=1}^m\left(z_j^{-}-z_{i j}\right)^2}

综合以上两个距离进行评分:

S_i=\frac{d_i^{-}}{d_i^{+}+d_i^{-}}

根据公式,当d+越小的时候,即我们的样例与最优解的差距越小的时候Si越大,最后根据Si的排序得到最优样例即是我们要求的解。

五、应用,数据为水域采集的样本值包括PH值、含氧量等内容,要求选出最好、最差的样例。

数据如下:

河流 含氧量(ppm) PH值 细菌总数(个/mL) 植物性营养物量(ppm)
A 4.69 6.59 51 11.94
B 2.03 7.86 19 6.46
C 9.11 6.31 46 8.91
D 8.61 7.05 46 26.43
E 7.13 6.5 50 23.57
F 2.39 6.77 38 24.62
G 7.69 6.79 38 6.01
H 9.3 6.81 27 31.57
I 5.45 7.62 5 18.46
J 6.19 7.27 17 7.51
K 7.93 7.53 9 6.52
L 4.4 7.28 17 25.3
M 7.46 8.24 23 14.42
N 2.01 5.55 47 26.31
O 2.04 6.4 23 17.91
P 7.73 6.14 52 15.72
Q 6.35 7.58 25 29.46
R 8.29 8.41 39 12.02
S 3.54 7.27 54 3.16
T 7.44 6.26 8 28.41

代码如下:

topsis.m:

%导入数据到matlab中
%先在工作区新建临时变量,将数据拷贝到临时变量后再存储为matlab内的数据文件
load data_water_quality.mat
[n,m] = size(X);
disp(['含有' num2str(n) '个评价对象,' num2str(m) '个评价对象']);
Judge = input(['这' num2str(m) '个指标是否需要正向化,需要输入1,不需要输入0:']);%判断是否需要正向化
if Judge == 1
    Position = input('输入需要正向化的指标列如2,3,6列,输入[2,3,6]:');%获取需要正向化的列
    disp('输入每列需要正向化的指标类型:1.极小型 2.中间型 3.区间型');%获取每列的正向化类型
    Type = input('输入每列需要的类型,如2列极小型输入1,3列为区间型输入3,6列为中间型输入2:');
    for i = 1:size(Position,2)
        X(:,Position(i)) = Positivization(X(:,Position(i)),Position(i),Type(i));%将正向化的数据存入X中
    end
    disp('正向化后的矩阵X = ');
    disp(X);
end
%对正向化后的矩阵进行标准化
Z = X./repmat(sum(X.*X).^0.5,n,1);
disp('标准化后的矩阵为:');
disp(Z);

%计算与最大值的距离和最小值的距离,并算出得分
D_p = sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5;
D_n = sum([(Z - repmat(min(Z),n,1)) .^ 2 ],2) .^ 0.5;
S  = D_n./(D_p+D_n);
disp('最后的得分为:')
stand_s = S/sum(S);
disp(stand_s);


        

Positivization.m:

function [position_x] = Positivization(x,i,type)
%x为需要正向化的列
%position为原始数据的所在列
%type为正向化的标准
    if type == 1
        disp(['第' num2str(i) '列是极小型,正在进行正向化处理']);
        position_x = Min2Max(x);
        disp(['正向化处理完成']);
        disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~~~');
    elseif type == 2
        disp(['第' num2str(i) '列是中间型']);
        best = input('请输入最佳值');
        position_x = Mid2Max(x,best);
        disp(['正向化处理完成']);
        disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~~~');
    elseif type == 3
        disp(['第' num2str(i) '列是区间型']);
        a = input('请输入区间的下界:');
        b = input('请输入区间的上界:');
        position_x = Inter2Max(x,a,b);
        disp(['正向化处理完成']);
        disp('~~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~~~~');
    else
        disp('没有这种类型的正向化处理,请检查是否输入错误');
        return;
    end
end

Min2Max.m:

function [posit_x] = Min2Max(x)
    posit_x = max(x) - x;
end

Mid2Max.m:

function [posit_x] = Mid2Max(x,best)
    M = max(abs(x-best));
    posit_x = 1 - abs(x - best)/M;
end

Inter2Max.m:

function [posit_x] = Inter2Max(x,a,b)
    r_x = size(x,1);
    M = max([a - min(x),max(x)-b]);
    posit_x = zeros(r_x,1);%初始化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

结果如下:范围我设置的为PH=7 营养物15-20

最后的得分为:
    0.0454 A
    0.0422 B
    0.0448 C
    0.0512 D
    0.0471 E
    0.0482 F
    0.0478 G
    0.0508 H
    0.0730 I
    0.0598 J
    0.0601 K
    0.0617 L
    0.0571 M
    0.0231 N
    0.0585 O 
    0.0487 P
    0.0470 Q
    0.0443 R
    0.0318 S
    0.0573 T

最优的为I样例 最差的为N样例

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐