机器学习入门(十二)ID3 决策树

决策树简介 -- 生活中的决策树

女孩相亲的决策树

女儿:多大年纪了?

母亲:26。

女儿:长的帅不帅?

母亲:挺帅的。

女儿:收入高不?

母亲:不算很高,中等情况。

女儿:是公务员不?

母亲:是,在税务局上班呢。

女儿:那好,我去见见。

决策树是一种树形结构,树中每个内部节点表示一个特征上的判断,每个分支代表一个判断结果的输出, 每个叶子节点代表一种分类结果。

决策树的建立过程

  1. 特征选择:选取有较强分类能力的特征。

  2. 决策树生成:根据选择的特征生成决策树。

  3. 决策树也易过拟合,采用剪枝的方法缓解过拟合。

信息熵

• 熵 Entropy : 信息论中代表随机变量不确定度的度量

• 熵越大,数据的不确定性越高,信息就越多

• 熵越小,数据的不确定性越低

• 计算方法 ,其中 P(xi) 表示数据中类别出现的概率,H(x) 表示信息的信息熵值。

1:计算数据 α(ABCDEFGH) 信息熵,其中A、B、C、D、E、F、G、H 出现的概率为:1/8。

2:计算数据 β(AAAABBCD) 信息熵 其中A 出现的概率为1/2,B 出现的概率为1/4,C、D 出现的概率为1/8

3:假如数据集有三个类别,分别占比为:{⅓, ⅓, ⅓},信息熵:

4:假如数据集有三个类别,分别占比为:{1/10, 2/10, 7/10},信息熵:

5:假如数据集有三个类别,分别占比为:{1, 0, 0},信息熵:

信息增益

概念

信息增益是指使用某个特征A对数据集D进行划分后,系统不确定性减少的程度 。换句话说,就是"这个特征能为分类带来多少信息"。决策树的构建本质上就是在递归地计算信息增益 的过程。特征a对训练数据集D的信息增益𝐺𝑎𝑖𝑛(𝐷, 𝑎)或g(D,a),定义为集合D的熵H(D)与特征a给定条件下D的熵H(D | a)之差。条件熵(加权平均熵) ,也用于度量一个数据集合的混乱程度不确定性。其物理意义是"为了消除不确定性所需的信息量"。

数学公式:,信息增益 = 熵 -条件熵。

条件熵(加权平均熵)

• 已知 某一个论坛客户流失率数据

• 需求 考察性别、活跃度特征哪一个特征对流失率的影响更大

• 分析

✓ 15条样本:5个正样本、10个负样本

✓ 1 计算熵

✓ 2 计算性别信息增益

✓ 3 计算活跃度信息增益

✓ 4 比较两个特征的信息增益

计算熵:

计算性别条件熵(a="性别")

计算性别信息增益(a="性别")

计算活跃度条件熵(a="活跃度")

计算活跃度信息增益(a="活跃度")

结论:活跃度的信息增益比性别的信息增益大,对用户流失的影响比性别大。

完整数学计算流程

数据集示例(经典的打球决策)

序号 天气(Outlook) 温度(Temp) 湿度(Humidity) 风力(Wind) 打球(Play)
1 Sunny Hot High Weak No
2 Sunny Hot High Strong No
3 Overcast Hot High Weak Yes
4 Rainy Mild High Weak Yes
5 Rainy Cool Normal Weak Yes
6 Rainy Cool Normal Strong No
7 Overcast Cool Normal Strong Yes
8 Sunny Mild High Weak No
9 Sunny Cool Normal Weak Yes
10 Rainy Mild Normal Weak Yes
11 Sunny Mild Normal Strong Yes
12 Overcast Mild High Strong Yes
13 Overcast Hot Normal Weak Yes
14 Rainy Mild High Strong No

统计:共14个样本,Yes=9,No=5

第1步:计算根节点的熵(整个数据集)

首先计算目标变量"Play"的熵:

  • P(Yes) = 9/14 ≈ 0.643

  • P(No) = 5/14 ≈ 0.357

Entropy(S) = -[P(Yes) × log₂(P(Yes)) + P(No) × log₂(P(No))]

= -[0.643 × log₂(0.643) + 0.357 × log₂(0.357)]

= -[0.643 × (-0.637) + 0.357 × (-1.487)] // log₂计算

= -[-0.410 - 0.531]

