Matlab常用模板

1. 归一化

1.1 映射到[0, 1]-线性归一化

公式:Xi = (Xi - min) / (max - min)
代码:
% 对象:X-->(m*n)
% 按列归一化
max = max(X); % 1*n
min = min(X); % 1*n
Denominator = max - min; % 1*n
Molecular = X - min; % m*n
X = Molecular ./ Denominator; % m*n

1.2 各元素平方和为1

公式:Xi = Xi / sqrt(X^2)
代码:
% 对象-->(m*n)
% 按列归一化
Denominator = sqrt(sum(X.^2)); % 1*n
X = X ./ Denominator; % m*n

2. 正向化

详细代码请见E:\竞赛考证类\数学建模\清风数模教程\课件及代码\第2讲.TOPSIS法(优劣解距离法)

2.1 极小型:

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

2.2 中间型:

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

2.3 区间型:

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
    end
end

2.4 正向化函数(转为最大型):

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之外的其他值')
    end
end

2.5 最终调用:

[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]
    % 注意,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

3. 灰色关联分析

%%
% Raw_Data是以列为单位,主要有子序列和母序列。比如子序列有k个、母序列有h个。
% 那么返回值将是h*k的矩阵,第h行代表第h个母序列与k个子序列的灰色关联度。
% 而且灰色关联度是经过归一化后的。
% y_start:母序列从第几列开始,比如子序列1、子序列2、子序列3、母1、母2
% 那么y_start=4,返回的灰色关联度矩阵是23%%
function [rela_dg_normalize] = GrayRelate(Raw_Data, y_start)
[m, n] = size(Raw_Data);  % 包含子序列和母序列
% 保存母序列与子序列的关联度,先置为0。维度为[母序列个数 子序列个数]
rela_dg = zeros(n-y_start+1, y_start-1);

% 标准化处理(每个数据除以均值)(1->以列求均值)
Raw_Data_mean = mean(Raw_Data, 1);
for i = 1:n
    Raw_Data(:, i) = Raw_Data(:, i) / Raw_Data_mean(i);
end
% 子序列X
X = Raw_Data(:, 1:y_start-1);
% 有多个目序列(矩阵Y),通过迭代来求每个母序列和子序列的关联度
Y = Raw_Data(:, y_start:end);
[y_m, y_n] = size(Y);
% 分辨系数,一般取0.5
rho = 0.5;

% 迭代母序列
for i = 1:y_n
    % 第i个母序列和子序列X的关联度计算
    Y_temp = Y(:, i);
    Y_tempminusX = abs(Y_temp-X);
    % 找到灰色关联需要的最小值和最大值(a、b)
    a = min(min(Y_tempminusX));
    b = max(max(Y_tempminusX));
    % 计算母序列和子序列关联度的第一步
    YrelaX = (a+rho*b) ./ (Y_tempminusX + rho*b);
    % 计算母序列和子序列关联度第二步(求均值)
    rela_dg(i, :) = mean(YrelaX, 1);
end

% 归一化关联度
[rela_m, rela_n] = size(rela_dg);
rela_sum = sum(rela_dg, 2);  % 按行求和
rela_sum = repmat(rela_sum, [1, rela_n]);
rela_dg_normalize = rela_dg ./ rela_sum;
rela_dg_normalize = rela_dg;
end

在这里插入图片描述

4. 数据剔除

function [Y] = DataCull(X,col)
% 以第col列按3δ原则进行数据剔除,具体几δ原则看效果,下面是2δ原则
% 即每一列代表一个指标。col可以为一个行向量
% 如col=[1 3 4],代表第134列数据都要作为剔除标准

[m_col, n_col] = size(col);  % m_col应该为1(行向量)
index_col = cell(m_col, n_col);  % 保存坏数据的索引
for i = 1:n_col
     aver = mean(X(:, col(i)));
    std_value = std(X(:, col(i)));
    % 2δ原则,找到不满足条件的索引
    index_col{i} = find(abs(X(:, col(i))-aver) > 2*std_value);
end
% 合并不满足条件的索引
index_all = [];
for i = 1:n_col
   index_all = [index_all;index_col{i}];
