泰坦尼克号沉没是历史上最著名的沉船事件。1912年4月15日,在她的处女航中,泰坦尼克号在与冰山相撞后沉没,在2224名乘客和船员中造成1502人死亡。这场耸人听闻的悲剧震惊了国际社会,并为船舶制定了更好的安全规定。 造成海难失事的原因之一是乘客和船员没有足够的救生艇。尽管幸存下来有一些运气因素,但有些人比其他人更容易生存,例如妇女,儿童和社会地位较高的人群。 在这个案例中,我们要求您完成对哪些人可能存活的分析
案例:Titanic - Machine Learning from Disaster | Kaggle
我们提取到的数据集中的特征包括票的类别,是否存活,乘坐班次,姓名,年龄,上船港口,房间,性别等。
数据:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
#1.1导入数据
import pandas as pd
#1.2.利用pandas的read.csv模块从互联网中收集泰坦尼克号数据集
titanic=pd.read_csv("data/泰坦尼克号数据集.csv")
#2.1首先观察数据的基本特征
titanic.head()
#2.2使用pandas的info属性查看数据的统计特征
titanic.info()
#注:数据共有1313条乘客信息,有些特征是完整的,有一些是不完整的,如name和pclass是完整的,age是不完整的。
#由于数据比较久远,难免会丢失掉一些数据造成数据的不完整,也有数据是没有量化的。
#在决策树模型之前,需要对数据做一些预处理和分析的工作。
#2.3特征选择,这里根据对泰坦尼克号的了解,sex,age,pclass作为判断生还的三个主要因素。
X=titanic[['Pclass','Age','Sex']]
y=titanic['Survived']
#对当前选择的特征进行探查
X.info()
#2.4根据上面的输出,设计几个数据处理的任务
#1)age这个数据列,只有633个,需要补全完整
#2)sex和pclass两个数据列都是类别型的值,需要转化为数值,比如one-hot编码。
#使用平均数或者中位数来填充,对模型偏离程度造成的影响比较小
X['Age'].fillna(X['Age'].mean(),inplace=True)
# 对类别特征进行one-hot编码
X = pd.get_dummies(X)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=33)
from sklearn.tree import DecisionTreeClassifier
#使用默认的配置初始化决策树模型
dtc=DecisionTreeClassifier()
#使用分割的数据进行模型的学习
dtc.fit(X_train,y_train)
#用训练好的模型来对测试数据集进行预测
y_predict=dtc.predict(X_test)
from sklearn.metrics import classification_report
#输出预测准确率
dtc.score(X_test,y_test) #0.8340807174887892
#输出更加详细的分类性能
print(classification_report(y_predict,y_test,target_names=['died','survived']))
# 决策树可视化
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(30,20))
plot_tree(dtc,
max_depth=3,
filled=True,
feature_names=['Pclass', 'Age', 'Sex_female', 'Sex_male'],
class_names=['died','survived']
)
plt.show()
相比其他学习模型,决策树在模型描述上有巨大的优势,决策树的逻辑推断非常直观,具有清晰的可解释性,也有很方便的模型的可视化。在决策树的使用中,无需考虑对数据量化和标准化,就能达到比较好的识别率。
整体代码如下:
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.tree import plot_tree
import joblib
import matplotlib.pyplot as plt
# 模型训练
def test01():
data = pd.read_csv("data/泰坦尼克号数据集.csv")
print(data.head())
# 确定特征值和目标值
x = data[["Pclass", "Age", "Sex"]].copy()
y = data["Survived"]
# 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
x['Age'].fillna(x['Age'].mean(), inplace=True)
# 类别特征进行独热编码
x = pd.get_dummies(x, columns=['Pclass', 'Sex'])
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)
# 5.模型评估
print('准确率:', estimator.score(x_test, y_test))
print('预测结果:', estimator.predict(x_test))
# 模型保存
joblib.dump(estimator, 'model/dt.pth')
# 决策树可视化
def test02():
# 1. 加载模型
estimator = joblib.load('model/dt.pth')
# 2. 决策树可视化
fig, ax = plt.subplots(figsize=(50, 50))
plot_tree(estimator,
ax=ax,
max_depth=3,
filled=True,
feature_names=['Age', 'Pclass_1', 'Pclass_2', 'Pclass_3', 'Sex_female', 'Sex_male'],
class_names=['生存', '不生存'])
plt.savefig('a.png', dpi=100)
if __name__ == '__main__':
test02()