算法原理
决策树算法依据对一系列属性取值的判定得出最终决策。在每个非叶子节点上进行一个特征属性的测试,每个分支表示这个特征属性在某个值域上的输出,而每个叶子节点对应于最终决策结果。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点对应的类别作为决策结果。算法的目的是产生一棵泛化性能强,即处理未见数据能力强的决策树。
实验内容
1、利用相应库中算法对鸢尾花数据构建决策树
2、可视化决策树
3、分别查看训练集、测试集上模型的评估指标(准确率)
思路:首先对数据进行预处理,主要包括缺失值的处理以及连续属性的离散化方法;然后进行各个模型的实现,包括:数据集中属性的信息增益(或信息增益率、gini指数)的计算;选择最佳划分属性;以及构建决策树的递归方法等。
from sklearn import tree
import pydotplus
import os
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from pylab import *
from sklearn.tree.export import export_text
os.environ["PATH"] += os.pathsep + 'D:\software\graphviz\\bin'
#导入数据
iris = load_iris()
#构建模型
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data,iris.target)
print(clf)
#导出树的结构
r = export_text(clf, feature_names=iris['feature_names'])
print(r)
dot_data = \
tree.export_graphviz(clf,
out_file=None,
feature_names=iris.feature_names,
filled=True,
impurity=False,
rounded=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.get_nodes()[7].set_fillcolor("#FFF2DD")
graph.write_png('iris.png')
# 训练集、测试集数据分割
seed = 1729140713
train, test, train_label, test_label = train_test_split(iris.data,iris.target,test_size=0.3,random_state=seed)
#选用机器学习算法
models = []
models.append(('DecisionTree', DecisionTreeClassifier())) #决策树
models.append(('GaussianNB', GaussianNB())) #朴素贝叶斯
models.append(('RandomForest', RandomForestClassifier())) #随机森林
models.append(('SVM', SVC())) #支持向量机SVM
#基于测试集test的预测及验证
for name, model in models:
model.fit(train, train_label)
pre = model.predict(test)
results = model.score(test, test_label)
print("算法:{}\n准确率:{}{} ".format(name, results * 100, "%"))
print(classification_report(test_label, pre, target_names=iris.target_names))
#交叉验证
print("***交叉验证***")
X_train, X_test, Y_train, Y_test = train_test_split(iris.data, iris.target)
names = []
scores = []
for name, model in models:
cfit = model.fit(X_train, Y_train)
cfit.score(X_test, Y_test)
cv_scores = cross_val_score(model, X_train, Y_train, cv=10)
scores.append(cv_scores)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_scores.mean(), cv_scores.std())
print(msg)
#算法比较
fig = plt.figure()
fig.suptitle('Prediction accuracy of four algorithms')#设置标题:四种算法准确率比较
ax = fig.add_subplot(1,1,1)
plt.ylabel('algorithm')#算法
plt.xlabel('Accuracy')#准确率
plt.boxplot(scores,vert=False,patch_artist=True,meanline=False,showmeans=True)
ax.set_yticklabels(names)
plt.show()
实验结果分析
由实验结果可看出所构建的决策树中有6层,叶子数目有9个,当以属性petal width<=0.8为划分条件时可将第一类和后两类鸢尾花分开,再以属性petal width<=1.75可将后两类鸢尾花大致分开,此时分类错误率为0.04。在此基础之上再以其他属性为划分条件效果相对较差,复杂了模型。同时,也可将其他三个属性作为首选的划分节点,对比使用不同属性划分的效果。通过所训练模型可得出四种算法的准确率。DecisionTree准确率93.33%,GaussianNB准确率97.78%,RandomForest准确率95.56%,SVM准确率100%。由此可见,支持向量机SVM的准确率最高,在交叉验证中四种算法准确率分别为93.9%、94.70%、93.79%、97.42%,在准确率中SVM算法准确率较高,且由于方差最小,算法比较稳定。