ML—决策树算法实现(train+test,matlab)

华电北风吹
天津大学认知计算与应用重点实验室
修改日期:2015/8/15

决策树是一种特别简单的机器学习分类算法。决策树想法来源于人类的决策过程。举个最简单的例子,人类发现下雨的时候,往往会有刮东风,然后天色变暗。对应于决策树模型,预测天气模型中的刮东风和天色变暗就是我们收集的特征,是否下雨就是类别标签。构建的决策树如下图所示
这里写图片描述
决策树模型构建过程为,在特征集合中无放回的依次递归抽选特征作为决策树的节点——当前节点信息增益或者增益率最大,当前节点的值作为当前节点分支出来的有向边(实际上主要选择的是这些边,这个由信息增益的计算公式就可以得到)。对于这个进行直观解释
来说一个极端情况,如果有一个特征下,特征取不同值的时候,对应的类别标签都是纯的,决策者肯定会选择这个特征,作为鉴别未知数据的判别准则。由下面的计算信息增益的公式可以发现这时候对应的信息增益是最大的。
g(D,A)=H(D)-H(D|A)
g(D,A):表示特征A对训练数据集D的信息增益
H(D):表示数据集合D的经验熵
H(D|A):表示特征A给定条件下数据集合D的条件熵。
反之,当某个特征它的各个取值下对应的类别标签均匀分布的时候H(D|A)最大,又对于所有的特征H(D)是都一样的。因此,这时候的g(D,A)最小。
总之一句话,我们要挑选的特征是:当前特征下各个取值包含的分类信息最明确。
下面我们来看一个MATLAB编写的决策树算法,帮助理解
树终止条件为
1、特征数为空
2、树为纯的
3、信息增益或增益率小于阀值

一、模型训练部分
训练模型主函数:

function decisionTreeModel=decisionTree(data,label,propertyName,delta)

global Node;

Node=struct('level',-1,'fatherNodeName',[],'EdgeProperty',[],'NodeName',[]);
BuildTree(-1,'root','Stem',data,label,propertyName,delta);
Node(1)=[];
model.Node=Node;
decisionTreeModel=model;

递归构建决策树部分

function BuildTree(fatherlevel,fatherNodeName,edge,data,label,propertyName,delta)

global Node;
sonNode=struct('level',0,'fatherNodeName',[],'EdgeProperty',[],'NodeName',[]);
sonNode.level=fatherlevel+1;
sonNode.fatherNodeName=fatherNodeName;
sonNode.EdgeProperty=edge;
if length(unique(label))==1
    sonNode.NodeName=label(1);
    Node=[Node sonNode];
    return;
end
if length(propertyName)<1
    labelSet=unique(label);
    k=length(labelSet);
    labelNum=zeros(k,1);
    for i=1:k
        labelNum(i)=length(find(label==labelSet(i)));
    end
    [~,labelIndex]=max(labelNum);
    sonNode.NodeName=labelSet(labelIndex);
    Node=[Node sonNode];
    return;
end
[sonIndex,BuildNode]=CalcuteNode(data,label,delta);
if BuildNode
    dataRowIndex=setdiff(1:length(propertyName),sonIndex);
    sonNode.NodeName=propertyName{sonIndex};
    Node=[Node sonNode];
    propertyName(sonIndex)=[];
    sonData=data(:,sonIndex);
    sonEdge=unique(sonData);

    for i=1:length(sonEdge)
        edgeDataIndex=find(sonData==sonEdge(i));
        BuildTree(sonNode.level,sonNode.NodeName,sonEdge(i),data(edgeDataIndex,dataRowIndex),label(edgeDataIndex,:),propertyName,delta);
    end
else
    labelSet=unique(label);
    k=length(labelSet);
    labelNum=zeros(k,1);
    for i=1:k
        labelNum(i)=length(find(label==labelSet(i)));
    end
    [~,labelIndex]=max(labelNum);
    sonNode.NodeName=labelSet(labelIndex);
    Node=[Node sonNode];
    return;
end

计算决策树下一个节点特征

function [NodeIndex,BuildNode]=CalcuteNode(data,label,delta)

LargeEntropy=CEntropy(label);
[m,n]=size(data);
EntropyGain=LargeEntropy*ones(1,n);
BuildNode=true;
for i=1:n
    pData=data(:,i);
    itemList=unique(pData);
    for j=1:length(itemList)
        itemIndex=find(pData==itemList(j));
        EntropyGain(i)=EntropyGain(i)-length(itemIndex)/m*CEntropy(label(itemIndex));
    end
    % 此处运行则为增益率,注释掉则为增益
    % EntropyGain(i)=EntropyGain(i)/CEntropy(pData); 
end
[maxGainEntropy,NodeIndex]=max(EntropyGain);
if maxGainEntropy<delta
    BuildNode=false;
end

计算熵

function result=CEntropy(propertyList)

result=0;
totalLength=length(propertyList);
itemList=unique(propertyList);
pNum=length(itemList);
for i=1:pNum
    itemLength=length(find(propertyList==itemList(i)));
    pItem=itemLength/totalLength;
    result=result-pItem*log2(pItem);
end

二、模型预测
下面这个函数是根据训练好的决策树模型,输入测试样本集合和特征名,对每个测试样本预测输出结果。

function label=decisionTreeTest(decisionTreeModel,sampleSet,propertyName)

