决策树是一种能够对一个决策进行建模的树形图
我们在数据结构课程中,学习树形结构的时候对决策树应该有过大概的了解。我们通过基于特征实例迭代将训练实例集合分到子集合中来学习
我们调用sk-learn库中的DecisionTreeClassifier类来完成决策树的构建。
决策树的优点和缺点
决策树属于勤奋学习模型,模型构建完成后可以进行较快的预测
而向KNN算法这样的懒惰学习模型就会延迟所有的泛化能力,直到被用于预测中。所以它的预测过程时间较长
由于决策树的勤奋,所有决策树容易过拟合。我们需要通过剪枝的策略来缓和这个问题
过拟合:在训练集上表现得很好,而在测试集上表现得很糟糕
高效的决策树算法是贪婪算法,每次通过找出局部最优解来建立决策树,但是这并不能保证每次的局部最优最后产出的就是全局最优解,所以我们使用这个类进行训练时,如果不设定random_state参数的话,我们每次拟合出来的决策树的得分会不太一样,这是因为DecisionTreeClassifier类会自动帮我们训练出很多个模型,然后选取一个模型给我们
我们通过两个参数random_state和splitter(best,random)来决定决策树的随机性
我们使用sk-learn库中的红酒数据建立一个决策树,并打印出它的评分
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import graphviz # 很好用的可视化软件,虽然安装比较麻烦
import pandas as pd
wine = load_wine()
print(wine.feature_names) # 打印了特征名字
x_train, x_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3) # 划分训练集和测试集
clf = tree.DecisionTreeClassifier(criterion='entropy')
# 这里使用了信息熵entropy,默认时gini
clf = clf.fit(x_train, y_train)
score = clf.score(x_test, y_test)
print(score)
# 打印得分
# feature_name = ['酒精', '苹果酸', '灰', '灰的碱性', '镁', '总酚', '类黄酮', '非黄烷类酚类', '花青素', '颜 色强度', '色调', 'od280/od315稀释葡萄酒', '脯氨酸']
feature_name = ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids',
'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue',
'od280/od315_of_diluted_wines', 'proline']
dot_data = tree.export_graphviz(clf
, feature_names=feature_name
, class_names=['Gin', 'Shirley', 'Belmud']
# 柯南迷双厨狂喜
, filled=True # 颜色
, rounded=True # 圆形框)
graph = graphviz.Source(dot_data)
graph.render('tree') # 保存为tree.pdf文件
输出的特征名字和得分:
['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
0.9444444444444444
我们的决策树输出就是这个样子
我们通过颜色的不同来判断酒的不同种类,我们这里是三种酒:琴酒、雪莉和贝尔摩德,所以会有三种深浅不一的颜色
至于颜色的深浅,它代表了不纯度也就是通过这几个特征判断酒的种类的难易程度或者准确度,越深代表越准越容易
在建立决策树时,我们不一定用到了所有的特征来建立我们的决策树
首先给出集成的概念
一个集成是指估计器的组合,其性能会优于其中任何一个组件
这里我们会提到三种创建集成的方法:套袋法,推进法,堆叠法
一种能够减少估计器方差的集成元算法,被用于分类和回归问题中
对于高方差,低偏差的估计器(如上面提到的决策树),套袋法是一种有用的元算法,由于它的广泛应用,所以它又被称为随机森林
我们使用sk-learn库来训练一个决策树和随机森林,比较他们性能
首先我们创建一颗决策树
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
x,y = make_classification(n_samples=2000, n_features=200,
n_informative=20, n_clusters_per_class=2, random_state=20)
# 我们使用了make_classification数据集
#第一个参数是样本数,第二个是特征数,第三个指出20特征是有效的(属于信息的)
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=20)
clf = DecisionTreeClassifier(random_state=20)
clf.fit(x_train, y_train)
prect = clf.predict(x_test)
print(classification_report(y_test, prect))
我们可以看到得分:
precision recall f1-score support
0 0.72 0.69 0.70 243
1 0.72 0.74 0.73 257
accuracy 0.72 500
macro avg 0.72 0.72 0.72 500
weighted avg 0.72 0.72 0.72 500
然后我们建立一个随机森林
clf1 = RandomForestClassifier(n_estimators=10, random_state=20)
clf1.fit(x_train, y_train)
predict = clf1.predict(x_test)
print(classification_report(y_test, predict))
输出得分
precision recall f1-score support
0 0.70 0.86 0.77 243
1 0.83 0.65 0.73 257
accuracy 0.75 500
macro avg 0.76 0.75 0.75 500
weighted avg 0.77 0.75 0.75 500
比较可以得知,随机森林的各方面指标都要比决策树要好
AdaBoost是一个迭代算法,初始化时,会给所有的训练实例赋予相等的权重,然后训练一个弱学习器(或其他如弱分类器),在之后的学习中,弱学习器会增加训练时预测错误的训练实例的权重,减少预测正确的训练实例的权重,然后从这个新的权重分配的训练实例上训练另一个弱学习器,由于权重的增加,所以弱学习器会更加关注预测错误的实例,经过迭代达到完美性能时,算法停止
我们训练一个AdaBoostClassifier 分类器,然后绘制出随着基础估计器数量增加,它的准确率的增长曲线
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
x, y = make_classification(n_samples=2000, n_features=200, n_informative=20, n_clusters_per_class=2, random_state=20)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=20)
clf = DecisionTreeClassifier(random_state=20)
clf.fit(x_train, y_train)
print(clf.score(x_test, y_test))
acc = []
clf1 = AdaBoostClassifier(n_estimators=50, random_state=20)
clf1.fit(x_train, y_train)
acc.append(clf.score(x_test, y_test))
plt.title('ensemble accuracy')
plt.ylabel('accuracy')
plt.xlabel('number of base estimators in ensemble')
plt.plot(range(1, 51), [acc for acc in clf1.staged_score(x_test, y_test)])
plt.show()
结果:
0.716 # 这是决策树的准确率
这是推进算法的准确率:
可以看到最后的准确率在0.825左右,还是优于决策树的
一种创建集成的方法,使用一个元估计器去合并基础估计器的预测结果
也就是说基础估计器的预测结果和真实情况会作为元估计器的训练集,从而元估计器可以在这种更复杂的,数据更多的情况下进行学习,从而提高预测准确率
看到这里了就点个赞呗