决策树(下):泰坦尼克号乘客生存预测

决策树算法是经常使用的数据挖掘算法。这是因为他呈现出来比较直观。基于决策树还诞生了很多数据挖掘算法,比如随机森林。

sklearn中的决策树模型
首先,需要知道sklearn中的自带的决策树分类器DecisionTreeClassifier,方法如下:

clf = DecisionTreeClassifier(criterion='entropy')

到目前为止,sklearn 中只实现了 ID3 与 CART 决策树,所以我们暂时只能使用这两种决策树,在构造 DecisionTreeClassifier 类时,其中有一个参数是 criterion,意为标准。它决定了构造的分类树是采用 ID3 分类树,还是 CART 分类树,对应的取值分别是 entropy 或者 gini:

  • entropy: 基于信息熵,也就是 ID3 算法,实际结果与 C4.5 相差不大;
  • gini:默认参数,基于基尼系数。CART 算法是基于基尼系数做属性划分的,所以 criterion=gini 时,实际上执行的是 CART 算法。

我们通过设置 criterion='entropy’可以创建一个 ID3 决策树分类器,然后打印下 clf,看下决策树在 sklearn 中是个什么东西?

DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
            max_features=None, max_leaf_nodes=None,
            min_impurity_decrease=0.0, min_impurity_split=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, presort=False, random_state=None,
            splitter='best')

在这里插入图片描述
在构造决策树分类器后,我们可以使用 fit 方法让分类器进行拟合,使用 predict 方法对新数据进行预测,得到预测的分类结果,也可以使用 score 方法得到分类器的准确率。
下面这个表格是 fit 方法、predict 方法和 score 方法的作用。
在这里插入图片描述
01:数据探索

import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier 

# 数据加载
train_data = pd.read_csv('./train.csv')
test_data = pd.read_csv('./test.csv')
# 数据探索
print(train_data.info())
print('-'*30)
print(train_data.describe())
print('-'*30)
print(train_data.describe(include=['O']))
print('-'*30)
print(train_data.head())
print('-'*30)
print(train_data.tail())

02:数据清洗
通过数据探索,我们发现 Age、Fare 和 Cabin 这三个字段的数据有所缺失。其中 Age 为年龄字段,是数值型,我们可以通过平均值进行补齐;Fare 为船票价格,是数值型,我们也可以通过其他人购买船票的平均值进行补齐。

# 数据清洗# 使用平均年龄来填充年龄中的 nan 值
train_data['Age'].fillna(train_data['Age'].mean(), inplace=True)
test_data['Age'].fillna(test_data['Age'].mean(),inplace=True)
# 使用票价的均值填充票价中的 nan 值
train_data['Fare'].fillna(train_data['Fare'].mean(), inplace=True)
test_data['Fare'].fillna(test_data['Fare'].mean(),inplace=True)

观察Embarked字段的取值,方法如下:

print(train_data['Embarked'].value_counts()) 

结果如下:

s644
c168
Q77

我们发现一共就 3 个登陆港口,其中 S 港口人数最多,占到了 72%,因此我们将其余缺失的 Embarked 数值均设置为 S:

# 使用登录最多的港口(众数)来填充登录港口的 nan 值
train_data['Embarked'].fillna('S', inplace=True)
test_data['Embarked'].fillna('S',inplace=True) 

03:特征选择
特征选择是分类器的关键。特征选择不同,得到的分类器也不同。

通过数据探索我们发现,PassengerId 为乘客编号,对分类没有作用,可以放弃;Name 为乘客姓名,对分类没有作用,可以放弃;Cabin 字段缺失值太多,可以放弃;Ticket 字段为船票号码,杂乱无章且无规律,可以放弃。其余的字段包括:Pclass、Sex、Age、SibSp、Parch 和 Fare,这些属性分别表示了乘客的船票等级、性别、年龄、亲戚数量以及船票价格,可能会和乘客的生存预测分类有关系。具体是什么关系,我们可以交给分类器来处理。

因此我们先将 Pclass、Sex、Age 等这些其余的字段作特征,放到特征向量 features 里。

# 特征选择
features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
train_features = train_data[features]
train_labels = train_data['Survived']
test_features = test_data[features] 

特征值里有一些是字符串,这样不方便后续的运算,需要转成数值类型,比如 Sex 字段,有 male 和 female 两种取值。我们可以把它变成 Sex=male 和 Sex=female 两个字段,数值用 0 或 1 来表示。

