https://blog.csdn.net/fuqiuai/article/details/79456971

相关文章:

数据挖掘领域十大经典算法之—K-Means算法(超详细附代码)
        数据挖掘领域十大经典算法之—SVM算法(超详细附代码)
        数据挖掘领域十大经典算法之—Apriori算法
        数据挖掘领域十大经典算法之—EM算法
        数据挖掘领域十大经典算法之—PageRank算法
        数据挖掘领域十大经典算法之—AdaBoost算法(超详细附代码)
        数据挖掘领域十大经典算法之—K-邻近算法/kNN(超详细附代码)
        数据挖掘领域十大经典算法之—朴素贝叶斯算法(超详细附代码)
        数据挖掘领域十大经典算法之—CART算法(超详细附代码)

数据挖掘十大经典算法如下:
这里写链接内容
简介

C4.5是决策树算法的一种。决策树算法作为一种分类算法,目标就是将具有p维特征的n个样本分到c个类别中去。常见的决策树算法有ID3,C4.5,CART。
基本思想

下面以一个例子来详细说明C4.5的基本思想
例子
上述数据集有四个属性,属性集合A={ 天气,温度,湿度,风速}, 类别标签有两个,类别集合L={进行,取消}。

1. 计算类别信息熵
类别信息熵表示的是所有样本中各种类别出现的不确定性之和。根据熵的概念,熵越大,不确定性就越大,把事情搞清楚所需要的信息量就越多。
这里写链接内容

2. 计算每个属性的信息熵
每个属性的信息熵相当于一种条件熵。他表示的是在某种属性的条件下,各种类别出现的不确定性之和。属性的信息熵越大,表示这个属性中拥有的样本类别越不“纯”。
这里写链接内容

3. 计算信息增益
信息增益的 = 熵 - 条件熵,在这里就是 类别信息熵 - 属性信息熵,它表示的是信息不确定性减少的程度。如果一个属性的信息增益越大,就表示用这个属性进行样本划分可以更好的减少划分后样本的不确定性,当然,选择该属性就可以更快更好地完成我们的分类目标。

信息增益就是ID3算法的特征选择指标。
这里写链接内容
但是我们假设这样的情况,每个属性中每种类别都只有一个样本,那这样属性信息熵就等于零,根据信息增益就无法选择出有效分类特征。所以,C4.5选择使用信息增益率对ID3进行改进。

4.计算属性分裂信息度量
用分裂信息度量来考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(instrisic information)。信息增益率用信息增益 / 内在信息,会导致属性的重要性随着内在信息的增大而减小(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它),这样算是对单纯用信息增益有所补偿。
这里写链接内容

5. 计算信息增益率
(下面写错了。。应该是IGR = Gain / H )
这里写链接内容

天气的信息增益率最高,选择天气为分裂属性。发现分裂了之后,天气是“阴”的条件下,类别是”纯“的,所以把它定义为叶子节点,选择不“纯”的结点继续分裂。
这里写链接内容

在子结点当中重复过程1~5。
至此,这个数据集上C4.5的计算过程就算完成了,一棵树也构建出来了。

总结算法流程为:

while (当前节点”不纯“)  
    (1)计算当前节点的类别信息熵Info(D) (以类别取值计算)  
    (2)计算当前节点各个属性的信息熵Info(Ai) (以属性取值下的类别取值计算)  
    (3)计算各个属性的信息增益Gain(Ai)=Info(D)-Info(Ai)  
    (4)计算各个属性的分类信息度量H(Ai) (以属性取值计算)  
    (5)计算各个属性的信息增益率IGR(Ai)=Gain(Ai)/H(Ai)  
end while  
当前节点设置为叶子节点

1
    2
    3
    4
    5
    6
    7
    8

优缺点
优点

产生的分类规则易于理解,准确率较高。
缺点

在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
代码

代码已在github上实现,这里也贴出来

# encoding=utf-8

import cv2
import time
import numpy as np
import pandas as pd

from sklearn.cross_validation import train_test_split
from sklearn.metrics import accuracy_score

# 二值化
def binaryzation(img):
    cv_img = img.astype(np.uint8)
    cv2.threshold(cv_img,50,1,cv2.THRESH_BINARY_INV,cv_img)
    return cv_img

def binaryzation_features(trainset):
    features = []

for img in trainset:
        img = np.reshape(img,(28,28))
        cv_img = img.astype(np.uint8)

img_b = binaryzation(cv_img)
        # hog_feature = np.transpose(hog_feature)
        features.append(img_b)

features = np.array(features)
    features = np.reshape(features,(-1,feature_len))

return features

