模式识别之数据降维(一):使用遗传算法进行特征提取

技术凯 2020-12-27 09:15:43 13790
一、前言

  在之前的文章中,我们已经接触了一些分类器,在使用这些分类器的时候,我们直接将数据集作为输入,虽然能够达到不错的分类效果,但是程序耗时普遍较高,尤其是多分类任务。毕竟我们使用的数据集维数为190,也就是说我们的数据集中每个数据都有190个特征。聪明的读者可能会想,这190个特征缺一不可吗?我们能不能只使用其中的个别特征就实现性能不错的分类器呢?答案当然是可以,本篇文章开始,我们将介绍数据降维的方法。
  数据降维可以分为两个大类:特征选择和特征提取。特征选择是直接选择对分类有用的特征,放弃其他的特征,以降低数据的维度。特征提取是将数据进行一定的变换,比如前面所讲的fisher线性判别,我们可以使用类似投影的方法,将高维数据变换到低维,以实现数据降维。我们先从特征选择开始介绍。本篇文章,我们将为大家介绍其中一种特征选择的方法,即使用遗传算法进行特征选择。关于遗传算法,我在另一个系列的文章中专门介绍过,感兴趣的读者可以自行查阅。

二、matlab实现

  使用遗传算法进行特征选择。经过20轮选择、交叉、变异的过程,选出最优的40个维度的特征。适应度设为bayes分类器的正确率。
相关代码如下:

(1)读取数据集并产生初始化种群

(2)经过20轮迭代,每轮进行一次选择、交叉、变异过程

(3)在最后一轮迭代生成的50个个体中,选出最优的一个,作为最终特征选择的结果

(4)初始化种群的函数

(5)选择过程函数。使用赌轮算法,适应度越大的个体越容易被选中

(6)交叉过程函数


(7)变异过程


(8)适应度函数。即贝叶斯分类过程,分类的正确率作为输出的适应度


完整代码如下:

%使用遗传算法进行特征选择,学习算法采用贝叶斯
clear
load('2-Class Problem.mat');
tic
% 产生初始化种群,其中含有50个个体,一个个体含有190个维度,最终选择出40个最优的维度
pop_init=pop_init_genrator(50,190,40);
pop_last=pop_init;
% 开始迭代
for iter=1:20
    fprintf('开始第%d次迭代\n',iter);
    pop_new=pop_select(pop_last,Training_class1,Training_class2,Testing,Label_Testing);%选择
    pop_new=cross(pop_new);%交叉
    pop_new=variation(pop_new);%变异
    pop_last=pop_new;
end
pop_selected=pop_last;
%计算适应度,选择最优的个体,即选出最终的特征
% fit=fitness_jd(pop_selected,Training_class1,Training_class2);
fit=fitness_bayes(pop_selected,Training_class1,Training_class2,Testing,Label_Testing);
fit_sort=sort(fit);
best_pop=pop_selected(fit==fit_sort(end),:);
feature_selected=find(best_pop==1);
save('feature_selected_GA','feature_selected');
toc
% 产生初始种群的函数 pop_nums:种群数量 precision:精度,这里指特征的总数量 
% positive:一个个体中‘1’的个数,这里指最终选择40个特征
function pop_init=pop_init_genrator(pop_nums,precision,positive)
    pop_init=zeros(pop_nums,precision);
    for i=1:pop_nums
        pop_init(i,:)=randerr(1,precision,positive);
    end
end
% 选择,使用赌轮算法
function pop_new=pop_select(pop_last,train_class1,train_class2,Testing,Label_Testing)
    disk=0;%初始化轮盘
%     fit=fitness_jd(pop_last,train_class1,train_class2);%计算上一代每个个体的适应度
    fit=fitness_bayes(pop_last,train_class1,train_class2,Testing,Label_Testing);
    pop_nums=size(fit,2);
%     定义轮盘,每一个个体的区域正比于个体的适应度,个体适应度越高,被选中的概率越大
    for i=1:pop_nums
        disk(i)=sum(fit(1:i));
    end
    rand_=max(fit)*rand(1,pop_nums);%产生一组随机数,随机数的个数等于种群的个体数
    %选择
    for i=1:pop_nums
        temp=find(disk<rand_(i));
        index=size(temp,2)+1;%找到随机数落在轮盘的位置
        pop_new(i,:)=pop_last(index,:);
    end
