泰坦尼克号人员是否生存预测

本篇文章的灵感来源于 han xiaoyang大神博主的博文,当然同时运用了kaggle的有关泰坦尼克号的数据。毕竟没有数据就没有研究嘛。。。

  现在就让我们进行本次的预测,首先说明一下本次预测的目的:通过分析原始数据集来进行预测假如当泰坦尼克号触礁时哪些乘客将会被救哪些乘客将会坠入大海死亡的怀抱。。。。虽然是马后炮,(PS:我们已经知道在泰坦尼克号触礁之后谁还活着,但是这也是一种预测,我们可以通过已有的数据进行未来的预测。)
  老套路,首先先看一下原始数据集:


原始数据集.png

  看到这些原始数据集就感觉生活不美好。但是默默地说,,分析还是要做的。首先通过分析原始数据集:我们可以发现Survived,Sex,Embarked,Pclass是有分类的,譬如Survived只有存活或者不存活(0或者1),Sex只有男或者女(male or female 当然也有其他的。。。。性别。。在此笔者就不描述了),Embarked代表出发港口(这里也只有三个港口可供选择),Pclass则代表人群的高贵程度。。。(譬如Pclass==1代表这哥们或者姐妹起码也是马云级别的人物。。)所以呢,难道你们不对这些分类的存活数量感兴趣吗???!!反正我很感兴趣,譬如我想知道当Pclass==1时,存活比例是多少。。当Pclass==3时,存活比例是多少。。。我身为一个Pclass==3的屌丝当然关心自己的生存几率了。。。是时候展示真正的图表了

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.subplot2grid((2,3),(0,0))
data['Survived'].value_counts().plot(kind='bar')
plt.legend()
plt.title('存活人数统计')

plt.subplot2grid((2,3),(0,1))
data['Pclass'].value_counts().plot(kind='bar')
plt.title('乘客等级分布')

plt.subplot2grid((2,3),(0,2))
plt.title('存活比例与年龄的关系')
sns.stripplot('Survived','Age',data=data[['Survived','Age']])

plt.subplot2grid((2,3),(1,0),colspan=2)
data[data['Pclass']==1]['Age'].plot(kind='kde')
data[data['Pclass']==2]['Age'].plot(kind='kde')
data[data['Pclass']==3]['Age'].plot(kind='kde')
plt.xlabel('年龄')
plt.ylabel('密度')
plt.legend((u'头等舱',u'次等舱',u'低等舱'))

plt.subplot2grid((2,3),(1,2))
plt.title('登录港口人口统计')
sns.countplot(x='Embarked',data=data[['Embarked']],palette='muted')
# 计算不同等级的人群获救数量
sns.factorplot(x='Survived',col='Pclass',hue='Pclass',kind='count',data=data,col_wrap=3,legend=True,palette='husl')

最终显示图表如下所示:

统计图表.png

1.通过第一个图表可以看出存活认识要远远低于死亡人数。
2.第二个图表表示像我这样的普通人还是比较多的。
3.船上低等舱和次等舱所有的人的年龄基本都在20-40岁之间,但是可以发现头等舱中的年龄分布在20-60岁之间。同时可以发现40-60岁的上层人要高于低等舱和次等舱。。。这是不是可以表明我们在40-60岁有很大的可能性走上人生巅峰,迎娶白富美。从此步入上层生活。当然啦。。。前提是40岁前好好努力才可以。。。。
4.最后一张图明确的表现出港口S绝对是个热门港口,因为基本一大半的游客都选择从这个港口登陆泰坦尼克号。
  在这部伟大的作品中有这么一段台词:Lady and childern first!(我瞎编的台词),所以我想观察一下这就话是否适用在这个预测中,那就观察一下男女获救比例吧:

sns.factorplot(x='Survived',col='Sex',kind='count',data=data,col_wrap=3,legend=True,palette='Set3')
男女获救比例.png

  很符合常识,不是吗?女性获救比例很高。。。同时可以发现死亡的绝大多数都是男性,这个其实可以想象的到。
  接下来就是见识见识是否人人平等的时候到了。。。。。:

sns.factorplot(x='Survived',col='Pclass',hue='Pclass',kind='count',data=data,col_wrap=3,legend=True,palette='husl')
各阶层存活人数.png

  看清楚了吗???没看清楚的话我再搞一个比例图供大家欣赏一下。。。