class Tree(object):
    def __init__(self,node_type,Class = None, feature = None):
        self.node_type = node_type  # 节点类型(internal或leaf)
        self.dict = {} # dict的键表示特征Ag的可能值ai,值表示根据ai得到的子树
        self.Class = Class  # 叶节点表示的类,若是内部节点则为none
        self.feature = feature # 表示当前的树即将由第feature个特征划分(即第feature特征是使得当前树中信息增益最大的特征)

def add_tree(self,key,tree):
        self.dict[key] = tree

def predict(self,features):
        if self.node_type == 'leaf' or (features[self.feature] not in self.dict):
            return self.Class

tree = self.dict.get(features[self.feature])
        return tree.predict(features)

# 计算数据集x的经验熵H(x)
def calc_ent(x):
    x_value_list = set([x[i] for i in range(x.shape[0])])
    ent = 0.0
    for x_value in x_value_list:
        p = float(x[x == x_value].shape[0]) / x.shape[0]
        logp = np.log2(p)
        ent -= p * logp

return ent

# 计算条件熵H(y/x)
def calc_condition_ent(x, y):
    x_value_list = set([x[i] for i in range(x.shape[0])])
    ent = 0.0
    for x_value in x_value_list:
        sub_y = y[x == x_value]
        temp_ent = calc_ent(sub_y)
        ent += (float(sub_y.shape[0]) / y.shape[0]) * temp_ent

return ent

# 计算信息增益
def calc_ent_grap(x,y):
    base_ent = calc_ent(y)
    condition_ent = calc_condition_ent(x, y)
    ent_grap = base_ent - condition_ent

return ent_grap

# C4.5算法
def recurse_train(train_set,train_label,features):
    
    LEAF = 'leaf'
    INTERNAL = 'internal'

# 步骤1——如果训练集train_set中的所有实例都属于同一类Ck
    label_set = set(train_label)
    if len(label_set) == 1:
        return Tree(LEAF,Class = label_set.pop())

# 步骤2——如果特征集features为空
    class_len = [(i,len(list(filter(lambda x:x==i,train_label)))) for i in range(class_num)] # 计算每一个类出现的个数
    (max_class,max_len) = max(class_len,key = lambda x:x[1])
    
    if len(features) == 0:
        return Tree(LEAF,Class = max_class)

# 步骤3——计算信息增益,并选择信息增益最大的特征
    max_feature = 0
    max_gda = 0
    D = train_label
    for feature in features:
        # print(type(train_set))
        A = np.array(train_set[:,feature].flat) # 选择训练集中的第feature列(即第feature个特征)
        gda = calc_ent_grap(A,D)
        if calc_ent(A) != 0:  ####### 计算信息增益比,这是与ID3算法唯一的不同
            gda /= calc_ent(A)
        if gda > max_gda:
            max_gda,max_feature = gda,feature

# 步骤4——信息增益小于阈值
    if max_gda < epsilon:
        return Tree(LEAF,Class = max_class)

# 步骤5——构建非空子集
    sub_features = list(filter(lambda x:x!=max_feature,features))
    tree = Tree(INTERNAL,feature=max_feature)

max_feature_col = np.array(train_set[:,max_feature].flat)
    feature_value_list = set([max_feature_col[i] for i in range(max_feature_col.shape[0])]) # 保存信息增益最大的特征可能的取值 (shape[0]表示计算行数)
    for feature_value in feature_value_list:

index = []
        for i in range(len(train_label)):
            if train_set[i][max_feature] == feature_value:
                index.append(i)

sub_train_set = train_set[index]
        sub_train_label = train_label[index]

sub_tree = recurse_train(sub_train_set,sub_train_label,sub_features)
        tree.add_tree(feature_value,sub_tree)

return tree

def train(train_set,train_label,features):
    return recurse_train(train_set,train_label,features)

def predict(test_set,tree):
    result = []
    for features in test_set:
        tmp_predict = tree.predict(features)
        result.append(tmp_predict)
    return np.array(result)

class_num = 10  # MINST数据集有10种labels,分别是“0,1,2,3,4,5,6,7,8,9”
feature_len = 784  # MINST数据集每个image有28*28=784个特征(pixels)
epsilon = 0.001  # 设定阈值

if __name__ == '__main__':

print("Start read data...")

time_1 = time.time()

raw_data = pd.read_csv('../data/train.csv', header=0)  # 读取csv数据
    data = raw_data.values
    
    imgs = data[::, 1::]
    features = binaryzation_features(imgs) # 图片二值化(很重要,不然预测准确率很低)
    labels = data[::, 0]