end
%交叉
function pop_output=cross(pop_input)
    pop_nums=size(pop_input,1);%种群数量
    pop_dim=size(pop_input,2);%特征数

    %将种群随机分成两部分,作为两个父代
    select_index=randperm(pop_nums,floor(pop_nums/2));
    father1=pop_input(select_index,:);
    father2=pop_input;
    father2(select_index,:)=[];
    for i=1:pop_nums/2
        cross_len=randi(pop_dim/2,1);%产生一个随机数,以确定交叉片段的长度
        father1_cross=father1(i,1:cross_len);
        pos_num1=size(father1_cross(father1_cross==1),2);%统计交叉片段中1的个数
        % 在第二个父代中搜寻同样长度的片段,并且1的个数应该与父代1中的待交换片段相等
        % 以满足交换后特征数不变,若搜寻不到,则跳过此次交叉过程
        for j=1:pop_dim-cross_len+1
            temp=father2(i,j:j+cross_len-1);
            pos_num2=size(temp(temp==1),2);
            if pos_num1==pos_num2
                %交换
                father1(i,1:cross_len)=temp;
                father2(i,j:j+cross_len-1)=father1_cross;
                break;
            end
        end
    end
    pop_output=[father1;father2];
end
%变异
function pop_output=variation(pop_input)
    pop_nums=size(pop_input,1);%种群数量
    pop_dim=size(pop_input,2);%特征数
    prob=rand(1,pop_nums);%产生一组随机数,决定是否变异的概率,大于0.5则变异
    for i=1:pop_nums
        if prob(i)<0.5
            continue;
        else
            %产生两个个随机数,确定变异的位置,为确保变异后特征数不变,需要变异的两个位置值不能相等
            index1=randi(pop_dim,1);
            index2=randi(pop_dim,1);
            while pop_input(i,index1)==pop_input(i,index2)
                index2=randi(pop_dim,1);
            end
            pop_input(i,index1)=~pop_input(i,index1);
            pop_input(i,index2)=~pop_input(i,index2);
        end
    end
    pop_output=pop_input;
end
% 适应度函数,选择类间距离,距离度量采用欧氏距离
function fit=fitness_jd(pop,train_class1,train_class2)
    pop_num=size(pop,1);
    class1_num=size(train_class1,2);
    class2_num=size(train_class2,2);
    for i=1:pop_num
        d=0;
        for j=1:class1_num
            for k=1:class2_num
                d=d+(train_class1(pop(i,:)==1,j)-train_class2(pop(i,:)==1,k))'*(train_class1(pop(i,:)==1,j)-train_class2(pop(i,:)==1,k));
            end
        end
        jd=d/(class1_num*class2_num);
        fit(i)=jd;
    end
end    
%贝叶斯算法的准确度作为可分性依据
function fit=fitness_bayes(pop,Training_class1,Training_class2,testing_data,Testing_label)
    pop_num=size(pop,1);
    %获取训练数量
    n1=size(Training_class1,2);
    n2=size(Training_class1,2);
    % 先验概率
    pw1=n1/(n1+n2);
    pw2=n2/(n1+n2);
    for p=1:pop_num
        %选择训练数据和测试数据相应位置的特征值
        Training_data1=Training_class1(pop(p,:)==1,:);
        Training_data2=Training_class2(pop(p,:)==1,:);
        Testing_data=testing_data(pop(p,:)==1,:);
        %参数估计
        [miu1,sigma1]=ParamerEstimation(Training_data1);
        [miu2,sigma2]=ParamerEstimation(Training_data2);
        %预测结果
        predict_label=0;
        test_num=size(Testing_data,2);%获取测试数据数量
        for i=1:test_num
            x=Testing_data(:,i);
            pxw1=gaussian(miu1,sigma1,x);
            pxw2=gaussian(miu2,sigma2,x);
            if pw1*pxw1>pw2*pxw2
                predict_label(i)=1;
            else
                predict_label(i)=2;
            end
        end
        % 计算精度
        acc=sum(predict_label==Testing_label)/test_num;
    end
    fit(p)=acc;
end

程序运行结果:

遗传算法经过20次迭代,最终选出最优的40个特征。

三、总结

  本文介绍了通过遗传算法进行数据降维,这是一种特征选择方法,接下来的文章,我们将使用选择的这40个特征进行分类,与不使用数据降维时的性能进行对比。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 96 9 评论 打赏
评论
2个
内容存在敏感词
手气红包
  • Wreck 2024-06-14 11:40:48
    回复
    Training_class1,Training_class2,Testing,Label_Testing无法识别好像没有定义这几个变量
  • jm 2022-11-14 15:53:49
    回复
    你好,请问可以提供2-Class Problem.mat这个数据集吗?有数据不知道该怎么代入算法,感谢感谢
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
技术凯
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区