同理 Embarked 有 S、C、Q 三种可能,我们也可以改成 Embarked=S、Embarked=C 和 Embarked=Q 三个字段,数值用 0 或 1 来表示。

那该如何操作呢,我们可以使用 sklearn 特征选择中的 DictVectorizer 类,用它将可以处理符号化的对象,将符号转成数字 0/1 进行表示。具体方法如下:

dvec=DictVectorizer(sparse=False)
train_features=dvec.fit_transform(train_features.to_dict(orient='record'))

你会看到代码中使用了 fit_transform 这个函数,它可以将特征向量转化为特征值矩阵。然后我们看下 dvec 在转化后的特征属性是怎样的,即查看 dvec 的 feature_names_ 属性值,方法如下:

print(dvec.feature_names_) 

结果如下:

['Age', 'Embarked=C', 'Embarked=Q', 'Embarked=S', 'Fare', 'Parch', 'Pclass', 'Sex=female', 'Sex=male', 'SibSp']

你可以看到原本是一列的 Embarked,变成了“Embarked=C”“Embarked=Q”“Embarked=S”三列。Sex 列变成了“Sex=female”“Sex=male”两列。

04:决策树模型
现在我们使用 ID3 算法,即在创建 DecisionTreeClassifier 时,设置 criterion=‘entropy’,然后使用 fit 进行训练,将特征值矩阵和分类标识结果作为参数传入,得到决策树分类器。

# 构造 ID3 决策树
clf = DecisionTreeClassifier(criterion='entropy')
# 决策树训练
clf.fit(train_features, train_labels) 

05:模型评估

test_features=dvec.transform(test_features.to_dict(orient='record'))
# 决策树预测
pred_labels = clf.predict(test_features)

在模型评估中,决策树提供了 score 函数可以直接得到准确率,但是我们并不知道真实的预测结果,所以无法用预测值和真实的预测结果做比较。我们只能使用训练集中的数据进行模型评估,可以使用决策树自带的 score 函数计算下得到的结果:

# 得到决策树准确率
acc_decision_tree = round(clf.score(train_features, train_labels), 6)
print(u'score 准确率为 %.4lf' % acc_decision_tree)

score准确率为 0.9820

你会发现你刚用训练集做训练,再用训练集自身做准确率评估自然会很高。但这样得出的准确率并不能代表决策树分类器的准确率。

这是为什么呢?

因为我们没有测试集的实际结果,因此无法用测试集的预测结果与实际结果做对比。如果我们使用 score 函数对训练集的准确率进行统计,正确率会接近于 100%(如上结果为 98.2%),无法对分类器的在实际环境下做准确率的评估。

那么有什么办法,来统计决策树分类器的准确率呢?

这里可以使用 K 折交叉验证的方式,交叉验证是一种常用的验证分类准确率的方法,原理是拿出大部分样本进行训练,少量的用于分类器的验证。K 折交叉验证,就是做 K 次交叉验证,每次选取 K 分之一的数据作为验证,其余作为训练。轮流 K 次,取平均值。

K 折交叉验证的原理是这样的:

  • 将数据集平均分割成 K 个等份;
  • 使用 1 份数据作为测试数据,其余作为训练数据;
  • 计算测试准确率;
  • 使用不同的测试集,重复 2、3 步骤。

在 sklearn 的 model_selection 模型选择中提供了 cross_val_score 函数。cross_val_score 函数中的参数 cv 代表对原始数据划分成多少份,也就是我们的 K 值,一般建议 K 值取 10,因此我们可以设置 CV=10,我们可以对比下 score 和 cross_val_score 两种函数的正确率的评估结果:

import numpy as np
from sklearn.model_selection import cross_val_score
# 使用K折交叉验证 统计决策树准确率
print(u'cross_val_score准确率为 %.4lf' % np.mean(cross_val_score(clf, train_features, train_labels, cv=10)))

cross_val_score准确率为 0.7835

这里很明显,对于不知道测试集实际结果的,要使用 K 折交叉验证才能知道模型的准确率。

06:决策树可视化
sklearn 的决策树模型对我们来说,还是比较抽象的。我们可以使用 Graphviz 可视化工具帮我们把决策树呈现出来。
在这里插入图片描述
安装 Graphviz 库需要下面的几步:
安装 graphviz 工具,这里是它的下载地址;http://www.graphviz.org/download/
将 Graphviz 添加到环境变量 PATH 中;
需要 Graphviz 库,如果没有可以使用 pip install graphviz 进行安装。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值