决策树
说明
决策树是一种基本的分类与回归方法,是最经常使用的数据挖掘算法之一。
决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。它可以认为是 if-else 规则的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。
决策树学习通常包括 3 个步骤:特征选择、决策树的生成和决策树的修剪。
决策树学习的损失函数通常是正则化的极大似然函数,决策树学习属于监督学习,可以认为是学习一个分类规则。
from sklearn.datasets import load_iris
from sklearn import tree
import numpy as np
iris = load_iris()
clf = tree.DecisionTreeClassifier(min_samples_leaf=15)
clf = clf.fit(iris.data, iris.target)
# 决策树模型为:先左后右,先上后下 负数表示没有
print("树结构-左节点:"+str(clf.tree_.children_left))
print("树结构-右节点:"+str(clf.tree_.children_right))
print("节点分裂特征:"+str(clf.tree_.feature))
print("节点分裂阈值:"+str(np.round(clf.tree_.threshold,2)))
print("节点类别:"+str(clf.classes_.take( [ np.argmax(i) for i in clf.tree_.value])))
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
左节点 | 1 | -1 | 3 | 4 | -1 | -1 | 7 | -1 | -1 |
右节点 | 2 | -1 | 6 | 5 | -1 | -1 | 8 | -1 | -1 |
分类特征 | 2 | -2 | 3 | 2 | -2 | -2 | 0 | -2 | -2 |
分裂阈值 | 2.45 | -2 | 1.75 | 4.45 | -2 | -2 | 6.35 | -2 | -2 |
节点类别 | 0 | 0 | 1 | 1 | 1 | 1 | 2 | 2 | 2 |
简单示例
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
clf = DecisionTreeClassifier(random_state=0)
# 计算最小成本复杂性修剪期间的修剪路径
path = clf.cost_complexity_pruning_path(X_train, y_train)
# 从路径中提取alpha值和相应的决策树
# 剪枝期间子树的有效 alpha
# 代价复杂度剪枝法,实质就是在树的复杂度与准确性之间取得一个平衡点。
# 原理参考:https://blog.csdn.net/ywj_1991/article/details/126846155
ccp_alphas, impurities = path.ccp_alphas, path.impurities
# 在 DecisionTreeClassifier中, 这种剪枝技术是通过成本复杂度参数ccp_alpha来参数化的。更大的ccp_alpha值增加被剪枝的节点数。
clfs = []
# ccp_alphas的值是通过cost_complexity_pruning_path获得的
for ccp_alpha in ccp_alphas:
# 每个循环创建一个决策树并将其添加到列表中
clf = DecisionTreeClassifier(random_state=0, ccp_alpha=ccp_alpha)
# 拟合决策树
clf.fit(X_train, y_train)
# 决策树模型为:先左后右,先上后下 负数表示没有
print("{} | 树结构-左节点长度:{},树结构-右节点长度:{}".format(ccp_alpha,len(clf.tree_.children_right),len(clf.tree_.children_left)))
# 将决策树添加到列表中
clfs.append(clf)
print("Number of nodes in the last tree is: {} with ccp_alpha: {}".format(
clfs[-1].tree_.node_count, ccp_alphas[-1]))
# 删除 ccp_alphas的最后一个值, 因为它对应于完全未剪枝的树
clfs = clfs[:-1]
# ccp_alphas也需要删除最后一个值, 因为它是完全未剪枝的树对应的值
ccp_alphas = ccp_alphas[:-1]
模型保存
import pickle
import os
# 保存模型
with open('clf_model_v1.pickle','wb') as f:
pickle.dump(clf,f)
# 加载模型
with open('clf_model_v1.pickle','rb') as f:
clf2 = pickle.load(f)
# 删除模型
os.remove('clf_model_v1.pickle')
import joblib
# 保存模型
joblib.dump(clf, 'new_app_model_v1.pkl')
# 加载模型
clf3 = joblib.load('new_app_model_v1.pkl')
# 删除模型
os.remove('new_app_model_v1.pkl')