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 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 以判断西瓜好坏为例,生成的决策树(源码)-- 上一篇文章--(决策树)的下文 -> 正文阅读

[人工智能]以判断西瓜好坏为例,生成的决策树(源码)-- 上一篇文章--(决策树)的下文


from random import choice
from collections import Counter
import math

# ==========
# 定义数据集
# ==========
D = [
    {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '乌黑', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '乌黑', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '青绿', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '软粘', '好瓜': '是'},
    {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '稍糊', '脐部': '稍凹', '触感': '软粘', '好瓜': '是'},
    {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '硬滑', '好瓜': '是'},
    {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '沉闷', '纹理': '稍糊', '脐部': '稍凹', '触感': '硬滑', '好瓜': '否'},
    {'色泽': '青绿', '根蒂': '硬挺', '敲声': '清脆', '纹理': '清晰', '脐部': '平坦', '触感': '软粘', '好瓜': '否'},
    {'色泽': '浅白', '根蒂': '硬挺', '敲声': '清脆', '纹理': '模糊', '脐部': '平坦', '触感': '硬滑', '好瓜': '否'},
    {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '模糊', '脐部': '平坦', '触感': '软粘', '好瓜': '否'},
    {'色泽': '青绿', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '稍糊', '脐部': '凹陷', '触感': '硬滑', '好瓜': '否'},
    {'色泽': '浅白', '根蒂': '稍蜷', '敲声': '沉闷', '纹理': '稍糊', '脐部': '凹陷', '触感': '硬滑', '好瓜': '否'},
    {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '软粘', '好瓜': '否'},
    {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '模糊', '脐部': '平坦', '触感': '硬滑', '好瓜': '否'},
    {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '稍糊', '脐部': '稍凹', '触感': '硬滑', '好瓜': '否'},
]


# ==========
# 决策树生成类
# ==========
class DecisionTree:
    def __init__(self, D, label, chooseA):
        self.D = D  # 数据集
        self.label = label  # 属性"好瓜" 作为标签 
        self.chooseA = chooseA  # 划分方法:根据信息增益
        self.A = list(filter(lambda key: key != label, D[0].keys()))  # 属性集合A(当然要去除"好瓜"这一判断属性了)

        # 获得A的每个className属性的可选项,加入到A_item集合中,如 色泽:对应 {'乌黑', '青绿', '浅白'}
        self.A_item = {}
        for a in self.A:
            self.A_item.update({a: set(self.getClassValues(D, a))})  # 此处的set,有个集合去重操作
            '''
            # print("self.A_item is"  ,self.A_item)
            最终的A_item:
            {
                '色泽': {'乌黑', '青绿', '浅白'}, 
                '根蒂': {'硬挺', '稍蜷', '蜷缩'}, 
                '敲声': {'清脆', '浊响', '沉闷'},
                '纹理': {'清晰', '稍糊', '模糊'}, 
                '脐部': {'稍凹', '凹陷', '平坦'}, 
                '触感': {'硬滑', '软粘'}
             }
            '''
        self.root = self.generate(self.D, self.A)  # 生成树并保存根节点
        # print("self.root is", self.root)

    # 获得D中所有className属性的值
    def getClassValues(self, D, className):
        '''
        :param D: 数据集
        :param className: 每个className
        :return: D中className属性对应的所有值
        '''
        return list(map(lambda sample: sample[className], D))

    # D中样本是否在A的每个属性上相同
    def isSameInA(self, D, A):
        for a in A:
            types = set(self.getClassValues(D, a))
            #print("types is ", types)
            if len(types) > 1:
                return False
        return True

    # 构建决策树,递归生成节点
    def generate(self, D, A):
        '''
        :param D: 数据集
        :param A: 所有className属性(不包含"好瓜")
        :return:
        '''
        node = {}  # 生成节点
        remainLabelValues = self.getClassValues(D, self.label)
        # D中的所有标签 如['是', '是', '是', '是', '是', '是', '是', '是', '否', '否', '否', '否', '否', '否', '否', '否', '否']

        remainLabelTypes = set(remainLabelValues)
        # D中含有哪几种标签 如{'是', '否'}

        if len(remainLabelTypes) == 1:  # 当前节点包含的样本全属于同个类别,无需划分
            return remainLabelTypes.pop()  # 标记Node为叶子结点,值为仅存的标签

        most = max(remainLabelTypes, key=remainLabelValues.count)  # D占比最多的标签 此处为"是"8个,"否"9个(此处为"否")

        if len(A) == 0 or self.isSameInA(D, A):
            # 当前属性集为空,或是所有样本在所有属性上取值相同,无法划分
            return most  # 标记Node为叶子结点,值为占比最多的标签

        # ******划分:******
        a = self.chooseA(D, A, self)  # a即为计算过的信息增益中(值最大)的className属性,作为节点,此时算出为"纹理"
        print("a(每次选的最大信息增益属性) is ", a)

        for type in self.A_item[a]:
            condition = (lambda sample: sample[a] == type)  # 决策条件
            remainD = list(filter(condition, D))  # 过滤掉不满足condition条件的样本
            #print("remainD is ",remainD)
            if len(remainD) == 0:
                # 当前节点包含的样本集为空,不能划分
                node.update({type: most})  # 标记Node为叶子结点,值为占比最多的标签
            else:
                # 继续对剩下的样本按其余属性划分
                remainA = list(filter(lambda x: x != a, A))  # 未使用的属性
                _node = self.generate(remainD, remainA)  # 递归生成子代节点
                node.update({type: _node})  # 把生成的子代节点更新到当前节点
        return {a: node}


