trees.py
import math
import operator
def calc_shannon_entropy(dataset):
"""
计算香农熵,似乎是全类的标记
熵越高,混合的数据越多
另一种度量如基尼不纯度,简单来讲就是随机选子项度量误分概率
"""
label_counts = {}
for feature_vec in dataset:
# 提取的就是那个分类的结果
current_label = feature_vec[-1]
# 计算一下各种结果一共有多少个
label_counts[current_label] = label_counts.get(current_label,0) + 1
# 香农熵
shannon_entropy = 0.
for key in label_counts.keys():
# 计算每一种结果的概率
prob = float(label_counts[key]) / len(dataset)
# 计算它的香农熵
shannon_entropy -= prob * math.log(prob,2)
return shannon_entropy
def create_dataset():
"""
简单版的创建数据
数据是列表,各个特征长度一致,最后一个是类别标签
"""
# 可以把其中一个换成'maybe'试一试,熵明显会变大
dataset = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no'],
]
labels = ['no surfacing', 'flippers']
return dataset, labels
def split_dataset(dataset,axis,value):
"""
划分数据集
"""
ret_dataset = []
for feature_vec in dataset:
if feature_vec[axis] == value:
# 反正这这两句的意思就是剔除[axis]对应的元素
reduced_feature_vec = feature_vec[:axis]
reduced_feature_vec.extend(feature_vec[axis+1:])
# 把剔除后的特征向量放进集合中
ret_dataset.append(reduced_feature_vec)
return ret_dataset
def choose_best_feature_to_split(dataset):
"""
熵的计算理解:按各自占的比例一直往下算,最后一步shannon_entropy -= prob * math.log(prob,2)
都计算完了再根据权值加回来
返回划分数据集最佳的特征
"""
# 减去类别标签,看有几个特征
num_features = len(dataset[0]) - 1
# 无序时候的基本熵
base_entropy = calc_shannon_entropy(dataset)
# 先任意初始化最佳信息增益和与之对应的最佳特征
best_info_gain = 0.
best_feature = -1
# 尝试用每一个特征来划分
for i in range(num_features):
feature