end
index_all = unique(index_all);  % 去除重复索引
Y = X;
Y(index_all, :) = [];  % 剔除掉不满足条件的数
% *** 从index_col{i}可以知道每一列数据剔除了多少个 ***
end

5. 找到连续n个1(logicMatrix)

m = [1,0,0,1,1,1,1,0,1,1,1,0,0,0,1];
% [0, m, 0] = [0, 1,0,0,1,1,1,1,0,1,1,1,0,0,0,1, 0];
% diff[0, m, 0] = [1,-1,0,1,0,0,0,-1,1,0,0,-1,0,0,1,-1];
k = find(diff([0,m,0]))';  % 前后补零、前向差分、找到非0元素索引
% 偶数位置-奇数位置。g的元素个数就代表了有几次连续的1
g = find(k(2:2:end)- k(1:2:end)>=3);  % 连续31及以上
[k(2*g-1),k(2*g)-1];

在这里插入图片描述

解读:第一次连续3个1以上是4-7、第二次是9-11
一般化

在一个向量中寻找n个连续的m

1.根据要求化为逻辑向量:X = (X == m)

X = [1 0 0 0 1 1 1 1 0 1 0];  % 逻辑化后

2.根据第一步,值为m的现在都为1,即现在就是找连续的n个1
3.X前后都补零,然后使用diff进行一阶前向差分:X = diff(X, 1)。

X = [0 1 0 0 0 1 1 1 1 0 1 0 0];  % 前后补零
X = [1,-1,0,0,1,0,0,0,-1,1,-1,0];  % 一阶前向差分后,且第一个非零元素为1

4.经过第3步后,X中非零元素的顺序必定是1和-1交替、且第一个是1,即1、-1、1、-1、…
1代表1的开始、-1代表1的结束
5.找到X中非零元素的索引:index = find(X)

index = [1,2,5,9,10,11];  % 非零元素的索引,且第一个为1
%X(index(2:2:end))都为-1X(index(1:2:end))都为11-1交替
% 而连续的n个1,其一阶前向差分后必定是1 0 0 ... 0 0 -1% 比如原本是 0 1 1 1 0 1、补零后 0 0 1 1 1 0 1 0
% 一阶前向差分后 0 1 0 0 -1 1 -1
% 有两段 1-1的变化,1代表1的开始、-1代表1的结束
% 非零偶数位置(-1) - 非零奇数位置(1)[5 7] - [2 6] = [3 1]

6.取index中偶数位置元素pos1 = index(2:2:end);取奇数位置元素pos2 = index(1:2:end)。
7.num = find((pos1 - pos2) >= n);
在一个逻辑向量X中找连续n个0,则在X的前后补1,然后一阶前向差分。得到的结果中除去零元素后只有-1和1,且第一个必定是-1。
在一个逻辑向量X中找连续n个1,则在X的前后补0,然后一阶前向差分。得到的结果中除去零元素后只有-1和1,且第一个必定是1。

MATLAB中,负值正向化的代码可以通过如下步骤实现: 1. 首先,你需要定义一个函数,比如称之为"guiyi"。这个函数接受四个输入参数,分别是待处理的向量x,归一化的下界和上界,以及一个参数a。具体的代码示例可以参考引用。 2. 在函数"guiyi"中,你可以使用MATLAB的条件判断语句来处理负值。比如,当x大于等于0时,保持不变;当x小于0时,将其转化为正数。具体的实现方法可以参考引用中的代码。 3. 运行主程序,使用"Ind"数组来指定需要处理的列数。如果某个指标是负值,将"Ind"数组中相应的元素改为2,即可实现对负值的正向化。具体的操作步骤可以参考引用中的代码。 4. 运行主程序后,即可得到处理后的权值"w",即各项的权值,它可以反映数据的重要程度。具体的计算方法可以参考引用中的代码。 总结来说,你可以使用条件判断语句来判断负值并对其进行处理,并通过指定"Ind"数组来确定需要处理的列数。这样就能实现MATLAB中负值的正向化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [美赛常用算法及matlab代码——(3)熵权法](https://blog.csdn.net/weixin_39881167/article/details/116038828)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值