泰坦尼克號獲救問題
數據來源:Kaggle數據集 → 共有1309名乘客數據,其中891是已知存活情況(train.csv),剩下418則是需要進行分析預測的(test.csv)
字段意義:
PassengerId: 乘客編號
Survived :存活情況(存活:1 ; 死亡:0)
Pclass : 客艙等級
Name : 乘客姓名
Sex : 性別
Age : 年齡
SibSp : 同乘的兄弟姐妹/配偶數
Parch : 同乘的父母/小孩數
Ticket : 船票編號
Fare : 船票價格
Cabin :客艙號
Embarked : 登船港口
目的:通過已知獲救數據,預測乘客生存情況
研究問題:
1、整體來看,存活比例如何?
要求:
① 讀取已知生存數據train.csv
② 查看已知存活數據中,存活比例如何?
提示:
① 注意過程中篩選掉缺失值之后再分析
② 這里用seaborn制圖輔助研究
2、結合性別和年齡數據,分析幸存下來的人是哪些人?
要求:
① 年齡數據的分布情況
② 男性和女性存活情況
③ 老人和小孩存活情況
3、結合 SibSp、Parch字段,研究親人多少與存活的關系
要求:
① 有無兄弟姐妹/父母子女和存活與否的關系
② 親戚多少與存活與否的關系
4、結合票的費用情況,研究票價和存活與否的關系
要求:
① 票價分布和存活與否的關系
② 比較研究生還者和未生還者的票價情況
5、利用KNN分類模型,對結果進行預測
要求:
① 模型訓練字段:'Survived','Pclass','Sex','Age','Fare','Family_Size'
② 模型預測test.csv樣本數據的生還率
提示:
① 訓練數據集中,性別改為數字表示 → 1代表男性,0代表女性
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import time
# 導入時間模塊
% matplotlib inline
import warnings
warnings.filterwarnings('ignore')
# 不發出警告
1、整體來看,存活比例如何?
要求:
① 讀取已知生存數據train.csv
② 查看已知存活數據中,存活比例如何?
提示:
① 注意過程中篩選掉缺失值之后再分析
② 這里用seaborn制圖輔助研究
# 讀取數據
os.chdir('C:/Users/Hjx/Desktop/項目15泰坦尼克號獲救問題/')
train_data = pd.read_csv('train.csv')
test_data = pd.read_csv('test.csv')
# 已知數據中存活比例
sns.set()
sns.set_style("ticks")
plt.axis('equal')
train_data['Survived'].value_counts().plot.pie(autopct='%1.2f%%')
print('存活比例為38.38%')

2、結合性別和年齡數據,分析幸存下來的人是哪些人?
要求:
① 年齡數據的分布情況
② 男性和女性存活情況
③ 老人和小孩存活情況
# 年齡數據的分布情況
train_data_age = train_data[train_data['Age'].notnull()]
plt.figure(figsize=(12,5))
plt.subplot(121)
train_data_age['Age'].hist(bins=70)
plt.xlabel('Age')
plt.ylabel('Num')
plt.subplot(122)
train_data.boxplot(column='Age',showfliers=False)
print('總體年齡分布: 去掉缺失值后樣本有714,平均年齡約為30歲,標准差14歲,最小年齡0.42,最大年齡80.')
train_data_age['Age'].describe()

# 男性和女性存活情況
train_data[['Sex','Survived']].groupby(['Sex']).mean().plot.bar()
survive_sex = train_data.groupby(['Sex','Survived'])['Survived'].count()
print(survive_sex)
# 女性生存率較高
print('女性存活率為%.2f%%,男性存活率為%.2f%%' %
(survive_sex.loc['female',1]/survive_sex.loc['female'].sum()*100, survive_sex.loc['male',1]/survive_sex.loc['male'].sum()*100))

# 年齡與存活的關系
fig,ax = plt.subplots(1,2, figsize = (18,8))
sns.violinplot("Pclass","Age",hue="Survived",data=train_data_age,split=True,ax=ax[0])
ax[0].set_title('Pclass and Age vs Survived')
ax[0].set_yticks(range(0,110,10))
print('按照不同船艙等級划分 → 船艙等級越高,存活者年齡越大,船艙等級1存活年齡集中在20-40歲,船艙等級2/3中有較多低齡乘客存活')
sns.violinplot("Sex","Age",hue="Survived",data=train_data_age,split=True,ax=ax[1])
ax[1].set_title('Sex and Age vs Survived')
ax[1].set_yticks(range(0,110,10))
print('按照性別划分 → 男性女性存活者年齡主要分布在20-40歲,且均有較多低齡乘客,其中女性存活更多')

