基于随机森林算法的葡萄酒种类识别

本文介绍了随机森林算法在葡萄酒种类识别中的应用,详细解析了CART算法、Gini系数及其在构建决策树过程中的作用。通过数据的随机选取和待选特征的随机选取,构建了随机森林模型,提高了分类性能。尽管存在一些小bug导致准确率偏低,但随机森林的优势在于优化过程中提高了模型准确性。
摘要由CSDN通过智能技术生成

唠两句

这篇文章是自己写实验报告的时候突发奇想写的,把这学期的计算时能答辩的课题改编成自己的博客,嗯总算实现老师说的写博客的意义了。源代码是借鉴自https://blog.csdn.net/cyberliferk800/article/details/90549795
但是很可惜啊这哥们儿(姐们儿)的代码根本跑不出来(不是diss您可能是matlab版本问题也好像是您确实sample错了如果有幸看到勿喷咱们理智辩解),我理解完了debug然后改写了整个逻辑,最后正确率还蛮喜人的嘿嘿嘿。
本文里葡萄酒种类预测只是为了满足了老师所吩咐的“现实意义”这一要求,并没有太大的研究意义,我就重点介绍随机森林算法了,接下来进入正题。

1. 随机森林算法原理

1.1 决策树的构建(CART算法)

CART算法由以下两步组成:
决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;
决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时损失函数最小作为剪枝的标准。
CART决策树的生成就是递归地构建二叉决策树的过程。CART决策树既可以用于分类也可以用于回归。本文我们仅讨论用于分类的CART。对分类树而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。

1.2 Gini系数

决策树建立后使用Gini系数判断其是否为一颗好树
Gini系数代表了模型的不纯度,基尼系数越小,不纯度越低,特征越好。
假设K个类别,第k个类别的概率为pk,概率分布的基尼系数表达式:
在这里插入图片描述
由于本文葡萄酒种类只存在两个类别,所以基尼系数表达式是:
在这里插入图片描述
又由需求最佳划分点,划分点左右两侧都有样本存在,左边样本点为n个,右边样本点为个,所以基尼系数时表达式应为:
在这里插入图片描述

1.3 随机森林的构建

决策树相当于一个大师,通过自己在数据集中学到的知识对于新的数据进行分类。那么随机森林的具体构建有两个方面:数据的随机性选取,以及待选特征的随机选取。
1.数据的随机选取:
首先,从原始的数据集中采取有放回的抽样,构造子数据集,子数据集的数据量是和原始数据集相同的。不同子数据集的元素可以重复,同一个子数据集中的元素也可以重复。第二,利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。最后,如果有了新的数据需要通过随机森林得到分类结果,就可以通过对子决策树的判断结果的投票,得到随机森林的输出结果了。如下图,假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。
在这里插入图片描述
图2-3 一个具有3个数据样本的数据集中的数据的随机选取
2.待选特征的随机选取
与数据集的随机选取类似,随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再在随机选取的特征中选取最优的特征进行划分。这样能够使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。
下图中,蓝色的方块代表所有可以被选择的特征,也就是目前的待选特征。橙色的方块是分裂特征。左边是一棵决策树的特征选取过程,通过在待选特征中选取最优的分裂特征(本文采用CART算法),完成分裂。右边是一个随机森林中的子树的特征选取过程。
在这里插入图片描述

2. 数据集来源

数据集来源于UCI数据库
在这里插入图片描述

3. 代码实现(核心代码)

3.1 随机森林函数

%随机森林,共有trees_num棵树

function result=random_forest(sample,trees_num,data,sample_select,decision_select,sample_limit)
type1=0;
type0=0;
conclusion=zeros(1,trees_num);

%data的最后一个改为自定义值,待会儿改成GUI传进来的值
data(size(data,1),:) = sample;

for i=1:trees_num
    [path,boundary,~,result]=decision_tree(data,sample_select,decision_select,sample_limit);
    conclusion(i)=decide(path,boundary,result);
    
    if conclusion(i)==1
        type1=type1+1; 
    else
        type0=type0+1;
    end
end
if type1>type0
    result=1;
else
    result=0;
end

3.2 决策树生成函数

%生成决策树,输入原始数据,采样样本数,采样决策属性数,预剪枝样本限制
function [path,boundary,gini,result]=decision_tree(data,sample_select,decision_select,sample_limit)
score=100;        
flag=0;
temp=inf;
%data(size(data,1),:)=sample;
%评价函数得分
while(score>(sample_select*0.3))   %直到找到好树才停止
   %%设置两个变量conclusion4_0和conclusion4_1,如果分类在第三层停下确保01的数量不一样
    conclusion3_0=0;
    conclusion3_1=0;
    %设置两个变量conclusion4_0和conclusion4_1,如果叶子结点数量多于一个要判断conclusion4_0和conclusion4_1的数量谁更多
    conclusion4_0=0;
    conclusion4_1=0;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%分界%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    data_new=select_sample_decision(data,sample_select,decision_select);
    %计算初始gini系数
    gini_now=gini_self(data_new);
    %主程序
    layer=1;                            %记录决策树当前层数
    leaf_sample=zeros(1,sample_select); %记录子结点样本个数
    leaf_gini=zeros(1,sample_select);   %叶子节点gini系数
    leaf_num=0;                         %记录叶子数
    path=zeros(decision_select,2^(decision_select-1));       %初始化路径
    gini=ones(decision_select,2^(decision_select-1));        %初始化gini
    boundary=zeros(decision_select,2^(decision_select-1));   %初始化划分边界
    result=ones(decision_select,2^(decision_select-1));      %初始化结果
    path(:)=inf;
    gini(:)=inf;
    boundary(:)=inf;
    result(1:4,1:8)=inf;
    %第一层
    [decision_global_best,boundary_global_best,data_new1,gini_now1,data_new2,gini_now2,~]=generate_node(data_new);

    path(layer,1)=data_new(size(data_new,1),decision_global_best);
    boundary(layer,1)=boundary_global_best;
    gini(layer,1)=gini_now;
    layer=layer+1;
    gini(layer,1)=gini_now1;
    gini(layer,2)=gini_now2;
    %第二层
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%二层1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    if  ((size(data_new1,1)-1)>=sample_limit)&&(gini(layer,1)>0)
        [decision_global_best,boundary_global_best,data_new1_1,gini_now1_1,data_new1_2,gini_now1_2,~]=generate_node(data_new1);
        path(layer,1)=data_new1(size(data_new1,1),decision_global_best);
        boundary(layer,1)=boundary_global_best;
        layer=layer+1;
        gini(layer,1)=gini_now1_1;
        gini(layer,2)=gini_now1_2;
        %%%%%%%%%%%%%%%%%%%%%%%%%三层1%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        if (size(data_new1_1,1)-1)>=sample_limit&&(gini(layer,1)>0)
            for i=1:size(data_new1_1,1)
                if(data_new1_1(i,end)==1)
                    conclusion3_1=conclusion3_1+1;
                else
                    conclusion3_0=conclusion3_0+1;
                end
            end
            [decision_global_best,boundary_global_best,data_new1_1_1,gini_now1_1_1,data_new1_1_2,gini_now1_1_2,~]=generate_node(data_new1_1);
            path(layer,1)=data_new1_1(size(data_new1_1,1),decision_global_best);
            boundary(layer,1)=boundary_global_best;
            layer
  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值