Python 决策树
1 声明
本文的数据来自网络,部分代码也有所参照,这里做了注释和延伸,旨在技术交流,如有冒犯之处请联系博主及时处理。
2 决策树简介
相关概念见下:
决策树是一个无参数的有监督的分类和回归算法。该算法通过IF-THEN-ELSE决策规则(比如:如果绩效考核是A则发奖金1000K,是B则发500)的方式来从数据中学习模型。这种决策的结构就像一个倒置树(第一个决策规则在最顶端,其它的节点随之展开)。在决策树里,每个决策规则都发生在一个决策节点上,该规则创建指向新节点的分支。一个在末端的没有决策规则的分支称为叶子节点。树越深决策树规则越复杂,模型拟合的越好。决策树构建时采用树形结构。树有两个或者多个分支,这里常见的是二分支。它能处理分类变量和连续型变量,适合处理非线性的关系。
决策树之所以较为流行是因为其较好的解释性,它的模型可以通过树状图形的方式直观的展示出来。
决策树示例(详细见韩家炜著《数据挖数据挖掘:概念与技术》内决策树部分介绍):
决策树模型总是试图一个在节点上找到产生最大的纯度的决策规则。划分纯度的指标有多,Scikit Learn里默认的是Gini。
这里 是节点t的杂质度(不纯净度,即分裂标准),
是节点t里类别是C的占比。这种寻找决策规则(该规则会产生分裂以增加不纯度)的过程会递归式重复执行,直到所有叶节点都是纯的(即节点划到某个类别)。
决策树回归
决策树回归与决策树分类类似,只不过它不是通过降低Gini不纯度或者熵,而是通过降低的残差平方和来度量。
这里 是目标变量的真实值,
是目标变量的预测值。
回归,就是根据特征向量来决定对应的输出值。回归树就是将特征空间划分成若干单元,每一个划分单元有一个特定的输出。因为每个结点都是“是”和“否”的判断,所以划分的边界是平行于坐标轴的。
那么得到的划分区域见下:
3 决策树代码与注释示例
- def irisdt():
- from sklearn import tree
- from sklearn import model_selection
- from sklearn.datasets import load_iris
- #from sklearn.grid_search import GridSearchCV
- from sklearn.model_selection import GridSearchCV
- from sklearn.metrics import classification_report
- import matplotlib.pyplot as plt
-
- iris = load_iris()
- x = iris.data
- y = iris.target
- X_train, X_test, y_train, y_test = model_selection \
- .train_test_split(x, y, test_size=0.2,
- random_state=123456)
- parameters = {
- 'criterion': ['gini', 'entropy'],
- 'max_depth': range(1,30),#[1, 2, 3, 4, 5, 6, 7, 8,9,10],
- 'max_leaf_nodes': [2,3,4, 5, 6, 7, 8, 9] #最大叶节点数
- }
- dtree = tree.DecisionTreeClassifier()
- grid_search = GridSearchCV(dtree, parameters, scoring='accuracy', cv=5)
- grid_search.fit(x, y)
-
- print(grid_search.best_estimator_) # 查看grid_search方法
- print(grid_search.best_score_) # 正确率
- print(grid_search.best_params_) # 最佳 参数组合
-
- dtree = tree.DecisionTreeClassifier(criterion='gini', max_depth=3)
- dtree.fit(X_train, y_train)
- pred = dtree.predict(X_test)
- print(pred)
- print(y_test)
- print(classification_report(y_test, pred,target_names=['setosa', 'versicolor', 'virginica']))
- print(dtree.predict([[6.9,3.3,5.6,2.4]]))#预测属于哪个分类
- print(dtree.predict_proba([[6.9,3.3,5.6,2.4]])) # 预测所属分类的概率值
- ##print(iris.target)
- print(list(iris.target_names)) #输出目标值的元素名称
- #print(grid_search.estimator.score(y_test, pred))
-
-
- def irisdecisontree():
- from sklearn import datasets
- iris = datasets.load_iris()
- X_train = iris.data[:,[0,1]][0:150]
- y_train = iris.target
- #print(iris.feature_names)
- #print(type(X_train))
- ##print(X_train[:,[0,1]][0:150])
- clf = tree.DecisionTreeClassifier(max_depth=3,criterion='entropy')
- clf = clf.fit(X_train, y_train)
- with open("../output/iristree.dot",'w') as f:
- f = export_graphviz(clf,feature_names=['sepallength','sepalwidth'],out_file=f)
- import os
- os.system('dot -Tpdf "../output/iristree.dot" -o "../output/iristree.pdf"')
- if __name__ == '__main__':
- irisdt()
4 总结
无