如何用matlaab把csv转为mat文件_数学建模竞赛学习笔记:用TOPSIS模型进行综合评价

笔记整理来自清风老师的数学建模课程(可以在B站里搜索到,头条无法放站外链接,我就不放了):TOPSIS教程

目录

1. 层次分析法的局限性(主观求权重方法)

2. TOPSIS法引入

2.1 一个指标的情况

2.2 2个指标的情况

2.2.1 指标正向化

2.2.2 指标标准化处理

2.2.3 计算得分

2.2.4 实例计算

3. TOPSIS简介

4. TOPSIS法步骤

4.1 将原始矩阵正向化(可以在Excel中完成)

4.1.1 极小型指标转换为极大型指标

4.1.2 中间型指标转换为极大型指标

4.1.3 区间型指标转换为极大型指标

4.2 正向化矩阵标准化

4.3 计算得分并归一化

5. 例题:评价水质情况

6. 代码讲解

6.1 将数据导入到MATLAB中

6.2 判断指标是否正向化

6.2.1 极小型指标正向化

6.2.3 中间型指标正向化

6.2.4 区间型指标正向化

6.2.5 指标正向化处理

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

6.4 计算得分并归一化(计算与最大值的距离和最小值的距离,并算出得分)

7. 模型拓展


1. 层次分析法的局限性(主观求权重方法)

层次分析法真正的核心是判断矩阵的填写,但是判断矩阵受人为因素比较大,所以最后计算得出的权重也比较主观。如果在有数据的情况下最好不要使用层次分析法。

(1)评价的决策层不能太多,太多的话n会很大,判断矩阵和一致性差异可能会很大。(可能会通过不了一致性检验)

beaef9ea8215e89de40538f307e09af7.png

(2)如果决策层中指标的数据是已知的,那么我们如何利用这些数据来使得评价更加准确呢?

可以分析数据内在的特征就行评价。(熵权法、TOPSIS法)

2. TOPSIS法引入

2.1 一个指标的情况

小明同宿舍共有四名同学,他们第一学期的高数成绩如下表所示:

0cf6fbc82aea259c8f6c48c8d9ae08ea.png

f4b138fe2e886ee7677a4e40d09cf072.gif

请你为这四名同学进行评分,该评分能合理的描述其高数成绩的高低。(注:这里要求的评分可以类比于上一讲层次分析法中要求的那个权重)

4c0ac6b7c489935a61cbfb617010e188.png

修正后的排名表示数字越大越好,评分用排名的得分/总得分

ce7120abcddc36584f6a6a7731f2c4c7.png

可以随便修改成绩,只要保证排名不变,那么评分就不会改变!

【矛盾】评分没变说明结果有问题,说明这种评分方式不能够全部反应原始数据的全部信息。

想法1:把数都减去一个最小值。结果通过与(max-min)相处,将数字变为【0,1】之间的数。

43aece5ed7c95831c42a9473ba9585c1.png

将数归一化:

47ab2bca1915136a47596ea1cc447d9d.png

需要说明的问题:如果用下面这种方法,虽然结果更加精确,能够反应更多的原始信息;比如60分时,我们得到的结果是0.6,而不是0。但是需要知道理论的最大值和最小值。

但是大多数情况下,我们是无法知道理论的最大值与最小值的,只能得到1组数据中的最大值与最小值,所以常用的评分方法是上一种。

11e4df9be0a5679e0f751a8d8d0037af.png

为什么不用上面表格这个理论最大值最小值的公式:

a4f7cd73647c41e3c06fad9e06aa2f43.png

2.2 2个指标的情况

新增加了一个指标,现在要综合评价四位同学,并为他们进行评分。

fef3a785a7a33106d40731959616e082.png

成绩是越高(大)越好,这样的指标称为极大型指标(效益型指标)。与他人争吵的次数越少(越小)越好,这样的指标称为极小型指标(成本型指标)

在进行分析的时候我们需要将指标统一为一个类型,一般都转为极大型指标。

2.2.1 指标正向化

将所有的指标转化为极大型称为指标正向化(最常用)

