特征选择是一种特殊的模型选择方法。考虑一种情况,当样本维数n远大于样本个数m的时候,根据经验风险与结构风险的关系,如下:
K表示模型的VC维,m表示训练集大小。
样本维数n很大,那么即使是用最简单的线性回归,K也能达到O(n),后一项很大。
样本数量m很小,那么后一项很大。
这样,很容易造成过拟合问题。如上就是小样本的情况。
处理这种情况,由于VC维很难再降低了,而样本数的增加也是受限制的,我们选择减小样本维数。
一种方法是PCA,LDA等模式识别中常见的方法,类似小波变换,求得线性高能量子空间。还有一种就是这里要论述的特征选择。
我们寻找特征集的一个子集。考虑到n个特征的子集有n^2个,我们无法遍历这么多的子集。于是采用启发式的方法,一个简单的方式就是顺序寻找,流程如下:
每一次迭代,采用交叉验证的方法,选择效果最好的一个特征加入现有特征集合。
与上面的算法基本相同,只不过特征集合从满集开始,每次选取效果最差的特征去除。
上面两种方法,每次迭代加入或去除一个特征,那么如果遍历所有的,时间复杂度为O(n^2)。
下面这种方法是一种启发式的方法,用很少的代价选择特征。对于每个特征,计算简单的衡量值S(i),以此决定是否选择特征。
一个常用的衡量方法是线性相似性度量,即衡量xi与标签y的线性相关性系数。或者进一步的,我们可以用互信息衡量非线性的相关性系数。
互信息表示,一直x,y的不确定度减少了多少。减少的越多,说明这个变量与标签越相关。
之所以说互信息是衡量非线性的相关性,如下:
X,y的互信息=p(x)p(y)与p(x,y)的KL距离,也就是用p(x)p(y)来替代p(x,y),所要增加信息量。如果x,y完全独立,那么p(x,y)=p(x)p(y),KL距离为0,即I(x,y)=0,无法根据x猜测关于y的任何信息。
选用数据集:http://archive.ics.uci.edu/ml/datasets/Statlog+%28Australian+Credit+Approval%29
这里选用SVM为分类器。
clear;
clc;
load ‘data.mat‘;
[N,M]=size(train_feature);
train=[];%不断增加的训练与测试集
test=[];
n_0=sum(test_label==0)
n_1=sum(test_label==1)
n=length(test_label);
flag=zeros(N,1);%标记哪些特征已在特征集中
F=zeros(N,1);%记录各个特征的F值
max_iter=10;%最大迭代次数
for iter=1:max_iter
F=zeros(N,1);
for i=1:N
if(flag(i)==0)
train_temp=[train;train_feature(i,:)];
test_temp=[test;test_feature(i,:)];
svmStruct=svmtrain(train_temp‘,(train_label+1)‘);
D=svmclassify(svmStruct,test_temp‘);
%计算测试F值
acc=0;
pd=0;
pf=0;
pre=0;
D=D-1;
for ii=1:n
if(D(ii)==test_label(ii))
acc=acc+1;
end
if(D(ii)==1&&test_label(ii)==0)
pf=pf+1;
end
if(D(ii)==1&&test_label(ii)==1)
pd=pd+1;
end
if(D(ii)==1)
pre=pre+1;
end
end
acc=acc/n;
pre=pd/pre;
pf=pf/n_0;
pd=pd/n_1;
Fmeasure = 2*pd*pre/(pd+pre);
F(i)=Fmeasure;
end
end
[a,b]=max(F);
flag(b)=1;
train=[train;train_feature(b,:)];
test=[test;test_feature(b,:)];
%把最大F值的特征加入到特征集中
end
结果为:F_measure=85.97%
clear;
clc;
load ‘data.mat‘;
[N,M]=size(train_feature);
n_0=sum(test_label==0);
n_1=sum(test_label==1);
n=length(test_label);
for i=1:N
temp=train_feature(i,:);
I(i)=Info(temp,train_label);
end
[a,b]=sort(I,‘descend‘);
train=[];
test=[];
max_i=10;
for i=1:max_i
train=[train;train_feature(b(i),:)];
test=[test;test_feature(b(i),:)];
end
svmStruct=svmtrain(train‘,(train_label+1)‘);
D=svmclassify(svmStruct,test‘);
%计算测试F值
acc=0;
pd=0;
pf=0;
pre=0;
D=D-1;
for ii=1:n
if(D(ii)==test_label(ii))
acc=acc+1;
end
if(D(ii)==1&&test_label(ii)==0)
pf=pf+1;
end
if(D(ii)==1&&test_label(ii)==1)
pd=pd+1;
end
if(D(ii)==1)
pre=pre+1;
end
end
acc=acc/n;
pre=pd/pre;
pf=pf/n_0;
pd=pd/n_1;
Fmeasure = 2*pd*pre/(pd+pre);
计算一个特征与标签的互信息函数:
function I=Info(feature,label)
A=unique(feature);
[n,m]=size(label);
[N,M]=size(A);
n_0=sum(label==0);
n_1=sum(label==1);
p_xy=zeros(M,2);
p_y=zeros(1,2);
p_x=zeros(M,1);
p_y(1)=sum(label==0)/m;
p_y(2)=sum(label==1)/m;
for i=1:M
p_xy(i,1)=sum(label(feature==A(i))==0)/m;
p_xy(i,2)=sum(label(feature==A(i))==1)/m;
p_x(i,1)=sum(feature==A(i))/m;
end
I=0;
for i=1:M
if(p_xy(i,1)~=0)
I=I+p_xy(i,1)*log(p_xy(i,1)/(p_x(i)*p_y(1)));
end
if(p_xy(i,2)~=0)
I=I+p_xy(i,2)*log(p_xy(i,2)/(p_x(i)*p_y(2)));
end
end
同样取K=10;
结果:F_measure=84.21%
原文:http://blog.csdn.net/ice110956/article/details/23559373