当我们碰到数据集的维度特别大的时候,如果保存所有变量置入模型,不可避免的出现算法迭代次数缓慢,极易导致CPU达到满负荷,并且计算结果并不尽如人意,所以有必要进行特征选择保留能够提供重要信息的特征。
过滤式选择
这里笔者学习南京大学周志华教授《机器学习》第11章特征选择中的过滤式选择一节(只考虑二分类)给出基本算法步骤
声明
- 工具:MATLAB
- 数据格式:行为样本数,列为特征数,label可与样本特征在一个数据集里
算法步骤
-
读入训练集样本,{( x 1 x_1 x1, y 1 y_1 y1),……,( x m , y m x_m,y_m xm,ym)}.并进行归一化
-
使用距离算法 d i s t dist dist(笔者采用闵氏距离),计算得到样本 x i x_i xi在同类样本(即与 y i y_i yi相同的样本)中距离最小的或称为最近邻样本 x i , n h x_{i,nh} xi,nh(这里周志华教授称此样本点为‘猜中紧邻’ n h nh nh为near-hit的缩写)
-
同理计算得到异类样本中最近邻点 x i , n m x_{i,nm} xi,nm
-
遍历完成后,应该得到每一个样本与其两个近邻点,计算统计量 δ j \delta^j δj
δ j = Σ i m − d i f f ( x i j , x i , n h j ) 2 + d i f f ( x i j , x i , n m j ) 2 \quad\quad\quad\delta^j=\Sigma_i^m{-diff(x_i^j,x_{i,nh}^j)^2+diff(x_i^j,x_{i,nm}^j)^2} δj=Σim−diff(xij,xi,nhj)2+diff(xij,xi,nmj)2
其中,函数diff(a,b)=|a-b|(这里笔者稍感疑惑,公式里已对diff的结果进行平方,那么不太需要绝对值),这样, δ j \delta^j δj是统计量 δ \delta δ第j个分量在所有样本上取值的加和 -
给定阈值 τ \tau τ,记录 δ \delta δ所有大于 τ \tau τ的分量索引,根据此索引保留原始特征
下面给出代码
function data_matrix = Relief(filename,tau)
data = xlsread(filename);%写入文件路径,读取数据
[data_row,data_col] = size(data); %获取样本行数列数
for i = 1:data_col-1
if max(data(:,i))~=0
data(:,i) = (data(:,i)-min(data(:,i)))/(max(data(:,i))-min(data(:,i)));
end
end
%进行归一化,分类样本只对特征进行归一化,不对label进行归一化
all_distance = cell(3,data_row);%创建一个元胞数组,储存每一个样本及其近邻样本
for j = 1:data_row
all_distance{1,j} = data(j,1:data_col-1);
middle_same = data(find(data(:,data_col)==data(j,data_col)),1:data_col-1);
j_find = find_this_matrix(middle_same,data(j,1:data_col-1));
middle_same(j_find,:) = [];
distance = dist(data(j,1:data_col-1),middle_same);
min_index = find(distance==min(distance));
if length(min_index)>1
u = min_index(1);
else
u = min_index;
end
all_distance{2,j} = middle_same(u,:);
middle_same = data(find(data(:,data_col)~=data(j,data_col)),1:data_col-1);
distance = dist(data(j,1:data_col-1),middle_same);
min_distance = find(distance==min(distance));
if length(min_distance)<1
u = min_distance(1);
else
u = min_distance;
end
all_distance{3,j} = middle_same(u,:);
end
%遍历样本寻找最近邻样本并储存在元胞数组中,其中dist()为笔者自编距离函数,读者可使用matlab自带求距离函数pdist2()
dota_matrix = zeros(data_row,data_col-1);
for o = 1:data_row
dota_matrix(o,:) = -(all_distance{1,o}-all_distance{2,o}).^2+(all_distance{1,o}-all_distance{3,o}).^2;
end
dota = sum(dota_matrix,1);%从上边for循环到此步,已然如算法步骤4公式计算得到δ
effect = find(dota>=tau);%得到索引
data_matrix = data(:,effect);%生成筛选后的数据集
end
其中find_this_matrix函数文件如下
function index = find_this_matrix(a,b)
%a is a matrix and b is a vector.
%the function aim to find row of a equal b
k = size(a,1);
i=0;
for j = 1:k
if a(j,:)==b
i = i+1;
index(i)=j;
end
end
index = index';
end
dist函数文件如下
function distance = dist(a,b,p)
if nargin == 2
p=2;
distance=dist(a,b,p);
end
%默认为欧氏距离
if size(a,2)~=size(b,2)
disp('error:两样本维度不同')
else%判断是否只是计算两个向量的距离
distance=zeros(1,size(b,1));
for j = 1:size(b,1)
distance(j) = (sum((a-b(j,:)).^2))^(1/p);
end
end
end
参考文献
周志华.机器学习[M],北京:清华大学出版社,2016.01.