泰坦尼克号python数据分析统计服_泰坦尼克号乘客数据分析

本文是优达学城数据分析师 P2 项目的结课报告,主要探寻泰坦尼克号上的生还率和各因素(客舱等级、年龄、性别、上船港口等)的关系。

# Imports

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns

%matplotlib inline

# Read titanic_data.csv

titanic_df = pd.read_csv('titanic_data.csv')

可以观察到,PassengerId\Name\Ticket 等提供不了和生还有关的有效信息,在分析前可以先去掉。

# Test data information

titanic_df.info()

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

# 删掉用处不大的数据

titanic_df = titanic_df.drop(['PassengerId','Name','Ticket'], axis = 1)

titanic_df.info()

RangeIndex: 891 entries, 0 to 890

Data columns (total 9 columns):

Survived 891 non-null int64

Pclass 891 non-null int64

Sex 891 non-null object

Age 714 non-null float64

SibSp 891 non-null int64

Parch 891 non-null int64

Fare 891 non-null float64

Cabin 204 non-null object

Embarked 889 non-null object

dtypes: float64(2), int64(4), object(3)

memory usage: 62.7+ KB

由此可见,Age/Cabin/Embarked 等字段有丢失值,在稍后的分析中应该先处理丢失值问题。

基本情况

#891人当中,共多少人生还?

total_survived_num = titanic_df['Survived'].sum()

total_no_survived_num = 891 - total_survived_num

print "生还者 %d 人,%d 人未生还。" % (total_survived_num,total_no_survived_num)

生还者 342 人,549 人未生还。

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

plt.subplot(121)

sns.countplot(x='Survived', data=titanic_df)

plt.title('Survival count')

plt.subplot(122)

plt.pie([total_no_survived_num, total_survived_num],labels=['No Survived','Survived'],autopct='%1.0f%%')

plt.title('Survival rate')

plt.show()

这891名乘客中,生还和未生还的比例分别为 38% 和 62%。

下面,分别分析 Pclass、Sex、Age、SibSp、Parch、Fare、Cabin 和 Embarked 等与“生还”的关系

Pclass

不同级别客舱的人数和比例

titanic_df[['Pclass','Survived']].groupby(['Pclass']).count() Survived Pclass 1 216 2 184 3 491

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

plt.subplot(121)

sns.countplot(x='Pclass', data=titanic_df)

plt.title('Pclass Count')

plt.subplot(122)

plt.pie(titanic_df[['Pclass','Survived']].groupby(['Pclass']).count(),\

labels=['1','2','3'],autopct='%1.0f%%')

plt.show()

海难发生前,一等舱、二等舱、三等舱的乘客分别为216、184、491人,分别占总人数的 24%, 21%, 55%。

不同级别客舱生还人数和占总生还人数的比例

survived_df = titanic_df[titanic_df[ 'Survived'] == 1 ]

survived_df[['Pclass','Survived']].groupby(['Pclass']).sum() Survived Pclass 1 136 2 87 3 119

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

plt.subplot(121)

sns.countplot(x='Pclass', data=survived_df)

plt.title('Pclass Survived')

plt.ylabel('Survived Count')

plt.subplot(122)

plt.pie(survived_df[['Pclass','Survived']].groupby(['Pclass']).sum(),\

labels=['1','2','3'],autopct='%1.0f%%')

plt.show()

海难发生后,一等舱、二等舱、三等舱的乘客人数变为136、87、119人,分别占总人数的 40%, 25%, 35%。

不同客舱分别的生还和未生还人数及生还率

pclass1 = titanic_df[titanic_df['Pclass'] == 1]

pclass2 = titanic_df[titanic_df['Pclass'] == 2]

pclass3 = titanic_df[titanic_df['Pclass'] == 3]

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

plt.subplot(421)

sns.countplot(x = 'Survived', data = pclass1)

plt.title('Pclass 1')

plt.subplot(422)

