IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 《machine learning in action》机器学习 算法学习笔记 决策树模型 -> 正文阅读

[数据结构与算法]《machine learning in action》机器学习 算法学习笔记 决策树模型

决策树模型

重要任务:是为了理解数据中所蕴含的知识信息,因此决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,这些机器根据数据集创建规则的过程就是机器学习的过程。

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。
缺点:可能会产生过度匹配问题。

范例:专家系统。

如何构造决策树:

  • 编写构造树的python代码
  • 度量算法成功率
  • 递归建立分类器
  • Matplotlib绘制决策树图

利用信息论划分数据集,伪代码:

IF (整个数据集属于同一个类型) return 类标签
Else 
	寻找划分数据集的最好特征
	划分数据集
	创建分支节点
		for 每个划分的子集
			递归继续划分
		return 分支节点

划分数据集的大原则是:将无序的数据变得更加有序。

信息增益

定义:在划分数据集之前之后的信息发生的变化称为信息增益。

可以用于评价一次信息划分的优劣。

集合信息的度量方式称为:香农熵

熵定义为信息的期望值。

如果待分类的事务可能划分在多个分类之中,则符号 x i x_i xi?的信息定义为:
l ( x i ) = ? l o g 2 p ( x i ) l(x_i)=-log_2p(x_i) l(xi?)=?log2?p(xi?)
p ( x i ) p(x_i) p(xi?)是选择该分类的概率。

根据期望的公式,得
H = ? ∑ i = 1 n p ( x i ) l o g 2 p ( x i ) H=-\sum^n_{i=1}p(x_i)log_2p(x_i) H=?i=1n?p(xi?)log2?p(xi?)
计算给定那个数据集的香农熵:

from math import log
def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet:#统计每个标签出现的频次,利用统计数
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    ShannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries#求概率
        ShannonEnt -= prob *log(prob,2)#求期望
    return ShannonEnt

基尼不纯度:另一种度量集合无序程度的方法。

决策树的构建过程实际上就是降低香农熵(无序度量值)的过程。

对于一个特征集合我们可以选择的划分方式就是各个特征,选择哪个特征能够更加快的降低数据集的无序度?

我们只需要尝试按照每一种方式划分,看看哪种划分更快的降低无序度,那么便选择它,这也就是上面伪代码讲的如何划分。

如何理解以下这段代码(由于书中并没有对这段代码解释,以下属于笔者的猜测):

for value in uniqueVals:
    subDataSet = splitDataSet(dataSet, i, value)
    prob = len(subDataSet)/float(len(dataSet))
    newEntropy += prob * calcShannonEnt(subDataSet)

我们可以知道信息熵的定义是期望,我们想要得到的是按照某一特征划分之后整体的期望。

那么可以得到一个新的公式,根据期望的计算 E = ∑ i = 1 n p ( x i ) ? x i E=\sum_{i=1}^{n}p(x_i)*x_i E=i=1n?p(xi?)?xi??。?

其中 x i x_i xi?表示的便是划分后的第i个集合的香农熵的值, p ( x i ) p(x_i) p(xi?)??表示选择该数据集的概率。

最终建立的树是用字典表示的,例如:

{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

若字典中的关键字的值对印的是类标签,则表示这是一个叶子结点,若为仍是字典,则表示这是一个判断结点。

利用matplotlib注释绘制属性图。

直接上结果吧

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ArgJhgty-1640959413711)(C:\Users\86187\Desktop\桌面\机器学习\图片\决策树图形化.png)]

trees.py:

from math import log
import operator
#------------计算给定数据集的香农熵-------------

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet:#统计每个标签出现的频次,利用统计数
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    ShannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries#求概率
        ShannonEnt -= prob *log(prob,2)#求期望
    return ShannonEnt

#-------------生成测试的数据集-----------------

def createDataSet():
    dataSet = [[1,1,'maybe'],
               [1,1,'yes'],
               [1,0,'no'],
               [0,1,'no'],
               [0,1,'no']]
    labels = ['no surfacing','flippers']
    return dataSet,labels

#-------------划分数据集------------------
#代码思路就是将axis维的特征值为value的放到一个新的数据集中
def splitDataSet(dataSet,axis,value):
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])#a.extend(b) [a,b]
            retDataSet.append(reducedFeatVec)#a.append(b) [a,[b]]
    return retDataSet

#------------选择最好的数据集划分方式---------------

def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1      #the last column is used for the labels
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0; bestFeature = -1
    #找到的是使得香农熵减少最多的划分方式
    for i in range(numFeatures):        #iterate over all the features
        featList = [example[i] for example in dataSet]#create a list of all the examples of this feature
        uniqueVals = set(featList)       #get a set of unique values
        newEntropy = 0.0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)
        infoGain = baseEntropy - newEntropy     #calculate the info gain; ie reduction in entropy
        if (infoGain > bestInfoGain):       #compare this to the best gain so far
            bestInfoGain = infoGain         #if better than current best, set to best
            bestFeature = i
    return bestFeature                      #returns an integer
#------------获取出现次数最多的分类名称--------------
#代码实现,利用map先计数后排序
def majorityCnt(classList):
    classCount={}
    for vote in classList:
        if vote not in classCount.keys(): classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

def createTree(dataSet,labels):
    classList = [example[-1] for example in dataSet]
    if classList.count(classList[0]) == len(classList):
        return classList[0]#递归结束条件之一,整个集合属于同一个类别
    if len(dataSet[0]) == 1: #递归结束条件二,已经没有特征可供划分,并且集合中的数据也没有被分为一类,那么就返回出现次数最多的类别,向现实低头了属于
        return majorityCnt(classList)
    bestFeat = chooseBestFeatureToSplit(dataSet)#得到最好的划分方式
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}}
    del(labels[bestFeat])
    featValues = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels[:]       #copy all of labels, so trees don't mess up existing labels
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
    return myTree

main.py

import treePlotter
import trees
myDat,labels=trees.createDataSet()
print(myDat)
print(trees.calcShannonEnt(myDat))
print(trees.splitDataSet(myDat,0,1))
print(trees.splitDataSet(myDat,1,1))
print(trees.chooseBestFeatureToSplit(myDat))
mytree=trees.createTree(myDat,labels)
print(mytree)

结语:

  • 决策树的工作原理就是将原本无序的数据集变得有序,并且这种有序是用树的方式呈现的,该模型的核心便是如何指导模型,使得数据集向有序变化。

  • 决策树使用的无序度,尽量让每一次的划分都能最大化的降低整体的无序度,通过这种方式一步一步的走向有序。

  • 同时,信息熵的概念同样让人着迷,尽管不知道为什么是 ? l o g 2 ( p ( x ) ) -log_2(p(x)) ?log2?(p(x)),但他确实好用,类似的还有交叉熵,等等,这些度量函数值得了解和学习。

  • 今天也是2021年的最后一天,在过去的一年,acm参加了七个赛站,最后以两铜结束,参加了数学建模没能完成论文,混了省一。高中初中小学,都有一点点的竞赛经验,但是都没有获奖,也不是十分重视,到了大学acm也算是圆了竞赛梦,尽管现实残酷。过去这一年的种种遗憾都将随时间流走,希望在新的一年里向着新的方向前行。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:11:59  更:2022-01-01 14:13:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 18:30:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码