# 避免过拟合,采用交叉验证,随机选取33%数据作为测试集,剩余为训练集
    train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.33, random_state=0)
    time_2 = time.time()
    print('read data cost %f seconds' % (time_2 - time_1))

# 通过C4.5算法生成决策树
    print('Start training...')
    tree = train(train_features,train_labels,list(range(feature_len)))
    time_3 = time.time()
    print('training cost %f seconds' % (time_3 - time_2))

print('Start predicting...')
    test_predict = predict(test_features,tree)
    time_4 = time.time()
    print('predicting cost %f seconds' % (time_4 - time_3))
    
    # print("预测的结果为:")
    # print(test_predict)
    for i in range(len(test_predict)):
        if test_predict[i] == None:
            test_predict[i] = epsilon
    score = accuracy_score(test_labels, test_predict)
    print("The accruacy score is %f" % score)

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188

测试数据集为MNIST数据集,获取地址为train.csv
运行结果

这里写链接内容
---------------------  
作者:fuqiuai  
来源:CSDN  
原文:https://blog.csdn.net/fuqiuai/article/details/79456971  
版权声明:本文为博主原创文章,转载请附上博文链接!

数据挖掘领域十大经典算法之—C4.5算法(超详细附代码)的更多相关文章

  1. 数据挖掘领域十大经典算法之—SVM算法(超详细附代码)

    https://blog.csdn.net/fuqiuai/article/details/79483057

  2. 【十大经典数据挖掘算法】C4.5

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 决策树模型与学习 决策树(de ...

  3. 【十大经典数据挖掘算法】kNN

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 引言 顶级数据挖掘会议ICDM ...

  4. 【十大经典数据挖掘算法】CART

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 前言 分类与回归树(Class ...

  5. ICDM评选:数据挖掘十大经典算法

    原文地址:http://blog.csdn.net/aladdina/article/details/4141177 国际权威的学术组织the IEEE International Conferenc ...

  6. 【十大经典数据挖掘算法】PageRank

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 我特地把PageRank作为[十大经 ...

  7. 【十大经典数据挖掘算法】EM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 极大似然 极大似然(Maxim ...

  8. 【十大经典数据挖掘算法】AdaBoost

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 集成学习 集成学习(ensem ...

  9. 【十大经典数据挖掘算法】SVM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...

随机推荐

  1. if条件和for循环语句、while、do..while、switch语法

    //if 语句 ; ) { NSLog(@"不及格"); }) { NSLog(@"及格"); } //if语句 判断条件存在多个情况下,判断一个年是否为润年 ...

  2. 在 Linux 使用 GCC 编译C语言共享库

    对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例如一个数据库服务器的接口,就像MySQL ...

  3. Python的Flask框架与数据库连接的教程

     命令行方式运行Python脚本 在这个章节中,我们将写一些简单的数据库管理脚本.在此之前让我们来复习一下如何通过命令行方式执行Python脚本. 如果Linux 或者OS X的操作系统,需要有执行脚 ...

  4. LINUX网络之ifconfig命令与ping

    ifconfig命令 网络配置 ifconfig命令被用于配置和显示Linux内核中网络接口的网络参数.用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在.要想将上述的配置信息 ...

  5. mysql存储过程中使用事务

    DROP PROCEDURE IF EXISTS test_sp1 CREATE PROCEDURE test_sp1( ) BEGIN ; ; START TRANSACTION; INSERT I ...

  6. 教你在windows下安装使用配置vim+gcc[转]

    转自http://blog.163.com/lixiangqiu_9202/blog/static/535750372012461190722/ 一直在使用linux,但有时也会去虚拟机里的winxp ...

  7. 剑指offer面试题5:逆序打印单链表(Java)

    Java创建单链表(头插法.尾插法),并逆序打印单链表: package day_0324; import java.util.Scanner; import java.util.Stack; cla ...

  8. Linux设备驱动剖析之SPI(一)

    写在前面 初次接触SPI是因为几年前玩单片机的时候,由于普通的51单片机没有SPI控制器,所以只好用IO口去模拟.最近一次接触SPI是大三时参加的校内选拔赛,当时需要用2440去控制nrf24L01, ...

  9. MDU某产品OMCI模块代码质量现状分析

    说明 本文参考MDU系列某产品OMCI模块现有代码,提取若干实例以说明目前的代码质量,亦可作为甄别不良代码的参考. 本文旨在就事论事,而非否定前人(没有前人的努力也难有后人的进步).希望以史为鉴,不破 ...

  10. Archive of all Android Studio releases / Eclipse 版本大全 / OpenJDK 各版本

    一 Android Studio 版本大全 https://developer.android.com/studio/archive.html Download Archives This is an ...