基于Relief-F过滤式特征选择方法计算特征权重

Relief-F特征选择算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
clear;clc;
load 'F:\2020.0902\wine.mat';%加载数据
%归一化
wine_l = wine(:,1:12);
[wine_l ,pstrain] = mapminmax(wine_l');
pstrain.ymin = 0;
pstrain.ymax = 1;
[wine_l ,pstrain] = mapminmax(wine_l ,pstrain);
wine_ll = wine_l';
wine =[wine_ll(:,:),wine(:,13)];
%
D=wine(:,1:size(wine,2)-1);%排除编号的一列
global I;
I = wine;
m=80; %抽样次数
k=8; %k近邻
N=20; %运行次数

for i=1:N
W(i,:)=RelifF(D,m,k);
end

for i=1:N %将每次计算的权重进行绘图
plot(1:size(W,2),W(i,:));%size(A,1)获取A矩阵行数,size(A,2)获取A矩阵列数
hold on
end
for i=1:size(W,2) %计算N次中,每个属性的平均值
result(1,i)=sum(W(:,i))/size(W,1);
end

调用函数:RelifF.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
%Relief函数实现
%D为输入的训练集合,输入集合去掉身份信息;k为最近邻样本个数
function W=RelifF(D,m,k)
global I;
Rows=size(D,1); %样本个数
Cols=size(D,2); %特征个数
%将数据分成两类,加快计算速度
D1=zeros(0,Cols);%第一类,0行 []
D2=zeros(0,Cols);%第二类

for i=1:Rows
if I(i,Cols+1)==1 %mei
D1(size(D1,1)+1,:)=D(i,:);%matlab变量弱类型可以动态修改
elseif I(i,Cols+1)==2 %gan
D2(size(D2,1)+1,:)=D(i,:);
end
end %分好类填入D1和D2中

W=zeros(1,Cols);%初始化特征权重,置为0

for i=1:m %选择循环操作
%从D中随机选择一个样本R
[R,Dh,Dm]=GetRandSamples(D,D1,D2,k);
%更新特征权重
for j=1:length(W)
W(1,j)=W(1,j)-sum(Dh(:,j))/(k*m)+sum(Dm(:,j))/(k*m);%按照公式这里的sum就是上面公式中从1到k的求和,因为Dh和Dm是k行
%sum不仅可以对矩阵求和,还能对矩阵元素满足条件的元素求和,比如sum(D(:,size(D,2)==2)
%这样只对D的最后一列是2的累计加1
end
end

调用函数:GetRandSamples.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
%获取随机R 找出邻近样本
%D:训练集 D1:类别1数据集 D2:类别2数据集
%Dh 与R同类相邻样本距离; Dm:与R不同类的相邻样本距离
function [R,Dh,Dm]=GetRandSamples(D,D1,D2,k)
global I;
%先随机产生一个随机数,确定选定的样本R
r=ceil(1+(size(D,1)-1)*rand);
R=I(r,:);%将第r行选中赋值给R
d1=zeros(1,0);%置0,d1,d2是与R的距离,0列 []
d2=zeros(1,0);
%D1,D2已经分好类了
for i=1:size(D1,1) %计算R与D1的距离
d1(1,i)=norm(R(:,1:10)-D1(i,:)); %norm用来求两个向量之间的距离,即求R和D1中每行的距离放入对应d1行中
end
for j=1:size(D2,1) %计算R与D2的距离
d2(1,j)=norm(R(:,1:10)-D2(j,:));
end
[v1,L1]=sort(d1);%对d1,d2进行排序,这里v1是排行序的结果,L1是现在排好序的位置处的元素原本是在哪个位置上的,即建立了原来和现在元素索引的一种映射
[v2,L2]=sort(d2);
if R(1,size(R,2))==1 %如果样本R=2是良性
H=D1(L1(1,2:k+1),:); %L1中是与R最近距离的变化,赋给H,除去自身的,因为第一个是R,不能加入
M=D2(L2(1,1:k),:);%
else
%之前版本
% H=D1(L1(1,1:k),:);
% M=D2(L2(1,2:k+1),:);%同上面的if中的H

%更改版本, 依据公式,这里H和M分别表示和R的同类与不同类的样本集。由于R的变化,所以这里H和M相比较之前的需要互换下位置
M=D1(L1(1,1:k),:);
H=D2(L2(1,2:k+1),:);%同上面的if中的H
end
%循环计算2个样本特征之间的特征距离
for i=1:size(H,1)
for j=1:size(H,2)
Dh(i,j)=abs(H(i,j)-R(1,j))/10; %公式进行求得diff值,因为A连续从1到10
Dm(i,j)=abs(M(i,j)-R(1,j))/10;
end
end%(R特征-Mk特征)/(max-min)

在MATLAB中可以采用其集成的函数直接计算:

1
2
3
4
5
load fisheriris;%matlab中自带的数据集

[ranks,weights] = relieff(meas,species,10,'method','classification');

plot(weights','DisplayName','weight')

Snipaste_2024-05-08_15-41-48.png