通俗易懂的泰坦尼克号生存分析(titanic)

作者:离散木木夕

欢迎大家给出宝贵的建议!


泰坦尼克号数据分析


一、前言


       主要目的是整理自己的思路。本文主要是关于泰坦尼克号生存率python分析,因为很多博客做这个项目都比较深入,感觉都比较高大上,我们初学者并不一定都能懂,甚至没兴趣看下去。这文章,也是从视频上学了之后,发现很不错,通俗易懂,非常推荐入门。我们可以共同学习。非常希望有人愿意指出我的不足。


二、正题


接下来开始进入本文的正题:


首先,我们要把数据集download下来吧,要准备好!

大家可以从kaggle平台里面下载,建议去了解一下,上面有很多经典的数据集。当然,其实百度也能搜索到。

软件平台吧,各取所好吧。我这里用的jupyter notebook,当然spyderpycharm,普通的IDE都可以。

我选择用这个软件,是因为我可以一个部分一个部分去分析解剖,并且找错误。有兴趣的同志可以去了解一下,我比较习惯这个软件。实际效果是一样的。

数据集下载下来之后呢,是个csv格式的表格,打开jupyter notebook,打开数据集,观察一下数据有哪些属性,并且选择出对我们分析生存率有帮助的信息。

相信大家看过泰坦尼克号的电影。没有看过的同志可以去百度了解一下。会对本项目有更深的理解。


打开下载的文件,由下面这幅图可以看见有:




其中:

PassengerId ,乘客的id号,这个我觉得对生存率没影响。因为一个人的id号不会影响我是否生存下来吧。这列可以忽略

Survived ,生存的标号,上面图的数值1表示这个人很幸运,生存了下来。数值0,则表示遗憾。

Pclass ,船舱等级,就是我们坐船有等级之分,像高铁,飞机都有。这个属性会对生产率有影响。因为一般有钱人,权贵才会住头等舱的。保留。

Name ,名字,这个不影响生存率。我觉得可以不用这列数据。可以忽略

Sex , 性别,这个因为全球都说lady first,女士优先,所有这列保留。

Age , 年龄,因为优先保护老幼,这个保留。

SibSp ,兄弟姐妹,就是有些人和兄弟姐妹一起上船的。这个会有影响,因为有可能因为救他们而导致自己没有上救生船船。保留这列

Parch , 父母和小孩。就是有些人会带着父母小孩上船的。这个也可能因为要救父母小孩耽误上救生船。保留

Ticket , 票的编号。这个没有影响吧。

Fare , 费用。这个和Pclass有相同的道理,有钱人和权贵比较有势力和影响力。这列保留

Cabin ,舱号。住的舱号没有影响。忽略。

Embarked ,上船的地方。这列可能有影响。我认为登陆地点不同,可能显示人的地位之类的不一样。我们先保留这列。


所以,我们大概知道需要提取哪些列的信息了,有:

Pclass、Sex、Age、SibSp、Parch、Fare、Embarked


三、代码及其解析


好了,我们分析完表格,就是我们要分析的这个数据集。我那时,就想,下一步应该要建模型来帮我们做分析了。

所以下一步,我就开始进入jupyter notebook去撸代码了。


import pandas                                    #导入pandas库,这个库是专门设计用来做数据分析的工具
titanic=pandas.read_csv('titanic_train.csv')      #读取文件titanic_train数据集
print(titanic.describe())                        #describe()函数是用来描述数据属性的,然后print打印出来


输入上面代码会显示出上面那幅图的结果:

count,是总数的意思。

mean,是平均值

std,是方差

min,最小值

max,最大值

25%、50%、75%,意思是位置分别是25%、50%、75%大的数据是什么。比如,Age,就是年龄大小排在25%的人的年龄是20.125岁,小数点表示年月。


由上面可知:

Age那列只有714个数。而其他属性都有891个数值。那说明,Age那列有空值,就是数据丢失了,一共有接近200个数据丢失。

那怎么办?因为我们一开始分析了,Age这一列对生存率分析有影响,我们必须保留,不能忽略。所以我选择补充上去。

那么问题来了,补充什么样的数据比较合理呢?才不会导致数据的准确性呢?我想应该补充平均值。


#机器学习中输入的数据集要求是M*N的矩阵,Age列有缺失值,median()函数代表去均值
titanic['Age']=titanic['Age'].fillna(titanic['Age'].median())   #fillna()表示补充,median()表示求平均值
print(titanic.describe())                                      #再看看表的变化




这里我们可以看见,Age这一列补充了数值了,到达891个。这列数据算是处理完了。

接下来,该看看我们刚刚分析其他列的数据有什么需要改进的地方。

我们可以看到Sex这一列的数据显示是为:female和male,下面可以输入代码可以显示出来:

print(titanic['Sex'].unique())  #返回其参数数组中所有不同的值,并且按照从小到大的顺序排列