52ce0bbd81f2b6c82bbb9f1b0993dd7b.png

7cd54c0cd45d0af7890cc0690302371b.png

可以在excel中进行计算。比如折扣需要正向化处理。

2.2.2 指标标准化处理

只有一个指标的时候不需要消除量纲的影响,但是2个指标及以上呢?

由于成绩和争吵次数的量纲不同(单位不同),所以需要消除指标对不同量纲的影响。

为了消去不同指标量纲的影响,需要对已经正向化的矩阵进行标准化处理

da25fd41293aa4236e2b38f6c202ee94.png

可以发现标准化后不会影响到指标的相对大小。

matlab代码:B = repmat(A,m,n):将矩阵A复制m×n块,即把A作为B的元素,B由m×n个A平铺而成。

X = [89 1; 60 3; 74 2; 99 0][n,m] = size(X)X./repmat(sum(X.*X).^0.5,n,1)
f4b138fe2e886ee7677a4e40d09cf072.gif

代码分解:

X.*X
f4b138fe2e886ee7677a4e40d09cf072.gif

得到

d7852014cff90ba4baa8e668f50347a1.png
f4b138fe2e886ee7677a4e40d09cf072.gif

4183b234aa382be811e2cc0ca58d9c59.png

sum(X.*X)

得到

cf964bb0e952f5b36952f56b1ceac911.png

5ead2cae664e1657ec6d4c66594fbcd3.png

sum(X.*X).^0.5

得到

96a3ae79a359759d217d09f869846758.png

3e78f6d8d0472da8ce331ed299628948.png

f4b138fe2e886ee7677a4e40d09cf072.gif

由于矩阵(点除)除法的运算需要行列一致。

repmat(sum(X.*X).^0.5,n,1)
aaa9805beb59d44c79f52c91da1474cd.png

f4b138fe2e886ee7677a4e40d09cf072.gif
 X./repmat(sum(X.*X).^0.5,n,1)
f4b138fe2e886ee7677a4e40d09cf072.gif

得到

dc349256a7b16c2f701b058e751486b7.png
f4b138fe2e886ee7677a4e40d09cf072.gif

f81f7a6575f94bac208723750232123c.png

f4b138fe2e886ee7677a4e40d09cf072.gif

所以:

f20fe2a47b1d52fda7b68d6e66282ac0.png

5fffd495a77080629b4e7f0db6892447.png

2.2.3 计算得分

9f209c613987f7871064e8eb9718471d.png

计算多个指标的得分时,可以类别只有一个指标时的得分。

68502b0288c447c9444377920ec0ac51.png

先求出每一列的最大值最小值,再求每个元素与最大值(最小值)的距离(欧式距离)。最后求得分即可。(和只有一个指标时的解法一样)

2.2.4 实例计算

cab436cf9c7e1a170d12105be1b7ccc8.png

a200cbc3841f7be0219f3b276abf4ff8.png

代码:

X = [89,1; 60,3; 74,2;99,0]%已经正向化后的矩阵[n,m] = size(X)Z = X./repmat(sum(X.*X) .^ 0.5,n,1)%标准化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);    % 未归一化的得分
f4b138fe2e886ee7677a4e40d09cf072.gif

D+代码分解:D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5; % D+ 与最大值的距离向量

 max(Z)%求出Z矩阵中每列的最大值。
f4b138fe2e886ee7677a4e40d09cf072.gif
30de4d22e9b65e00e0ba363b8c3269e5.png

repmat(max(Z),n,1)%将max(Z)矩阵复制n次
f4b138fe2e886ee7677a4e40d09cf072.gif
e6a585e1549d6d785ccb092e9bcc4b3a.png

f4b138fe2e886ee7677a4e40d09cf072.gif
(Z - repmat(max(Z),n,1))%得到每一行的数与最大值的差
f4b138fe2e886ee7677a4e40d09cf072.gif
118323c7d3bd2b18b2905b260def8643.png

f4b138fe2e886ee7677a4e40d09cf072.gif
 (Z - repmat(max(Z),n,1)) .^ 2%得到每行中的每个数与其最大值差的平方
