数据蛙数据分析每周作业

泰坦尼克练习(上)

2019-03-15  本文已影响4人  怀柔小龙虾

这个项目是kaggle上的练手项目,实践方面是参考于csdn上一位大佬的总结,自己对其进行了实现和理解,主要是为了解整个项目操作的流程,并且,由于篇幅过长,所以会分为两部分记录

数据导入

import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

import warnings
warnings.filterwarnings('ignore')
#导入数据
train_data = pd.read_csv('C:/Users/Youngy/Desktop/Titanic_dataset/train.csv')
test_data = pd.read_csv('C:/Users/Youngy/Desktop/Titanic_dataset/test.csv')
#查看前几行的源数据
sns.set_style('whitegrid')#设定图表的主题,其中whitegrid的主题比较简洁
train_data.head()
输出结果
#查看所有的数据信息概况
train_data.info()
test_data.info()
train的输出结果
test的输出结果
#绘制存活的比例
train_data['Survived'].value_counts().plot.pie(autopct = '%1.2f%%')
存活比例

缺失值处理

#众数
train_data.Embarked.dropna().mode().values
#将众数赋值到源数据中
train_data.Embarked[train_data.Embarked.isnull()] = train_data.Embarked.dropna().mode().values
train_data['Cabin'] = train_data.Cabin.fillna('U0')
#采用随机森林来预测
from sklearn.ensemble import RandomForestRegressor

age_df = train_data[['Age','Survived','Fare', 'Parch', 'SibSp', 'Pclass']]#提取数据
age_df_notnull = age_df.loc[(train_data['Age'].notnull())]#训练集
age_df_isnull = age_df.loc[(train_data['Age'].isnull())]#测试集(即需要进行缺失值填充的数据)

X = age_df_notnull.values[:,1:]#训练集的输入X
y = age_df_notnull.values[:,0]#训练集的输出标签y

RFR = RandomForestRegressor(n_estimators=1000,n_jobs=-1)#调用随机森林,进行训练模型
RFR.fit(X,y)

predictAges = RFR.predict(age_df_isnull.values[:,1:])#预测
train_data.loc[train_data['Age'].isnull(),['Age']] = predictAges#将预测的结果赋值到源数据中
#查看缺失值处理后的结果
train_data.info()
缺失值处理后的结果

分析数据关系

分析数据之间的关系,也就是分析特征与特征之间的关系,下面我们依次分析

性别与是否生存的关系

train_data.groupby(['Sex','Survived'])['Survived'].count()
统计结果
train_data[['Sex','Survived']].groupby(['Sex']).mean().plot.bar()
统计结果的柱状图
train_data[['Sex','Survived']].groupby(['Sex']).mean()
         Survived
Sex 
female    0.742038
male      0.188908

基于以上的图表,可以发现这里性别之中,女性的生存率更高,所以有相当大的关系

船舱等级和生存与否的关系

train_data.groupby(['Pclass','Survived'])['Pclass'].count()
统计结果
train_data[['Pclass','Survived']].groupby(['Pclass']).mean().plot.bar()
柱状图
train_data[['Sex','Pclass','Survived']].groupby(['Pclass','Sex']).mean().plot.bar()
柱状图
train_data.groupby(['Sex','Pclass','Survived'])['Survived'].count()
统计结果

由上面的图表可以看出,虽然每种船舱里都体现着女性优先,但最终,生存的情况和船舱等级有密不可分的联系

年龄与存活与否的关系

fig,axes = plt.subplots(1,2,figsize = (10,5))
sns.violinplot(x = 'Pclass' , y = 'Age' , hue = 'Survived' , data = train_data , split = True , ax = axes[0])
axes[0].set_title('Pclass and Age vs Survived')
axes[0].set_yticks(range(0,110,10))

sns.violinplot(x = 'Sex' , y = 'Age' , hue = 'Survived' , data = train_data , split = True , ax = axes[1])
axes[1].set_title('Sex and Age vs Survived')
axes[1].set_yticks(range(0,110,10))

