社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

死里逃生?机器学习算法揭露泰坦尼克号幸存者之谜

数据魔术师 • 6 年前 • 1314 次点击  

“你一定会脱险的,你要活下去,生很多孩子,看着他们长大。你会安享晚年,安息在温暖的床上,而不是今晚在这里,不是像这样死去。”

——电影《泰坦尼克号》

1997年,一部凄美的《泰坦尼克号》让人记住了迎着黄昏拥立在船头的杰克和罗丝,也让人忘不了那艘号称“永不沉没之船”的巨轮如何一点点淹没在大海。

“后来,700多个人在大海上等着,等着活,等着死,等着做忏悔,遥遥无期。”

——电影《泰坦尼克号》


Part1 案例背景


影片根据真实事件改编,片中的泰坦尼克号是英国白星航运公司下辖的一艘奥林匹克级邮轮,于1909年动工建造,1912年首次航行。1912年4月15日,在首次航行期间,泰坦尼克号撞上冰山后沉没,2224名乘客和机组人员中有1502人遇难。这场轰动的旷世悲剧震撼了国际社会,并警醒人们制定了更完善的船舶安全条例。


本研究中,我们希望分析具有哪种特征的人可能在这样的灾难中存活。具体而言,就是运用机器学习算法来预测哪些乘客将幸免于难,从而帮助人们做好灾前预警,提高在灾难中的存活率。


本项目使用随机森林进行预测。

Part 2 数据来源及变量说

本研究数据来源于Kaggle中的项目:Titanic: Machine Learning from Disaster,网页链接:https://www.kaggle.com/c/titanic。Kaggle提供的数据集包括Training Set (train.csv)、Test Set (test.csv),其中训练集有891个观察值和12个变量,测试集有418个观察值和11个变量(缺失Survived变量)。变量说明如下:

变量类型

变量

类型

定义

取值范围/示例

因变量

Survived

int

存活与否

0=No, 1=Yes

自变量

PassengerId

int

乘客序号

1-1309


Pclass

int

乘客序号

1-1309


Name

chr

姓名

Braund, Mr. Owen Harris; Cumings, Mrs. John Bradley (Florence Briggs Thayer); Nicola-Yarred, Miss. Jamila等


Sex

chr

性别

male, female


Age

num

年龄

0.17-80 (如果年龄小于1,则年龄是分数。如果为估计年龄,为xx.5)


SibSp

int

共同登船的兄弟姐妹&配偶的总数

0-8


Parch

int

共同登船的父母&子女的总数

0-9


Ticket

chr

票号



Fare

num

票价

0-512.3292


Cabin

chr

舱号

A/B/C/D/E/F/G+数字


Embarked

chr

登船港口

C = Cherbourg, Q = Queenstown, S = Southampton


Part 3 加载数据及初步探索

第一,加载和安装必要的R包,并将测试集和训练集导入R。


第二,定义测试集的Survived变量为NA,合并测试集和训练集。


第三,查看数据完整性,是否有缺失值。


#查看数据完整性

sapply(all, function(x) {sum(is.na(x))})

结果显示:



从输出结果可以看出,变量Survived缺失的刚好是418个值,对应测试集的418个观察值,这是我们需要预测的目标。变量Age、Fare、Cabin、Embarked存在缺省值,后续需要填补缺省值。


第四,发现重要变量Sex和Pclass。


首先将Survived、Sex和Pclass转化为因子变量。接着我们调用ggplot()函数绘制了以下图形,总览了训练集中死亡和幸存的人数。


Figure 2 训练集中死亡和幸存的人数


经计算观察,在泰坦尼克号上的1309人(训练集891人+测试集418人)中,64.4%是男性。这一比例与训练集中的男性比例几乎相同(64.7%)。在训练集中,81.1%的男性死亡,25.8%的女性死亡。性别不同导致的存活率差异巨大,因此我们认为Sex似乎是一个非常重要的预测指标。


另一方面,经绘图观察,存活与否和乘客阶层密切相关。大部分头等乘客幸存下来,大多数三等乘客死亡。同样值得注意的是,几乎所有一、二等的女性都幸存下来了。而对于男性来说,二等乘客的存活率几乎和三等乘客一样糟糕(见图3)。


Figure 3 阶层、性别和存活的关系   


由此可见,Pclass和Sex同时影响存活与否,所以我们将两个变量结合,创造出PclassSex变量。PclassSex变量为因子变量,包括6个水平——“P1Male”、“P2Male”、“P3Male”、“P1Female”、“P2Female”、“P3Female”。

Part 4 数据清洗

我们对原始的变量进行一定的处理,主要是对缺省值进行处理。

4.1

>>挖掘Name中的称谓,建立“Title”变量 <<<