f4b138fe2e886ee7677a4e40d09cf072.gif
70a01619de5aa2dd6b1d7c015f805ca6.png

f4b138fe2e886ee7677a4e40d09cf072.gif
 sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2)%得到(Z - repmat(max(Z),n,1)) .^ 2 ]矩阵每一行的和 后面不加2默认是求每一列的和。
f4b138fe2e886ee7677a4e40d09cf072.gif
25bd3513e69247a79c8e284e796d3557.png
f4b138fe2e886ee7677a4e40d09cf072.gif

fd2b849ce1c30e860a9f25256f0586d5.png
f4b138fe2e886ee7677a4e40d09cf072.gif

 sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) .^ 0.5 %将 sum([(Z - repmat(max(Z),n,1)) .^ 2 ],2) 的结果开根号
f4b138fe2e886ee7677a4e40d09cf072.gif

最后求得的结果就是D+的结果。

1fdfde13acfed2f2f737ad9d965c6629.png

f4b138fe2e886ee7677a4e40d09cf072.gif

结果如下:

737d78c98f23471dd9c4bfb64f7d2636.png

f4b138fe2e886ee7677a4e40d09cf072.gif

3. TOPSIS简介

C.L.Hwang 和 K.Yoon 于1981年首次提出 TOPSIS (Technique for Order Preference by Similarity to an Ideal Solution),可翻译为逼近理想解排序法,国内常简称为优劣解距离法

TOPSIS 法是一种常用的综合评价方法,能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。基本过程为:

(1)将原始数据矩阵统一指标类型(一般正向化处理)得到正向化的矩阵;

(2)再对正向化的矩阵进行标准化处理以消除各指标量纲的影响;

(3)并找到有限方案中的最优方案和最劣方案;

(4)然后分别计算各评价对象与最优方案和最劣方案间的距离;

(5)获得各评价对象与最优方案的相对接近程度,以此作为评价优劣的依据。

该方法对数据分布及样本含量没有严格限制,数据计算简单易行。

4. TOPSIS法步骤

4.1 将原始矩阵正向化(可以在Excel中完成)

d36731be7ddfceb3d4b5f3bfb2e7fe2c.png

f4b138fe2e886ee7677a4e40d09cf072.gif

所谓的将原始矩阵正向化,就是要将所有的指标类型统一转化为 极大型指标。(转换的函数形式可以不唯一哦~ )

多指标综合评价中指标正向化和无量纲化方法的选择

4.1.1 极小型指标转换为极大型指标

e547d527817f24a95dea2c8ce3443e0f.png

f4b138fe2e886ee7677a4e40d09cf072.gif

4.1.2 中间型指标转换为极大型指标

de39c13a22a00ef0b154c25a3325fe49.png

f4b138fe2e886ee7677a4e40d09cf072.gif

化简后的结果尽量在[0,1]之间。并且越靠近于最优值(这里为7)越接近于1.

4.1.3 区间型指标转换为极大型指标

da1b7726565b9b792b5b33a5568f5c7a.png

f4b138fe2e886ee7677a4e40d09cf072.gif

4.2 正向化矩阵标准化

标准化的目的是消除不同指标量纲的影响

7b5f767d08c727607991c12bc18a9431.png

f4b138fe2e886ee7677a4e40d09cf072.gif

【注意】标准化的方法有很多种,其主要目的就是去除量纲的影响,未来我们还可能见到更多 种的标准化方法,例如:(x‐x的均值)/x的标准差;具体选用哪一种标准化的方法在多数情况下 并没有很大的限制,这里我们采用的是前人的论文中用的比较多的一种标准化方法。

几种数据标准化的方法

指标标准化的方法

7d0b1959218fa4da150e3da5b9f86a46.png

f4b138fe2e886ee7677a4e40d09cf072.gif

4.3 计算得分并归一化

6ad84ba58d2a1bf9e6e5fc06afe4e3a3.png

f4b138fe2e886ee7677a4e40d09cf072.gif

5. 例题:评价水质情况

评价下表中20条河流的水质情况