= 0.941

根节点熵Entropy(S) = 0.941

第2步:计算每个特征的信息增益

2.1 特征:天气(Outlook)

天气有三个取值:Sunny(5个), Overcast(4个), Rainy(5个)

a) Sunny分支 (5个样本:Yes=2, No=3)

P(Yes|Sunny) = 2/5 = 0.4 P(No|Sunny) = 3/5 = 0.6 Entropy(Sunny) = -[0.4×log₂(0.4) + 0.6×log₂(0.6)] = -[0.4×(-1.322) + 0.6×(-0.737)] = -[-0.529 - 0.442] = 0.971

b) Overcast分支 (4个样本:Yes=4, No=0)

复制代码
P(Yes|Overcast) = 4/4 = 1.0
P(No|Overcast) = 0/4 = 0.0
Entropy(Overcast) = -[1.0×log₂(1.0) + 0.0×log₂(0.0)]
                  = -[1.0×0 + 0]  // log₂(1)=0, log₂(0)未定义但权重为0
                  = 0

c) Rainy分支 (5个样本:Yes=3, No=2)

复制代码
P(Yes|Rainy) = 3/5 = 0.6
P(No|Rainy) = 2/5 = 0.4
Entropy(Rainy) = -[0.6×log₂(0.6) + 0.4×log₂(0.4)]
               = -[0.6×(-0.737) + 0.4×(-1.322)]
               = -[-0.442 - 0.529]
               = 0.971

d) 计算加权平均熵

复制代码
权重(Sunny) = 5/14 ≈ 0.357
权重(Overcast) = 4/14 ≈ 0.286
权重(Rainy) = 5/14 ≈ 0.357

平均熵 = (5/14)×0.971 + (4/14)×0 + (5/14)×0.971
       = 0.357×0.971 + 0.286×0 + 0.357×0.971
       = 0.347 + 0 + 0.347
       = 0.694

e) 信息增益

复制代码
Gain(S, Outlook) = Entropy(S) - 平均熵
                 = 0.941 - 0.694
                 = 0.247

2.2 特征:温度(Temp)

温度有三个取值:Hot(4个), Mild(6个), Cool(4个)

a) Hot分支 (4个样本:Yes=2, No=2)

复制代码
P(Yes|Hot) = 2/4 = 0.5
P(No|Hot) = 2/4 = 0.5
Entropy(Hot) = -[0.5×log₂(0.5) + 0.5×log₂(0.5)]
             = -[0.5×(-1) + 0.5×(-1)]
             = -[-0.5 - 0.5]
             = 1.0

b) Mild分支 (6个样本:Yes=4, No=2)

复制代码
P(Yes|Mild) = 4/6 ≈ 0.667
P(No|Mild) = 2/6 ≈ 0.333
Entropy(Mild) = -[0.667×log₂(0.667) + 0.333×log₂(0.333)]
              = -[0.667×(-0.585) + 0.333×(-1.585)]
              = -[-0.390 - 0.528]
              = 0.918

c) Cool分支 (4个样本:Yes=3, No=1)

复制代码
P(Yes|Cool) = 3/4 = 0.75
P(No|Cool) = 1/4 = 0.25
Entropy(Cool) = -[0.75×log₂(0.75) + 0.25×log₂(0.25)]
              = -[0.75×(-0.415) + 0.25×(-2.0)]
              = -[-0.311 - 0.5]
              = 0.811

d) 加权平均熵

复制代码
平均熵 = (4/14)×1.0 + (6/14)×0.918 + (4/14)×0.811
       = 0.286×1.0 + 0.429×0.918 + 0.286×0.811
       = 0.286 + 0.394 + 0.232
       = 0.912

e) 信息增益

复制代码
Gain(S, Temp) = 0.941 - 0.912 = 0.029

2.3 特征:湿度(Humidity)

湿度有两个取值:High(7个), Normal(7个)

a) High分支 (7个样本:Yes=3, No=4)

复制代码
P(Yes|High) = 3/7 ≈ 0.429
P(No|High) = 4/7 ≈ 0.571
Entropy(High) = -[0.429×log₂(0.429) + 0.571×log₂(0.571)]
              = -[0.429×(-1.222) + 0.571×(-0.808)]
              = -[-0.524 - 0.461]
              = 0.985