plt.pie([pclass1['Survived'][pclass1['Survived'] == 0].count(),pclass1['Survived'][pclass1['Survived'] == 1].count()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.subplot(423)

sns.countplot(x = 'Survived', data = pclass2)

plt.title('Pclass 2')

plt.subplot(424)

plt.pie([pclass2['Survived'][pclass2['Survived'] == 0].count(),pclass2['Survived'][pclass2['Survived'] == 1].count()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.subplot(425)

sns.countplot(x = 'Survived', data = pclass3)

plt.title('Pclass 3')

plt.subplot(426)

plt.pie([pclass3['Survived'][pclass3['Survived'] == 0].count(),pclass3['Survived'][pclass3['Survived'] == 1].count()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.subplot(427)

survived_by_pclass = titanic_df.groupby('Pclass')['Survived'].mean()

survived_by_pclass.plot(kind = 'bar')

plt.show()

一等舱生还率为 63%,二等舱为 47%,三等舱为 24%。可见客舱等级越高,生还率越高。

Sex

船上男女人数及比例?

male_sum = titanic_df['Sex'][titanic_df['Sex'] == 'male'].count()

female_sum = titanic_df['Sex'][titanic_df['Sex'] == 'female'].count()

print male_sum,female_sum

577 314

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

plt.subplot(121)

sns.countplot(x='Sex', data=titanic_df)

plt.subplot(122)

plt.pie([male_sum,female_sum],\

labels=['male', 'female'],autopct='%1.0f%%')

plt.show()

海难发生前,891人中,男性共577人,女性314人,男女比例为 65% 和 35%。

存活的男女数量及男女比例?

survived_male_sum = survived_df['Sex'][survived_df['Sex'] == 'male'].count()

survived_female_sum = survived_df['Sex'][survived_df['Sex'] == 'female'].count()

print survived_male_sum, survived_female_sum

109 233

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

plt.subplot(121)

sns.countplot(x='Sex', data=survived_df)

plt.subplot(122)

plt.pie([survived_male_sum, survived_female_sum],\

labels=['male', 'female'],autopct='%1.0f%%')

plt.show()

# 如何改变countplot中的条形顺序?

海难发生后,男性变为109人,女性变为233人,男女比例变为 32% 和 68%。

男性的生还数量及生还率?

male_df = titanic_df[titanic_df['Sex'] == 'male']

male_df['Survived'][male_df['Survived'] == 1].count()

109

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = male_df)

plt.subplot(122)

plt.pie([male_df['Survived'][male_df['Survived'] == 0].count(),male_df['Survived'][male_df['Survived'] == 1].count()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

男性生还109人,生还率仅为 19%。

女性的生还数量及生还率?

female_df = titanic_df[titanic_df['Sex'] == 'female']

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = female_df)

plt.subplot(122)

plt.pie([female_df['Survived'][female_df['Survived'] == 0].count(),female_df['Survived'][female_df['Survived'] == 1].count()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

女性生还 233 人,生还率为 74%。远远高于男性的 19%。

survived_by_pclass = titanic_df.groupby('Sex')['Survived'].mean()

survived_by_pclass.plot(kind = 'bar')

plt.show()

上图为女性生还率和男性生还率的对比图,女性 74% 的生还率远远高于男性的 19%。

Age

由于 Age 有丢失值,先处理丢失值问题。 Age 的丢失值较多,填充的年龄为年龄平均值的上下一个标准差范围内的随机数。

# 求年龄的平均值,标准差以及丢失值的数量

average_age_titanic = titanic_df["Age"].mean()

std_age_titanic = titanic_df["Age"].std()

count_nan_age_titanic = titanic_df["Age"].isnull().sum()

# 求年龄随机数,范围在 (mean - std, mean + std)

rand_1 = np.random.randint(average_age_titanic - std_age_titanic, average_age_titanic + std_age_titanic, size = count_nan_age_titanic)

# 将随机数填充进 Age 的丢失值中

titanic_df["Age"][np.isnan(titanic_df["Age"])] = rand_1

C:\Users\Gao\Anaconda2\lib\site-packages\ipykernel\__main__.py:10: SettingWithCopyWarning:

A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: [Indexing and Selecting Data](http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy)

年龄分布?

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

plt.subplot(121)

titanic_df['Age'].hist(bins = 70)

plt.xlabel('Age')

plt.ylabel('Num')

plt.subplot(122)

titanic_df.boxplot(column='Age', showfliers=False)

plt.show()

titanic_df['Age'].describe()

count 891.000000

mean 29.550135

std 13.522555

min 0.420000

25% 20.000000

50% 28.000000

75% 37.000000

max 80.000000

Name: Age, dtype: float64

样本的 891 人中,平均年龄约为 30 岁, 标准差 15 岁,最小年龄为 0.42 ,最大年龄 80。

按照年龄,将乘客划分为儿童、少年、成年人和老年人,分析四个群体生还情况

children_df = titanic_df[ titanic_df['Age'] <= 12]

juvenile_df = titanic_df[(titanic_df['Age'] > 12) & (titanic_df['Age'] < 18)]

adults_df = titanic_df[(titanic_df['Age'] >= 18) & (titanic_df['Age'] < 65)]

agedness_df = titanic_df[titanic_df['Age'] >= 65]

# 各年龄段生还人数

children_survived_sum = children_df['Survived'].sum()

juvenile_survived_sum = juvenile_df['Survived'].sum()

adults_survived_sum = adults_df['Survived'].sum()

agedness_survived_sum = agedness_df['Survived'].sum()

print children_survived_sum, juvenile_survived_sum, adults_survived_sum , agedness_survived_sum

40 27 274 1

四个群体生还率对比

# 各年龄段生还率

children_survived_rate = children_df["Survived"].mean()

juvenile_survived_rate = juvenile_df['Survived'].mean()

adults_survived_rate = adults_df['Survived'].mean()

agedness_survived_rate = agedness_df['Survived'].mean()

print children_survived_rate, juvenile_survived_rate, adults_survived_rate, agedness_survived_rate

0.579710144928 0.44262295082 0.365333333333 0.0909090909091

x = ['children', 'juvenile', 'adults', 'agedness']

b = [40, 25, 276, 1]

y = [children_survived_rate, juvenile_survived_rate , adults_survived_rate, agedness_survived_rate]

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

plt.subplot(121)

# 画条

x_pos = list(range(len(x)))

rects = plt.bar(x_pos, b, align='center', alpha=0.5)

# 标签

def autolabel(rects):

for ii,rect in enumerate(rects):

height = rect.get_height()

plt.text(rect.get_x()+rect.get_width()/2., 1.02*height, '%s'% (b[ii]),

ha='center', va='bottom')

autolabel(rects)

# 设置标题

plt.ylabel('Survival num')

plt.xticks(x_pos, x)

plt.subplot(122)

# 画条

x_pos = list(range(len(x)))

rects = plt.bar(x_pos, y, align='center', alpha=0.5)

# 标签

def autolabel(rects):

for ii,rect in enumerate(rects):

height = rect.get_height()

plt.text(rect.get_x()+rect.get_width()/2., 1.02*height, '%s'% (y[ii]),

ha='center', va='bottom')

autolabel(rects)

# 设置标题

plt.ylabel('Survival rate')

plt.xticks(x_pos, x)

plt.show()

在样本中,生还的儿童、少年、成年和老年人数分别为40、 21、 228 和 1人,生还率分别为 58%, 48%, 39% 和 9%。

优达 Reviewer 给出的更简洁划分代码

bins = [0, 12, 18, 65, 100]

titanic_df['Age_group'] = pd.cut(titanic_df['Age'], bins)

by_age = titanic_df.groupby('Age_group')['Survived'].mean()

by_age

Age_group

(0, 12] 0.579710

(12, 18] 0.410526

(18, 65] 0.364395

(65, 100] 0.125000

Name: Survived, dtype: float64

by_age.plot(kind = "bar")

SibSp

# 分为有兄弟姐妹和没有兄弟姐妹两组

sibsp_df = titanic_df[titanic_df['SibSp'] != 0]

no_sibsp_df = titanic_df[titanic_df['SibSp'] == 0]

有兄弟姐妹的乘客的生还人数和生还率

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = sibsp_df )

plt.subplot(122)

plt.pie([sibsp_df['Survived'][sibsp_df['Survived'] == 0].count(),sibsp_df['Survived'].sum()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

print sibsp_df['Survived'][sibsp_df['Survived'] == 0].count(), sibsp_df['Survived'].sum()

151 132

有兄弟姐妹的乘客,生还 132 人,生还率为 47%。

没有兄弟姐妹的乘客的生还人数和生还率

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = no_sibsp_df )

plt.subplot(122)

plt.pie([no_sibsp_df['Survived'][no_sibsp_df['Survived'] == 0].count(),no_sibsp_df['Survived'].sum()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

print no_sibsp_df['Survived'].sum()

210

没有兄弟姐妹的乘客,共生还 210 人,生还率为 35%。

Parch

# 分为有父母子女和没有父母子女两组

parch_df = titanic_df[titanic_df['Parch'] != 0]

no_parch_df = titanic_df[titanic_df['Parch'] == 0]

有父母子女的乘客的生还人数和生还率

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = parch_df )

plt.subplot(122)

plt.pie([parch_df['Survived'][parch_df['Survived'] == 0].count(),parch_df['Survived'].sum()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

print parch_df['Survived'].sum()

109

有父母或子女同船的乘客,生还 109 人,生还率为 51%。

没有父母子女的乘客的生还人数和生还率

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

plt.subplot(121)

sns.countplot(x = 'Survived', data = no_parch_df)

plt.subplot(122)

plt.pie([no_parch_df['Survived'][no_parch_df['Survived'] == 0].count(),no_parch_df['Survived'].sum()],\

labels=['No Survived', 'Survived'],autopct='%1.0f%%')

plt.show()

print no_parch_df['Survived'].sum()

233

没有父母子女同船的乘客,生还 233 人,生还率仅为 34%。

Fare

票价分布

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

titanic_df['Fare'].hist(bins = 70)

titanic_df.boxplot(column='Fare', by='Pclass', showfliers=False)

plt.show()

titanic_df['Fare'].describe()

count 891.000000

mean 32.204208

std 49.693429

min 0.000000

25% 7.910400

50% 14.454200

75% 31.000000

max 512.329200

Name: Fare, dtype: float64

fare_not_survived = titanic_df["Fare"][titanic_df["Survived"] == 0]

fare_survived = titanic_df["Fare"][titanic_df["Survived"] == 1]

avgerage_fare = pd.DataFrame([fare_not_survived.mean(), fare_survived.mean()])

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

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

plt.show()

可见,票价与生还有一定相关性,生还者的平均票价要比未生还的高。

Cabin

丢失值太多,不能用此数据分析出 Cabin 不同对生存率的影响,丢掉。

titanic_df.drop("Cabin",axis=1,inplace=True)

Embarked

Embarked 有两个丢失值,计划用众数填充

titanic_df["Embarked"] = titanic_df["Embarked"].fillna("S")

不同港口上船的乘客是否与生还率有关系?

sns.factorplot('Embarked','Survived', data=titanic_df,size=3,aspect=2)

plt.show()

从 C 上船的生还率最高, Q 次之, S 最低。

各港口上船人数、生还人数及生还率

fig, (axis1,axis2,axis3) = plt.subplots(1,3,figsize=(15,5))

sns.countplot(x='Embarked', data=titanic_df, ax=axis1)

sns.countplot(x='Survived', hue="Embarked", data=titanic_df, order=[1,0], ax=axis2)

embark_perc = titanic_df[["Embarked", "Survived"]].groupby(['Embarked'],as_index=False).mean()

sns.barplot(x='Embarked', y='Survived', data=embark_perc,order=['S','C','Q'],ax=axis3)

plt.show()

S 港口生还人数最多,C 次之, Q 最少。从生还率来看, C 港上船的生还率最高, Q 次之, S 生还率最低。

分析总结

总结分为两个部分,分别是本次数据分析得出的规律和对于分析的限制性进行讨论。

数据分析总结

本次分析主要探寻泰坦尼克号上的生还率和各因素(客舱等级、年龄、性别、上船港口等)的关系。

样本数量为 891,海难发生后,生还者还剩 342 人,生还率为 38%。

泰坦尼克号上有一\二\三等舱三种船舱类型。海难发生前,一等舱有 216 人,二等舱 184 人,三等舱 491 人,分别占总人数的 24%, 21%, 55%。海难发生后,一等舱、二等舱、三等舱的乘客人数变为136、87、119人,分别占总人数的 40%, 25%, 35%。一等舱生还率为 63%,二等舱为 47%,三等舱为 24%。可见客舱等级越高,生还率越高。

891 人中,891人中,男性共577人,女性314人,男女比例为 65% 和 35%。海难发生后,男性变为109人,女性变为233人,男女比例变为 32% 和 68%。男性生还109人,生还率仅为 19%。女性生还 233 人,生还率为 74%,远远高于男性的 19%。可见女性比男性在这次事故中更容易生还,表明“女士优先”的原则在本次事故中得到了发扬。

样本的 891 人中,平均年龄约为 30 岁, 标准差 15 岁,最小年龄为 0.42 ,最大年龄 80。按照儿童(0-12)、少年(12-18)、成人(18-65)、老年人(65及以上)划分为四类,四类人的生还率分别为58%, 48%, 39% 和 9%。可见年龄越大,生还率越低。“尊老爱幼”的原则在本次事故中没有很好体现。

有兄弟姐妹的乘客,生还 132 人,生还率为 47%,而没有兄弟姐妹的乘客,共生还 210 人,生还率为 35%。可见有兄弟姐妹同船的生还率比没有兄弟姐妹同船的生还率要高。

有父母或子女同船的乘客,生还 109 人,生还率为 51%。没有父母子女同船的乘客,生还 233 人,生还率仅为 34%。可见有父母或子女同船的生还率比没有的生还率要高。综合前一条分析,可以得出推论,有家人在船上的比没有家人在船上的生还概率要大。

票价与生还有一定相关性,生还者的平均票价要比未生还的高。

S 港口生还人数最多,C 次之, Q 最少。从生还率来看, C 港上船的生还率最高, Q 次之, S 生还率最低。

分析限制讨论

此数据并非全部乘客的数据,据了解,泰坦尼克号上共有乘客 2224 人,而本数据集共有 891 人。如果该数据集是从 2224 人中随机选出,根据中心极限定理,该样本也足够大,分析结果有代表性;如果不是随机选出,那么分析结果就不可靠了。

可能还有其他因素影响生还情况。比如乘客的国别是否与生还状况有关系?乘客的身高是否与生还状况有关系?乘客是否会游泳是否和生还情况有关系?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,数据分析泰坦尼克号是一个经典的案例,用于入门机器学习和数据科学项目。泰坦尼克号灾难的数据通常包含乘客的基本信息(如年龄、性别、船票等级等)、船上的舱位信息以及是否存活的数据。这个数据集可以从Kaggle(<https://www.kaggle.com/c/titanic>)获取。 使用Python进行泰坦尼克号数据分析的主要步骤包括: 1. **数据加载**:使用pandas库加载csv文件,`pandas.read_csv()`函数可以读取数据。 ```python import pandas as pd data = pd.read_csv('titanic.csv') ``` 2. **数据预处理**:查看数据的前几行,理解数据结构;处理缺失值,可能需要填充、删除或使用平均值、众数等代替;对类别特征(如性别、船票等级)进行编码(one-hot encoding或LabelEncoder)。 3. **探索性数据分析**(EDA):分析各个变量之间的关系,比如生存率与年龄、性别、船票等级的关系。 ```python data.describe() # 描述性统计 data.groupby('Survived').count() # 按生存结果分组计数 ``` 4. **特征工程**:创建新的特征,如家庭大小、是否独自旅行等,并考虑特征的重要性。 5. **建立模型**:选择机器学习算法,如逻辑回归、决策树、随机森林或支持向量机等,用训练数据训练模型预测幸存者。 ```python from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X_train, y_train) ``` 6. **模型评估**:使用测试数据评估模型性能,如准确率、精确率、召回率和F1分数。 7. **优化与调参**:根据评估结果调整模型参数,或尝试其他模型。 8. **报告结果**:将最终模型和关键发现写成报告或可视化展示。 相关问题: 1. 在泰坦尼克号数据分析中,如何处理缺失值? 2. 如何通过特征工程提高模型预测的准确性? 3. 你能解释一下逻辑回归在泰坦尼克号预测中的应用吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值