plt.show()
琴图
# 我们先用直方图和箱线图看一下所有人的年龄分布
plt.figure(figsize=(10,5))
plt.subplot(121)
train_data['Age'].hist(bins = 70)
plt.xlabel('Age')
plt.ylabel('Num')

plt.subplot(122)
train_data.boxplot(column='Age',showfliers=False)
plt.show()
直方图和箱线图
# 看一下不同年龄段的生存与否的分布情况
facet= sns.FacetGrid(train_data,hue = 'Survived',aspect=3)#aspect是关于图像大小的参数
facet.map(sns.kdeplot,'Age',shade=True)
facet.set(xlim=(0,train_data['Age'].max()))
facet.add_legend()
# 再观察一下不同年龄下的平均生存率
fig,axes1 = plt.subplots(1,1,figsize=(10,5))
train_data['Age_int'] = train_data['Age'].astype(int)#源数据里的Age是float64,现在转换为int32,并且作为一个新的特征加入源数据

#做一个数据的聚合,将平均值mean的数值作为Survived属性的新数据,然后将Age_int和Survived特征放到新的数据集average_age中
average_age = train_data[['Age_int','Survived']].groupby(['Age_int'],as_index = False).mean()
sns.barplot(x='Age_int',y='Survived',data=average_age)
各个年龄的平均生存率
# 观察年龄统计
train_data['Age'].describe()
输出
bins = [0,12,18,65,100]
train_data['Age_group']= pd.cut(train_data['Age'],bins)
by_age = train_data.groupby('Age_group')['Survived'].mean()
by_age
输出结果
by_age.plot(kind = 'bar')
image.png

乘客姓名与存活与否的关系

