ML—F值与特征选择

华电北风吹

天津大学认知计算与应用重点实验室

最后修改日期:2015/8/22


      在现实数据处理中很多时候往往都需要对得到的数据做特征选择,因为很多采集的样本特征是无效的,最明显的例子就是核磁数据,每一个核磁数据样本都是上万维的数据,降维大部分依赖于mask的获取。但是mask的获取需要先验知识来确定固定的脑区mask,但是如果没有先验知识的话我们就需要一个标准来将特征排序,供我们选择有用的特征。本文介绍F值在特征选择中的原理及应用。

      首先,来说一说单因素方差分析。单因素方差分析的前提是不同条件下各个样本服从正态分布,每一个条件下的样本服从于这个类别的正态分布,并且相互独立。零假设是:所有条件下样本的均值相等;备择假设当然是均值不等了。然后怎么来判断是否要拒绝零假设(这里记得还有一个问题就是拒绝不代表接受,这个涉及到第一类错误和第二类错误问题,详细介绍参看方差分析相关博文),方差分析告诉我们F值是组间平方和的均值与组内平方和的均值的商,F值越大,代表组间差距越大,因此接受零假设的概率就越小。

      其次,对于样本的每一个特征来说这些特征是来自于不同的类别,我的目标是得到有助于我进行分类的那些特征,为了区分出不同的类别,我要挑选的特征肯定是与类别相关的,而F值在方差分析中的原理告诉我们F值越大,组间差距就越大,而且对于采集到的样本来说他们的F分布的自由度是完全相同的,因此F值具有可比性,所以可以利用F值排序,F值大的先选择,一次往后,直到挑选够想要的特征个数。

      接下来说说我对F值做特征选择的思考,有不对的地方,欢迎大家交流。F值仅仅是一种参考指标,因为方差分析里面F值有效需要满足正态分布的前提,而这里不管样本所属类别是否满足正态性。

      第一个函数计算F值调用了matlab做方差分析的内部函数,第二个是参考F值的计算公式。

函数一:

function [selected_indices, selected_feature_matrix] = FValueCalcuation(feature_matrix, labels, selected_feature_num)

feature_number = size(feature_matrix, 2);
f_values = zeros(feature_number, 1);

for i = 1 : feature_number
    [p,table] = anova1(feature_matrix(:, i),labels, 'off'); %#ok<ASGLU>
    f_values(i, 1) = table{2, 5};
end

index_f_value = [(1:feature_number)', f_values];
index_f_value = flipdim( sortrows(index_f_value, 2), 1 );


selected_indices = sort(index_f_value(1:selected_feature_num, 1));
selected_feature_matrix = feature_matrix(:, selected_indices);
end

函数二:

function [result] = FScoreCalculate(Data,Label)
% 自己写的
% F-Score, use the N var formulation,详细解释见数据分析 单因素方差分析F值计算公式
% Data, the data, each raw is an instance
% Label, the label in 1 2 3 ... format,stand for the classtype


classNum = max(Label);
[~, featureNum] = size(Data);
result.fisherscore = zeros(1,featureNum);


% statistic for classes
classSet = cell(classNum,1);
classLength = zeros(classNum,1);
for k = 1:classNum
    classSet{k} = find(Label(:)==k);
    classLength(k) = length(classSet{k});
end


% calculate score for each features
for i = 1:featureNum
    temp1 = 0;
    temp2 = 0;
    feature = Data(:,i);
    totalmean = mean(feature);
    for k = 1:classNum
        classmean = mean(feature(classSet{k}));
        classvar = var(feature(classSet{k}),1);
        temp1 = temp1+classLength(k)*(classmean-totalmean)^2;
        temp2 = temp2+(classLength(k)-1)*classvar;
    end
    
    if temp1 == 0
        result.fisherscore(i) = 0;
    else
        if temp2 == 0
            result.fisherscore(i) = 100;
        else
            result.fisherscore(i) = temp1/temp2;
        end
    end
end


[~, result.DescendList] = sort(result.fisherscore, 'descend');


------------------
祝身体健康,万事如意

张正义

天津大学计算机科学与技术学院

天津市卫津路92号

邮编: 300072

邮箱: [email protected]


你可能感兴趣的:(matlab,特征选择,方差分析,F值)