目录
一、评价类模型
1.AHP(层次分析法)
2.TOPSIS法(优劣解距离方法)
二、插值与拟合模型
1.插值算法
2.拟合算法(cftool工具箱)
最基础的评价类模型,通过打分解决评价类问题(两两比较,推算权重)。
Matlab代码:
disp('请输入判断矩阵A')
A=input('A=');
[n,n] = size(A);
% 方法1:算术平均法求权重
Sum_A = sum(A);
SUM_A = repmat(Sum_A,n,1);
Stand_A = A ./ SUM_A;
disp('算术平均法求权重的结果为:');
disp(sum(Stand_A,2)./n)
% 方法2:几何平均法求权重
Prduct_A = prod(A,2);
Prduct_n_A = Prduct_A .^ (1/n);
disp('几何平均法求权重的结果为:');
disp(Prduct_n_A ./ sum(Prduct_n_A))
% 方法3:特征值法求权重
[V,D] = eig(A);
Max_eig = max(max(D));
[r,c]=find(D == Max_eig , 1);
disp('特征值法求权重的结果为:');
disp( V(:,c) ./ sum(V(:,c)) )
% 计算一致性比例CR
CI = (Max_eig - n) / (n-1);
RI=[0 0.0001 0.52 0.89 1.12 1.26 1.36 1.41 1.46 1.49 1.52 1.54 1.56 1.58 1.59];
CR=CI/RI(n);
disp('一致性指标CI=');disp(CI);
disp('一致性比例CR=');disp(CR);
if CR<0.10
disp('因为CR<0.10,所以该判断矩阵A的一致性可以接受!');
else
disp('注意:CR >= 0.10,因此该判断矩阵A需要进行修改!');
end
一种常用的综合评价方法,能充分利用原始数据的信息,反映各评价方案之间的差距。
改进:带权重的Topsis法(AHP or 熵权法)
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]: '); %[2,3,4]
disp('请输入需要处理的这些列的指标类型(1:极小型, 2:中间型, 3:区间型) ')
Type = input('例如:第2列是极小型,第3列是区间型,第6列是中间型,就输入[1,3,2]: '); %[2,1,3]
for i = 1 : size(Position,2)
X(:,Position(i)) = Positivization(X(:,Position(i)),Type(i),Position(i));
end
disp('正向化后的矩阵 X = ')
disp(X)
end
% 矩阵标准化
Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 Z = ')
disp(Z)
% 是否需要增加权重
disp("请输入是否需要增加权重向量,需要输入1,不需要输入0")
Judge = input('请输入是否需要增加权重: ');
if Judge == 1
Judge = input('使用熵权法确定权重请输入1,否则输入0: ');
if Judge == 1
if sum(sum(Z<0)) >0
disp('原来标准化得到的Z矩阵中存在负数,所以需要对X重新标准化')
for i = 1:n
for j = 1:m
Z(i,j) = [X(i,j) - min(X(:,j))] / [max(X(:,j)) - min(X(:,j))];
end
end
disp('X重新进行标准化得到的标准化矩阵Z为: ')
disp(Z)
end
weight = Entropy_Method(Z);
disp('熵权法确定的权重为:')
disp(weight)
else
disp(['如果你有3个指标,你就需要输入3个权重,例如它们分别为0.25,0.25,0.5, 则你需要输入[0.25,0.25,0.5]']);
weight = input(['你需要输入' num2str(m) '个权数。' '请以行向量的形式输入这' num2str(m) '个权重: ']);
OK = 0;
while OK == 0
if abs(sum(weight) -1)<0.000001 && size(weight,1) == 1 && size(weight,2) == m
OK =1;
else
weight = input('你输入的有误,请重新输入权重行向量: ');
end
end
end
else
weight = ones(1,m) ./ m ; %如果不需要加权重就默认权重都相同,即都为1/m
end
% 计算与最大值的距离和最小值的距离,并算出得分
D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ] .* repmat(weight,n,1) ,2) .^ 0.5;
D_N = sum([(Z - repmat(min(Z),n,1)) .^ 2 ] .* repmat(weight,n,1) ,2) .^ 0.5;
S = D_N ./ (D_P+D_N);
disp('最后的得分为:')
stand_S = S / sum(S)
[sorted_S,index] = sort(stand_S ,'descend')
数学建模中,常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,“模拟产生”一些新的但又比较靠谱的值来满足需求,这就是插值的作用。
分段三次埃尔米特插值 & 三次样条插值
Matlab代码:
% 在同一个脚本文件里面,要想画多个图,需要给每个图编号,否则只会显示最后一个图
% plot函数用法:
% plot(x1,y1,x2,y2)
% 线方式: - 实线 :点线 -. 虚点线 - - 波折线
% 点方式: . 圆点 +加号 * 星号 x x形 o 小圆
% 颜色: y黄; r红; g绿; b蓝; w白; k黑; m紫; c青
x = -pi:pi;
y = sin(x);
new_x = -pi:0.1:pi;
% 分段三次埃尔米特插值
p1 = pchip(x,y,new_x);
% 三次样条插值
p2 = spline(x,y,new_x);
plot(x,y,'o',new_x,p1,'r-',new_x,p2,'b-')
legend('样本点','分段三次埃尔米特插值','三次样条插值','Location','SouthEast')
总结:三次样条插值生成的曲线更加光滑。在实际建模中,由于我们不知道数据的生成过程,因此两种插值方法都可以使用。
一个Excel 数据插值实例
Matlab代码:
%% 插值预测中间周的水体评价指标
load Z.mat
x=Z(1,:);
[n,m]=size(Z);
% 注意Matlab的数组中不能保存字符串,如果要生成字符串数组,就需要使用元胞数组,用大括号{}定义和引用
ylab={'周数','轮虫','溶氧','COD','水温','PH值','盐度','透明度','总碱度','氯离子','透明度','生物量'};
disp(['共有' num2str(n-1) '个指标要进行插值。'])
P=zeros(11,15);
for i=2:n
y=Z(i,:);
new_x=1:15;
p1=pchip(x,y,new_x);
subplot(4,3,i-1);
plot(x,y,'ro',new_x,p1,'-');
axis([0 15,-inf,inf])
% xlabel('星期')
ylabel(ylab{i})
P(i-1,:)=p1;
end
legend('原始数据','三次埃尔米特插值数据','Location','SouthEast')
%把P的第一行加上周数
P = [1:15; P]
与插值问题不同,在拟合问题中不需要曲线一定经过给定的点。拟合问题的目标是寻求一个函数(曲线),使得该曲线在某种准则下与所有的数据点最为接近,即曲线拟合的最好(最小化损失函数)。
Matlab代码:
load data1
plot(x,y,'o')
xlabel('x的值')
ylabel('y的值')
n = size(x,1);
k = (n*sum(x.*y)-sum(x)*sum(y))/(n*sum(x.*x)-sum(x)*sum(x))
b = (sum(x.*x)*sum(y)-sum(x)*sum(x.*y))/(n*sum(x.*x)-sum(x)*sum(x))
% 继续在之前的图形上来画图形
hold on
% 显示网格线
grid on
f=@(x) k*x+b;
fplot(f,[2.5,7]);
legend('样本数据','拟合函数','location','SouthEast')
% y的拟合值
y_hat = k*x+b;
% 回归平方和
SSR = sum((y_hat-mean(y)).^2)
% 误差平方和
SSE = sum((y_hat-y).^2)
% 总体平方和
SST = sum((y-mean(y)).^2)
% 拟合优度
R_2 = SSR / SST
强大的曲线拟合工具箱:cftool
注意调整 Fit Options 参数的起始点!
(导出图像可以在渲染设置中调整为高分辨率)
Matlab代码:
x = rand(30,1) * 10;
y = 3 * exp(0.5*x) -5 + normrnd(0,1,30,1);
% cftool
内容原作者:数学建模清风
学习用途,仅作参考。