各阶层存活比例.png

  是不是很想说一声:what's the fuck? 通过这两张图表我们可以很容易的发现:处于上层的人的的存活比例很明显的更高,。。同时低层的人死亡率明显更高。。。
  接下来我们可以观察一下每个阶层等级存活的人数。

sns.factorplot(x='Pclass', col='Survived', hue='Sex', kind='count', data=data[['Pclass', 'Survived', 'Sex']],palette='Set2')

最终显示如下所示:

数据5.png

  从这张图中可以看出越有权势的人存活几率越大,,,对的,没说错。越有权势的人存活几率越大。
  当然我们可以观察一下不同港口的存活比例:

sns.factorplot(x='Embarked', col='Survived', hue='Sex', kind='count', data=data[['Embarked', 'Survived', 'Sex']], palette='Set1')

结果如下所示:

口获救直方图.png

  从这张图可以看出S港口的存活率和死亡率都比较高,,,我猜想原因可能是因为该港口人数多。。也就是基数大。所以我制作了一张饼状图进行观察。

plt.subplot2grid((1, 2), (0, 0))
plt.title('判断不同港口的未获救比例')
colors = ["#9b59b6", "#3498db", "#2ecc71"]
data[data['Survived'] == 0]['Embarked'].value_counts().plot(kind='pie', autopct='%.2f', colors=colors,
                                                            explode=(0, 0.1, 0))
plt.subplot2grid((1, 2), (0, 1))
plt.title('判断不同港口的获救比例')
data[data['Survived'] == 1]['Embarked'].value_counts().plot(kind='pie', autopct='%1.1f%%', colors=colors,
                                                            explode=(0, 0.1, 0))

最终图表显示:

港口获救比例图.png

  所以此时我对S港口进行格外留意。
现在进行不同港口进出乘客人员总数统计:

 plt.title('不同港口的登陆人数')
 sns.countplot(x='Embarked',data=data[['Embarked']],palette='Set1')

  结果果然和我们的预期一样。S港口的基数很大。

不同港口人数统计.png

数据预处理

  通过观察原始数据可以发现。在Age 这一选项中存在一定量的缺失值。同时 Cabin 这一选项中也存在一定量的缺失值。Age 这一选项毋庸置疑必须要完整的数据,用脚想一下也知道,小孩子肯定是优先被考虑获救的。所以我们需要年龄这一选项进行评估。而cabin这一选项的话,并不确定,所以我选择查看一下有Cabin信息和无Cabin信息的获救比例:

plt.subplot2grid((1,2),(0,0))
plt.title('当Cabin有相关信息时')
data[data['Cabin'].notnull()]['Survived'].value_counts().plot(kind='bar')
plt.subplot2grid((1,2),(0,1))
plt.title('当Cabin没有相关信息时')
data[data['Cabin'].isnull()]['Survived'].value_counts().plot(kind='bar')
plt.show()

最终显示结果如下所示:

Cabin影响因素.png

  通过这张图可以看出。若有Cabin这一选项可以发现获救的概率会大大增加。所以Cabin应该很有必要进行处理一下。但是此处我就舍弃了Name,Ticket,选项。因为我想不出这些有何联系。所以暂时先排除这些因素。
  所以此时就可以进行数据预处理,看过我第一篇文章的朋友应该知道我接下来要做什么。当然是将所有非数值类型的选项全部转换为数值类型。这样我们就需要pandas中的get_dummies()函数。废话不多说直接上代码:

import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from scipy.interpolate import lagrange
from sklearn.preprocessing import Imputer
filename = 'D:/数据/RMS/test.csv'
# filename='D:/数据/RMS/age.xls'
outputfile = 'D:/数据/RMS/trainprocess.csv'
data = pd.read_csv(filename)

age_data = data[['Age', 'Fare', 'Parch', 'SibSp', 'Pclass']]
#     乘客分为已知和未知
age_known = age_data[age_data['Age'].notnull()].as_matrix()
age_unknown = age_data[age_data['Age'].isnull()].as_matrix()
# y为目标年龄
y = age_known[:, 0]
# x为特征属性
x = age_known[:, 1:]
rfr = RandomForestRegressor(n_estimators=1000, n_jobs=-1, random_state=50, max_features="auto")
rfr.fit(x, y)
predict = rfr.predict(age_unknown[:, 1::])
# data.loc[(data['Age'].isnull()), 'Age'] = predict
score = rfr.score(x, y)

  为了证明插值的准确,可以进行测试其准确率:

插值准确率.png

  上述步骤是为了对Age进行补全。

import pandas as pd
import numpy as np
import sklearn.preprocessing as processing
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import svm

filename = 'D:/数据/RMS/train.csv'
outputfile = 'D:/数据/RMS/final1.csv'
train_filename = 'D:/数据/RMS/trainprocess.csv'
data = pd.read_csv(filename)
data_test = pd.read_csv(train_filename)
data_test = data_test[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'Cabin']]
data_test.loc[(data_test['Cabin'].notnull()), 'Cabin'] = 'Yes'
data_test.loc[(data_test['Cabin'].isnull()), 'Cabin'] = 'No'
dummies_Embarked = pd.get_dummies(data_test['Embarked'], prefix='Embarked')
dummies_Sex = pd.get_dummies(data_test['Sex'], prefix='Sex')
dummies_Pclass = pd.get_dummies(data_test['Pclass'], prefix='Pclass')
dummies_Cabin = pd.get_dummies(data_test['Cabin'], prefix='Cabin')
data_test = pd.concat([data_test, dummies_Embarked, dummies_Sex, dummies_Pclass, dummies_Cabin], axis=1)
data_test = data_test.drop(['Embarked', 'Sex', 'Pclass', 'Cabin'], axis=1)

data = data[['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'Cabin']]
data.loc[(data['Cabin'].notnull()), 'Cabin'] = 'Yes'
data.loc[(data['Cabin'].isnull()), 'Cabin'] = 'No'
dummies_Embarked = pd.get_dummies(data['Embarked'], prefix='Embarked')
dummies_Sex = pd.get_dummies(data['Sex'], prefix='Sex')
dummies_Pclass = pd.get_dummies(data['Pclass'], prefix='Pclass')
dummies_Cabin = pd.get_dummies(data['Cabin'], prefix='Cabin')
data = pd.concat([data, dummies_Embarked, dummies_Sex, dummies_Pclass, dummies_Cabin], axis=1)
data = data.drop(['Embarked', 'Sex', 'Pclass', 'Cabin'], axis=1)

  通过这一步骤就可以实现把所有的非数值类型转换为数值类型。但是观察Ages这一选项可以发现Age年龄范围跳跃太大。熟悉数据挖掘预处理的朋友应该都知道,我们在数据预处理时要避免这种情况,还好Sklearn中有这一种处理方法。

scaler = processing.StandardScaler()
age_scale = scaler.fit(data['Age'])
data['Age_scale'] = scaler.fit_transform(data['Age'], age_scale)
fare_scale = scaler.fit(data['Fare'])
data['Fare_scale'] = scaler.fit_transform(data['Fare'], fare_scale)
data = data.drop(['Age', 'Fare'], axis=1)

age_scale = scaler.fit(data_test['Age'])
data_test['Age_scale'] = scaler.fit_transform(data_test['Age'], age_scale)
fare_scale = scaler.fit(data_test['Fare'])
data_test['Fare_scale'] = scaler.fit_transform(data_test['Fare'], fare_scale)
data_test = data_test.drop(['Age', 'Fare'], axis=1)

  这一步骤就可以实现把Age所有的数据都缩放至[-1,1]之间。接下来就是模型运用了。在这方面我首先想到的就是随机森林模型。
同样的和第一篇博文一样。训练模型如下所示:

data_information = data.drop(['Survived'], axis=1).values
data_Survived = data['Survived'].values
X_train, X_test, y_train, y_test = train_test_split(data_information, data_Survived, test_size=0.5)
# 逻辑回归模型测试
lr = LogisticRegression()
lr.fit(X_test, y_test)
# print('LR\'s accuracy rate is:', lr.score(X_train, y_train))
# 随机森林模型测试
rfr = RandomForestClassifier()
rfr.fit(X_test, y_test)
# print('rfr\'s accuracy rate is:', rfr.score(X_train, y_train))
# svm模型测试
svm_model = svm.SVC()
svm_model.fit(X_test, y_test)

精确度如下所示:

模型正确率.png

  接下来就采用随机森林模型进行评估。最终可以得到预测准确率如下所示:

预测.png

  可以看出预测准确率高达85%。
  最终得到结果如下所示:

最终结果.png

  Survived1代表添加Cabin选项,Survived2代表没有添加,corrent代表真实的数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容