lengthSample=size(sampleSet,1);
label=zeros(lengthSample,1);
for sampleIndex=1:lengthSample
    sample=sampleSet(sampleIndex,:);
    Nodes=decisionTreeModel.Node;
    rootNode=Nodes(1);
    head=rootNode.NodeName;
    index=GetFeatureNum(propertyName,head);
    edge=sample(index);
    k=1;
    level=1;
    while k<length(Nodes)
        k=k+1;
        if Nodes(k).level==level
            if strcmp(Nodes(k).fatherNodeName,head)
                if Nodes(k).EdgeProperty==edge
                    if Nodes(k).NodeName<10
                        label(sampleIndex)=Nodes(k).NodeName;
                        break;
                    else
                        head=Nodes(k).NodeName;
                        index=GetFeatureNum(propertyName,head);
                        edge=sample(index);
                        level=level+1;
                    end
                end
            end
        end
    end
end

由于训练好的决策树模型里面保存的是节点名,所以在预测的时候需要将节点名对应的特征得到。下面这个函数是为了方便得到特征维数序号。

function result=GetFeatureNum(propertyName,str)
result=0;
for i=1:length(propertyName)
    if strcmp(propertyName{i},str)==1
        result=i;
        break;
    end
end

三、决策树实验
这是很多书本上都有的一个例子,可以看出预测结果准确率100%。

clear;clc;

% OutlookType=struct('Sunny',1,'Rainy',2,'Overcast',3);
% TemperatureType=struct('hot',1,'warm',2,'cool',3);
% HumidityType=struct('high',1,'norm',2);
% WindyType={'True',1,'False',0};
% PlayGolf={'Yes',1,'No',0};
% data=struct('Outlook',[],'Temperature',[],'Humidity',[],'Windy',[],'PlayGolf',[]);

Outlook=[1,1,3,2,2,2,3,1,1,2,1,3,3,2]';
Temperature=[1,1,1,2,3,3,3,2,3,3,2,2,1,2]';
Humidity=[1,1,1,1,2,2,2,1,2,2,2,1,2,1]';
Windy=[0,1,0,0,0,1,1,0,0,0,1,1,0,1]';

data=[Outlook Temperature Humidity Windy];
PlayGolf=[0,0,1,1,1,0,1,0,1,1,1,1,1,0]';
propertyName={'Outlook','Temperature','Humidity','Windy'};
delta=0.1;
decisionTreeModel=decisionTree(data,PlayGolf,propertyName,delta);

label=decisionTreeTest(decisionTreeModel,data,propertyName);
### 机器学习算法MLA)的具体实现 #### MATLAB 中的朴素贝叶斯算法实现MATLAB 中,可以通过内置函数 `fitcnb` 来快速构建朴素贝叶斯分类器。该函数允许用户指定训练数据集以及标签,并返回一个经过训练的模型对象。以下是具体的代码示例: ```matlab % 加载样本数据 load fisheriris; % 将类别名称转换为数值型标签 species_num = grp2idx(species); % 训练朴素贝叶斯分类器 nbModel = fitcnb(meas, species_num); % 使用测试数据预测 predictedLabels = predict(nbModel, meas); % 显示混淆矩阵 confusionchart(species_num, predictedLabels); ``` 上述代码展示了如何加载 Iris 数据集并使用其测量值来训练朴素贝叶斯分类器[^1]。 --- #### Python 中的朴素贝叶斯算法实现 Python 提供了强大的库支持,例如 Scikit-Learn,用于简化机器学习流程。下面是一个完整的例子,展示如何使用 GaussianNB 实现朴素贝叶斯分类器: ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.naive_bayes import GaussianNB from sklearn.metrics import confusion_matrix, accuracy_score # 加载数据集 data = load_iris() X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.3, random_state=42) # 初始化朴素贝叶斯分类器 gnb = GaussianNB() # 模型训练 gnb.fit(X_train, y_train) # 预测 y_pred = gnb.predict(X_test) # 输出评估指标 print(f"Accuracy: {accuracy_score(y_test, y_pred)}") print("Confusion Matrix:") print(confusion_matrix(y_test, y_pred)) ``` 此代码片段说明了如何分割数据集、训练模型以及计算准确率和混淆矩阵。 --- #### MLA 的通用实现框架 机器学习算法(Machine Learning Algorithm, MLA)的核心目标是让计算机能够从经验中自动改进性能[^3]。为了实现这一目的,通常遵循以下设计原则和技术要点: 1. **数据预处理** 原始数据往往需要清洗、标准化或归一化以便于后续建模过程。这一步骤对于提升最终模型的表现至关重要。 2. **特征工程** 特征的选择直接影响模型的效果。通过降维技术(如 PCA)、编码离散变量等方式优化输入空间结构。 3. **选择合适的算法** 不同类型的 ML 算法适用于解决特定领域内的问题。例如监督学习中的回归分析适合连续输出场景;而无监督聚类则探索未知模式分布情况。 4. **集成方法的应用** Boosting 和 Bagging 是两种常见的元策略,它们组合多个弱学习者形成强整体解决方案。这种方法有助于减少偏差或者方差从而提高泛化能力[^4]。 5. **高效工具选型** 当前存在许多优秀的开源项目可供开发者选用,像 TensorFlow/Keras 主攻深度神经网络方向;而对于传统统计学派别的 LightGBM 则因其卓越的速度表现成为梯度提升决策树领域的佼佼者[^5]。 ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值