用决策树做泰坦尼克号乘客的生存预测

前言

前些天学习了一下决策树算法(ID3、C4.5、cart算法),今天实际练习一下。

数据集、测试集地址:

https://github.com/cystanford/Titanic_Data

原始数据:

train.csv 是训练数据集,包含特征信息和存活与否的标签;

test.csv: 测试数据集,只包含特征信息。

我们需要做的,就是使用训练集的数据,构建决策树,然后对测试集数据进行预测。

训练集中的数据特征:

数据分析流程:

 

 

接下来我们会按照以上这6个步骤,去对泰坦尼克号乘客进行生存预测。

数据探索:

数据探索,其实就是对现有数据进行分析。比如行数、列数、数据完整度等。

进行数据探索,你需要知道如下几个函数:

使用info()查看数据表的基本信息:行数、列数、每列的数据类型、数据完整度;

使用describe()了解数据表的统计情况:总数、平均值、标准值、最小值、最大值等;

使用describe(include=['0'])查看字符串(非数字)类型的整体情况

使用head查看前几行数据(默认5行)

使用tail查看后几行数据(默认后5行)

接下来我们执行一下这些命令

import pandas as pd

# 数据加载
train_data = pd.read_csv('../niki/train.csv')

info()查看数据表基本信息

# 数据探索
print(train_data.info())

可以看到它展示了:行数、数据完整度、数据类型、字段名、数据类型数、内存使用情况。

describe()查看数据表的统计信息:

# 数据探索
print(train_data.describe())

 可以看出,它展示的依次是:数据量、平均值、标准差、最小值、还有25%、50%、75%所含的数据、最大值

上面的输出结果只展示了部分数据,如果想展示全部的数据,只需要在describe方法执行之前,加上上面两句指令即可:

# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)

describe(include=['0'])查看字符串类型整体情况:

# 数据探索
print(train_data.describe(include=['O']))

 

 展示了数据的数量,有多少数据是不等的,出现数量最多的数据是什么,出现了几次。

head tail查看数据的前几行和后几行:

这两条命令和linux查看文件的命令是一样的。

# 数据探索
print(train_data.head())
print('-'*50)
print(train_data.tail())

 

数据清洗:

我们对训练集和测试集中的数据进行探索,可以得知:

Age、Fare、Cabin、Embarked存在缺失,Age数值型,代表年龄。我们可以用平均值补齐,Fare是船票价格,同理。

# 数据清洗
train_data['Age'].fillna(train_data['Age'].mean(), inplace=True)
test_data['Age'].fillna(test_data['Age'].mean(), inplace=True)

train_data['Fare'].fillna(train_data['Fare'].mean, inplace=True)
test_data['Fare'].fillna(test_data['Fare'].mean, inplace=True)

Cabin为船舱信息,由于训练集和测试集中有大量的缺失数据,所以无法进行补齐。

Embarked是港口信息,我们可以使用value_counts()方法进行观察:

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

发现S的占比超过了70%,所以我们可以用s值进行补齐

train_data['Embarked'].fillna('S', inplace=True)
test_data['Embarked'].fillna('S', inplace=True)

特征选择:

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

我们现将这些值放到特征向量里:

# 特征选择
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 来表示。我们可以用klearn 特征选择中的 DictVectorizer 类进行上述操作:

from sklearn.feature_extraction import DictVectorizer
dvec = DictVectorizer(sparse=False)
train_features = dvec.fit_transform(train_features.to_dict(orient='record'))

fit_transfrom可以将特征向量转换成特征矩阵,然后我们可以通过查看dvec的feature_name_属性来获取特征值。

 

 

 这样我们就得到了一个10个特征值,891个样本的10列的特征矩阵。

决策树模型:

我们可以使用ID3算法构建决策树,即创建DecisionTreeClassifier的时候,设置criterion='entropy'

from sklearn.tree import DecisionTreeClassifier

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

模型的预测 & 评估:

我们首先应该得到测试集的特征矩阵,然后使用训练好的clf树进行预测。

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

在模型评估中,我们可以使用决策树的score函数得到准确率,但是由于我们不知道测试集中的结果,所以我们这里使用训练集的数据,进行一下预测。

  但是这么做显然是不准确的,因为我们的决策树是通过训练集数据构建出来的。所以它的正确率会趋近于100%,那么有没有什么方法可以在不知道测试机数据结果的时候,来统计决策树的准确率呢?

这里就会使用k折交叉验证的方式。

    1. K折交叉验证是这样的,我们将整个训练集分成k等份
    2. 使用其中的1份作为测试数据,其余的数据作为训练数据
    3. 计算测试数据的准确性
    4. 使用不同的训练集重复2、3动作

sklearn的model_selection模型中,就提供了用于k折交叉验证的函数,cross_val_score,参数cv代表将原始数据划分成多少份。

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)))

 可以看出,结果差异还是比较大的

决策树可视化:

我们可以用Grapviz进行决策树的可视化:

import graphviz
from sklearn import tree

# 决策树可视化
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.view()

结果:

 

 

 决策树下载地址:https://github.com/cystanford/Titanic_Data

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-11-13 22:53  进击的李同学  阅读(3870)  评论(0编辑  收藏  举报