# 老人和小孩存活情況
plt.figure(figsize=(18,4))
train_data_age['Age_int'] = train_data_age['Age'].astype(int)
average_age = train_data_age[["Age_int", "Survived"]].groupby(['Age_int'],as_index=False).mean()
sns.barplot(x='Age_int',y='Survived',data=average_age, palette = 'BuPu')
plt.grid(linestyle = '--',alpha = 0.5)
print('災難中,老人和小孩存活率較高')

3、結合 SibSp、Parch字段,研究親人多少與存活的關系
要求:
① 有無兄弟姐妹/父母子女和存活與否的關系
② 親戚多少與存活與否的關系
# 有無兄弟姐妹/父母子女和存活與否的關系
sibsp_df = train_data[train_data['SibSp'] != 0]
no_sibsp_df = train_data[train_data['SibSp'] == 0]
# 篩選出有無兄弟姐妹數據
parch_df = train_data[train_data['Parch'] != 0]
no_parch_df = train_data[train_data['Parch'] == 0]
# 篩選出有無父母子女數據
plt.figure(figsize=(12,3))
plt.subplot(141)
plt.axis('equal')
sibsp_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%',colormap = 'Blues')
plt.xlabel('sibsp')
plt.subplot(142)
plt.axis('equal')
no_sibsp_df['Survived'].value_counts().plot.pie(labels=['No Survived','Survived'],autopct= '%1.1f%%',colormap = 'Blues')
plt.xlabel('no_sibsp')
plt.subplot(143)
plt.axis('equal')
parch_df['Survived'].value_counts().plot.pie(labels=['No Survived', 'Survived'], autopct= '%1.1f%%',colormap = 'Reds')
plt.xlabel('parch')
plt.subplot(144)
plt.axis('equal')
no_parch_df['Survived'].value_counts().plot.pie(labels=['No Survived', 'Survived'], autopct = '%1.1f%%',colormap = 'Reds')
plt.xlabel('no_parch')
print('有兄弟姐妹、父母子女的乘客存活率更大')

# 親戚多少與存活與否的關系
fig, ax=plt.subplots(1,2,figsize=(15,4))
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')
# 查看兄弟姐妹個數與存活率
train_data['Family_Size'] = train_data['Parch'] + train_data['SibSp']+1
train_data[['Family_Size','Survived']].groupby(['Family_Size']).mean().plot.bar(figsize = (15,4))
# 查看父母子女個數與存活率
print('若獨自一人,那么其存活率比較低;但是如果親友太多的話,存活率也會很低')


4、結合票的費用情況,研究票價和存活與否的關系
要求:
① 票價分布和存活與否的關系
② 比較研究生還者和未生還者的票價情況
# 票價分布和存活與否的關系
fig, ax=plt.subplots(1,2,figsize=(15,4))
train_data['Fare'].hist(bins=70, ax = ax[0])
train_data.boxplot(column='Fare', by='Pclass', showfliers=False,ax = ax[1])
# 查看票價分布情況
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,figsize = (15,4),grid = True)
# 查看票價與是否生還的關系
print('生還者的平均票價要大於未生還者的平均票價')


5、利用KNN分類模型,對結果進行預測
要求:
① 模型訓練字段:'Survived','Pclass','Sex','Age','Fare','Family_Size'
② 模型預測test.csv樣本數據的生還率
提示:
① 訓練數據集中,性別改為數字表示 → 1代表男性,0代表女性
# 數據清洗,提取訓練字段
knn_train = train_data[['Survived','Pclass','Sex','Age','Fare','Family_Size']].dropna()
knn_train['Sex'][knn_train['Sex'] == 'male'] = 1
knn_train['Sex'][knn_train['Sex'] == 'female'] = 0
test_data['Family_Size'] = test_data['Parch'] + test_data['SibSp']+1
knn_test = test_data[['Pclass','Sex','Age','Fare','Family_Size']].dropna()
knn_test['Sex'][knn_test['Sex'] == 'male'] = 1
knn_test['Sex'][knn_test['Sex'] == 'female'] = 0
print('清洗后訓練集樣本數據量為%i個' % len(knn_train))
knn_train.head()
print('清洗后測試集樣本數據量為%i個' % len(knn_test))
knn_test.head()
# 模型預測test.csv樣本數據的生還率
from sklearn import neighbors
# 導入KNN分類模塊
knn = neighbors.KNeighborsClassifier()
knn.fit(knn_train[['Pclass','Sex','Age','Fare','Family_Size']], knn_train['Survived'])
# 構建模型
knn_test['predict'] = knn.predict(knn_test)
pre_survived = knn_test[knn_test['predict'] == 1].reset_index()
del pre_survived['index']
# 預測存貨情況
print('finished!')
pre_survived