Kaggle 泰坦尼克号生存分析(数据概览和缺失值处理部分)

Kaggle 泰坦尼克号生存分析

数据概览

#导入pandas库方便数据读取和预处理,导入os库方便修改工作路径
import os
import pandas as pd
#读取数据
os.chdir("F:/titianic_data")
train = pd.read_csv("raw/train.csv")
test = pd.read_csv("raw/test.csv")
train.shape
(891, 12)
train.head(3)#默认打印前5行
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
#查看有无缺失值
train.isnull().sum()
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
#查看数据维度和类型
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
#描述性统计分析
train.describe()
PassengerIdSurvivedPclassAgeSibSpParchFare
count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
max891.0000001.0000003.00000080.0000008.0000006.000000512.329200
#查看字段的特征数量
train.nunique()
PassengerId    891
Survived         2
Pclass           3
Name           891
Sex              2
Age             88
SibSp            7
Parch            7
Ticket         681
Fare           248
Cabin          147
Embarked         3
dtype: int64

特征类型较少的,可视化分析

(1)定类数据:Embarked,Parch,Pclass,Sex,SibSp

(2)连续型数据:Age,Fare

特征类型较多的,后续处理再进行分析

(1)Name,Ticket,Cabin.

#合并train.csv以及test.csv进行下一步的数据缺失值处理
alldata = pd.concat([train,test],axis=0)

缺失值处理

缺失值的处理方式有多种:

1.用某些集中趋势度量(均值、众数)进行填充

2.用统计模型来预测缺失值,例如决策树、随机森林RF、回归模型

3.删除缺失值

4.保留缺失值

第一个字段:Embarked

#Embarked字段

#观察数据的总体情况
print(train['Embarked'].value_counts())#训练集

print(test['Embarked'].value_counts())#测试集
S    644
C    168
Q     77
Name: Embarked, dtype: int64
S    270
C    102
Q     46
Name: Embarked, dtype: int64

对于Embarked类别型的特征字段,采用频率最高的特征值进行填充

# 忽略警告提示
import warnings
warnings.filterwarnings('ignore')
alldata.Embarked[alldata.Embarked.isnull()] = alldata.Embarked.dropna().mode().values
#还有三种表达方式
#alldata['Embarked'].fillna('S',inplace=True)
#alldata.loc[alldata.Embarked.isnull(),'Embarked']='S'
#alldata['Embarked'] = alldata['Embarked'].fillna(alldata['Embarked'].mode()[0])#通常默认使用第一个众数值
print(alldata['Embarked'].isnull().sum())#查看是否填补成功
0

第二个字段:Cabin

Cabin缺失比较严重,在train数据集中,891个观测值有687条观测值缺失,缺失比例达到 77%

处理这类数据方法之一是用一种特殊的字符来填充缺失值:把缺失值当成一类去对待,认为缺失本身是一种信息,应该保持它的独立性。

但这种方法比较适合类别变量,若要对连续变量使用该方法,需要首先对连续变量离散化,变成和类别变量一样的形式。

客舱位缺失可能代表这些人没有舱位,不妨使用’NO’来填充

alldata['Cabin'] = alldata['Cabin'].fillna('NO')
#其他表达方式
#alldata.loc[alldata.Cabin.isnull(),'Cabin'] = 'NO'
#alldata['Cabin'][alldata.Cabin.isnull()] = 'NO'
print(alldata['Cabin'].isnull().sum())#查看是否填补成功
0

第三个字段:Age

Age这个变量看上去比较重要,下面介绍几种填充方式

(1)采用与头衔相对应的年龄中位数进行填补

#不同方法得到结果有所不同,将数据拷贝一份,以防混淆不同方式得到的结果
title_alldata = alldata.copy()

train数据集中,891个观测值,姓名字段有891个不同的结果,直接拿来使用,没太大意义,但是值得注意的是姓名中有头衔存在,头衔又是身份地位的象征

有可能身份地位越高,越容易存活