注:含氧量越高越好;PH值越接近7越好;细菌总数越少越好;植物性营养物量介于10‐20之间最佳,超 过20或低于10均不好。

b24e89e891749d052c4b4604097856cf.png

f4b138fe2e886ee7677a4e40d09cf072.gif

代码知识点:

(1)将EXCEL中的数据导入到Matlab,并另存为mat文件,下次可直接load Matlab中函数的编写和调用

(2)magic(n)幻方矩阵

(3)sort函数

(4)zeros和ones函数

6. 代码讲解

6.1 将数据导入到MATLAB中

第一步:Ctrl+C复制Excel中的数据

91313708377fb5baacde5a047969d4d3.png

f4b138fe2e886ee7677a4e40d09cf072.gif

第二步:在工作区新建一个空白的数据文件(.mat),命名为data_water.

dbbfba1fb460e44e30664ffc3dec98f5.png

f4b138fe2e886ee7677a4e40d09cf072.gif

第三步:双击data_water,将数据按住Ctrl+v粘贴到里面即可。

5fa17bdda6ff7ce5af22ccd678ec9ba4.png

第四步:右击数据文件,另存为.mat文件,下次使用时可以直接用load导入数据。

401f2593c60e34ad1a26d2376a6575ee.png
f4b138fe2e886ee7677a4e40d09cf072.gif

3d2d2e07a4d13eccb7e499bd8e35a111.png
f4b138fe2e886ee7677a4e40d09cf072.gif

代码:

load data_water.mat
f4b138fe2e886ee7677a4e40d09cf072.gif

然后可以将数据表的文件名改成X(短一些,好写代码)

b1012aaebf15ed0f60339ce746eae504.png

f4b138fe2e886ee7677a4e40d09cf072.gif

6.2 判断指标是否正向化

第一步:判断是否需要正向化,只有当存在非极大型指标时才需要正向化处理。

[n,m] = size(X);disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标']) Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0:  ']);
f4b138fe2e886ee7677a4e40d09cf072.gif

这里采用矩阵的形式拼接字符。

c9733dfe6b2d0843a56f7a3c68f206b8.png

f4b138fe2e886ee7677a4e40d09cf072.gif

第二步:如果需要正向化处理,输入1.

if Judge == 1    Position = input('请输入需要正向化处理的指标所在的列,例如第2、3、6三列需要处理,那么你需要输入[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
f4b138fe2e886ee7677a4e40d09cf072.gif
4939f2551cca9727fbbc9c4941019b0a.png

6.2.1 极小型指标正向化

d1d4a1d8f750553c1c8122bf981588a6.png

function [posit_x] = Min2Max(x)    posit_x = max(x) - x;     %posit_x = 1 ./ x;    %如果x全部都大于0,也可以这样正向化end
f4b138fe2e886ee7677a4e40d09cf072.gif

6.2.3 中间型指标正向化

0964c6f12c08be5f7018efb85c156e65.png

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

6.2.4 区间型指标正向化

1e99fa5892256aa123d05a249446dda1.png

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    endend
f4b138fe2e886ee7677a4e40d09cf072.gif

6.2.5 指标正向化处理

% 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向量中是否有除了1、2、3之外的其他值')    endend
f4b138fe2e886ee7677a4e40d09cf072.gif

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

20db41e9618e5af17ce581fc16b1f13c.png

Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);disp('标准化矩阵 Z = ')disp(Z)
f4b138fe2e886ee7677a4e40d09cf072.gif

6.4 计算得分并归一化(计算与最大值的距离和最小值的距离,并算出得分)

e9ce3a67e218a70bb31588a9004f6fa4.png

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')
f4b138fe2e886ee7677a4e40d09cf072.gif
306f6977c6fbc680ac90f65ac7378fa2.png

排序(可以在Excel中完成),可以看出河流K的得分最高,排名最高。

06bb48e941de29957b99b9fc241e9697.png
7fa78ef84db80fa57dd326ae80926202.png

7. 模型拓展

0bfeeb2ba7adf8ab40a33a83acaeb5f9.png

如果觉得笔记不清楚,可以点击下方去CSDN博客观看。如有侵权,请联系删除。