在数据中,“名字”(name)变量是完整的(即非空的),但是实际上这个变量不仅仅包含了姓氏和名字,还包括了对每个人的称呼(Title),我们必须将其分开,以便整理数据。同理,将姓氏分解出来(Surname,在称呼之前),我们想在后续分析家庭是否一起旅行时使用这个变量。



从上边的表格中我们可以看到,部分Title的数量很少,我们希望能够减少Title的种类,以便更好的用于预测。Ms.经常用于较年轻的已婚女士,因此我们希望将Ms.加入到Miss中,在法语中,Mlle同样也可以用Miss来表示。再者,我们假设Mme代表已婚女士,我们将其加入Mrs。对于其他低频的Title,我们将用“Rare Title”来代替。



4.2

>>处理Age缺失值 <<<

我们绘制Age和Survived变量的密度图,如下:



从密度图中可以看出,18岁以下的存活几率相对更大。


为了处理年龄缺失值,我们试图探究Age变量和Title变量、Pclass变量之间的关系。从箱线图可以看到,不同的年龄段对应不同的称谓(Title)。值得注意的是,Master这个称谓都是儿童。通过搜索得知,Master这个称谓一般指的是最大的儿子,因此有Master称谓的都是男孩。



我们进行线性回归,结果如下:



可以看出,Pclass变量和Title变量与Age之间的关系更为显著,与前面箱线图预期一致。


之后我们利用回归出来的方程预测年龄的缺省值,具体如下:


4.3

>>处理Fare和Embarked缺失值 <<<

登船地点变量(Embarked)存在2个缺失值,票价(Fare)存在着1个缺省值。登船地点对票价来说是重要的,因为不同的登船地点表示的路程不同。



没有家人陪同而出来旅行的两个女性(Fsize =1),彼此之间肯定是朋友,她们是结伴出行的,因为他们的船票号码都相同,为113572(没有其他人的船票号码和她们一样)。


我们尝试找出登船地点信息与票价信息都存在的乘客的信息后,对它们按照登船地点与船舱等级分组,算出每组中人均票价的中位数。



因为这两个平均票价都是40,所以她们可能在Cherbourgh登船的,因此我们补全票价数据。


同理,我们运用同样的方法预测Mr Story的票价。



由于Mr.Story是阶级三且在S港登船,我们预测Mr Story的票价为7.8。


尽管现在票价这个变量已经没有空缺值了,但我们留意到有17个人的票价为0,且这些人都不是儿童。虽然我们觉得信息可能正确的(可能有些人的船票是靠赢来的呢?),但我们认为这些票价会扰乱算法。比如,在一等船舱,有些乘客的票价也为0。避免这些问题,我们用每个人的等级所对应票价的中位数去代替那些为0的票价值。


处理数据后,fare的数据如下:

4.4

>>处理Cabin缺失值 <<<

Cabin变量的值的第一个字母代表的是甲板的层级,甲板A-E是顶级的,往往是第一阶层的人住在里面。


用甲板U来代替Cabin的缺失值,并且只保留Cabin变量的第一个字母。


各阶层各舱位的乘客存活情况直方图如下:



可以看到,甲板A的存活率不高,甲板F和甲板E的存活率较高。


我们具体看下缺省值的数量:



可以看到Cabin的缺失值很多,尽管Cabin可以较好地预测乘客的存活与否,但是我们没有一个合适的方法进行筛选,考虑之下,我们在后续还是选择放弃这个变量。

4.5

>>寻找一起旅行的团体 <<<

逻辑上来讲,如果是以团体出行的,出事时一起生存的概率会提高(可能是更好的对灾难反应)。我们希望能够找到在泰坦尼克号上一起旅行的团体,这些团体可能包括直系家庭(如父母、孩子),也可能包括旁系家庭(如表、堂),也有可能包括一起订票的朋友,在本部分中我们将尝试区分出这些团体。

4.5.1

>> 家庭规模:兄弟姐妹、配偶、父母和孩子 <<

为了能够建立每个人在船上的家庭规模,我们将个体在船上的父母/孩子数量(Parch)和兄弟姐妹/配偶(SibSp)相加起来,当然,再加上自己。


从下面的图中可以很明显的看到,单独旅行的人有更大的可能遇险。此外,我们可以看到,家庭成员在2-4个人之间的有更大的可能性生存下来。然而,5及5个人以上的大家庭生存的几率明显降低。



现在我们可以按照家庭规模将数据分为3组——包括单独(solo),小规模家庭(small family)和大规模家庭(large family),但是在这之前,我们想先检验下数据中家庭规模是否与其他变量(如Surname)存在矛盾。

4.5.2

>> 检验家庭规模是否存在矛盾 <<

为了检验家庭规模数据的不一致性,我们建立一个变量(FsizeName),这个变量连接Surname和Fsize,之后,我们对不一致的数据进行定位,分别处理。