b) Normal分支 (7个样本:Yes=6, No=1)

复制代码
P(Yes|Normal) = 6/7 ≈ 0.857
P(No|Normal) = 1/7 ≈ 0.143
Entropy(Normal) = -[0.857×log₂(0.857) + 0.143×log₂(0.143)]
                = -[0.857×(-0.222) + 0.143×(-2.807)]
                = -[-0.190 - 0.401]
                = 0.591

c) 加权平均熵

复制代码
平均熵 = (7/14)×0.985 + (7/14)×0.591
       = 0.5×0.985 + 0.5×0.591
       = 0.493 + 0.296
       = 0.789

d) 信息增益

复制代码
Gain(S, Humidity) = 0.941 - 0.789 = 0.152

2.4 特征:风力(Wind)

风力有两个取值:Weak(8个), Strong(6个)

a) Weak分支 (8个样本:Yes=6, No=2)

复制代码
P(Yes|Weak) = 6/8 = 0.75
P(No|Weak) = 2/8 = 0.25
Entropy(Weak) = -[0.75×log₂(0.75) + 0.25×log₂(0.25)]
              = -[0.75×(-0.415) + 0.25×(-2.0)]
              = -[-0.311 - 0.5]
              = 0.811

b) Strong分支 (6个样本:Yes=3, No=3)

复制代码
P(Yes|Strong) = 3/6 = 0.5
P(No|Strong) = 3/6 = 0.5
Entropy(Strong) = -[0.5×log₂(0.5) + 0.5×log₂(0.5)]
                = -[0.5×(-1) + 0.5×(-1)]
                = -[-0.5 - 0.5]
                = 1.0

c) 加权平均熵

复制代码
平均熵 = (8/14)×0.811 + (6/14)×1.0
       = 0.571×0.811 + 0.429×1.0
       = 0.463 + 0.429
       = 0.892

d) 信息增益

复制代码
Gain(S, Wind) = 0.941 - 0.892 = 0.049

第3步:选择根节点特征

比较所有增益:

复制代码
Gain(Outlook) = 0.247  ← 最大
Gain(Humidity) = 0.152
Gain(Wind) = 0.049
Gain(Temp) = 0.029

选择 Outlook 作为根节点,因为它信息增益最大。

现在树的结构开始形成:

复制代码
         [Outlook]
        /    |    \
   Sunny  Overcast  Rainy
   (5个)   (4个)    (5个)

第4步:递归处理各个分支

4.1 分支:天气Outlook = Overcast

数据子集(4个样本):

复制代码
序号 温度 湿度 风力 Play
3   Hot  High  Weak   Yes
7   Cool Normal Strong Yes
12  Mild High  Strong Yes
13  Hot  Normal Weak   Yes

计算

  • Yes = 4, No = 0

  • P(Yes) = 4/4 = 1.0

  • P(No) = 0/4 = 0.0

  • Entropy(Overcast) = -[1.0×log₂(1.0) + 0.0×log₂(0.0)] = 0

判定

  • 节点纯净(熵=0)

  • 创建叶子节点:Play = Yes


4.2 分支:天气Outlook = Sunny

数据子集(5个样本):

复制代码
序号 温度 湿度 风力 Play
1   Hot  High  Weak   No
2   Hot  High  Strong No
8   Mild High  Weak   No
9   Cool Normal Weak   Yes
11  Mild Normal Strong Yes
4.2.1 计算Sunny分支的熵
  • Yes = 2, No = 3

  • P(Yes) = 2/5 = 0.4

  • P(No) = 3/5 = 0.6

  • Entropy(S_sunny) = -[0.4×log₂(0.4) + 0.6×log₂(0.6)] = 0.971

4.2.2 计算剩余特征的信息增益

a) 特征:湿度Humidity (在Sunny分支)

  • High: 3个样本(全部No)

  • Normal: 2个样本(全部Yes)

复制代码
Entropy(High|Sunny) = -[P(Yes)×log₂(P(Yes)) + P(No)×log₂(P(No))]
                    = -[0×log₂(0) + 1×log₂(1)] = 0(全是No)

Entropy(Normal|Sunny) = -[P(Yes)×log₂(P(Yes)) + P(No)×log₂(P(No))]
                      = -[1×log₂(1) + 0×log₂(0)] = 0(全是Yes)