这里就有个问题了。

机器学习算法一般来说解决不了对字符的分类。因为我们是要对Survived这列‘’0‘’和"1"进行分类嘛。

所以我们就要把"Sex"这一列的数据进行处理,把它改为数值型。那我们就把"male"和“female”进行处理,分别用0和1替代。

下面是代码:

#loc是通过行标签索引行数据,iloc是通过行号获取行数据, ix是结合前两种的混合索引
#注意loc后面加的是中括号,不是小括号
titanic.loc[titanic['Sex']=='male','Sex']=0
titanic.loc[titanic['Sex']=='female','Sex']=1


同时,我们也把"Embarked"这一列数据进行同样的处理:

print(titanic['Embarked'].unique())
titanic['Embarked']=titanic['Embarked'].fillna('S')
titanic.loc[titanic['Embarked']=='S','Embarked']=0
titanic.loc[titanic['Embarked']=='C','Embarked']=1
titanic.loc[titanic['Embarked']=='Q','Embarked']=2

好了,到这里基本数据就处理完了。我们下一步就要做什么?就是要建立模型了,就是撸代码。让这模型替我们做分析做分类。


下面我们分别用线性模型、逻辑回归、随机森林这三种机器学习算法模型来分析这个案例,就是分析生存率。

(1)我们先用线性模型进行分析。


#在线性模型模块中导入线性回归
#交叉验证,把训练数据集分成三份。最后去平均值
from sklearn.linear_model import LinearRegression
from sklearn.cross_validation import KFold

#这里的数据都对预测生存有影响
predictors=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']

#把线性回归导进来
alg=LinearRegression()

#选择做几倍的交叉验证,n_folds意思是几倍
kf=KFold(titanic.shape[0],n_folds=3,random_state=1)

predictions=[]
for train,test in kf:
    #意思是把训练数据拿出来
    train_predictors=(titanic[predictors].iloc[train,:])
    #the target we're using to train the algorithm
    train_target=titanic['Survived'].iloc[train]
    #把线性回归应用在train_pridictors,train_target数据集上
    alg.fit(train_predictors,train_target)
    #we can now make predictors on the test fold
    test_predictions=alg.predict(titanic[predictors].iloc[test,:])
    #我们要进行预测,是要对测试集进行预测
    predictions.append(test_predictions)

下面调用sklearn里面的模型,sklearn被称为机器学习的核武器,里面封装了几乎所有我们想得到的算法模型。我们直接调用就行了。

import numpy as np

#The predictions are in three separate numpy arrays. Concatenate them into one
#we concatenate them on axis 0, as they only one axis.
predictions=np.concatenate (predictions,axis=0)

#Map predictions to outcomes(only possible outcomes are 1 and 0)
predictions[predictions>.5]=1
predictions[predictions<=.5]=0
accuracy=sum(predictions[predictions==titanic['Survived']])/len(predictions)
print(accuracy)


这段代码算是撸完了,但是告诉你们一个我的悲剧,我这段代码分析的生存率准确性很低,我还没找出原因。原本准确率正常,后来重新撸了一遍,出问题了。

大家帮我找找问题,给我留言一下。谢谢!

(2)下面我们用逻辑回归算法模型

#这里用的是逻辑回归的算法方式
from sklearn import cross_validation
from sklearn.linear_model import LogisticRegression
#Initialize our algorithm
alg=LogisticRegression(random_state=1)
#Compute the accuracy score for all the cross validation folds.(much simpler than what we did before!)
scores=cross_validation.cross_val_score(alg,titanic[predictors],titanic['Survived'],cv=3)
#Take the mean of the scores(because we have one for each fold)
print(scores.mean())

准确率是 0.787878787879,这个还算正常。


(3)下面是随机森林的算法模型

#以下用的是随机森林的算法方式
from sklearn import cross_validation
from sklearn.ensemble import RandomForestClassifier

predictors=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']

#这里后面的samples不要少写一个“s”
#n_estimators是决策树的个数,min_samples_split是根据属性划分节点时,每个划分最少的样本数。min_samples_leaf:叶子节点最少的样本数。
alg=RandomForestClassifier(random_state=1,n_estimators=100,min_samples_split=4,min_samples_leaf=2)

kf=cross_validation.KFold(titanic.shape[0],n_folds=3,random_state=1)
scores=cross_validation.cross_val_score(alg,titanic[predictors],titanic['Survived'],cv=kf)

print(scores.mean()) 

准确率是 0.814814814815,这个因为调了参数,准确率升高了,原本和逻辑回归差不多。

这里我们是需要调参数的。大家可以看见上面有

n_estimators=100,min_samples_split=4,min_samples_leaf=2

这里上面的数值我们是需要调整的。这是必经之路,没办法。而且是人工的。哈哈!

猜你喜欢

转载自blog.csdn.net/jonyhwang/article/details/78932466