# ==========
#  定义划分方法
# ==========

# 信息熵
def Ent(D, label, a, a_v):
    '''
    :param D:
    :param label:
    :param a: 某一具体className属性 如"色泽"
    :param a_v: 此属性对应的具体值 ,如"青绿、乌黑、浅白"三种中的一个
    :return:
    '''
    D_v = filter(lambda sample: sample[a] == a_v, D)  # 如此处,举个例子,选的是色泽="青绿"的瓜,共6个
    D_v = map(lambda sample: sample[label], D_v)  # 将色泽="青绿"的瓜按标签分类为好瓜=3个,坏瓜=3个
    D_v = list(D_v)
    D_v_length = len(D_v)
    counter = Counter(D_v)
    info_entropy = 0
    for k, v in counter.items():  # 计算色泽="青绿"信息熵
        p_k = v / D_v_length
        info_entropy += p_k * math.log(p_k, 2)
    return -info_entropy


# 信息增益
def information_gain(D, A, tree: DecisionTree):
    gain = {}
    for a in A:
        gain[a] = 0
        values = tree.getClassValues(D, a)
        counter = Counter(values)
        # print("counter.items() is", counter.items())
        for a_v, nums in counter.items():  # 分别计算所有className属性的信息增益,此处以属性=色泽为例注释
            gain[a] -= (nums / len(D)) * Ent(D, tree.label, a, a_v)  # 分别计算"青绿、乌黑、浅白"所对应的(信息熵 *该属性值所占比)
    #print("gain is ", gain)
    return max(gain.keys(), key=lambda key: gain[key])  # 选择信息增益最大的那个属性作为节点,此时算出来是"纹理"


# ==========
#  创建决策树
# ==========
if __name__ == '__main__':
    desicionTreeRoot = DecisionTree(D, label='好瓜', chooseA=information_gain).root
    print('决策树:', desicionTreeRoot)
最终生成的决策树如下:
a(每次选的最大信息增益属性) is  纹理
a(每次选的最大信息增益属性) is  触感
a(每次选的最大信息增益属性) is  根蒂
a(每次选的最大信息增益属性) is  色泽
a(每次选的最大信息增益属性) is  触感
决策树: {'纹理': {'稍糊': {'触感': {'软粘': '是', '硬滑': '否'}}, '清晰': {'根蒂': {'稍蜷': {'色泽': {'乌黑': {'触感': {'软粘': '否', '硬滑': '是'}}, '浅白': '是', '青绿': '是'}}, '蜷缩': '是', '硬挺': '否'}}, '模糊': '否'}}

有话就说, 感谢ww提供的材料~哈哈游表示很开心哈

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:19:21  更:2021-11-29 16:19:25 
 
开发: 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/27 3:50:20-

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