权重(High) = 3/5 = 0.6
权重(Normal) = 2/5 = 0.4

加权平均熵 = 0.6×0 + 0.4×0 = 0

Gain(Sunny, Humidity) = Entropy(S_sunny) - 加权平均熵
                      = 0.971 - 0 = 0.971

b) 特征:温度Temp (在Sunny分支)

  • Hot: 2个样本(全部No)

  • Mild: 2个样本(1Yes, 1No)

  • Cool: 1个样本(1Yes, 0No)

复制代码
# Hot分支
P(Yes|Hot) = 0/2 = 0, P(No|Hot) = 2/2 = 1
Entropy(Hot|Sunny) = -[0×log₂(0) + 1×log₂(1)] = 0

# Mild分支
P(Yes|Mild) = 1/2 = 0.5, P(No|Mild) = 1/2 = 0.5
Entropy(Mild|Sunny) = -[0.5×log₂(0.5) + 0.5×log₂(0.5)] = 1.0

# Cool分支
P(Yes|Cool) = 1/1 = 1, P(No|Cool) = 0/1 = 0
Entropy(Cool|Sunny) = -[1×log₂(1) + 0×log₂(0)] = 0

加权平均熵 = (2/5)×0 + (2/5)×1.0 + (1/5)×0 = 0.4

Gain(Sunny, Temp) = 0.971 - 0.4 = 0.571

c) 特征:风力Wind (在Sunny分支)

  • Weak: 3个样本(1Yes, 2No)

  • Strong: 2个样本(1Yes, 1No)

复制代码
# Weak分支
P(Yes|Weak) = 1/3 ≈ 0.333, P(No|Weak) = 2/3 ≈ 0.667
Entropy(Weak|Sunny) = -[0.333×log₂(0.333) + 0.667×log₂(0.667)]
                    = -[0.333×(-1.585) + 0.667×(-0.585)]
                    = -[-0.528 - 0.390] = 0.918

# Strong分支
P(Yes|Strong) = 1/2 = 0.5, P(No|Strong) = 1/2 = 0.5
Entropy(Strong|Sunny) = -[0.5×log₂(0.5) + 0.5×log₂(0.5)] = 1.0

加权平均熵 = (3/5)×0.918 + (2/5)×1.0 = 0.951

Gain(Sunny, Wind) = 0.971 - 0.951 = 0.020
4.2.3 比较并选择
复制代码
Gain(Sunny, 湿度Humidity) = 0.971 ← 最大
Gain(Sunny, 温度Temp) = 0.571
Gain(Sunny, 风力Wind) = 0.020

选择 湿度Humidity 作为Sunny分支的节点


4.2.4 继续递归:Sunny → 湿度Humidity 分支

分支1: 湿度Humidity = High

数据子集(3个样本):

复制代码
序号 温度 风力 Play
1   Hot  Weak   No
2   Hot  Strong No
8   Mild Weak   No
  • Yes = 0, No = 3

  • 判定:节点纯净(全是No)

  • 创建叶子节点:Play = No

分支2: 湿度Humidity = Normal

数据子集(2个样本):

复制代码
序号 温度 风力 Play
9   Cool Weak   Yes
11  Mild Strong Yes
  • Yes = 2, No = 0

  • 判定:节点纯净(全是Yes)

  • 创建叶子节点:Play = Yes


4.3 分支:天气Outlook = Rainy

数据子集(5个样本):

复制代码
序号 温度 湿度 风力 Play
4   Mild High  Weak   Yes
5   Cool Normal Weak   Yes
6   Cool Normal Strong No
10  Mild Normal Weak   Yes
14  Mild High  Strong No
4.3.1 计算Rainy分支的熵
  • Yes = 3, No = 2

  • P(Yes) = 3/5 = 0.6

  • P(No) = 2/5 = 0.4

  • Entropy(S_rainy) = -[0.6×log₂(0.6) + 0.4×log₂(0.4)] = 0.971

4.3.2 计算剩余特征的信息增益

a) 特征:湿度Humidity (在Rainy分支)

  • High: 2个样本(1Yes, 1No)

  • Normal: 3个样本(2Yes, 1No)

复制代码
# High分支
P(Yes|High) = 1/2 = 0.5, P(No|High) = 1/2 = 0.5
Entropy(High|Rainy) = 1.0

