决策树介绍与示例

决策树用一连串是否问题把样本分成几类。我先说明它怎么选问题,再用一组「天气、温度 → 是否出门」的数据把树建出来。

决策树从根节点开始,每次选一个问题把样本拆开,走到叶子就给出类别。选哪个问题,看拆完之后类别变得有多纯。

纯度用熵衡量。一组样本里类别越杂,熵越大;全部属于同一类时,熵为 0。某一问法拆分前后熵的下降量叫信息增益,树在当前节点选择增益最大的问题。

8 条样本、两个特征,标签是是否出门:

天气 温度 出门
晴 热 否
晴 适中 否
阴 热 是
雨 适中 是
雨 凉 是
阴 凉 是
晴 凉 是
雨 热 否

其中 5 条是「是」、3 条是「否」,整组熵约 0.954。按温度拆,信息增益是 0.36;按天气拆,增益是 0.266。根节点因此先问温度。

  • 凉:3 条全是「是」,成为叶子。
  • 热:再问天气。晴、雨为「否」,阴为「是」。
  • 适中:再问天气。晴为「否」,雨为「是」。

新样本「晴、凉」走到「凉」这片叶子,预测出门;「雨、热」走到「热 → 雨」,预测不出门。

import math

from collections import Counter

def entropy(labels):

n = len(labels)

h = 0.0

for count in Counter(labels).values():

p = count / n

h -= p * math.log2(p)

return h

def majority(labels):

return Counter(labels).most_common(1)00

def build(rows, features):

labels = row\[-1 for row in rows]

if len(set(labels)) == 1 or not features:

return {"leaf": majority(labels)}

base = entropy(labels)

best_gain = -1

best = None

for index, name in features:

groups = {}

for row in rows:

groups.setdefault(rowindex, \[\]).append(row)

remain = 0.0

for group in groups.values():

remain += len(group) / len(rows) * entropy(row\[-1 for row in group])

gain = base - remain

if gain > best_gain:

best_gain = gain

best = (index, name, groups, gain)

index, name, groups, gain = best

rest = (i, n) for i, n in features if i != index

return {

"feature": name,

"gain": round(gain, 3),

"branches": {value: build(group, rest) for value, group in groups.items()},

}

def predict(node, sample):

while "leaf" not in node:

node = node"branches"sample\[node\["feature"]]

return node"leaf"

rows = [

("晴", "热", "否"),

("晴", "适中", "否"),

("阴", "热", "是"),

("雨", "适中", "是"),

("雨", "凉", "是"),

("阴", "凉", "是"),

("晴", "凉", "是"),

("雨", "热", "否"),

]

tree = build(rows, list(enumerate("天气", "温度")))

print(predict(tree, {"天气": "晴", "温度": "凉"}))

print(predict(tree, {"天气": "雨", "温度": "热"}))

输出是 是 和 否。

特征是数值时,问题变成「是否小于某个阈值」。算法把这一列的取值排序,尝试相邻值的中点,仍然取信息增益最大的那个切分。CART 用基尼不纯度代替熵,比较的仍是拆分之后哪一组更纯。

样本很少时,树可以一直拆到每片叶子只有一个样本,这时它记住的是这批数据的细节。限制树的深度,或规定节点里至少还要有若干样本才继续拆,叶子会保留多数类,换一批新样本时更稳。

相关推荐
动词ing1 小时前
【题目练习】字符串相乘
算法
临床数据科学和人工智能兴趣组1 小时前
正则表达式的基础语法的基本符号
开发语言·人工智能·python·正则表达式·r语言·r语言-4.2.1·workbudyy
王中阳Go1 小时前
Go 后端转 AI:非科班怎么补?一张 3 列路线表(可保存)
开发语言·人工智能·后端·python·golang·大语言模型
计算机编程指导师2 小时前
【计算机毕设选题推荐】基于Hadoop的宫颈癌变进程光谱数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·数据分析·spark·毕业设计·宫颈癌变
0+1112 小时前
算法 --链表
数据结构·算法·leetcode·链表
aqiu1111112 小时前
【C++算法打怪专栏】C++ `unordered_set` 常用初始化与插入方法总结
开发语言·c++·算法
Terra.K2 小时前
高精度阶乘求和模板深度解析
开发语言·c++·算法
夜雪一千2 小时前
应用层加密的优缺点
python
计算机编程指导师2 小时前
【计算机毕设选题推荐】基于Hadoop+Spark的化妆品销售大数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·spark·毕业设计·课程设计·化妆品