Decision Tree Python Code
Test data
使用三个指标,是否为985,学历,编程语言,来判断是否面试录取
Decision Tree Algorithm
将所有指标添加进指标列表
计算指标列表中每个指标的熵,并按照最小熵的指标进行划分
如果能够成功划分则直接得出结果
否则将该指标从指标列表移除后之前前一个步骤
并且将结果添加到决策树中
```python
import numpy as np
from collections import Counter
from math import log2
# 用于计算信息熵的辅助函数
def entropy(y):
counter = Counter(y) # 统计每个类别的样本数量
total = len(y) # 样本总数
ent = 0.0
for count in counter.values():
p = count / total # 计算类别概率
ent -= p * log2(p) # 计算信息熵
return ent
def geni(y_label):
"""
计算基尼系数
参数:
y_label (list): 类别标签列表
返回:
float: 基尼系数
"""
counter = Counter(y_label) # 统计每个类别的样本数量
g = 1.0 # 基尼系数初始化为1
for num in counter.values():
p = num / len(y_label) # 计算类别概率
g -= p * p # 基尼系数公式
return g
class DecisionTree:
def __init__(self): # 初始化方法
self.tree = {} # 初始化决策树为空字典
# 训练决策树
def fit(self, X, y):
cols = list(range(X.shape[1])) # 获取所有特征列的索引
# 对X的每一列数据,计算分割后的信息熵
self.tree = self._genTree(cols, X, y) # 生成决策树
# 递归生成决策树
def _genTree(self, cols, X, y):
# 计算最小信息熵的特征
imin = cols[0] # 最小熵的列
emin = 100 # 最小熵值,初始化为一个较大值
for i in cols:
coli = X[:, i] # 拿到第i个特征数据,X里面有行和列,行是数据,列是第ith 特征数据
enti = sum([entropy(y[coli == d]) for d in set(coli)]) # 计算该特征的总熵值,y[coli == d]相当走过所有的这些特征数据?
if enti < emin:
imin = i # 更新最小熵特征列
emin = enti # 更新最小熵值
# 根据最小熵特征有几个值,生成几个新的子树分支
newtree = {}
mincol = X[:, imin] # 获取最小熵特征的数据
cols.remove(imin) # 移除已使用的特征列
# 针对这个特征的每个值,进一步划分树
for d in set(mincol):
entd = entropy(y[mincol == d]) # 计算该特征值的熵
if entd < 1e-10: # 如果已经完全分开
newtree[d] = y[mincol == d][0] # 直接取该特征值的分类结果
else: # 还需要进一步细分
newtree[d] = self._genTree(cols.copy(), X[mincol == d, :], y[mincol == d]) # 递归生成子树
return {imin: newtree} # 将列号作为索引,返回新生成的树
# 预测新样本
def predict(self, X):
X = X.tolist() # 将输入数据转换为列表
y = [None for i in range(len(X))] # 初始化预测结果
for i in range(len(X)):
predictDict = self.tree # 从根节点开始预测
while predictDict != 'Yes' and predictDict != 'No': # 如果不是叶子节点
col = list(predictDict.keys())[0] # 获取当前节点的特征列
predictDict = predictDict[col] # 更新预测字典到子树
predictDict = predictDict[X[i][col]] # 根据样本特征值选择子树
else: # 如果是叶子节点
y[i] = predictDict # 记录预测结果
return y # 返回所有样本的预测结果
```
```python
import numpy as np
from collections import Counter
from math import log2
X=np.array([['Yes985','本科','C++'],
['Yes985','本科','Java'],
['No985' ,'硕士','Java'],
['No985' ,'硕士','C++'],
['Yes985','本科','Java'],
['No985' ,'硕士','C++'],
['Yes985','硕士','Java'],
['Yes985','博士','C++'],
['No985' ,'博士','Java'],
['No985' ,'本科','Java']])
y=np.array(['No','Yes','Yes','No','Yes','No','Yes','Yes','Yes','No'])
# Test data
# 使用三个指标,是否为985,学历,编程语言,来判断是否面试录取
# Decision Tree Algorithm
# 将所有指标添加进指标列表
# 计算指标列表中每个指标的熵,并按照最小熵的指标进行划分
# 如果能够成功划分则直接得出结果
# 否则将该指标从指标列表移除后之前前一个步骤
# 并且将结果添加到决策树中
dt = DecisionTree()
dt.fit(X, y)
print(dt.tree)
print(dt.predict(X))
```
Reference:
Last updated