# Normal分支
P(Yes|Normal) = 2/3 ≈ 0.667, P(No|Normal) = 1/3 ≈ 0.333
Entropy(Normal|Rainy) = -[0.667×log₂(0.667) + 0.333×log₂(0.333)]
                      = 0.918

加权平均熵 = (2/5)×1.0 + (3/5)×0.918 = 0.951

Gain(Rainy, Humidity) = 0.971 - 0.951 = 0.020

b) 特征:温度Temp (在Rainy分支)

  • Hot: 0个样本(不计算)

  • Mild: 3个样本(2Yes, 1No)

  • Cool: 2个样本(1Yes, 1No)

复制代码
# Mild分支
P(Yes|Mild) = 2/3 ≈ 0.667, P(No|Mild) = 1/3 ≈ 0.333
Entropy(Mild|Rainy) = 0.918

# Cool分支
P(Yes|Cool) = 1/2 = 0.5, P(No|Cool) = 1/2 = 0.5
Entropy(Cool|Rainy) = 1.0

加权平均熵 = (3/5)×0.918 + (2/5)×1.0 = 0.951

Gain(Rainy, Temp) = 0.971 - 0.951 = 0.020

c) 特征:风力Wind (在Rainy分支)

  • Weak: 3个样本(全部Yes)

  • Strong: 2个样本(全部No)

复制代码
# Weak分支
P(Yes|Weak) = 3/3 = 1, P(No|Weak) = 0/3 = 0
Entropy(Weak|Rainy) = 0

# Strong分支
P(Yes|Strong) = 0/2 = 0, P(No|Strong) = 2/2 = 1
Entropy(Strong|Rainy) = 0

加权平均熵 = (3/5)×0 + (2/5)×0 = 0

Gain(Rainy, Wind) = 0.971 - 0 = 0.971
4.3.3 比较并选择
复制代码
Gain(Rainy, 风力Wind) = 0.971 ← 最大
Gain(Rainy, 湿度Humidity) = 0.020
Gain(Rainy, 温度Temp) = 0.020

选择 风力Wind 作为Rainy分支的节点


4.3.4 继续递归:Rainy → 风力Wind 分支

分支1:Wind = Weak

数据子集(3个样本):

复制代码
序号 温度 湿度 Play
4   Mild High  Yes
5   Cool Normal Yes
10  Mild Normal Yes
  • Yes = 3, No = 0

  • 判定:节点纯净(全是Yes)

  • 创建叶子节点:Play = Yes

分支2:Wind = Strong

数据子集(2个样本):

复制代码
序号 温度 湿度 Play
6   Cool Normal No
14  Mild High  No
  • Yes = 0, No = 2

  • 判定:节点纯净(全是No)

  • 创建叶子节点:Play = No


第5步:所有叶子节点的判定过程汇总

节点路径 样本数 Yes No 纯度 判定类别 停止原因
Outlook=Overcast 4 4 0 1.00 Yes 节点纯净
Outlook=Sunny, Humidity=High 3 0 3 1.00 No 节点纯净
Outlook=Sunny, Humidity=Normal 2 2 0 1.00 Yes 节点纯净
Outlook=Rainy, Wind=Weak 3 3 0 1.00 Yes 节点纯净
Outlook=Rainy, Wind=Strong 2 0 2 1.00 No 节点纯净

第6步:最终决策树的完整结构

复制代码
            [Outlook: Gain=0.247]
           /         |         \
          /          |          \
         /           |           \
    Sunny          Overcast      Rainy
   (Entropy=0.971)  (纯Yes)    (Entropy=0.971)
        |                           |
    [湿度Humidity: Gain=0.971]      [风力Wind: Gain=0.971]
      /           \               /         \
  湿度=高       湿度=正常       风力=弱      风力=强
 (Entropy=0)   (Entropy=0)  (Entropy=0)  (Entropy=0)
    |             |            |            |
    No            Yes          Yes          No
(3个样本)      (2个样本)    (3个样本)    (2个样本)

代码

python 复制代码
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 设置随机种子保证可重复性
np.random.seed(42)

# 生成更丰富的数据(类似于天气预测是否打球的例子)
n_samples = 200

# 生成特征数据
weather_options = ['晴', '阴', '雨']
weather = np.random.choice(weather_options, size=n_samples, p=[0.4, 0.3, 0.3])