train_data['Name'].head(5)
输出
train_data['Title'] = test_data['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)

pd.crosstab(train_data['Title'],train_data['Sex'])
输出
train_data[['Title','Survived']].groupby(['Title']).mean().plot.bar()[图片上传中...(image.png-cfdce2-1552632604968-0)]
image.png
fig,axis1 = plt.subplots(1,1,figsize = (10,5))
train_data['Name_length'] = train_data['Name'].apply(len)
name_length = train_data[['Name_length','Survived']].groupby(['Name_length'],as_index=False).mean()
sns.barplot(x='Name_length',y='Survived',data=name_length)
image.png
在计算名字的长度时,我们用到了pandas.apply函数,这个函数是所有函数中自由度最高的函数

有无兄弟姐妹和存活与否的关系

# 我们先将数据分为有兄弟姐妹和没兄弟姐妹两组
sibsp_df = train_data[train_data['SibSp']!=0]
np_sibsp_df = train_data[train_data['SibSp']==0]

#再对两组数据进行可视化
plt.figure(figsize = (10,5))

plt.subplot(121)
sibsp_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%')
plt.xlabel('sibsp')

plt.subplot(122)
sibsp_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%')
plt.xlabel('no_sibsp')

plt.show()
image.png

有无父母子女和存活与否的关系

parch_df = train_data[train_data['Parch']!=0]
no_parch_df = train_data[train_data['Parch']==0]

plt.figure(figsize=(10,5))

plt.subplot(121)
parch_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%')
plt.xlabel('parch')

plt.subplot(122)
no_parch_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%')
plt.xlabel('no_parch')

plt.show()
image.png

亲友的人数和存活与否的关系 SibSp & Parch

# 先看一下有兄弟姐妹、有父母这两个属性与存活之间的数据统计
fig,ax=plt.subplots(1,2,figsize=(10,5))
train_data[['Parch','Survived']].groupby(['Parch']).mean().plot.bar(ax=ax[0])
ax[0].set_title('Parch and Survived')
train_data[['SibSp','Survived']].groupby(['SibSp']).mean().plot.bar(ax=ax[1])
ax[1].set_title('SibSp and Survived')
image.png
# 再看一下SibSp & Parch在一起后与存活之间的关系
train_data['Family_Size'] = train_data['Parch'] + train_data['SibSp'] + 1
train_data[['Family_Size','Survived']].groupby(['Family_Size']).mean().plot.bar()
image.png

票价分布和存活与否的关系 Fare

fig,axes = plt.subplots(1,2,figsize = (10,5))

train_data['Fare'].hist(bins=70,ax = axes[0])
train_data.boxplot(column='Fare',by='Pclass',showfliers=False,ax = axes[1])

plt.show()
image.png
train_data['Fare'].describe()
image.png
#绘制生存与否与票价均值和方差的关系
fare_not_survived = train_data['Fare'][train_data['Survived']==0]
fare_survived = train_data['Fare'][train_data['Survived']==1]

average_fare= pd.DataFrame([fare_not_survived.mean(),fare_survived.mean()])
std_fare = pd.DataFrame([fare_not_survived.std(),fare_survived.std()])

average_fare.plot(yerr=std_fare,kind='bar',legend=False)

plt.show()
image.png

船舱类型和存活与否的关系 Cabin

#加入一个新的特征‘Has_Cabin’
train_data.loc[train_data.Cabin.isnull(),'Cabin'] = 'U0'
train_data['Has_Cabin'] = train_data['Cabin'].apply(lambda x: 0 if x=='U0' else 1)

train_data[['Has_Cabin','Survived']].groupby(['Has_Cabin']).mean().plot.bar()
image.png
#接着对不同类型的船舱进行分析
train_data['CabinLetter'] = train_data['Cabin'].map(lambda x : re.compile('([a-zA-Z]+)').search(x).group())

train_data['CabinLetter'] = pd.factorize(train_data['CabinLetter'])[0]
train_data[['CabinLetter','Survived']].groupby(['CabinLetter']).mean().plot.bar()
image.png

可见,不同的船舱生存率也有不同,但是差别不大。所以在处理中,我们可以直接将特征删除

港口和存活与否的关系 Embarked

sns.countplot('Embarked',hue = 'Survived',data = train_data)
plt.title('Embarked and Survived')
image.png
sns.factorplot('Embarked','Survived',data=train_data,size=3,aspect=2)
plt.title('Embarked and survived rate')
image.png

其他可能和存活与否有关系的特征


变量转换

定性转换

Dummy Variables

embark_dummies = pd.get_dummies(train_data['Embarked'])
train_data = train_data.join(embark_dummies)
train_data.drop(['Embarked'],axis=1,inplace=True)
embark_dummies = train_data[['S','C','Q']]
embark_dummies.head()
image.png

Factorizing

train_data['Cabin'][train_data.Cabin.isnull()] = 'U0'
train_data['CabinLetter'] = train_data['Cabin'].map(lambda x : re.compile("([a-zA-Z]+)").search(x).group())
train_data['CabinLetter'] = pd.factorize(train_data['CabinLetter'])[0]

train_data['CabinLetter'].head()
image.png

定量(Quantitative)转换

scaling缩放

#对Age进行缩放

from sklearn import preprocessing

assert np.size(train_data['Age']) == 891

scaler = preprocessing.StandardScaler()
train_data['Age_scaled'] = scaler.fit_transform(train_data['Age'].values.reshape(-1,1))

train_data['Age_scaled'].head()
image.png

Binning

train_data['Fare_bin'] = pd.qcut(train_data['Fare'],5)
train_data['Fare_bin'].head()
image.png
pd.qcut是根据这些值的频率来选择箱子的均匀间隔,即每个箱子中含有的数的数量是相同的
pd.cut将根据值本身来选择箱子均匀间隔,即每个箱子的间距都是相同的
#factorize化
train_data['Fare_bin_id'] = pd.factorize(train_data['Fare_bin'])[0]

#dummies化
fare_bin_dummies_df = pd.get_dummies(train_data['Fare_bin']).rename(columns=lambda x: 'Fare_' + str(x))
train_data = pd.concat([train_data, fare_bin_dummies_df], axis=1)
上一篇下一篇

猜你喜欢

热点阅读