Python机器学习:决策树1

昨天学习了KNN,今天来看到决策树,这是一种常用的机器学习算法,回归和分类都可以使用,我看着书上的示例,感觉这个和switch或者连续的if、else条件这些控制流一样:

图1:简单决策树示例

 它其实是很朴素的思想:有一个集合,其中的每个样本由若干个属性构成,那么决策树就是通过贪心策略来挑选最优属性,对于离散属性,就用不同的属性值作为节点,对于连续属性,就用属性的特定分割点来作为节点,每个样本划分到不同的子树中去,再在各个子树上通过递归对子树上的样本进行划分,知道满足一定条件为止,他有着很强的数据拟合能力,往往产生过拟合现象,所以要对决策树进行剪枝,以减小复杂度,提高泛化能力,常用的算法有:ID3、C4.5、CART算法等。

其实看到上面那个图,我就想着小小的试验一下,当然不是算法,就是简单的控制流:

#include<iostream>
using namespace std;
struct node
{
    int age;
    int color;
    int smell; 
};
int main(){
    node appletest[3];
    cout<<"input tester:"<<endl;
    for(int i=0;i<3;i++){
    cout<<"input tester "<<i<<"'s age:";
    cin>>appletest[i].age;
    cout<<"input tester "<<i<<"'s color:";
    cin>>appletest[i].color;
    cout<<"input tester "<<i<<"'s smell:";
    cin>>appletest[i].smell;
    }
    cout<<"start "<<endl;
// 1是最好的,2是一般,3是不好
    for(int i=0;i<3;i++){
        if (appletest[i].age<10)
        {
            if (appletest[i].color==1)
            {
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
                
            }
            else if(appletest[i].color==2){
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
            else{
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
        }
        else if(appletest[i].age>=10&&appletest[i].age<25){
            if (appletest[i].color==1)
            {
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
                
            }
            else if(appletest[i].color==2){
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
            else{
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
        }
       else{
            if (appletest[i].color==1)
            {
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
                
            }
            else if(appletest[i].color==2){
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
            else{
                if (appletest[i].smell==1)
                {
                    cout<<"apple "<<i<<"is great"<<endl;
                }
                else if(appletest[i].smell==2){
                    cout<<"apple "<<i<<"not really great"<<endl;
                }
                else{
                    cout<<"apple "<<i<<"is bad"<<endl;
                }
            }
        }
    }
    return 0;
}
图2:结果

很长,很繁琐,看来还得是用算法才行,不过,感谢前人积淀,有很多算法供我们使用,真好!

一、特征属性:

要构建一棵决策树,关键就在于每次划分子树的时候,选择哪个属性特征进行划分,信息论中,我们用熵来描述随机变量分布的不确定性,对于离散型随机变量X,假设有n个取值,分别是:\left \{ x_1x_2,x_3,\cdots,x_n \right \}我们用频率来表示概率,随机变量的概率分布为:

p_i=P(X=x_i)=\frac{N_i}{N}

那么,X的熵,就是p的熵,定义为:

H(x)=H(p)=\sum_{i=1}^{n}p_ilog\frac{1}{p_i}=-\sum_{i=1}^{n}p_ilogp_iH(D|A^i)=\sum_{j=1}^{K_i}\frac{N_j}{m}H(D_j)=-\sum_{j=1}^{K_i}\frac{N_j}{m}\sum_{j=1}^{K}\frac{N_{jk}}{N_j}log\frac{N_{jk}}{N_j}

那么,在给定离散型随机变量(X,Y),假设X和Y的取值个数分别是n和m,那么其联合分布律为:

p_{ij}=P(X=x_i,Y=y_i)=\frac{N_{ij}}{N}

边缘分布率为:

p_{i\cdot }=P(X=x_i)=\sum_{j=1}^{n}p_{ij}\frac{N_ij}{N}

给定X条件下Y的条件熵:

H(Y|X)=\sum_{i=1}^{n}p_iH(Y|X=x_i)

根据上面的定义,我们引入信息增益的概念,信息增益最早用于决策树模型的特征选择指标,就是ID3算法的核心,对于给定样本集合D=\left \{ (x_1,y_1),(x_2,y_2),....(x_m,y_m) \right \},设y_i \in \left \{ c_1,c_2,\cdots,c_K \right \},A^i是数据集中任一属性变量,其中S^i=\left\{a^{i1},a^{i2},\cdots,a^{iK_i}\right\}表示该属性的可能取值,对使用属性A^i进行数据集划分获得的信息增益进行定义:

G(D,A^i)=H(D)-H(D|A^i)

H(D|A^i)=\sum_{j=1}^{K_i}\frac{N_j}{m}H(D_j)=-\sum_{j=1}^{K_i}\frac{N_j}{m}\sum_{j=1}^{K}\frac{N_{jk}}{N_j}log\frac{N_{jk}}{N_j}

其中D_j表示属性A^i取值为a^{ij}时的样本子集,N_j是对应的样本数目,N_{jk}D_j中标签为c_k的样本数目 。

好了,今天就学到这里吧,早上起床有点迟了,电脑没油了,先不写了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值