数据中显示,有93个样本数据的“NumObs”和“Fsize”不一致,即同家庭规模同姓氏的人数与同一个家庭的人数不相等。通过网络搜索我们发现,泰坦尼克号上确实有大约1300名乘客(其余的为船员),所以我们的数据集中应该没有缺失的乘客。

4.5.3

>> 尝试纠正退票带来的影响 <<

对于家庭规模中存在的矛盾,一个合理的解释是,部分乘客订票后又将票取消(这种情况下,SibSp和Parch不会实时更新)。我们以“Davies”为例,从表格中我们可以看到,这里应该有2个Davies家庭(Fsize=3,NumObs=5)。在我们上一步的检查过程中,由于Surname一致,这两个家庭的姓氏被加总了,导致了不一致。



票号为A/4的三位“Davies”应该是完整的一个家庭。因此错误应该出现在编号【550】和【1222】两位乘客上。通过SibSp和Parch的数据可以推测,No.550和No.1222是母子。一种可能是,No.1222号乘客原来打算携带2位孩子登船,但最终只带了一位。



严格意义上来说,数据集中肯定还有类似这样的错误没有被修正,但是考虑到最终可能对模型结果影响很小,也考虑到可行性,我们决定暂时忽略这类错误,寻找并修正其他错误。

4.5.4

>> 家庭规模:叔叔阿姨、表兄弟姐妹等 <<

在这些数据里面,其实有一些隐藏的家庭关系比退票情况更为有趣。例如, Hockings和Richards这两个姓氏很可能是相关的。我们将这两个姓氏的异常值输出。



从表格上来看,我们可以猜测,438号乘客带了2个孩子(408和832),一位母亲(775),一个弟弟(530)和一个妹妹(944),对于438号乘客来说,这些都是直系亲属。但是,对于其他人来说,这些可能是间接相关的。比如408和832两个孩子,对于他们来说,只会计算SibSp为1和Parch为1,不会将530和944这类间接相关的亲属计算进去。这样导致了Fsize将会虚高,这些大规模的家庭实际上可以细分成更小的群组。438这位乘客作为母亲更可能跟530和832两位孩子在一起,而她的弟弟(530)和妹妹(944)更可能与她的母亲(775)待在一起。

 

为了处理这种情况,将大的家庭规模分解成更小的家庭,我们需要先将归属于女方(maiden name)的家庭找出来



如图我们可以看到,以女方为线索,一共有7个大规模家庭被找出,这些家庭成员没有一致的Fsize, 这意味着他们存在着间接的亲属关系(如祖父母等)。同理,我们将未处理的男方的大规模家庭寻找出来。



我们以Mr Julius Vander Planke(1037)为例子,他与他的妻子(19)和2个兄弟姐妹(39和334)一起旅行。而他的妻子和他的兄弟姐妹实际上是间接相关的。



经过上面的分析,我们可以看到一共有9个家庭(涉及37个乘客)包含间接家庭成员。我们希望能够给这些家庭一样的Fsize(这将给每个在这样的家庭里面的成员拥有一致的生存机会)。为了降低家庭规模,我们将各个姓氏家庭的不同Fsize进行平均。



这确实是我们想要的效果,我们想要赋予这些属于同个家庭的人一个一致的Fsize(给予这些成员共同的生存机会),但并不想用最大Fsize去替代,因为比起直系家庭,这些大规模家庭在灾难发生时,不太可能一直呆在一起。

4.5.5

>> 寻找更多的二级家庭 <<

我们在考虑是否忽略了某些二级家庭,我们对数据进行再次的浏览,发现有些具有相同Surname的人的票号(Ticket)往往具有一致性。


这些人没有兄弟姐妹、配偶、父母或者孩子在船上,他们之间票号的关联更可能意味着他们是表兄弟姐妹或者叔伯关系。在本项目中,我们并不是想将所有的人的家庭关系都找出来,而是想知道灾难发生时这些人是否有可能待在一起。一个合理的假设是,一般来说直系家庭(比如父母和孩子)经常会待在一起,而叔伯/堂表兄弟姐妹更可能相互照顾。我们在数据集中,寻找家庭规模(Fsize)只有1个人,但是Surname有重复且Ticket只差两位尾数的乘客,一共有56个人。下表我们只展示前12个人。


4.5.6

>> 一起旅行的朋友 <<

除了我们上面所提及的家庭群组之外,朋友之间也有可能一起旅行。以Ticket号为1601的乘客为例:

上述这几个乘客,年龄基本相仿,所预定的票号也是一致的,我们有理由相信这是一个团队来出游(或许是旅行团呢)。因此,我们将拥有一样Ticket号码的人进行统计,并且建立Tsize变量。