temp_options = ['热', '中', '冷']
temperature = np.random.choice(temp_options, size=n_samples, p=[0.4, 0.4, 0.2])

humidity_options = ['高', '正常']
humidity = np.random.choice(humidity_options, size=n_samples, p=[0.5, 0.5])

wind_options = ['强', '弱']
wind = np.random.choice(wind_options, size=n_samples, p=[0.4, 0.6])

# 基于规则生成目标变量(模拟真实决策过程)
play = []
for w, t, h, wd in zip(weather, temperature, humidity, wind):
    # 设置一些决策规则
    if w == '晴':
        if h == '高':
            play.append('否')  # 晴天+湿度高 → 不打球
        else:
            play.append('是')  # 晴天+湿度正常 → 打球
    elif w == '阴':
        # 阴天大多数情况打球
        if t == '热' and h == '高':
            play.append('否')  # 阴天+热+高湿 → 不打球
        else:
            play.append('是')
    else:  # 雨天
        if wd == '强':
            play.append('否')  # 雨天+强风 → 不打球
        else:
            play.append('是')  # 雨天+弱风 → 打球

# 添加一些噪声(让数据更真实)
for i in range(int(n_samples * 0.1)):  # 10%的噪声
    idx = np.random.randint(0, n_samples)
    play[idx] = '是' if play[idx] == '否' else '否'

# 创建DataFrame
df = pd.DataFrame({
    '天气': weather,
    '温度': temperature,
    '湿度': humidity,
    '风力': wind,
    '打球': play
})

print("数据预览:")
print(df.head(2))
print(f"\n数据形状:{df.shape}")
print("\n数据分布:")
print(df['打球'].value_counts())
print("\n特征分布:")
for col in ['天气', '温度', '湿度', '风力']:
    print(f"{col}: {df[col].value_counts().to_dict()}")

# 数据预处理
X = df[['天气', '温度', '湿度', '风力']]
y = df['打球']

# one-hot 编码
X_encoded = pd.get_dummies(X, drop_first=False)

print(f"\n编码后特征维度:{X_encoded.shape}")
print("\n编码后特征列名:")
print(X_encoded.columns.tolist())

# 训练决策树(ID3使用entropy作为标准)
clf = DecisionTreeClassifier(
    criterion='entropy',  # 使用信息增益(ID3的核心)
    max_depth=4,  # 限制树深度,避免过拟合
    min_samples_split=5,  # 最小分裂样本数
    min_samples_leaf=2,  # 叶节点最小样本数
    random_state=42
)

# 训练模型
clf.fit(X_encoded, y)

# 可视化决策树
plt.figure(figsize=(16, 10))
plot_tree(clf,
          feature_names=X_encoded.columns.tolist(),
          class_names=['否', '是'],
          filled=True,
          rounded=True,
          fontsize=10,
          max_depth=4)
plt.title("ID3决策树 - 天气预测是否打球", fontsize=14, pad=20)
plt.tight_layout()
plt.show()

# 打印树的结构信息
print("\n=== 决策树结构信息 ===")
print(f"树深度: {clf.get_depth()}")
print(f"叶节点数: {clf.get_n_leaves()}")
print(f"特征重要性:")
for feature, importance in zip(X_encoded.columns, clf.feature_importances_):
    if importance > 0:
        print(f"  {feature}: {importance:.3f}")

# 测试模型性能
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 训练集上的预测
y_pred = clf.predict(X_encoded)
accuracy = accuracy_score(y, y_pred)
print(f"\n训练集准确率: {accuracy:.3f}")

# 生成测试数据
test_data = pd.DataFrame({
    '天气': ['晴', '阴', '雨', '晴', '雨'],
    '温度': ['热', '中', '冷', '中', '中'],
    '湿度': ['高', '正常', '高', '正常', '正常'],
    '风力': ['弱', '强', '弱', '强', '弱']
})

print("\n=== 测试预测 ===")
for i in range(len(test_data)):
    # 准备测试样本
    test_sample = pd.DataFrame([test_data.iloc[i]])
    test_encoded = pd.get_dummies(test_sample)

    # 对齐特征列
    test_encoded = test_encoded.reindex(columns=X_encoded.columns, fill_value=0)

    # 预测
    prediction = clf.predict(test_encoded)
    probability = clf.predict_proba(test_encoded)

    print(f"\n样本 {i + 1}:")
    print(f"  特征: {dict(test_data.iloc[i])}")
    print(f"  预测: {'打球' if prediction[0] == '是' else '不打球'}")
    print(f"  概率: 不打球={probability[0][0]:.2f}, 打球={probability[0][1]:.2f}")

