精华内容
下载资源
问答
  • 背景: 泰坦尼克号(RMS Titanic)作为英国白星航运公司下的一艘奥林匹克级邮轮,是20世纪最著名的邮轮之一,这不仅因为其在建成后是当时世界上最大的豪华客运轮船,还因为这艘被誉为‘永不沉没’的轮船竟然在其处女航...

    d49f7e7c42c4a7a24c03b55998285b08.png

    背景: 泰坦尼克号(RMS Titanic)作为英国白星航运公司下的一艘奥林匹克级邮轮,是20世纪最著名的邮轮之一,这不仅因为其在建成后是当时世界上最大的豪华客运轮船,还因为这艘被誉为‘永不沉没’的轮船竟然在其处女航中就遭遇了厄运。在1912年4月15号,载有2224人的泰坦尼克号因与冰山相撞而沉没,这次事故造成了1502人死亡,同时也震惊了世界。在这次事故中,造成如此多的伤亡主要原因之一是由于船上没有配备足够的救生船,但是对于幸存者而言还有一些其他的因素导致了他们更有可能比别人活下来。那么,哪些因素会使得存活率较高?好,下面就开始运用R软件进行数据分析和预测。

    目的:预测泰坦尼克号中存活率与哪些因素有关?

    数据来源:Kaggle上的一篇名为“Titanic: Machine Learning from Disaster”的Competitions:Titanic: Machine Learning from Disaster

    何为kaggle,如何入手?Kaggle竞赛入门教程之Kaggle简介(新手向) - CSDN博客;在注册kaggle时,总是无法验证?可查考:解决kaggle邮箱验证不能confirm的问题 - CSDN博客。如果不想注册kaggle,可以直接从中获取数据练习:链接: https://pan.baidu.com/s/1RKMKyQ4R1RSCYI0FWQVAFQ 密码: tgjp

    目录:

    一、数据的导入和整理

    二、数据分析(哪个变量对存活率影响更重要?)

    三、建模(logistics regression、randomForest、SVM)

    四、预测(predict)

    五、上传kaggle


    一、数据的导入和整理

    (一)变量解释:

    ed65c1899268272d2f8ac57b0379f3e9.png

    (二)先载入需要的安装包

    tidyverse包的介绍:为“Tidyverse”疯狂打call!

    #tidyverse是万能包,里面包含很多包,所以只要加载这个包,可以省去很多包的加载
    library("tidyverse")  #ggplot2/dplyr/stringrb等万能包
    library("randomForest")
    library("mice")
    (.packages())  #查看已安装的包

    (三)数据获取

    具体的获取内容,上面已讲述,直接将数据载入R中即可。

    数据集总共有三个,一个训练集(train)+一个测试集(test),还有一个是提交预测结果到kaggle的格式要求。现在将这两个数据集合并才一起进行数据预处理,保证数据集格式的一致性。

    #数据导入
    train<-read.csv("C:Program FilesRstudioTitanictrain.csv",header = TRUE,sep=",")
    test<-read.csv("C:Program FilesRstudioTitanictest.csv",header = TRUE,sep=",")

    dim()查看数据集有几行和多少变量,colnames()是参看数据集变量都有哪些,通过下面,可以发现train与test两个数据集,相差一个变量Survived。

    8076ad0c41710208cb96f9c3ddbb294d.png

    运用bind_rows()函数合并train与test数据集,可以发现合并后test中少的Survived变量,系统默认用NA填充。head()指查看数据集full前六行,tail()指查看数据集后六行。

    full<-bind_rows(train,test)

    1b3a9cb16cd87128fb0d57d82a9c29be.png

    (四)数据预处理

    1、转换数据类型

    参看数据集中的变量都是哪些数据类型?运用str()函数可以参看变量的属性

    b6a3e0a5a050b0182d6a202dcdd264a5.png

    通过上述,可以看出数据集full有1309个观测值12个变量,survived,pclass.变量为int,需要转为factor类型,因为这些是分类变量,0,1不是实际的数值,如:survived中的0指死亡,1指存活,所以要将整型变量转为因子类型。运用as.factor();

    sibsp,parch默认为int类型,要转换为数值类型:as.numeric()

    full$Survived<-as.factor(full$Survived)
    full$Pclass<-as.factor(full$Pclass)
    full$SibSp<-as.numeric(full$SibSp)
    full$Parch<-as.numeric(full$Parch)

    2、处理缺失值

    在运用随机森林建模时,数据集是不能存在缺失值的,所以,下面开始进行处理缺失值

    (1)查看哪些变量存在缺失值或空值?

    3248f53e37cf739566ad0adfc71f1861.png

    从图中,可以看出survived变量有418个缺失值,个数正好为test数据集的个数,这个缺失值为正常现象,是因为train与test合并所导致的。

    Age变量有263个缺失值;Fare变量有1个缺失值;Cabin有1014个空值,Embarked有两个空值。这四个变量都是要处理的变量,我们先从较少的缺失值开始。

    (2)处理缺失值或空值

    • Fare缺失值的处理(缺失值1个)
    >which(is.na(full$Fare))  #由于只有1个缺失值,可以有which()参看哪行为缺失值?
    [1] 1044
    #目前知道fare变量中,第1044行存在缺失值,费用在本例中与购买船舱等级与登船港口有关。
    > full[which(is.na(full$Fare)),c("Pclass","Embarked")]  #可以发现1044行的乘客够买的是三等舱,从S港口进舱的。
         Pclass Embarked
    1044      3        S
    #筛选出购买三等舱以及S港口进港乘客的乘船费用;对该费用求平均,即为1044乘客的乘船费用
    >fare_3s<-full[which(full$Pclass=="3"&full$Embarked=="S"),"Fare"]
    #由于求平均数有两个函数,具体哪个函数会比较好呢?
    > median(fare_3s,na.rm=TRUE)
    [1] 8.05
    > mean(fare_3s,na.rm = TRUE)
    [1] 14.43542
    #通过绘图,可以发现直方图的众数是在5-10之间的,发现median()更符合实际要求,所以将8.05赋值给1044行的费用(Fare)
    > hist(fare_3s)
    

    d4daca6e47e10eac48c25fc4bdec9a9e.png
    > full$Fare[1044]<-8.05
    #赋值完后,查看fare变量已经没有缺失值
    > sapply(full,function(x) sum(is.na(x)))
    PassengerId    Survived      Pclass        Name         Sex         Age 
              0         418           0           0           0         263 
          SibSp       Parch      Ticket        Fare       Cabin    Embarked 
              0           0           0           0           0           0 
    • Embarked空值处理(空值2个)

    思路:先用which()查看哪两行的Embarked为空值;确定行数后,把对应行数的变量Pclass,Fare确定;最后根据客舱等级与费用推测两个乘客的进港口

    > which(full$Embarked=="")  #确定空值的行数为多少?
    [1]  62 830
    > full[which(full$Embarked==""),c("Pclass","Fare")]
        Pclass Fare
    62       1   80
    830      1   80

    通过上面可以发现,Embarked为空值第62、830行的乘客,都是乘坐一等舱,费用为80美元。接下来,将一等舱乘客的 Fare、Pclass 、Embarked筛选出来。再根据乘坐一等舱从不同的进港口的费用平均为多少?若是80元,即可以推测出两个空值的对应进港口。那么,具体都有哪些进港口?利用unique()可以快速查询。

    > unique(full$Embarked)  #发现实际只有三个进港口
    [1] "S" "C" "Q" "" 
    > filter1<-full[which(full$Pclass=="1"),c("Fare","Pclass","Embarked")]
    > head(filter1)
           Fare Pclass Embarked
    2   71.2833      1        C
    4   53.1000      1        S
    7   51.8625      1        S
    12  26.5500      1        S
    24  35.5000      1        S
    28 263.0000      1        S
    > S_fare<-median(filter1$Fare[which(filter1$Embarked=="S")])
    > S_fare
    [1] 52
    > C_fare<-median(filter1$Fare[which(filter1$Embarked=="C")])
    > C_fare
    [1] 76.7292
    > Q_fare<-median(filter1$Fare[which(filter1$Embarked=="Q")])
    > Q_fare
    [1] 90
    #可以发现,从C进港口的费用与80接近,所以,将两个Embarked缺失值赋值为C
    > full$Embarked[c(62,830)]<-"C"
    > sapply(full,function(x) sum(x==""))
    PassengerId    Survived      Pclass        Name         Sex         Age 
              0          NA           0           0           0          NA 
          SibSp       Parch      Ticket        Fare       Cabin    Embarked 
              0           0           0           0        1014           0 
    

    通过上面处理,发现Embarked变量不存在空值.

    • Cabin缺失值的处理(有1014个空值)

    full数据集的观测个数1309,空值就占了1014(1014/1309=77.46%),由于该变量的信息过少,所以可以直接把该变量剔除。

    > colnames(full) #查看full的变量有哪些,目前有12个变量
     [1] "PassengerId" "Survived"    "Pclass"      "Name"        "Sex"        
     [6] "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"       
    [11] "Cabin"       "Embarked"   
    > full$Cabin<-NULL  #将Cabin变量删除,只要赋值FULL即可
    > colnames(full)  #再查看full的变量,发现变量只有11个
     [1] "PassengerId" "Survived"    "Pclass"      "Name"        "Sex"        
     [6] "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"       
    [11] "Embarked"   

    029cd3bc815d90e4984dedab28be236c.png
    • Age缺失值的处理(263个缺失值)

    思路:由于缺失值个数较多,运用mice包,进行系统自动根据数据特征自动填补缺失值。先利用mice()函数建模,再利用complete()函数生成完整的数据。

    > library("mice") #加载安装包
    > md.pattern(full)  查看缺失数据特征
    > tempfull<-mice(full[,!names(full)%in%c('PassengerId','Ticket','Survived','Name')],method ="pmm")  #插补缺失值
    > summary(tempfull)  #输出tempfull的属性,此时的tempfull是列表形式存在
    > tempfull$imp$Age
    > completefull<-complete(tempfull)
    > head(completefull)
      Pclass    Sex Age SibSp Parch    Fare Embarked
    1      3   male  22     1     0  7.2500        S
    2      1 female  38     1     0 71.2833        C
    3      3 female  26     0     0  7.9250        S
    4      1 female  35     1     0 53.1000        S
    5      3   male  35     0     0  8.0500        S
    6      3   male  20     0     0  8.4583        Q
    > sapply(completefull,function(x) sum(is.na(x)))
      Pclass      Sex      Age    SibSp    Parch     Fare Embarked 
           0        0        0        0        0        0        0 
    > sapply(completefull,function(x) sum(x==""))
      Pclass      Sex      Age    SibSp    Parch     Fare Embarked 
           0        0        0        0        0        0        0 

    通过上述可以发现,Age变量不存在缺失值了。那系统自动根据变量特征对应填补的缺失值,会不会改变原先变量的数据特征?下面可以通过作图比较下:

    > par(mfrow=c(1,2))  #设置图形的放置(1行有2个图形)
    > hist(full$Age,freq = F,main='Age: Original data',col="darkgreen",ylim=c(0,0.04))
    > hist(completedfull$Age,freq =F,main='Age: Mice output ',col='lightgreen',ylim=c(0,0.04) ) #通过图形可发现前后两个图形分布,大致没有什么变化,说明我们插补缺失值比较好,没有影响到总体
    > par(mfrow=c(1,1)) #恢复一行一个图形的设置

    55f4cd4bd481669dc179663f7847f4a3.png

    通过图形可以发现,原先的full中Age的密度分布图和填补过后的completefull中Age的密度分布图没有多大差异,所以该填补缺失值是成功的。现在就将completefull中Age的值赋值给full中Age。

    > full$Age<-completefull$Age

    到这里,数据预处理就完成了~下面开始进行分析,哪些变量对存活率有更大的影响?敬请期待~~~


    二、数据分析

    1、Pclass对生存率的影响

    ggplot(full[1:nrow(train),],mapping = aes(x=Pclass,y=..count..,fill=Survived))+ #添加画图面板
    geom_bar(stat="count",position = "dodge")+  #绘制柱状图
    labs(title="Different Pclass impact Survived",x="Pclass",y="count")+  #添加标签(标题,横纵坐标)
    theme(plot.title = element_text(hjust=0.5))+ #设置标题位置
    scale_fill_manual(values = c("blue","green"))+ #修改填充柱状图颜色
    geom_text(stat="count",aes(label=..count..),position =position_dodge(0.9),vjust=0)  #添加文本(添加柱状图上面的数字)

    8f1790285146c26424712d19ac609a65.png

    结论:通过图片可以发现,一等舱的乘客一大半都存活了,二等舱的乘客接近一半存活,而三等舱只有31.99%的存活率。所以,可以发现舱位等级越高,存活率越高。

    2、头衔Title对存活率的影响

    姓名中的头衔,会不会跟幸存率有关呢?在国外,一般会用Mr、Miss、Mrs等,现在开始探个究竟~

    #从姓名中得到头衔数据,运用正则表达式
    full$Title<-gsub("(.*,)|(..*)","",full$Name) #把姓名中的头衔分列出来
    table(full$Title) #统计各个头衔的个数
    which(table(full$Title)<20) #由于较少的头衔不具有代表性,所以将头衔个数小于20的筛选出来
    rare<-names(which(table(full$Title)<20))
    rare
    full$Title[full$Title %in% rare]<-"rare_title" #同一头衔个数小于20的,全部改为rare_title
    full$Title<-as.factor(full$Title) 
    summary(full$Title)

    绘图:

    ggplot(full[1:nrow(train),],mapping = aes(x=Title,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      labs(title="Different Title impact Survivor" ,x="Title",y="count")+
      theme(plot.title =element_text(hjust=0.5))+
      geom_text(stat="count",aes(label=..count..),position = position_dodge(0.9),vjust=0)

    9a2708a6d122d37a445c1303d5250bd3.png

    通过画图,可以发现头衔Miss/Mrs幸存率更高些,而Mr头衔的存活率只有16%(81/517)

    3.Sex对存活率的影响

    在沉船时,按照“妇女与小孩先走”的规则,这一原则会不会使得女性比男性存率更高些呢?下面用数据(绘图)说话:

    full$Sex<-as.factor(full$Sex)
    ggplot(full[1:nrow(train),],mapping = aes(x=Sex,y=..count..,fill=Survived))+
      geom_bar(stat="count",position = "dodge")+
      labs(title="How Sex impact survivor",x="Sex",y="count")+
      theme(plot.title = element_text(hjust = 0.5),legend.position = "bottom")+
      geom_text(stat="count",aes(label=..count..),position =position_dodge(width = 1),vjust=-0.5)

    6f28c4c379392ae1b43a97cda183d8ec.png

    通过图形,可以发现女性的存活率到达74.2%(233/(81+233)*100%),而男性的存活率只有18.89%.说明我们前面的假设是正确的,女性的存活率比男性高。

    4、Age对存活率的影响

    • 分析age与存活率的关系:
    ggplot(full[!is.na(full$Survived),],aes(Age,color=Survived))+
        geom_line(aes(label=..count..), stat = 'bin', binwidth=5)  + 
        labs(title = "Different Age impact survivor", x = "Age", y = "Count", fill = "Survived")+
        theme(plot.title = element_text(hjust = 0.5), legend.position="bottom")

    2f6286250d354f0f6e7807b11dd1d730.png

    通过图形可知,未成年的幸存率高于成年人,同时,青壮年遇难率较高。沉船时,按照“妇女与小孩先走”的规则,可以设想未成年是否幸存率更高?新增一列变量,将年龄分为两个部分(age小于18和age小于或等于18)。

    • 新增一列变量New_age,将age进行划分为未成年人和成年人
    >full$New_age[full$Age<18]<-"Child"
    >full$New_age[full$Age>=18]<-"Adult"
    >table(full$New_age,full$Survived)

    绘图:

    ggplot(full[1:nrow(train),],aes(x=New_age,y=..count..,fill=Survived))+
      geom_bar(stat="count",position="dodge")+
      ggtitle("Child and Adult impact Survivor")+
      geom_text(stat="count",aes(label=..count..),position = position_dodge(width=1),vjust=-.05)+
      theme(plot.title = element_text(hjust = 0.5))

    60e4f46d05c76ef23ff4fe2d447ca879.png

    结论:通过图形可以看出,未成年幸存率的确高于成年人。

    5、家庭人数对存活率的影响

    • 分别绘图Sibsp、Parch对生存率的影响
    #绘图Sibsp对存活率的影响:
    ggplot(full[1:nrow(train),],aes(x=SibSp,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      ggtitle("How sibsp impact Survivor")+
      theme(plot.title = element_text(hjust=0.5))+
      geom_text(stat="count",aes(label=..count..),position = position_dodge(width = 1),vjust=-0.5)
    #绘图Parch对存活率的影响:
    ggplot(full[1:nrow(train),],aes(x=Parch,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      ggtitle("How Parch impact Survivor")+
      geom_text(stat="count",aes(label=..count..),position=position_dodge(width = 1),vjust=-0.5)+
      theme(plot.title = element_text(hjust = 0.5))

    dd5b5789dd672a168d3a071774e24f6e.png

    610db133a12282e28928a4a64ee28af5.png

    结论:通过两次绘图,发现两幅图有同样特点1-3个家属的存活率较高,没有家属或者家属超过3个以上的存活率比较低。那么,是否可以把这两个这两个变量合成一个变量呢?下面来试试~

    • 新增变量(将Sibsp与Pach变量相加变成一个变量)
    #合并变量
    full$Familysize<-full$SibSp+full$Parch
    #绘图
    ggplot(full[1:nrow(train),],aes(x=Familysize,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      ggtitle("How Familysize impact Survivor")+
      geom_text(stat="count",aes(label=..count..),position=position_dodge(width = 1),vjust=-0.5)+
      theme(plot.title = element_text(hjust = 0.5))

    a6adb9d2cd1d5612ba8009e4c78a915f.png

    结论:合并后,证实了我们之前的假设:家属个数有1-3个幸存率高些,家属个数为零或者大于3个的幸存率较低。后期建模时,用这个派生变量Familysize代替Sibsp+Parch即可。

    6、Ticket船票号对生存率的影响

    船票号重复率比较低,不能直接运算,计算每张船票号的出现次数。现将所有乘客按照Ticket分为两组,一组是使用单独票号,另一组是与他人共享票号,并统计出各组的幸存与遇难人数。

    #求每张船票号总共出现几次?
    >ticket.count<-aggregate(full$Ticket,by=list(full$Ticket),function(x) sum(!is.na(x)))
    > head(Ticket.count)
      Group.1 x
    1  110152 3
    2  110413 3
    3  110465 2
    4  110469 1
    5  110489 1
    6  110564 1
    >full$TicketCount <- apply(full, 1, function(x) ticket.count[which(ticket.count[, 1] == x['Ticket']), 2])
    >full$TicketCount<-factor(sapply(full$TicketCount,function(x) ifelse(x>1,"share","unique")))

    80864c9a533d3b83dc23b0ffb8333a3f.png
    代码结果

    绘图:

    ggplot(full[1:nrow(train),],aes(x=TicketCount,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      ggtitle("How TicketCount impact Survivor")+
      geom_text(stat="count",aes(label=..count..),position=position_dodge(width = 1),vjust=-0.5)+
      theme(plot.title = element_text(hjust = 0.5))

    43146002437f5ab92120abf8460a24b0.png

    结论:通过图形可以发现,共享票号的存活率已达一半212/(198+212)=51.7%;而单独票号的幸存率比较低130/(351+130)=27%.

    7、Fare船票费用高低对存活率的影响

    ggplot(full[1:nrow(train),],aes(x=Fare,y=..count..,color=Survived))+
      geom_line(aes(label=..count..),stat = "bin",binwidth=5)+
      ggtitle("Different Fare impact Survivor")+
      theme(plot.title = element_text(hjust=0.5))

    4a7136ed68477dfe60a5c6c4cceae95e.png

    结论:通过图形可以发现,购买船票的价格越高,幸存率越高。

    8.Embarked不同进舱口与存活率的关系:

    ggplot(full[1:nrow(train),],aes(x=Embarked,y=..count..,fill=Survived))+
      geom_bar(stat = "count",position = "dodge")+
      ggtitle("How Embarked impact Survivor")+
      geom_text(stat="count",aes(label=..count..),position=position_dodge(width = 1),vjust=-0.5)+
      theme(plot.title = element_text(hjust = 0.5))

    cd4ab863f8425c204a5ae6e0d62fe444.png

    结论:通过图形可以发现,在S舱口上船的人,幸存率很低。


    到这里,数据预处理完大功告成~说明我距离成功仅剩30%的距离。因为在处理一个项目时,70%的时间都是在搜索数据和数据的清理。

    建模和预测留到下篇文章,未完待续~~~敬请期待!


    参考资料

    【讲座】数问自习室第一期 Kaggle Titanic_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

    使用R语言预测泰坦尼克号乘客生存率_黎明前的黑暗_新浪博客、

    机器学习(二) 如何做到Kaggle排名前2%

    First try | Kaggle

    泰坦尼克号生存预测(kaggle排名129前2%)

    展开全文
  • # 票号和船舱是无关的特征,将它们去除掉 # axis的0轴匹配的是index, 涉及上下运算;1轴匹配的是columns, 涉及左右运算 train . drop ( [ 'Ticket' , 'Cabin' ] , axis = 1 , inplace = True ) 12. ...

    1. 通过热力图的方式来查看缺失的数据

    sns.heatmap(train.isnull(), yticklabels=False, cbar=False, cmap='viridis')
    

    tip:对于有些数据集中可能不是显式的存在缺失值,而是把缺失值替换成了特殊的字符,这种情况的话可以先将特殊字符替换为np.nan,再用isnull()函数。

    2. 查看离散变量和连续变量的属性

    # 统计离散变量的属性:离散变量为字符串,属性为'object'
    train.describe(include=['O'])
    # 统计连续变量的属性
    train.describe()
    

    3. countplot查看存活的人与未存活人的比例

    # 设置白色网格为主题
    # 使用countplot 对'存活'的一个标签进行计数绘图,使用x表示横轴上的图,y表示纵轴 上的图
    sns.set_style('whitegrid')
    sns.countplot(x='Survived',data=train)
    

    4. countplot和group查看存活的人与性别的关系

    # 设置白色网格为主题
    # 使用countplot 对'存活'和'性别'两个标签进行计数绘图
    sns.set_style('whitegrid')
    sns.countplot(x='Survived',hue='Sex',data=train)
    
    train[['Sex', 'Survived']].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
    
    

    5. countplot和group查看存活的人与船舱级别的关系

    sns.set_style('whitegrid')
    sns.countplot(x='Survived', hue='Pclass', data=train)
    
    train[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
    

    6. distplot查看年龄的分布

    # 根据开始的空值判断中,可以得出age中有空值,所以需要进行drop
    
    # 通过displot绘制直方图的观测值的单变量分布:纵坐标表示的是比率
    # kde为高斯核函数,bins为直方图的宽
    sns.distplot(train['Age'].dropna(), kde=False, bins=30)
    

    7. countplot和group查看乘船人的家族关系以及和存活之间的关系

    sns.countplot(x='SibSp', data=train)
    
    train[['SibSp', 'Survived']].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)
    

    8. hist查看乘客的票价分布

    # 当然这里也可以用seaborn的displot进行绘制,但是displot的纵坐标是比率,hist的纵坐标是实际个数count;
    # figsize调整画布大小
    train['Fare'].hist(color='green', bins=30, figsize=(8,4))
    

    对比,hist和distplot直方图分布的区别
    使用hist的直方图分布,纵坐标是count值;
    使用displot的直方图分布,纵坐标是比率radio;

    9. 箱型图查看年龄和船舱等级的分布

    箱型图不仅可以来找出异常值,也可以用来说明样本分布的情况:

    1. 如果箱子比较扁, ,说明分布比较靠拢;
      如果箱子比较长,说明分布比较离散;
    2. 就是判断出箱子图中所处的范围在哪块;
    plt.figure(figsize=(12,7))
    sns.boxplot(x='Pclass', y='Age', data=train)
    

    在这里插入图片描述
    通过箱型图大致可以判断出:三等舱的乘客年龄分布都比较小,一等舱的乘客年龄分布都比较大。

    10. 填补缺失值

    填补缺失值有很多种方法,这里是根据之前的箱型图:三等舱的乘客年龄分布比较小,一等舱的乘客年龄分布比较大。于是来根据船舱的类别填入该类别年龄的平均值。

    # 首先得出各个船舱年龄的平均值
    [train[train['Pclass'] == i]['Age'].mean() for i in range(1,4)]
    
    def infer_age(cols):
        Age = cols[0]
        Pclass = cols[1]
        
        if pd.isnull(Age):
            if Pclass == 1:
                return 37
            elif Pclass == 2:
                return 29
            else:
                return 24
        else:
            return Age
     # 使用apply方法应用函数
     train['Age'] = train[['Age', 'Pclass']].apply(infer_age, axis=0)
    

    11.去除无关的数据列

    # 票号和船舱号是无关的特征,将它们去除掉
    # axis的0轴匹配的是index, 涉及上下运算;1轴匹配的是columns, 涉及左右运算
    train.drop(['Ticket', 'Cabin'], axis=1, inplace=True)
    

    12. 考虑人名的特征,只保留前面的姓氏

    # 通过正则表达式留下.之前的形式
    train['Title'] = train.Name.str.extract('([A-Za-z]+)\.', expand=False)
    

    在这里插入图片描述

    13. 检查下名称是否对应着性别

    pd.crosstab(train['Title'], train['Sex'])
    

    在这里插入图片描述

    14.将不同类的title,根据个数不同进行聚合

    for dataname in [train, test]:
        dataname['Title'] = dataname['Title'].replace(['Lady', 'Countess', 'Capt', 'Col', 'Don', 'Dr', 'Major', \
                                                'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
        dataname['Title'] = dataname['Title'].replace(['Mlle', 'Ms'], 'Miss')
        dataname['Title'] = dataname['Title'].replace('Mme', 'Mrs')
    
    train[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
    

    15. 通过map将名称的变量离散值连续化

    title_mapping = {'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Rare': 5}
    train['Title'] = train['Title'].map(title_mapping)
    

    16. 对缺失数据进行删除

    # inplace表示在原地操作,不返回对象
    train.dropna(inplace=True)
    

    17. 将性别和上船地点也转变为离散变量

    # drop_first = True的含义是使用k-1个哑变量来表示k个特征
    sex = pd.get_dummies(train['Sex'], drop_first=True)
    embark = pd.get_dummies(train['Embarked'], drop_first=True)
    # 删除原来的离散变量,并将新的哑变量的dataframe与原来的连接
    train.drop(['Sex','Embarked','Name', 'PassengerId'], axis=1, inplace=True)
    train = pd.concat([train, sex, embark], axis=1)
    

    18. 拆分数据集

    拆分数据集进行训练主要是为了防止过拟合的情况。

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(train.drop('Survived', axis=1), train['Survived'], test_size=0.2, random_state=2019)
    

    19. 模型训练

    展开全文
  • 下图引用于kaggle-泰坦尼克号存活率预测项目。 文章流程考虑到文章篇幅的原因,这里就不去预测哪些人更可能存活下来,将写另外一篇文章去做它。数据概览清洗数据2.1 数据预处理2.2 特征选择决...

    此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉。

    前言

    最近学习了 预测泰坦尼克号存活率,是一个烂大街的项目了,它是kaggle科学竞赛网站上一个入门的数据分析案例。

    下图引用于kaggle-泰坦尼克号存活率预测项目。

    文章流程

    考虑到文章篇幅的原因,这里就不去预测哪些人更可能存活下来,将写另外一篇文章去做它。

    数据概览

    清洗数据

    2.1 数据预处理

    2.2 特征选择

    决策树建模(至于什么是决策树,参考百度百科–决策树。)

    预测结果

    决策树可视化

    1. 数据概览

    数据从数据科学竞赛平台kaggle获取。kaggle-泰坦尼克号存活率预测项目。

    如下图所示,点击下载即可。

    下载的数据有gender_submission.csv和test.csv以及train.csv三个文件。

    train为训练集,是用来分析和构建机器学习模型,包含有存活情况信息;

    test为测试集,不提供存活信息,项目目的就是预测该文档中的乘客的存活率;

    gender_submission文档是没用的,可以忽略。

    两个文档的数据概览如下:

    可以看到数据整体上都一样,唯一不同的地方在于 train.csv多了Survived这一列(即存活)。

    那文档中各个字段代表的是什么意思呢?

    字段

    定义

    Key

    Passengerld

    乘客编号

    Survival

    存活与否

    0 = No, 1 = Yes

    Pclass

    船票级别

    class 1 = 1st, 2 = 2nd, 3 = 3rd

    Name

    乘客姓名

    Sex

    性别

    Age

    年龄

    Sibsp

    乘客兄妹 / 配偶

    Parch

    乘客父母 / 子女

    Ticket

    船票号码

    Fare

    船票价格

    Cabin

    船舱号

    Embarked

    登船港口

    C = Cherbourg, Q = Queenstown, S = Southampton

    2. 清洗数据

    2.1 数据预处理

    导入数据:

    import pandas as pd

    test_pd = pd.read_csv('test.csv')

    train_pd = pd.read_csv('train.csv')

    查看数据集基本信息:

    # 查看数据几行几列

    print('train数据集的行数和列数:',train_pd.shape)

    # 间隔

    print('- ' * 20)

    # 查看索引dtype和列dtype,非空值和内存使用情况

    print(train_pd.info())

    # 查看文档中各列的缺失值总数

    print('- ' * 20)

    print(train_pd.isnull().sum())

    result:

    可以看到train文档是(891行,12列)

    Age、Cabin、Embarked字段都存在空值,这个后面是需要填充的。

    train数据集的行数和列数: (891, 12)

    - - - - - - - - - - - - - - - - - - - -

    RangeIndex: 891 entries, 0 to 890

    Data columns (total 12 columns):

    # Column Non-Null Count Dtype

    --- ------ -------------- -----

    0 PassengerId 891 non-null int64

    1 Survived 891 non-null int64

    2 Pclass 891 non-null int64

    3 Name 891 non-null object

    4 Sex 891 non-null object

    5 Age 714 non-null float64

    6 SibSp 891 non-null int64

    7 Parch 891 non-null int64

    8 Ticket 891 non-null object

    9 Fare 891 non-null float64

    10 Cabin 204 non-null object

    11 Embarked 889 non-null object

    dtypes: float64(2), int64(5), object(5)

    memory usage: 83.7+ KB

    None

    - - - - - - - - - - - - - - - - - - - -

    PassengerId 0

    Survived 0

    Pclass 0

    Name 0

    Sex 0

    Age 177

    SibSp 0

    Parch 0

    Ticket 0

    Fare 0

    Cabin 687

    Embarked 2

    dtype: int64

    Age可以用平均值填充;

    # 使用平均年龄来填充年龄中的nan值

    train_pd['Age'].fillna(train_pd['Age'].mean(), inplace=True)

    Cabin缺失太多,不好补充,遂填充为unknown,意为未知的;

    # 填充缺失值为unknown

    train_pd['Cabin'].fillna('unknown', inplace=True)

    Embarked缺失2个,可选择删除对应行或者填充处出现次数最高的值。

    # 查看Embarked的值出现的次数

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

    result:

    S 646

    C 168

    Q 77

    Name: Embarked, dtype: int64

    # 填充缺失值为S

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

    填充缺失之后,可以看到已经没有空值了。

    2.2 特征选择

    该项目的主要目的是预测乘客存活率,所以这一步需要从数据集中选择特征,作为预测存活率的关键。

    除了画框的这一列(存活率),还有剩余11个特征。

    根据我不成熟的思考后判断得出:

    PassengerId为乘客编号,与存活率相关性不大,可去掉;

    Name为乘客姓名,对分类不起什么作用,可去掉;

    Ticket为船票号码,并且无命名规律,可去掉;

    Cabin为船舱号,缺失值太多,也去掉。

    最后剩下 Pclass、Sex、Age、SibSp、Parch 和 Fare,Embarked 7个特征,他们可能和乘客的存活率的分类有关,但具体是什么关系,这个交给机器学习去头疼吧!

    (1)将上面说的可去掉的特征删除:

    train_pd.drop(["PassengerId","Cabin","Name","Ticket"],inplace=True,axis=1)

    这时候的数据是这样的。

    特征值里有一些不是数值类型,为方便后续的运算这里需要将他转换为数值类型。

    Sex 字段,的男和女,用 0 或 1 来表示。

    Embarked 的 S、C、Q ,用数值 0、1和2 来表示。

    (2)将’Age’改成数值类型。

    train_pd['Sex'] = train_pd['Sex'].map({'male': 0, 'female': 1}).astype(int)

    (3)将’Embarked’改成数值类型。

    # 方法一

    train_pd['Embarked'] = train_pd['Embarked'].map( {'S': 0, 'C': 1,'Q':2},).astype(int)

    # 方法二

    #用unique将Embarked的唯一值转化为list, 然后用索引进行数字替换

    labels = train_pd["Embarked"].unique().tolist()

    train_pd["Embarked"] = train_pd["Embarked"].apply(lambda x: labels.index(x))

    处理后的数据如下:

    3. 决策树建模

    到这一步,只需要将特征矩阵和标签塞到决策树模型里面就完事了。

    特征矩阵是不包括存活率的,所以这里要删除Survived这一行。

    分类标识也就是Survived这一列。

    # 特征矩阵

    train_labels = train_pd["Survived"]

    # 分类标识

    train_pd = train_pd.drop(['Survived'], axis=1)

    导入决策树模块

    from sklearn.tree import DecisionTreeClassifier

    # 构建决策树

    clf = DecisionTreeClassifier(criterion="entropy")

    # 决策树训练

    clf.fit(train_pd, train_labels)

    百度百科–交叉验证

    简单来说,K折交叉验证可以提高决策树的准确度。

    cross_val_score 函数中的参数 cv 代表对原始数据划分成多少份,也就是K值,这里使用cv=10

    from sklearn.model_selection import cross_val_score

    print(cross_val_score(clf, train_pd, train_labels, cv=10).max())# 最大值

    print(cross_val_score(clf, train_pd, train_labels, cv=10).min())# 最小值

    print(cross_val_score(clf, train_pd, train_labels, cv=10).mean())# 平均值

    # 0.8539325842696629

    # 0.6853932584269663

    # 0.7744569288389513

    然后接下来还可以使用GridSearchCV 调参,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。感兴趣的可以从网上学习。

    因为这个不熟悉,不敢误人子弟。遂直接采用别人的答案!

    经GridSearchCV 调参后,得出决策树的 criterion=‘gini’,max_depth=9,min_samples_leaf=6 的时候,准确度最高。

    这里也可以明显看到,准确度是有所提高的。

    clf = DecisionTreeClassifier(criterion='gini', min_samples_leaf=5, max_depth=9)

    print(cross_val_score(clf, train_pd, train_labels, cv=10).max())

    print(cross_val_score(clf, train_pd, train_labels, cv=10).min())

    print(cross_val_score(clf, train_pd, train_labels, cv=10).mean())

    # 0.8876404494382022

    # 0.7528089887640449

    # 0.8317103620474408

    4. 预测结果

    对测试集进行数据清洗。

    # 导入数据集

    test_pd = pd.read_csv('test.csv')

    # 填充缺失值

    test_pd ["Age"] = test_pd ["Age"].fillna(test_pd ["Age"].mean())

    test_pd ["Fare"] = test_pd ["Fare"].fillna(test_pd ["Fare"].mean())

    test_pd ['Embarked'] = test_pd ['Embarked'].fillna('S')

    # 删除不需要的特征

    test_pd.drop(["PassengerId","Cabin","Name","Ticket"],inplace=True,axis=1)

    #

    test_pd['Sex'] = test_pd['Sex'].map({'male': 0, 'female': 1}).astype(int)

    test_pd['Embarked'] = test_pd['Embarked'].map( {'S': 0, 'C': 1,'Q':2},).astype(int)

    预估结果:

    test_pd['Survived']=pd.DataFrame(clf.predict(test_pd))

    此时的数据如下:

    看看存活率如何:

    # 训练集存活率

    Survived = train_pd['Survived'].value_counts(normalize=True)

    print(f'训练集:死亡率{Survived[0]:.3%} ,存活率{Survived[1]:.3%}')

    # 测试集存活率

    Survived = df_test['Survived'].value_counts(normalize=True)

    print(f'测试集:死亡率{Survived[0]:.3%} ,存活率{Survived[1]:.3%}')

    result:

    可以看到,训练集和测试集的差别是不大的。

    训练集:死亡率61.616% ,存活率38.384%

    测试集:死亡率62.679% ,存活率37.321%

    5. 决策树可视化

    后面再补上。

    后话

    分类树预测经典实例——泰坦尼克号幸存者预测,部分参考该文章。

    如上,因为学习的不够深入,所以分享出来的也很菜。

    文章多有不通之处,还请各位不吝赐教。

    本次分享到此结束。纯当个人笔记,不可做为系统学习以及学习参考!!!

    展开全文
  • 泰坦尼克号存活率预测--学习笔记数据引入和初步分析csv数据引入和概览初步探索分析***Pclass******Sex******Name******SibSp******Parch****** Embarked ******Fare***可视化分析***Age******Age &amp;amp;amp;...

    泰坦尼克号的沉没是历史上著名的海难事件,当时登船乘客数以千计。他们的个人信息各不相同,生还罹难遭遇各异。虽然,人们对他们的遭遇表示不幸,但是这个灾难也给数据分析和预测提供了比较丰富的数据样品。

    本文的题目描述和数据集源自https://www.kaggle.com/c/titanic,将以给定的训练集数据进行分析,来对预测测试集样品对应的存活几率进行推测。本文为练习笔记总结,问题在所难免,待以后纠正和完善。

    变量说明 :
    Survival(存活与否) 0 = No, 1 = Yes
    Pclass(船票等级) 可以代表社会经济地位,1 = 1st(Upper), 2 = 2nd(Middle), 3 = 3rd(Lower)
    Sex(性别) male/female
    Age(年龄) 年龄小于1的为小数,大于1有小数部分的年龄为估计值
    Sibsp(兄弟姐妹/配偶登船数)
    Parch(父母/子女登船数) 有的孩子是跟保姆旅行,他们的Parch = 0
    ticket(票号)
    Fare(票价)
    Cabin(客舱)
    Embarked(登船港口) C = Cherbourg(法国瑟堡,为第二登船港口), Q = Queenstown(爱尔兰皇后镇,现科夫,为入海港口), S = Southampton(英国南安普顿,为启航港口)

    数据引入和初步分析

    从csv中引入训练集和测试集数据,并对各个字段进行初步分析。

    csv数据引入和概览

    引入所需的库:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    import seaborn as sns
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn.linear_model import Perceptron
    from sklearn.linear_model import SGDClassifier
    from sklearn.naive_bayes import GaussianNB
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.svm import SVC, LinearSVC
    from sklearn.tree import DecisionTreeClassifier
    
    # 导入训练集和测试集数据
    data_train = pd.read_csv('train.csv')
    data_test = pd.read_csv('test.csv')
    
    # 创建合并数据集,方便分析预测
    data_combined = [data_train, data_test]
    # 打印数据集的主要信息
    for d in data_combined:
        print('表首尾数据:')
        print(d.head())
        print('_'*80)
        print(d.tail())
        print('数值统计信息:')
        print(d.describe())
        print('_'*80)
        print('分类值统计信息:')
        print(d.describe(include=['O']))
        print('_'*80)
        print('表信息:')
        print(d.info())
        print('='*80)
    # 打印Age和Cabin字段缺失值   
    for d in data_combined:
        print('Age缺失值数量为{0}个, 占总比{1}'.format(d.Age.isnull().sum(), d.Age.isnull().sum()/len(d.Age)))
        print('Cabin缺失值数量为{0}个, 占总比{1}'.format(d.Cabin.isnull().sum(), d.Cabin.isnull().sum()/len(d.Cabin)))
        print('_'*60)
    

    这一步打印信息过长,暂且省略,以下是“打印Age和Cabin字段缺失值”语句运行结果:
    Age缺失值数量为177个, 占总比0.19865319865319866
    Cabin缺失值数量为687个, 占总比0.7710437710437711


    Age缺失值数量为86个, 占总比0.20574162679425836
    Cabin缺失值数量为327个, 占总比0.7822966507177034


    • AgeCabin列有大量缺失值
    • 训练集的Embarked和测试集的Fare有少量的缺失值
    • 非数值列NameSexTicketCabinEmbarked等列需要进行数值化以便统计

    初步探索分析

    对各个字段进行初步分析

    Pclass

    # 按照Pclass分类,简单观察与Survived之间的关系
    data_train[['Pclass', 'Survived']].groupby(by=['Pclass'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Pclass Survived
    0 1 0.629630
    1 2 0.472826
    2 3 0.242363
    • 表面上看,船票等级越高,存活率越高

    Sex

    # 按照Sex分类,简单观察与Survived之间的关系
    data_train[['Sex', 'Survived']].groupby(by=['Sex'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Sex Survived
    0 female 0.742038
    1 male 0.188908
    • 表面上看,女性存活率较高

    Name

    Name字段可以获取长度、首字母以及头衔等作为指标
    头衔包括MrMissMaster等,格式为"xxx."
    暂不进行处理分析

    SibSp

    # 按照SibSp分组,简单观察其与存活率之间的关系
    data_train[['SibSp', 'Survived']].groupby(by=['SibSp'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    SibSp Survived
    1 1 0.535885
    2 2 0.464286
    0 0 0.345395
    3 3 0.250000
    4 4 0.166667
    5 5 0.000000
    6 8 0.000000
    • 兄弟姐妹和配偶同行越少,存活率越高
    • 没有兄弟姐妹和配偶同行的存活率中等偏上

    Parch

    # 按照Parch分组,简单观察其与存活率之间的关系
    data_train[['Parch', 'Survived']].groupby(by=['Parch'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Parch Survived
    3 3 0.600000
    1 1 0.550847
    2 2 0.500000
    0 0 0.343658
    5 5 0.200000
    4 4 0.000000
    6 6 0.000000
    • 父母和子女同行人数少(1至3人)比同行人数多(4至6人)的存活率高
    • 无父母和子女同行的存活率中等

    Embarked

    # 按照Embarked分组,简单查看其与存活率之间的关系
    data_train[['Embarked', 'Survived']].groupby(by=['Embarked'], as_index=False).mean().sort_values(by='Survived', ascending=False)
    
    Embarked Survived
    0 C 0.553571
    1 Q 0.389610
    2 S 0.336957
    • 在C港登船的人平均存活率超过一半,S港的船客大约有1/3存活几率,Q港上船的人平均存活几率有不到40%居于中间

    Fare

    # 查看一下Fare > 0的记录的统计信息
    data_train.Fare[data_train.Fare > 0].describe()
    
    count    876.000000
    mean      32.755650
    std       49.936826
    min        4.012500
    25%        7.925000
    50%       14.500000
    75%       31.275000
    max      512.329200
    Name: Fare, dtype: float64
    
    • 票价里有为0的记录,不知道是不是特殊安排的船票,本次分析不算入内
    • 可以观察到票价的差距很大(从4~512左右),可能跟登船港口和船客社会经济地位有关
    • 偏差较大的票价可能会影响统计中的存活人数和比例,可能需要划分为不同范围再统计

    可视化分析

    FacetGrid适用于数据集绘制单变量分布或多变量关系,三个维度为rowcolhue,即横纵轴和颜色

    Age

    # 分别绘制生还和罹难人员的年龄分布
    fg = sns.FacetGrid(data_train, col='Survived', size=3, aspect=1.5)
    fg.map(plt.hist, 'Age', bins=20)
    
    <seaborn.axisgrid.FacetGrid at 0x17137208>
    

    在这里插入图片描述

    • 乘客大部分人为中青年人(15~35)
    • 未成年乘客总体上存活率较高
    • 15~30年龄段的乘客罹难人数非常多

    Age & Sex

    结合Age和Sex观察生还几率

    # 绘制各性别的年龄-生还回归模型图
    generations = [10, 20, 40, 60, 80]
    sns.lmplot('Age', 'Survived',data_train, hue='Sex', x_bins=generations)
    
    D:\Anaconda3\lib\site-packages\scipy\stats\stats.py:1633: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
      return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval
    
    <seaborn.axisgrid.FacetGrid at 0x17162048>
    

    在这里插入图片描述

    • 女性比男性存活率高
    • 女性年纪越大越容易存活,男性则相反

    下面是另一个年龄段划分 [15,30,40,80]的图形(可能更明显):
    在这里插入图片描述

    Pclass & Age

    # 分别绘制各船票等级生还和罹难人员年龄分布图
    fg = sns.FacetGrid(data_train, row='Pclass', col='Survived', size=3, aspect=1.5)
    fg.map(plt.hist,'Age', bins=20)
    fg.add_legend()
    
    <seaborn.axisgrid.FacetGrid at 0x174f3128>
    

    在这里插入图片描述

    • 持有1等船票的存活率整体高于50%,2等则大略相当于50%人数也处于中等水平(略低于1等船票),3等对应人数最多且超过一半罹难
    • 持有1和2等船票的年轻乘客基本都存活了
    • Pclass随年龄分布变化适用于模型训练

    下面是各等级船票持有者生还几率随年龄段([15, 30, 40, 80])变化的回归模型图(可能更直观):
    在这里插入图片描述

    • 船票等级越高存活率越高
    • 各船票类别中,年纪越大,存活率越低

    Pclass & Sex & Embarked

    # 绘制各登船港口生还几率与船票等级关系点线图
    fg = sns.FacetGrid(data_train, col='Embarked', size=3, aspect=1.5)
    fg.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='dark')
    fg.add_legend()
    
    D:\Anaconda3\lib\site-packages\scipy\stats\stats.py:1633: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
      return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval
    
    <seaborn.axisgrid.FacetGrid at 0x1a812278>
    

    在这里插入图片描述

    • 在S和Q港口登船的女性比男性存活几率高很多,在C港口登船的男性比女性更容易存活

    Embarked & Sex & Fare

    # 绘制各登船地点生还和罹难人员各性别票价柱形图
    fg = sns.FacetGrid(data_train, row='Embarked', col='Survived', size=3, aspect=1.5)
    fg.map(sns.barplot, 'Sex', 'Fare', alpha=0.75, ci=None)
    fg.add_legend()
    
    <seaborn.axisgrid.FacetGrid at 0x1c4c5588>
    

    在这里插入图片描述

    • 船的票价差距很大从大约4到大于512不等,所以本次分析无法用船费统计人数和存活率,后续分析可能需要划分为不同区间
    • 在C和S港口登船的人存活的人比罹难的人平均票价要高得多,而Q港男性存活者的船票略高,女性罹难者的票价略高

    数据整理

    PassengerId

    # PassengerId是用作索引的列,没有统计意义,可以去除掉
    data_train = data_train.drop(['PassengerId'], axis=1)
    
    # Ticket和Cabin为观察到明显的生还几率相关性
    data_train = data_train.drop(['Ticket', 'Cabin'], axis=1)
    data_test = data_test.drop(['Ticket', 'Cabin'], axis=1)
    
    # 打印数据集维度变化
    print('数据集维度变化:\n\t整理前:\n\t\t训练集:\t{0}\t测试集:\t{1}\n\t整理后:\n\t\t训练集:\t{2}\t测试集:\t{3}'.format(data_combined[0].shape, data_combined[1].shape, data_train.shape, data_test.shape))
    # 合并数据集以便统计分析
    data_combined = [data_train, data_test]
    
    数据集维度变化:
    	整理前:
    		训练集:	(891, 12)	测试集:	(418, 11)
    	整理后:
    		训练集:	(891, 9)	测试集:	(418, 9)
    

    Title

    # 从Name字段提取称谓对应的Title字段
    for d in data_combined:
        d['Title'] = d.Name.str.extract(' ([A-Z]\w+)\.', expand=False)
    
    pd.crosstab(data_train['Title'], data_train['Sex'])
    
    Sex female male
    Title
    Capt 0 1
    Col 0 2
    Countess 1 0
    Don 0 1
    Dr 1 6
    Jonkheer 0 1
    Lady 1 0
    Major 0 2
    Master 0 40
    Miss 182 0
    Mlle 2 0
    Mme 1 0
    Mr 0 517
    Mrs 125 0
    Ms 1 0
    Rev 0 6
    Sir 0 1
    • 创建头衔或称谓列Title
    • Title列可以观察人员的大致社会经济地位:

    Title字段对应值的一些基本含义:
    Capt.为船长或上尉、机长或副巡长
    Col.为上校
    Countess.为伯爵夫人或女伯爵
    Don.为意大利、西班牙、葡萄牙、拉丁美洲和菲律宾对男子的尊称(应该有对应的Dona)
    Dr.为医生或博士
    Jonkheer.为荷兰低等贵族
    Lady.为贵族夫人或女贵族
    Major.为陆军少校
    Master.为商船船长、大师、院长等
    Miss.为小姐
    Mlle.为法语Mademoiselle小姐的缩写
    Mme.为法语Madame太太的缩写
    Mr.为先生
    Mrs.为夫人
    Ms.为女士
    Rev.为牧师
    Sir.为爵士

    其中,Mlle、Ms和Miss,Mme和Mrs分别对等,数量较多更具有统计意义;其他的头衔人数很少,不具有太大统计意义,可以归为一类(Don或许应该和Mr对应,Dona和Miss对等)

     # 将Title字段归入对应的值
    for d in data_combined:
        d.Title = d.Title.replace(['Lady', 'Countess', 'Capt', 'Col', 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
        d.Title = d.Title.replace('Mlle', 'Miss') 
        d.Title = d.Title.replace('Ms', 'Miss')
        d.Title = d.Title.replace('Mme', 'Mrs')
    # 按照Title字段分类查看与生还几率之间的关系
    data_train[['Title', 'Survived']].groupby(by=['Title'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Title Survived
    3 Mrs 0.793651
    1 Miss 0.702703
    0 Master 0.575000
    4 Rare 0.347826
    2 Mr 0.156673
    • Mrs和Miss代表的女性存活率较高(分别为大约80%和70%)
    • Master代表的有身份地位的男性存活率接近60%
    • Mr代表的普通男性只有略高于15%的存活几率
    • Rare代表的有特殊头衔的乘客存活于中等偏下为不到35%,但是这些人员头衔各异,人数又少,可能意义不大

    将分类值转变为数值以便模型分析和预测

    Title -> 123

    # 将Title转变为数值
    title_map = {'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Rare': 5}
    for d in data_combined:
        d.Title = d.Title.map(title_map)
        d.Title = d.Title.fillna(0)
    

    drop Name

    # 删除Name列
    data_train = data_train.drop(['Name'], axis=1)
    data_test = data_test.drop(['Name'], axis=1)
    data_combined = [data_train, data_test]
    

    Sex -> 123

    # 将性别转变为数值
    for d in data_combined:
        d.Sex = d.Sex.map({'male': 1, 'female': 0})
    

    Age & Sex & Pclass

    • Age变量和Sex、Pclass等变量关联
    # 绘制各等级船票持有者各性别的年龄分布图
    fg = sns.FacetGrid(data_train, row='Pclass', col='Sex', size=3, aspect=1.5)
    fg.map(plt.hist, 'Age', alpha=0.75, bins=20)
    fg.add_legend()
    
       <seaborn.axisgrid.FacetGrid at 0x1cca1160>
    

    在这里插入图片描述

    # 预先分配数组用以存放Sex和Pclass各组合对应的年龄
    ages_guessed = np.zeros((2, 3))
    
    # 为各性别各等级船票持有者年龄空值记录赋值为对应的众数
    for d in data_combined:
        for i in range(0, 2):
            for j in range(0, 3):
                age_guessed = d[(d.Sex == i) & (d.Pclass == j+1)].Age.dropna().median()
                #ages_guessed[i, j] = round(age_guessed)
                ages_guessed[i, j] = int(age_guessed + 0.25)
        for i in range(0, 2):
            for j in range(0, 3):
                d.loc[(d.Sex == i) & (d.Pclass == j+1) & d.Age.isnull(), 'Age'] = ages_guessed[i, j]
        d.Age = d.Age.astype(int)
    
    data_train.head()
    
    Survived Pclass Sex Age SibSp Parch Fare Embarked Title
    0 0 3 1 22 1 0 7.2500 S 1
    1 1 1 0 38 1 0 71.2833 C 3
    2 1 3 0 26 0 0 7.9250 S 2
    3 1 1 0 35 1 0 53.1000 S 3
    4 0 3 1 35 0 0 8.0500 S 1

    Band_Age

    # 根据年龄分布情况将其划分为5段
    data_train['Band_Age'] = pd.cut(data_train.Age, 5)
    data_train[['Band_Age', 'Survived']].groupby(by=['Band_Age'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Band_Age Survived
    0 (-0.08, 16.0] 0.550000
    3 (48.0, 64.0] 0.434783
    2 (32.0, 48.0] 0.412037
    1 (16.0, 32.0] 0.337374
    4 (64.0, 80.0] 0.090909
    • 0~16岁的乘客有过半的生存概率
    • 其次为49至64岁、33至48岁、17至32岁的乘客,生存概率在44%至34%左右
    • 65~80岁的乘客,存活概率最低不到10%
    # 分段观察Age变量之后可以删除
    data_train = data_train.drop('Band_Age', axis=1)
    data_combined = [data_train, data_test]
    
    # 根据分段边界划分年龄到各区段
    for d in data_combined:
        d.loc[d.Age <= 16, 'Age'] = 0
        d.loc[(d.Age <= 32) & (d.Age > 16), 'Age'] =1
        d.loc[(d.Age <= 48) & (d.Age > 32), 'Age'] =2
        d.loc[(d.Age <= 64) & (d.Age > 48), 'Age'] =3
        d.loc[(d.Age > 64), 'Age'] =4
    
    # 分别绘制罹难和生还人员各年龄段人数分布图
    fg = sns.FacetGrid(data_train, col='Survived')
    fg.map(plt.hist, 'Age', bins=4)
    
    <seaborn.axisgrid.FacetGrid at 0x1cfb0278>
    

    在这里插入图片描述

    Families

    # Families计算家人数,包括父母、兄弟姐妹、配偶和子女
    for d in data_combined:
        d['Families'] = d.SibSp + d.Parch
        
    data_combined = [data_train, data_test]
    
    data_train.head()
    
    Survived Pclass Sex Age SibSp Parch Fare Embarked Title Families
    0 0 3 1 1 1 0 7.2500 S 1 1
    1 1 1 0 2 1 0 71.2833 C 3 1
    2 1 3 0 1 0 0 7.9250 S 2 0
    3 1 1 0 2 1 0 53.1000 S 3 1
    4 0 3 1 2 0 0 8.0500 S 1 0
    data_combined[0].head()
    
    Survived Pclass Sex Age SibSp Parch Fare Embarked Title Families
    0 0 3 1 1 1 0 7.2500 S 1 1
    1 1 1 0 2 1 0 71.2833 C 3 1
    2 1 3 0 1 0 0 7.9250 S 2 0
    3 1 1 0 2 1 0 53.1000 S 3 1
    4 0 3 1 2 0 0 8.0500 S 1 0
    # 查看Families和Survived之间的关系
    data_train[['Families', 'Survived']].groupby(by=['Families'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Families Survived
    3 3 0.724138
    2 2 0.578431
    1 1 0.552795
    6 6 0.333333
    0 0 0.303538
    4 4 0.200000
    5 5 0.136364
    7 7 0.000000
    8 10 0.000000

    登船家人人数少的存活几率超过50%,3至1人几率在72%至55%,依次递减
    登船家人人数适中的存活几率较低,6/4/5人分别在1/3、1/5和3/20左右
    登船家人人数为7和10人的人无人存活
    单独登船的人有不到1/3几率存活,可以创建一个Alone变量

    Alone

    # 创建Alone变量字段
    for d in data_combined:
        d['Alone'] = 0
        d.loc[d.Families == 0, 'Alone'] = 1
    
    data_train.head()
    
    Survived Pclass Sex Age SibSp Parch Fare Embarked Title Families Alone
    0 0 3 1 1 1 0 7.2500 S 1 1 0
    1 1 1 0 2 1 0 71.2833 C 3 1 0
    2 1 3 0 1 0 0 7.9250 S 2 0 1
    3 1 1 0 2 1 0 53.1000 S 3 1 0
    4 0 3 1 2 0 0 8.0500 S 1 0 1
    # 按照是否无家人陪同分类查看生存几率
    data_train[['Alone', 'Survived']].groupby(by=['Alone'], as_index=False).mean()
    
    Alone Survived
    0 0 0.505650
    1 1 0.303538

    drop SibSp, Parch, Families

    # 将SibSp,Parch和Families列去除,专门分析Alone列
    data_train = data_train.drop(['SibSp', 'Parch', 'Families'], axis=1)
    data_test = data_test.drop(['SibSp', 'Parch', 'Families'], axis=1)
    data_combined = [data_train, data_test]
    
    data_train.head()
    
    Survived Pclass Sex Age Fare Embarked Title Alone
    0 0 3 1 1 7.2500 S 1 0
    1 1 1 0 2 71.2833 C 3 0
    2 1 3 0 1 7.9250 S 2 1
    3 1 1 0 2 53.1000 S 3 0
    4 0 3 1 2 8.0500 S 1 1

    Age x Pclass

    # 创建Age*Pclass字段
    for d in data_combined:
        d['Age*Pclass'] = d.Age * d.Pclass
    data_train[['Age', 'Pclass', 'Age*Pclass', 'Survived']].head()
    
    Age Pclass Age*Pclass Survived
    0 1 3 3 0
    1 2 1 2 1
    2 1 3 3 1
    3 2 1 2 1
    4 2 3 6 0

    Embarked->123

    print('训练集中Embarked空值个数为{}'.format(data_train.Embarked.isnull().sum()))
    
    训练集中Embarked空值个数为2
    
    # 将Embarked少量空值填充为众数
    for d in data_combined:
        d.Embarked = d.Embarked.fillna(data_train.Embarked.dropna().mode()[0])
    
    # 按照登船地点分类查看与存活几率之间的关系
    data_train[['Embarked', 'Survived']].groupby(by=['Embarked'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Embarked Survived
    0 C 0.553571
    1 Q 0.389610
    2 S 0.339009
    # 将登船地点转化为数值
    for d in data_combined:
        d.Embarked = d.Embarked.map({'S': 0, 'C': 1, 'Q': 2}).astype(int)
    

    Fare

    print('测试集中Fare空值个数为{}'.format(data_test.Fare.isnull().sum()))
    
    测试集中Fare空值个数为1
    
    # 填充少量Fare的缺失值为众数
    for d in data_combined:
        d.Fare.fillna(d.Fare.dropna().median(), inplace=True)
    

    Band_Fare

    # 分别绘制罹难和生还人员票价分布图
    fg = sns.FacetGrid(data_train, col='Survived', size=3, aspect=1.5)
    fg.map(plt.hist, 'Fare', bins=10)
    
    <seaborn.axisgrid.FacetGrid at 0x1cfddef0>
    

    在这里插入图片描述

    # pandas.qcut按照样品数量等分,pandas.cut等分样品区间
    data_train['Band_Fare'] = pd.qcut(data_train.Fare, 4)
    data_train[['Band_Fare', 'Survived']].groupby(by=['Band_Fare'], as_index=False).mean().sort_values(by=['Survived'], ascending=False)
    
    Band_Fare Survived
    3 (31.0, 512.329] 0.581081
    2 (14.454, 31.0] 0.454955
    1 (7.91, 14.454] 0.303571
    0 (-0.001, 7.91] 0.197309
    • 区段票价越高,存活率越高

    Fare->123

    # 将票价归入对应的区间并赋值
    for d in data_combined:
        d.loc[(d.Fare <= 7.91), 'Fare'] = 0
        d.loc[(d.Fare > 7.91) & (d.Fare <= 14.454), 'Fare'] = 1
        d.loc[(d.Fare > 14.454) & (d.Fare <= 31.0), 'Fare'] = 2
        d.loc[(d.Fare > 31.0), 'Fare'] = 3
        d.Fare = d.Fare.astype(int)
    

    drop Band_Fare

    data_train = data_train.drop(['Band_Fare'], axis=1)
    
    data_train.head()
    
    Survived Pclass Sex Age Fare Embarked Title Alone Age*Pclass
    0 0 3 1 1 0 0 1 0 3
    1 1 1 0 2 3 1 3 0 2
    2 1 3 0 1 1 0 2 1 3
    3 1 1 0 2 3 0 3 0 2
    4 0 3 1 2 1 0 1 1 6
    data_test.head()
    
    PassengerId Pclass Sex Age Fare Embarked Title Alone Age*Pclass
    0 892 3 1 2 0 2 1 1 6
    1 893 3 0 2 0 0 3 0 6
    2 894 2 1 3 1 2 1 1 6
    3 895 3 1 1 1 0 1 1 3
    4 896 3 0 1 1 0 3 0 3

    各变量热力图

    # 简单观察各个变量相关性
    colormap = plt.cm.jet
    plt.figure(figsize=(10, 10))
    sns.heatmap(data_train.astype(float).corr(), linewidth=0.1, vmax=1.0, square=True, cmap=colormap, linecolor='white', annot=True)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x1e359da0>
    

    在这里插入图片描述

    预测模型

    已知训练集包含生存结果,需要将测试集结果归类,是监督学习下进行回归分析
    考虑以下数据集:
    + 逻辑回归(Logistic Regression)
    + k近邻算法(k-Nearest Neighbors)
    + 支持向量机(Support Vector Machines)
    + 朴素贝叶斯分类器(Naive Bayes classifier)
    + 决策树(Decision Tree)
    + 随机森林(Random Forrest)
    + 感知机(Perceptron)
    + 线性支持向量机(Linear SVC)
    + 随机梯度下降法(Stochastic Gradient Descent)
    + 人工神经网络(Artificial neural network)
    + 相关向量机(Relevance Vector Machine)

    x_train = data_train.drop(['Survived'], axis=1)
    y_train = data_train.Survived
    x_test = data_test.drop(['PassengerId'], axis=1)
    x_train.shape, y_train.shape, x_test.shape
    
    ((891, 8), (891,), (418, 8))
    

    逻辑回归

    逻辑回归适用于因变量为分类值(本例中为0或1用以代表是否存活),用以估计的概率衡量因变量和一或多个自变量之间的关系

    # 实例化逻辑回归类对象
    lgrg = LogisticRegression()
    # 以训练集训练模型
    lgrg.fit(x_train, y_train)
    # 以测试集测试模型
    y_predict = lgrg.predict(x_test)
    # 估计一下模型精度
    acc_lgrg = round(lgrg.score(x_train, y_train) * 100, 2)
    print('Logistic Regression:\n\tAccuracy:\t{}'.format(acc_lgrg))
    
    Logistic Regression:
    	Accuracy:	80.92
    
    corr_ftr = pd.DataFrame(x_train.columns)
    corr_ftr.columns = ['Features']
    corr_ftr['Correlations'] = pd.Series(lgrg.coef_[0])
    corr_ftr.sort_values(by=['Correlations'], ascending=False)
    
    Features Correlations
    5 Title 0.440642
    6 Alone 0.377805
    4 Embarked 0.292706
    3 Fare 0.061489
    7 Age*Pclass -0.138891
    2 Age -0.217198
    0 Pclass -0.885901
    1 Sex -2.119842
    • 负相关中相关性最大为Sex(male=1, female=0),这与最初观察相符,男性存活率比女性低;Pclass也类似
    • 正相关中Title、Alone和Embarked的相关度较高

    支持向量机

    支持向量机是与相关的学习算法有关的监督学习模型,可以分析数据,识别模式,用于分类和回归分析。给定一组训练样本,每个标记为属于两类,一个SVM训练算法建立了一个模型,分配新的实例为一类或其他类,使其成为非概率二元线性分类。

    svc = SVC()
    svc.fit(x_train, y_train)
    y_predict = svc.predict(x_test)
    acc_svc = round(svc.score(x_train, y_train) * 100, 2)
    print('Support Vector Machines:\n\tAccuracy:\t{}'.format(acc_svc))
    
    Support Vector Machines:
    	Accuracy:	83.5
    

    k近邻算法

    k临近算法是一个非参数分类和回归方法,这个模型用于预测距离特征空间最近的因变量值

    # 寻找最适合的n_neighbors值
    range_k = range(3, 9)
    list_acc = []
    for k in range_k:
        knc = KNeighborsClassifier(n_neighbors = k)
        knc.fit(x_train, y_train)
        y_predict = knc.predict(x_test)
        list_acc.append(round(knc.score(x_train, y_train) * 100, 2))
    
    plt.plot(range_k, list_acc)
    plt.xlabel('k for KNN')
    plt.ylabel('Accuracy')
    
    Text(0,0.5,'Accuracy')
    

    在这里插入图片描述

    • 最适合的k值为3
    print('k-Nearest Neighbors:\n\tAccuracy:\t{}'.format(list_acc[0]))
    
    k-Nearest Neighbors:
    	Accuracy:	84.06
    

    朴素贝叶斯分类器

    朴素贝叶斯分类器假定样本每个特征与其他特征都不相关,具有高度可伸缩且适用于大数据集

    gnb = GaussianNB()
    gnb.fit(x_train, y_train)
    y_predict = gnb.predict(x_test)
    acc_gnb = round(gnb.score(x_train, y_train) * 100, 2)
    print('Naive Bayes classifier:\n\tAccuracy:\t{}'.format(acc_gnb))
    
    Naive Bayes classifier:
    	Accuracy:	76.88
    

    感知机

    pct = Perceptron()
    pct.fit(x_train, y_train)
    y_predict = pct.predict(x_test)
    acc_pct = round(pct.score(x_train, y_train) * 100, 2)
    print('Perceptron:\n\tAccuracy:\t{}'.format(acc_pct))
    
    Perceptron:
    	Accuracy:	78.45
    
    
    D:\Anaconda3\lib\site-packages\sklearn\linear_model\stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.perceptron.Perceptron'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.
      "and default tol will be 1e-3." % type(self), FutureWarning)
    

    线性支持向量机

    线性支持向量机通常最适于文本分类问题,是支持向量机分类器在线性核函数上的应用。

    lsvc = LinearSVC()
    lsvc.fit(x_train, y_train)
    y_predict = lsvc.predict(x_test)
    acc_lsvc = round(lsvc.score(x_train, y_train) * 100, 2)
    print('Linear Supported Vector classifier:\n\tAccuracy:\t{}'.format(acc_lsvc))
    
    Linear Supported Vector classifier:
    	Accuracy:	79.57
    

    随机梯度下降法

    随机梯度下降法在损失函数梯度方向迭代更新权重参数直至取得最小值.不同于传统的梯度下降法,不使用整个数据集计算每次迭代的梯度;相反随机选择单个数据集中的数据点,并沿着该点对应的梯度方向移动。

    sgdc = SGDClassifier()
    sgdc.fit(x_train, y_train)
    y_predict = sgdc.predict(x_test)
    acc_sgdc = round(sgdc.score(x_train, y_train) * 100, 2)
    print('Stochastic Gradient Descent:\n\tAccuracy:\t{}'.format(acc_sgdc))
    
    Stochastic Gradient Descent:
    	Accuracy:	80.36
    
    
    D:\Anaconda3\lib\site-packages\sklearn\linear_model\stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.
      "and default tol will be 1e-3." % type(self), FutureWarning)
    

    决策树

    决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别

    dtc = DecisionTreeClassifier()
    dtc.fit(x_train, y_train)
    y_predict = dtc.predict(x_test)
    acc_dtc = round(dtc.score(x_train, y_train) * 100, 2)
    print('Decision Tree:\n\tAccuracy:\t{}'.format(acc_dtc))
    
    Decision Tree:
    	Accuracy:	86.64
    

    随机森林

    随机森林是用于分类和回归等的集成学习方法,它包含多个决策树的分类器,其输出的类别是由个别树输出的类别的众数而定。

    rfc = RandomForestClassifier(n_estimators=10)
    rfc.fit(x_train, y_train)
    y_predict = rfc.predict(x_test)
    acc_rfc = round(rfc.score(x_train, y_train) * 100, 2)
    print('Random Forest classifier:\n\tAccuracy:\t{}'.format(acc_rfc))
    
    Random Forest classifier:
    	Accuracy:	86.64
    
    # 获得特征重要性
    importances_feature = rfc.feature_importances_
    # 排序
    index_sorted = np.argsort(importances_feature)
    positions = np.arange(index_sorted.shape[0])
    
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.figure(figsize=(8, 6))
    plt.barh(positions, importances_feature[index_sorted], align='center')
    plt.yticks(positions, x_train.columns[index_sorted])
    plt.title('变量重要性')
    plt.show()
    

    在这里插入图片描述

    汇总模型预测效果

    acc_model = pd.DataFrame({'model': ['Logistic Regression', 'k-Nearest Neighbors', 'Support Vector Machines',\
                                        'Naive Bayes classifier', 'Decision Tree', 'Random Forrest', 'Perceptron', 'Linear SVC', \
                                        'Stochastic Gradient Descent'], \
                              'acc': [acc_lgrg, list_acc[0], acc_svc, acc_gnb, acc_dtc, acc_rfc, acc_pct, acc_lsvc, acc_sgdc]})
    
    acc_model.sort_values(by=['acc'], ascending=False)
    
    acc model
    4 86.64 Decision Tree
    5 86.64 Random Forrest
    1 84.06 k-Nearest Neighbors
    2 83.50 Support Vector Machines
    0 80.92 Logistic Regression
    7 79.57 Linear SVC
    6 78.45 Perceptron
    8 77.10 Stochastic Gradient Descent
    3 76.88 Naive Bayes classifier
    index_sorted = np.argsort(acc_model.acc)
    positions = np.arange(index_sorted.shape[0])
    
    plt.figure(figsize=(8, 5))
    plt.barh(positions, acc_model.acc[index_sorted], align='center')
    plt.yticks(positions, acc_model.model[index_sorted])
    plt.title('各模型准确度')
    plt.show()
    

    在这里插入图片描述

    • 决策树和随机森林精确度相同,但是决策树有过拟合训练数据集的倾向,随机森林更优

    留待解决的问题

    1. Ticket,Cabin,Name长度和首字母的影响未列入
    2. 某些分析还可以以更加直观的图形表现(如在同一张图堆叠绘制生还和罹难人员人数随年龄变化的曲线或分布图,可以比较各年龄段生还比例)

    Kaggle上可参考的Solution链接

    https://www.kaggle.com/arthurtok/introduction-to-ensembling-stacking-in-python
    https://www.kaggle.com/startupsci/titanic-data-science-solutions

    展开全文
  • 4.训练模型,得出存活率 首先引用库(没用的和有用的都在里面,需要你们自己去选择): from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn.ensemble import RandomForestClass...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 141
精华内容 56
热门标签
关键字:

泰坦尼克号存活率预测