利用python分析泰坦尼克号数据集
1 引言
刚接触python与大数据不久,这个是学长给出的练习题目。知识积累太少,学习用了不少的时间。尽量详细的写,希望对各位的学习有所帮助。
2 背景
2.1 Kaggle
本次数据集来自于Kaggle。Kaggle是一个数据分析建模的应用竞赛平台。想要了解详细资料的小伙伴请自行百度。
2.2 泰坦尼克号
请到Data页面下载数据集
数据集的各属性在Data页面下有详细介绍。
问题就是以大家熟悉的泰坦尼克号为背景展开的,本次任务的目的就是构建一个可以根据乘客个人信息推测乘客是否生存的数据模型。
3 工具介绍
3.1 Python
我所用的python版本为:Python 3.5.2 。
3.2 Anaconda3
Anaconda 是一个很好用的数据分析工具集,其中的Spyder 与 Jupyter Notebook今后会经常使用,而且使用非常方便。
4 初探数据
相信你已经将数据下载到你的电脑中了,下面我们来将数据经行导入及简单分析。
请先打开Spyder。
4.1 导入训练集数据
import pandas as pd #数据分析
import numpy as np #科学计算
from pandas import Series,DataFrame
data_train = pd.read_csv(r'E:\Data\train.csv') #根据数据位置自行修改
运行后我们会在Spyder窗口右上部看到data_train数据。点击后即可显示数据表格,如下:
4.2 数据简单分析
观察图表我们可以知道,共有891行、12列。这代表本训练集共有891条数据,每条数据有12类信息。包括:
• PassengerId => 乘客ID
• Survived => 获救情况(1为获救,0为未获救)
• Pclass => 乘客等级(1/2/3等舱位)
• Name => 乘客姓名
• Sex => 性别
• Age => 年龄
• SibSp => 堂兄弟/妹个数
• Parch => 父母与小孩个数
• Ticket => 船票信息
• Fare => 票价
• Cabin => 客舱
• Embarked => 登船港口
初步观察,我们会发现一些数据信息值为:nan,这就代表该条数据该类信息缺失。在数据分析中,处理缺失值是一个很重要的步骤。一开始,我们不如统计各类信息的缺失的总体情况,让自己对该数据集有所了解。
我们可以在IPython console框中输入:
data_train.info()
回车运行后,即可出现以下内容:
由此可知,Age(年龄)有714人有记录,Cabin(客舱)有204人有记录,Embarked(登陆港口)有少量缺失。
我们还可以用下列语句进行数据的总体统计:
data_train.describe()
结果如下:
由此我们可知,乘客的平均年龄为29.7,最大年龄为80.0,最小年龄为0.42。获救人数为总体的0.383838,等等。
5 数据图形化分析
进行完总体的初步分析,我们接下来进行数据相关性的分析,为了便于观察,我们利用图表展示。
5.1 乘客各属性
代码:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['font.family']='sans-serif'
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
fig = plt.figure()
fig.set(alpha=0.2) # 设定图表颜色alpha参数
plt.subplot2grid((2,3),(0,0)) # 在一张大图里分列几个小图
data_train.Survived.value_counts().plot(kind='bar')# 柱状图
plt.title(u"获救情况 (1为获救)") # 标题
plt.ylabel(u"人数") # Y轴标签
plt.subplot2grid((2,3),(0,1))
data_train.Pclass.value_counts().plot(kind="bar") # 柱状图显示
plt.ylabel(u"人数")
plt.title(u"乘客等级分布")
plt.subplot2grid((2,3),(0,2))
plt.scatter(data_train.Survived, data_train.Age) #为散点图传入数据
plt.ylabel(u"年龄") # 设定纵坐标名称
plt.grid(b=True, which='major', axis='y')
plt.title(u"按年龄看获救分布 (1为获救)")
plt.subplot2grid((2,3),(1,0), colspan=2)
data_train.Age[data_train.Pclass == 1].plot(kind='kde') # 密度图
data_train.Age[data_train.Pclass == 2].plot(kind='kde')
data_train.Age[data_train.Pclass == 3].plot(kind='kde')
plt.xlabel(u"年龄")# plots an axis lable
plt.ylabel(u"密度")
plt.title(u"各等级的乘客年龄分布")
plt.legend((u'头等舱', u'2等舱',u'3等舱'),loc='best') # sets our legend for our graph.
plt.subplot2grid((2,3),(1,2))
data_train.Embarked.value_counts().plot(kind='bar')
plt.title(u"各登船口岸上船人数")
plt.ylabel(u"人数")
plt.show()
结果如下:
如果Spyder无法显示中文标签,可以将代码放入IPython Notebook中运行。
我们可以从这五张图中形象的了解到乘客的信息,获救人数少于未获救人数(之前我们以得到此结论),三等乘客人数最多,获救人员各年龄段分布(第一列第三张图,左边竖列标签为0,右边竖列标签为1),S口岸上船的乘客最多。等等。
这时,我们就要将乘客各属性与其是否获救联系起来:
获救情况和乘客等级是否有关?
获救情况和乘客性别、年龄是否有关?(毕竟,妇女、小孩和老人优先搭乘救生艇)
登船口岸是否是获救因素呢?(虽然感觉关系不大,但是也要考虑全面)
5.2 各属性与获救情况的关联
各乘客等级的获救情况
Survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts() # 未获救
Survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts() # 获救
df = pd.DataFrame({u'获救':Survived_1,u'未获救':Survived_0})
df.plot(kind = 'bar', stacked = True)
plt.title(u'各乘客等级的获救情况')
plt.xlabel(u'乘客等级')
plt.ylabel(u'人数')
plt.show()
根据图表可以清楚看到第一等级的乘客,获救人数多于未获救人数,而其它两个等级的乘客,获救人数则少于未获救人数。
所以,乘客等级与获救情况有关联。
各性别的获救情况
Survived_m = data_train.Survived[data_train.Sex == 'male'].value_counts()
Survived_f = data_train.Survived[data_train.Sex == 'female'].value_counts()
df = pd.DataFrame({u'男性':Survived_m,u'女性':Survived_f})
df.plot(kind = 'bar', stacked = True)
plt.title(u'按性别看获救情况')
plt.xlabel(u'性别')
plt.ylabel(u'人数')
plt.show()
很明显看出,未获救人员中男性乘客比例较大,获救人员中女性乘客比例较大。
那么,可以确定性别也是获救情况的一个重要因素。
根据舱等级和性别的获救情况(第一、二等级为高级舱,第三等级为低级舱)
fig = plt.figure()
plt.title(u'根据舱等级和性别的获救情况')
ax1 = fig.add_subplot(141) # 将图像分为1行4列,从左到右从上到下的第1块
data_train.Survived[data_train.Sex == 'female'][data_train.Pclass != 3].value_counts().plot(kind = 'bar', label = 'female high class', color = '#FA2479')
ax1.set_xticklabels([u'获救',u'未获救'], rotation = 0) # 根据实际填写标签
ax1.legend([u'女性/高级舱'], loc = 'best')
ax2 = fig.add_subplot(142, sharey = ax1) # 将图像分为1行4列,从左到右从上到下的第2块
data_train.Survived[data_train.Sex == 'female'][data_train.Pclass == 3].value_counts().plot(kind = 'bar', label = 'female low class', color = 'pink')
ax2.set_xticklabels([u"未获救", u"获救"], rotation=0)
plt.legend([u"女性/低级舱"], loc='best')
ax3 = fig.add_subplot(143, sharey = ax1)
data_train.Survived[data_train.Sex == 'male'][data_train.Pclass != 3].value_counts().plot(kind = 'bar', label = 'male high class', color = 'lightblue')
ax3.set_xticklabels([u'未获救',u'获救'], rotation = 0)
plt.legend([u'男性/高级舱'], loc = 'best')
ax4 = fig.add_subplot(144, sharey = ax1)
data_train.Survived[data_train.Sex == 'male'][data_train.Pclass == 3].value_counts().plot(kind = 'bar', label = 'male low class', color = 'steelblue')
ax4.set_xticklabels([u'未获救',u'获救'], rotation = 0)
plt.legend([u'男性/低级舱'], loc = 'bast')
plt.show()
很明显高级舱女性的生还率高于低级舱,低级舱男性的死亡率高于高级舱。在四种情况中,高级舱女性的生还率最高,低级舱男性的死亡率最高。
将与获救情况相关联的两种属性结合后,所得到的结果可以更明显知晓他们的相关性。
各登陆港口乘客的获救情况
fig = plt.figure()
fig.set(alpha = 0.2)
Survived_0 = data_train.Embarked[data_train.Survived == 0].value_counts()
Survived_1 = data_train.Embarked[data_train.Survived == 1].value_counts()
df = pd.DataFrame({u'获救':Survived_1,u'未获救':Survived_0})
df.plot(kind = 'bar', stacked = True)
plt.title(u'各登陆港口乘客的获救情况')
plt.xlabel(u'登陆港口')
plt.ylabel(u'人数')
plt.show()
获救情况与上船口岸的联系,根据上图感觉相关性并不强。C港的获救率高一些。
堂兄弟/妹,孩子/父母有几人,对是否获救的影响
g = data_train.groupby(['SibSp','Survived']) # 数据分组
df = pd.DataFrame(g.count()['PassengerId'])
print (df)
g = data_train.groupby(['Parch','Survived'])
df = pd.DataFrame(g.count()['PassengerId'])
print (df)
堂兄弟/妹,孩子/父母有几人,对是否获救的影响并不明显。
按Cabin有无看获救情况
fig = plt.figure()
fig.set(alpha = 0.2)
Survived_cabin = data_train.Survived[pd.notnull(data_train.Cabin)].value_counts()
Survived_nocabin = data_train.Survived[pd.isnull(data_train.Cabin)].value_counts()
df = pd.DataFrame({u'有':Survived_cabin, u'无':Survived_nocabin}).transpose()
df.plot(kind = 'bar', stacked = True)
plt.title(u'按Cabin有无看获救情况')
plt.xlabel(u'Cabin有无')
plt.ylabel(u'人数')
plt.show()
有客舱信息的获救情况较高一点。但情况复杂,比如生还者上岸后进行信息统计的话,就会影响信息有无对获救情况的关系。
6 简单数据预处理
#我们将测试集导入,再将删除Survived数据的训练集与测验集进行合并,这样便于进行数据处理
data_test = pd.read_csv(r'E:\Data\test.csv') # 导入测验集数据
y = data_train['Survived'] # 将训练集Survived 数据存储在y中
del data_train['Survived'] # 删除训练集Survived数据
sum_id = data_test['PassengerId'] # 存储测试集乘客ID
df = pd.merge(data_train, data_test,how='outer') # 合并无Survived数据的训练集与测验集,how = ‘outer’ 意为并集
#删掉无关因素
df = df.drop(['Name','PassengerId','Ticket','Cabin'],axis=1) # 删除姓名、ID、船票信息、客舱信息,axis=0 删除行,=1 删除列
#缺失数据填充
df['Age'] = df['Age'].fillna(df['Age'].mean()) # 用平均值填充空值
df['Fare'] = df['Fare'].fillna(df['Fare'].mean())
df['Embarked'] = df['Embarked'].fillna( df['Embarked'].value_counts().index[0]) # 用数量最多项填充
#将性别与港口用哑变量表示
dumm = pd.get_dummies(df[['Sex','Embarked']]) # '哑变量'矩阵
df = df.join(dumm)
del df['Sex'] // 删除
del df['Embarked']
#数据降维
df['Age'] = (df['Age']-df['Age'].min()) /(df['Age'].max()-df['Age'].min())
df['Fare'] = (df['Fare']-df['Fare'].min()) /(df['Fare'].max()-df['Fare'].min())
#训练模型
data_train = df[:len(data_train)] # 将合并后的数据分离
data_test = df[len(data_train):]
7 训练并预测
from sklearn.cross_validation import train_test_split
X_train, X_val, y_train,y_val = train_test_split(data_train,y,test_size=0.3, random_state=42) # 以7:3(0.3)将训练集与获救结果随机拆分,随机种子为42
from sklearn.linear_model import LogisticRegression # 引入逻辑回归
LR = LogisticRegression()
LR.fit(X_train, y_train) # 训练数据
print('训练集准确率:\n',LR.score(X_train, y_train)) # 分数
print('验证集准确率:\n',LR.score(X_val, y_val))
#预测测验集
pred= LR.predict(data_test) # pred 为预测结果
pred = pd.DataFrame({'PassengerId':sum_id.values, 'Survived':pred}) # 格式化预测结果
pred.to_csv('pred_LR.csv',index=None) # 导出数据
结果:
最后,也可以将导出的csv文件在Kaggle中进行提交。
8 结语
这是个不太复杂的数据处理题目,预测结果只有两种,但是题目所给因素较多,需要经行无关因素排除,排除后要将数据经行预处理。预处理时,先将缺失值进行补全,再进行降维处理,本题在降维前要将分类变量Sex、Embarked变为哑变量。最后进行train_test_split方法拆分数据,利用逻辑回归训练模型。
附:佳句
来了,爱了,给了她一颗星星,走了。
——云天明《三体》
以上
利用python分析泰坦尼克号数据集的更多相关文章
- 利用Python分析GP服务运行结果的输出路径 & 实现服务输出路径的本地化 分类: Python ArcGIS for desktop ArcGIS for server 2015-08-06 19:49 3人阅读 评论(0) 收藏
最近,一直纠结一个问题:做好的GP模型或者脚本在本地运行,一切正常:发布为GP服务以后时而可以运行成功,而更多的是运行失败,甚至不能知晓运行成功后的结果输出在哪里. 铺天盖地的文档告诉我,如下信息: ...
- 利用python分析nginx日志
最近在学习python,写了个脚本分析nginx日志,练练手.写得比较粗糙,但基本功能可以实现. 脚本功能:查找出当天访问次数前十位的IP,并获取该IP来源,并将分析结果发送邮件到指定邮箱. 实现前两 ...
- 利用Python分析羊车门问题
题目描述:有3扇关闭的门,一扇门后面停着汽车,其余门后是山羊,只有主持人知道每扇门后面是什么.参赛者可以选择一扇门,在开启它之前,主持人会开启另外一扇门,露出门后的山羊,然后允许参赛者更换自己的选择. ...
- 利用 python 分析基金,合理分析数据让赚钱赢在起跑线!
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 白玉无冰 PS:如有需要Python学习资料的小伙伴可以加点击下方 ...
- 利用 Python 分析微信好友性别和位置
今天用到一个非常有意思的库——itchat,它已经完成了 wechat 的个人账号API接口,使爬取个人微信信息更加方便. 下载 爬取微信好友信息 这样就将你所有微信好友的信息都返回了,我们并不需要 ...
- 利用python数据分析与挖掘相关资料总结
小生今年研二,目前主要从事软件工程数据挖掘与分析.之前一直苦于找不到一个从数据预处理.数据分析.数据可视化和软件建模的统一平台.因此,小生辗转反辙学习了java,R语言,python,scala等等. ...
- 利用python进行微信好友分析
欢迎python爱好者加入:学习交流群 667279387 本文主要利用python对个人微信好友进行分析并把结果输出到一个html文档当中,主要用到的python包为itchat,pandas,py ...
- 利用Python进行异常值分析实例代码
利用Python进行异常值分析实例代码 异常值是指样本中的个别值,也称为离群点,其数值明显偏离其余的观测值.常用检测方法3σ原则和箱型图.其中,3σ原则只适用服从正态分布的数据.在3σ原则下,异常值被 ...
- 利用python绘制分析路易斯安那州巴吞鲁日市的人口密度格局
前言 数据来源于王法辉教授的GIS和数量方法,以后有空,我会利用python来实现里面的案例,这里向王法辉教授致敬. 绘制普查人口密度格局 使用属性查询提取区边界 import numpy as np ...
随机推荐
- mysql 免安装版后续操作
在安装好mysql后,软件默认的root用户的密码为空. 1.进入mysql 2.创建数据库 3.创建表格 4.插入数据 5.显示数据库.表信息
- (win32)解决虚拟按键被输入法截获(转)
源博客地址:http://blog.csdn.net/kencaber/article/details/51417871 响应WM_KEYDOWN消息时发现`~快捷键无效,设置断点发现得到的按键消息根 ...
- Ubuntu18.04可执行文件运行提示No such file or directory
参考原文见 https://blog.csdn.net/sun927/article/details/46593129? 最近我也遇到一个类似问题,同一个工具在Ubuntu16.04里面运行是好的,但 ...
- 098-PHP二维数组的元素输出
<?php $stu=array(array(76,87,68), array(65,89,95), array(90,80,66), array(90,95,65)); //定义一个二维数组 ...
- opencv+python+dlib人脸关键点检测、实时检测
安装的是anaconde3.python3.7.3,3.7环境安装dlib太麻烦, 在anaconde3中新建环境python3.6.8, 在3.6环境下安装dlib-19.6.1-cp36-cp36 ...
- HDU 5282:Senior's String
Senior's String Accepts: 30 Submissions: 286 Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- Jetson TX2 安装JetPack3.3教程
Jetson TX2 刷机教程(JetPack3.3版本) 参考网站:https://blog.csdn.net/long19960208/article/details/81538997 版权声明: ...
- #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释
#define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define 定义一个预处理宏#undef ...
- 百度地图API提供Geocoder类进行地址解析
根据地址描述获得坐标百度地图API提供Geocoder类进行地址解析,您可以通过Geocoder.getPoint()方法来将一段地址描述转换为一个坐标. // 创建地址解析器实例var myGeo ...
- C语言-字符类型
C语言-字符类型 char不仅是一种整数,也是一种特殊的类型:字符(character). 常用单引号表示字符的字面量,如'a', '1'. 单引号''也是一个字符,printf和scanf里用的%c ...