与家庭规模非常类似,从下面的柱状图可以看到,2-4人的小规模团体往往有更高的几率生存下来。



经过上述的分组后,家庭规模和朋友(用Ticket分组)规模可能有一部分重叠,我们将Fsize和Tsize结合起来,利用这些数据创建一个分类变量。


由于1个人和2个人旅行生存机会显然不同,我们将其分为两个组(solo和group),3个人和4个人似乎有最好的生存机会(group),5个及5个人以上显然有更加糟糕的生存机会。


4.6

>>根据票号(Ticket)分组 <<<

票号可以检查是否有集体出游的人存活下来,考虑到,处在同个位置的组有人存活下来的话,组内其他人存活的概率更大。我们由此建立AnySurvivors变量。

4.7

>>考虑儿童对模型的影响 <<<

从之前绘制的年龄与存活的密度图看到,大概在14.5岁以下的儿童比其他年龄段的人存活率高。但是年龄在14.5岁以下的儿童大部分来自第三阶层,并且绝大多数没有存活下来,因此我们认为第三阶层是一个噪音,需要考虑从模型中去除。



同时考虑到将第三阶层儿童分离出来这种分类是否合理,所以我们也生成一个新的变量:是否儿童-IsChild。

Part 5 建立模型

随机森林模型拟合度较高,且过度拟合问题不严重,首先我们选择了随机森林模型来进行分析。


首先我们利用原始变量作出第一步模型预测,基于前文的分析,我们选取了5个变量来进行随机森林模拟(分别是Pclass,Sex,Age,Cabin,Embarked)。


#情况一:'Pclass', 'Sex', 'Age', 'Cabin', 'Embarked'



该随机模型用了891个样本。5个自变量,要预测的变量的结果是0或1。Accuracy的值最大时,模型最合适。所以,我们选择了mtry = 2,此时对应的Accuracy是0.804。


初步预测的准确率似乎已经较高,我们将基于前文对各变量的分析,进一步调整模型变量以期继续调整模型预测准确度。即使前面我们分析了那么多变量,为了避免产生拟合过度的问题,我们模型预测时,变量个数均不超过5个。我们依次考虑了是否加入港口(Embarked)、是否是一二层级小孩(IsChildP12)、是否是小孩(IsChild)变量。具体结果分析见附录一。最终当我们加入AnySurvivors变量时,我们发现选择5个变量(PclassSex,GroupSize,FarePP,AnySurvivors,IsChildP12)预测时,此时准确率显著提高。


#情况二:'PclassSex', 'GroupSize', 'FarePP', 'AnySurvivors', 'IsChildP12'



Accuracy的值最大时, mtry = 3,此时对应的Accuracy是0.857。


MeanDecreaseGini通过基尼(Gini)指数计算每个变量对分类树每个节点上观测值的异质性的影响,从而比较变量的重要性。该值越大表示该变量的重要性越大。所以,我们用MeanDecreaseGini来对5个变量的重要性进行评分:



考虑到IschildP12变量重要性最低,我们进一步考虑采用Ischild来代替IschildP12。


#情况三:'PclassSex', 'GroupSize', 'FarePP', 'AnySurvivors', 'IsChild'


#显示预测质量



最后,我们可以用训练出来的模型去预测测试集里的存活变量(Survived):


solution_rf


##随机森林模型的Accuracy是0.868。


-- the end --


后台回复【泰坦尼克号】,即可下载本文代码和数据


精彩文章推荐

数模竞赛|数学建模比赛该如何准备?

你永远都不知道男生有多想和18岁女孩子谈恋爱!

"最萌身高差"究竟有多萌?

年薪百万的王宝强和月入三千的吴彦祖,你更愿意pick谁?


扫一扫,获取数据和模型

还有更多算法学习课件分享哟



文案、代码、审核 / 张元新、郑少淳、李大伟、郭丽丽、朱小青(皆为研二)

排版 / 陈志(大四)

指导老师 / 朱文斌教授


如对文中内容有疑问,欢迎交流。PS:部分资料来自网络。

朱文斌(华南理工大学工商管理学院教授、i@zhuwb.com)

张元新(华南理工大学工商管理学院研究生二年级、jerry.yx@foxmail.com)

郑少淳(华南理工大学工商管理学院研究生二年级、sczheng_zoe@163.com)

李大伟(华南理工大学工商管理学院研究生二年级、397406076@qq.com)

郭丽丽(华南理工大学工商管理学院研究生二年级、201720130156@mail.scut.edu.cn)

朱小青(华南理工大学工商管理学院研究生二年级、1740384223@qq.con)





今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/JjXqgIE1Ns
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/23871
 
1314 次点击  
文章 [ 1 ]  |  最新文章 6 年前
因为粥凉了
Reply   •   1 楼
因为粥凉了    6 年前

泰坦尼克号