练习-泰坦尼克号 乘客生还预测
昨天,有群友分享万维钢老师《精英日课》专栏的151课。
看了一下。是用Python实操写一个人工智能程序。自己颇感兴趣,就照着代码练习一下。
泰坦尼克号背景介绍
泰坦尼克号是一艘奥林匹克级邮轮,于1912年4月首航时撞上冰山后沉没。泰坦尼克号由位于北爱尔兰贝尔法斯特的哈兰·沃尔夫船厂兴建,是当时最大的客运轮船,由于其规模相当一艘现代航空母舰,因而号称“上帝也沉没不了的巨型邮轮”。在泰坦尼克号的首航中,从英国南安普敦出发,途经法国瑟堡-奥克特维尔以及爱尔兰昆士敦,计划横渡大西洋前往美国纽约市。但因为人为错误,于1912年4月14日船上时间夜里11点40分撞上冰山;2小时40分钟后,即4月15日凌晨02点20分,船裂成两半后沉入大西洋,死亡人数超越1500人,堪称20世纪最大的海难事件,同时也是最广为人知的海难之一。 当时报道
泰坦尼克乘客的数据已经被人放在了亚马逊的云服务器上,可以随便下载 。
# 先导入pyndas模块
import pandas as pd
#下载数据并存储为表格名为:train
train_url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/train.csv"
train = pd.read_csv(train_url)
test_url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/test.csv"
自己用jupyter python3版本 做练习
数据字段说明:
PassengerId: 乘客的id
Survival: 是否幸存 0 = No, 1 = Yes
Pclass: 舱位 1 = 头等舱, 2 = 二等舱, 3 = 三等舱
Name: 姓名
Sex: 性别
Age: 年龄
SibSp: 船上兄弟姐妹以及配偶的个数
Parch: 船上父母以及者子女的个数
Ticket: 船票号码
Fare: 票价
Cabin: 在船上住的房间编号
Embarked: 登船码头(在英国哪个口岸上的船) C = Cherbourg, Q = Queenstown, S = Southampton
查询各个舱位都有多少乘客
train["Pclass"].value_counts() # 运行结果 3 491 1 216 2 184 Name: Pclass, dtype: int64
头等舱有216名乘客,二等舱有184名,三等舱有491人。
查询乘客中男女各多少人
train["Sex"].value_counts() # 运行结果 male 577 female 314 Name: Sex, dtype: int64
男乘客577人,女乘客314人。
查询遇难率
train["Survived"].value_counts() # 运行结果 0 549 1 342 Name: Survived, dtype: int64
549/(549+342) #运行结果 0.6161616161616161
这819名乘客中有549人遇难,342人幸存,遇难率是61.6%。
当你知道遇难率是61.6%时,其实现在你就可以做一次预测了。随便指定一位乘客,让你预测他是遇难还是存活,你只要预测他遇难 —— 这个预测的准确率高达61.6%。
现在我们要让这个预测更准确。
我们看电影知道上救生艇是女士和孩子优先,那么性别对于存活的影响应该很大。简单做个统计操作 ——
# Males that survived vs males that passed away print(train["Survived"][train["Sex"] == 'male'].value_counts()) #运行结果 0 468 1 109 Name: Survived, dtype: int64
109/(468+109) #运行结果 0.18890814558058924
男性的存活率只有18.9%
#Females that survived vs females that passed away print(train["Survived"][train["Sex"] == 'female'].value_counts()) #运行结果 1 233 0 81 Name: Survived, dtype: int64
233/(233+81) #运行结果 0.7420382165605095
女性的存活率是74.2%
加上性别这一维度来进行预测,我们就可以得到一个更准确的预测。
要想进一步提高准确度,我们就要上机器学习算法了。布鲁萨德选取的算法叫“决策树(Decision Tree)”,你现在不需要知道它的细节,直接调用就可以,调用方法是一行代码
from sklearn import tree, preprocessing
下面的思路非常简单。刚才我们说了,乘客的性别对存活与否影响很大。那为了更精确地预测,你能不能想想,还有哪些因素对存活可能有比较重要的影响。我们要做的就是把所有这些因素都交给“决策树”算法,让算法自动用这些因素的数据生成一个模型。
比如像姓名和编号这些数据,你能想到肯定没啥用。我们选取四项指标:
- 舱位,据说头等舱有上救生艇优先权;
- 性别,女士优先;
- 年龄,小孩优先;
- 船票费用
其实每一项因素具体起到什么作用你都不用管,你只要能猜测出来大概这几个因素有用就行了,一切都交给算法自动发现。
现在有个问题是算法要求每个数据都得有数值,可是“年龄”这一项只有714个人的数据。为此我们还得把剩下一百多个人的年龄数据给补上,就用所有乘客年龄的中位数来代替。这种事情在实际操作中非常常见,对付对付先用上再说。
# 将年龄字段中的 所有缺失值用年龄的中位数去填补
train["Age"] = train["Age"].fillna(train["Age"].median())
好,现在生成模型,也是整个机器学习的核心部分,只要以下这么短短几行代码
target = train["Survived"].values
# Preprocess
encoded_sex = preprocessing.LabelEncoder()
# Convert into numbers
train.Sex = encoded_sex.fit_transform(train.Sex)
features_one = train[["Pclass","Sex","Age","Fare"]].values
# Fit the first decision tree: my_tree_one
my_tree_one = tree.DecisionTreeClassifier()
my_tree_one = my_tree_one.fit(features_one,target)
基本上就是你告诉程序要预测的目标是乘客是否存活,影响目标的四个因素是舱位、性别、年龄和船票价格,你选取的机器学习模型是“决策树”。
最后生成的这个“my_tree_one”,就是预测模型。大功告成!
我们先看看这个模型的性质
# Look at the importance and score of the included features
print(my_tree_one.feature_importances_)
# 运行结果
[ 0.12717495 0.31274009 0.2355224 0.32456255]
结果显示四项指标在统计上的重要程度分别是:舱位占12.7%,性别占31.3%,年龄占23.6%,船票花费占33.5%。注意这只是一个综合的统计性质,模型内部非常复杂,并不是对这几个数据做什么加权平均。反正我们现在知道,船票花费是个比性别更重要的存活因素。
好,现在看看这个模型的预测准确度。利用现有的训练数据,做一次操作
print(my_tree_one.score(features_one,target))
# 运行结果
0.977553310887
模型的预测准确率高达97%。这是一个非常好的成绩,但是可以理解,因为毕竟你的模型就是用这组数据训练出来的。
对模型的真正考验是使用刚才说的那个“测试”数据。测试数据里只有11项指标,不包含存活信息。我们要把这个 test 数据拿过来,用刚才训练好的模型直接预测这些我们完全没接触过的乘客的存活情况!DataCamp 网站会帮你评分,具体的步骤我就不写了,直接告诉你结果。结果是,我们这个模型用于测试数据的准确度仍然高达97%!
你想想吧。我们只知道泰坦尼克号上一半旅客的存活信息,我们根据这些信息做了一个预测模型,然后就能用这个模型,以97%的准确度,预测另一半旅客中每个人是否活了下来!
回顾一遍,整个步骤是这样的
- 把所有数据分成两组,一组用于训练,一组用于检验;
- 数据都是数组,其中包括你想要预测的目标信息(是否存活),以及可能影响这个目标的各种信息;
- 选择几个你认为最有可能影响目标的信息(舱位、性别、年龄、票价);
- 选择一个机器学习算法(“决策树”);
- 把目标和可能影响目标的几个信息作为数组变量输入算法,训练得到一个预测模型;
- 把预测模型用于检验数据,看看这个模型的准确度。
现在你已经完成了一次人工智能编程。