import re
#提取头衔
title_alldata['title'] = title_alldata.Name.apply(lambda x:re.search('\w+\.',x).group()).str.replace('.','')
#查看一共有多少种不同的结果
title_alldata.title.unique()
array(['Mr', 'Mrs', 'Miss', 'Master', 'Don', 'Rev', 'Dr', 'Mme', 'Ms',
       'Major', 'Lady', 'Sir', 'Mlle', 'Col', 'Capt', 'Countess',
       'Jonkheer', 'Dona'], dtype=object)

头衔的解读:

Mr:既可以用于已婚男性,也可以用于未婚男性

Mrs:已婚女士

Miss:称呼未婚女士,有时也用于自己不了解的年龄较大的妇女

Master:男童或男婴

Don:大学老师

Rev:牧师

Dr:医生或者博士

Mme:女士

Ms:既可以用于已婚女士也可以用于未婚女士

Major:陆军少校

Lady:公侯伯爵的女儿

Sir:上级长官

Mile:小姐

Col:上校(常用于陆空军)

Capt:船长

Countess:伯爵夫人

Jonkheer:乡绅

头衔太多,最终决定再次分类,查看每个头衔与性别对应的人数

title_sex = pd.crosstab(title_alldata.title,title_alldata.Sex)
title_sex.T
titleCaptColCountessDonDonaDrJonkheerLadyMajorMasterMissMlleMmeMrMrsMsRevSir
Sex
female0010110100260210197200
male140107102610007570081

决定将少数部分归为’Rare’(中文翻译:稀少的)

‘Mlle’、'Ms’用’Miss’代替

将’Mme’用’Mrs’代替

title_alldata['title'] = title_alldata['title'].replace(['Capt','Col','Countess','Don','Dr','Jonkheer','Lady','Major','Rev','Sir'],'Rare')
title_alldata['title'] = title_alldata['title'].replace(['Mlle','Ms'],'Miss')
title_alldata['title'] = title_alldata['title'].replace('Mme','Mrs')
#查看再次分类后,还有多少种不同的结果
title_alldata.title.unique()
array(['Mr', 'Mrs', 'Miss', 'Master', 'Rare', 'Dona'], dtype=object)

查看头衔与幸存的结果

import matplotlib.pyplot as plt
#绘制柱状图
title_survived = pd.crosstab(title_alldata['title'],title_alldata['Survived'])
title_survived.plot(kind='bar')
plt.xticks(np.arange(len(title_survived.index)),title_alldata.index,rotation = 360)
plt.title('Survived Status By Title')
Text(0.5,1,'Survived Status By Title')

不同头衔的生存情况

幸存机会大对应的头衔:

Master,Miss,Mrs

幸存机会小对应的头衔:

Mr,Rare

train数据集中Age缺失值有177个,缺失比例约为20%,缺失数据也不少,而且Age在本次分析中比较重要(副船长当时坚持“小孩和女士先走”),因此缺失值不能删除也不能保留缺失值

方式之一:采用与头衔相对应的年龄中位数进行填补

#求出每个头衔对应的年龄中位数
age_title_median = title_alldata.groupby('title')['Age'].median()
#在当前表设置title为索引
title_alldata.set_index('title',inplace=True)
#在当前表填充缺失值
title_alldata.Age.fillna(age_title_median,inplace=True)
#重置索引
title_alldata.reset_index(inplace=True)
print(title_alldata['Age'].isnull().sum())
0

(2)采用均值进行填补

mean_alldata = alldata.copy()
print(alldata['Age'].isnull().sum())
263
mean_alldata['Age']=mean_alldata['Age'].fillna( mean_alldata['Age'].mean() )
print(mean_alldata['Age'].isnull().sum())
0

参考资料

http://url.cn/52f3eDc

http://www.cnblogs.com/star-zhao/p/9801196.html

https://mp.weixin.qq.com/s/lKEma5gAYvNw4lvEMu621g

https://www.kaggle.com/c/titanic/data

《Python机器学习及实战_从零开始通往KAGGLE之路》

如有违反或冒犯,请联系作者删除,QQ:2168849535。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值