决策树(decision tree)是一类常见的机器学习方法,目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树。
本文目的在于快速通过sklearn实践算法而获得直观感受,因此对于算法的原理不做过多深入介绍,感兴趣的朋友可以看下这篇博客:机器学习实战(三)——决策树
下面我们通过实际的例子了解一下决策树是什么。本文使用的数据来自于一部经典的电影:泰坦尼克号所发生的真实事故的相关数据,如今,许多科学家视图通过计算机模拟和分析找出潜藏在数据背后的生还逻辑,例如下图的一个简单的决策树模型:
正如上图所示,决策树节点(node)代表数据特征,如性别,年龄,舱位等,而决策树所以叶子节点(leaf)则显示模型的决策结果,本文的数据是二分类任务,因此只有生存或死亡两种结果。
集成(Ensemble)分类模型,通过综合考量多个分类器的预测结果,从而做出决策。这种综合考量方式大致分为两种:
简单的介绍就到这里,下面我们来看一下泰坦尼克号的数据吧:
import pandas as pd
#通过pandas读取网上的泰坦尼克号数据
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
#观察前几行数据
print(titanic.head())
#titanic是dataframe格式,因此可以使用info()方法查看数据的统计特性
print(titanic.info())
由于案例数据年代过于久远,难免有信息丢失和不完整,甚至许多特征还没有向量化,因此在使用决策树模型进行学习之前,还需要对数据做一些预处理和分析工作,如下所示:
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
#通过pandas读取网上的泰坦尼克号数据
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
#观察前几行数据
print(titanic.head())
#titanic是dataframe格式,因此可以使用info()方法查看数据的统计特性
print(titanic.info())
#选择三个重要的特征
X = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
#查看X的数据信息
print(X.info()) #发现age中有600多个NaN值,sex和pclass是类别变量需要转换为特征数值
#用平均数补充age中的缺失值
X['age'].fillna(X['age'].mean(), inplace=True)
print(X.info()) #确认age特征得到了补充
#使用feature_extraction中的特征转换器,把类别变量中的特征都单独剥离出来,独立成一列特征
vec = DictVectorizer(sparse=False)
X = vec.fit_transform(X.to_dict(orient='record'))
print(vec.feature_names_)
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
#通过pandas读取网上的泰坦尼克号数据
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
#观察前几行数据
print(titanic.head())
#titanic是dataframe格式,因此可以使用info()方法查看数据的统计特性
print(titanic.info())
#选择三个重要的特征
X = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
#查看X的数据信息
print(X.info()) #发现age中有600多个NaN值,sex和pclass是类别变量需要转换为特征数值
#用平均数补充age中的缺失值
X['age'].fillna(X['age'].mean(), inplace=True)
print(X.info()) #确认age特征得到了补充
#使用feature_extraction中的特征转换器,把类别变量中的特征都单独剥离出来,独立成一列特征
vec = DictVectorizer(sparse=False)
X = vec.fit_transform(X.to_dict(orient='record'))
print(vec.feature_names_)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)
#使用单一决策树进行模型训练和预测分析
dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)
y_dtc_predict = dtc.predict(X_test)
#使用随机森林分类器进行模型训练和预测分析
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
y_rfc_predict = rfc.predict(X_test)
#使用梯度上升决策树分类器进行模型训练和预测分析
gbc = GradientBoostingClassifier()
gbc.fit(X_train, y_train)
y_gbc_predict = gbc.predict(X_train)
#输出三种分类器的预测结果
print('The Accuracy of DecisionTreeClassifier is:', dtc.score(X_test, y_test))
print('The Accuracy of RandomForestClassifier is:', rfc.score(X_test, y_test))
print('The Accuracy of GradientBoosstingClassifier is:', gbc.score(X_test, y_test))
输出结果:
The Accuracy of DecisionTreeClassifier is: 0.7963525835866262
The Accuracy of RandomForestClassifier is: 0.8054711246200608
The Accuracy of GradientBoosstingClassifier is: 0.8085106382978723
上述输出结果表明,在相同的训练和测试数据下,仅仅使用模型的默认配置,梯度上升决策树具有最佳的性能,其次是随机森林分类器,最后是单一决策树。大量在其他数据上的模型实践也证明了上述结论的普适性。
一般而言,工业界为了追求更强劲的预测性能,经常使用随机森林分类模型作为基线系统。