# 创建更简单的示例来展示完整的树
print("\n=== 简单示例展示完整树结构 ===")
simple_data = {
    '天气': ['晴', '晴', '阴', '雨', '雨', '雨', '阴', '晴', '晴', '雨'],
    '温度': ['热', '热', '热', '中', '冷', '冷', '冷', '中', '冷', '中'],
    '湿度': ['高', '高', '高', '高', '正常', '正常', '正常', '正常', '高', '正常'],
    '打球': ['否', '否', '是', '是', '是', '否', '是', '否', '是', '是']
}

simple_df = pd.DataFrame(simple_data)
X_simple = simple_df[['天气', '温度', '湿度']]
y_simple = simple_df['打球']
X_simple_encoded = pd.get_dummies(X_simple)

simple_clf = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=42)
simple_clf.fit(X_simple_encoded, y_simple)

plt.figure(figsize=(12, 8))
plot_tree(simple_clf,
          feature_names=X_simple_encoded.columns.tolist(),
          class_names=['否', '是'],
          filled=True,
          rounded=True,
          fontsize=9)
plt.title("简单示例的完整决策树", fontsize=14, pad=20)
plt.tight_layout()
plt.show()

执行结果

python 复制代码
数据预览:
  天气 温度  湿度 风力 打球
0  晴  中   高  强  是
1  雨  热  正常  强  否
风力: {'弱': 111, '强': 89}

编码后特征维度:(200, 10)

编码后特征列名:
['天气_晴', '天气_阴', '天气_雨', '温度_中', '温度_冷', '温度_热', '湿度_正常', '湿度_高', '风力_弱', '风力_强']

=== 决策树结构信息 ===
树深度: 4
叶节点数: 15
特征重要性:
  天气_晴: 0.198
  天气_雨: 0.074
  温度_冷: 0.023
  温度_热: 0.167
  湿度_正常: 0.334
  风力_弱: 0.204

训练集准确率: 0.865

=== 测试预测 ===

样本 1:
  特征: {'天气': '晴', '温度': '热', '湿度': '高', '风力': '弱'}
  预测: 不打球
  概率: 不打球=1.00, 打球=0.00

样本 2:
  特征: {'天气': '阴', '温度': '中', '湿度': '正常', '风力': '强'}
  预测: 打球
  概率: 不打球=0.03, 打球=0.97

样本 3:
  特征: {'天气': '雨', '温度': '冷', '湿度': '高', '风力': '弱'}
  预测: 打球
  概率: 不打球=0.10, 打球=0.90

样本 4:
  特征: {'天气': '晴', '温度': '中', '湿度': '正常', '风力': '强'}
  预测: 打球
  概率: 不打球=0.03, 打球=0.97

样本 5:
  特征: {'天气': '雨', '温度': '中', '湿度': '正常', '风力': '弱'}
  预测: 打球
  概率: 不打球=0.00, 打球=1.00

=== 简单示例展示完整树结构 ===
相关推荐
Francek Chen2 小时前
【自然语言处理】02 文本规范化
人工智能·pytorch·深度学习·自然语言处理·easyui
wechat_Neal2 小时前
智能汽车人机交互(HMI)领域的最新研究趋势
人工智能·汽车·人机交互
板面华仔2 小时前
机器学习入门(一)——KNN算法
人工智能·算法·机器学习
xixixi777772 小时前
2026 年 1 月 26 日通信与安全行业前沿日报,聚焦核心动态、市场数据与风险事件,为决策提供参考
人工智能
玄同7652 小时前
MermaidTrace库:让Python运行时“自己画出”时序图
开发语言·人工智能·python·可视化·数据可视化·日志·异常
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-数据库设计核心业务方案(微调)
java·数据库·人工智能·spring boot·领域驱动
_ziva_2 小时前
大模型面试与实用技巧教学
人工智能
kaoshi100app2 小时前
2026年注册安全工程师报考条件解读
开发语言·人工智能·职场和发展·学习方法
deepdata_cn2 小时前
交叉熵损失分类及应用
人工智能·分类·数据挖掘