Titanic生存率预测

文章目录

  • 1.提出问题
  • 2.理解数据
    • 2.1采集数据
    • 2.2导入数据
    • 2.3查看数据集信息
  • 3.数据清洗
    • 3.1数据预处理
    • 3.2特征工程
      • 3.2.1数据分类
      • 3.2.2特征选择
  • 4.构建模型
    • 4.1建立训练数据集和测试数据集
    • 4.2选择机器学习算法
    • 4.3训练模型
  • 5.评估模型
  • 6.方案实施
    • 6.1预测结果
    • 6.2结论

1.提出问题

1912年4月15日,一艘号称“永不沉没”的泰坦尼克号邮轮,在首航期间便撞上冰山后沉没。

船上一共2224名乘客和机组人员,但其中只有772人存活下来,生还率只有32%。 这一骇人听闻的悲剧震撼了国际社会,引起社会各界对船舶安全条例的重视。

泰坦尼克号的航行路线:从4月10日12点在英国 南安普顿(Southampton) 出发,晚上7点(19点)船停在法国瑟堡市(Cherbourg),晚上9点(21点)离开法国瑟保市。第2天(1912年4月11日)中午12点半到达爱尔兰昆士敦(Queenstown),下午2点(14点)离开爱尔兰驶向航行的目的,也就是美国的纽约。

航行到第5天(1912年4月14日)晚上11点40不幸与冰山相撞,直到第6天早上(1912年4月15日)2点20全船沉没。

导致这么多人遇难的原因之一就是乘客和船员没有足够的救生艇,虽然在上船前,女主角露丝就像船长提出救生艇不够的问题,但没有得到足够的重视。

虽然能够幸存下来的人存在部分运气因素,但一些人(如:妇女、儿童和上层阶级)比其他人更有可能生存的机会。

所以我们研究的问题是:什么样的人在泰坦尼克号中更容易存活?

2.理解数据

理解数据包括:

2.1 采集数据:根据研究问题,采集数据

2.2 导入数据:将数据导入到Python中的数据结构中。

2.3 查看数据集信息

2.1采集数据

从Kaggle中下载项目数据

2.2导入数据

#忽略警告提示
import warnings
warnings.filterwarnings('ignore')
#导入数据
import numpy as np
import pandas as pd
#导入数据
#导入训练数据集
train = pd.read_csv("./Titanic_train.csv")
#导入测试数据集
test = pd.read_csv("./Titanic_test.csv")
print('训练数据集:',train.shape,'测试训练集:',test.shape)

训练数据集: (891, 12) 测试训练集: (418, 11)

rowNum_train = train.shape[0]
rowNum_test = test.shape[0]
print('kaggle训练数据集行数:',rowNum_train,
     ',kaggle测试数据集行数:',rowNum_test)

kaggle训练数据集行数: 891 ,kaggle测试数据集行数: 418

#对训练数据集和测试数据集进行合并
full = train.append( test , ignore_index = True)
#对训练数据集和测试数据集进行合并
full = train.append( test , ignore_index = True)

print('合并数据集:',full.shape)

合并数据集: (1309, 12)

2.3查看数据集信息

#查看数据集
full.head()

Titanic生存率预测_第1张图片

#获取数据类型的描述统计信息
full.describe()

Titanic生存率预测_第2张图片

#查看每一列的数据总数,统计缺失数据
full.info()

Titanic生存率预测_第3张图片
数据共有1309行,其中:

数字类型中年龄(Age)、船舱号(Cabin)有缺失数据:

  • 年龄(Age)缺失263条数据
  • 船票价格(Fare)缺失1条数据

字符串类型中登船港口(Embarked)、船舱号(Cabin)有缺失数据:

  • 登船港口(Embarked)缺失2条数据
  • 船舱号(Cabin)缺失1014条数据

3.数据清洗

3.1数据预处理

#对缺失值进行处理
#对数据类型,使用平均数填充缺失值
print('处理前:')
full.info()
#年龄(Age)
full['Age'] = full['Age'].fillna(full['Age'].mean())
#船票价格(Fare)
full['Fare'] = full['Fare'].fillna(full['Age'].mean())
print('处理后:')
full.info()

Titanic生存率预测_第4张图片

#检查数据处理是否正常
full.head()

Titanic生存率预测_第5张图片

#查看登船港口(Embarked)数据
full['Embarked'].head()

0 S
1 C
2 S
3 S
4 S
Name: Embarked, dtype: object

#登船港口(Embarked)数据列中只有两个缺失值
#将缺失值填充为出现最频繁的值:S
full['Embarked'] = full['Embarked'].fillna('S')```
#查看船舱号(Cabin)数据
full['Cabin'].head()

0 NaN
1 C85
2 NaN
3 C123
4 NaN
Name: Cabin, dtype: object

#船舱号(Cabin)数据列缺失数据较多,将缺失值填充为U(Uknow)
full['Cabin'] = full['Cabin'].fillna('U')
#查看缺失值处理情况
full.info()

Titanic生存率预测_第6张图片

#查看数据处理是否正常
full.head()

Titanic生存率预测_第7张图片

3.2特征工程

3.2.1数据分类

对不同数据类型采用不同的特征提取方法:

  1. 数值类型:
  • 乘客编号(PassengerId)
  • 年龄(Age)
  • 船票价格(Fare)
  • 同代直系亲属人数(SibSp)
  • 不同代直系亲属人数(Parch)
  1. 分类数据:

1)有直接类别:

  • 乘客性别(Sex):男性male,女性female
  • 登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
  • 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱

2)字符串类型:

  • 乘客姓名(Name)
  • 客舱号(Cabin)
  • 船票编号(Ticket)
full.info()

Titanic生存率预测_第8张图片
对有直接类别的数据列进行分类

  • 乘客性别(Sex):男性male,女性female
  • 登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
  • 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱

性别

#查看性别这一列的数据
full['Sex'].head()

0 male
1 female
2 female
3 female
4 male
Name: Sex, dtype: object

#将性别的值映射为对应的数值:
#男性(male)对应数值为1,女性(female)对应数值为0
#map函数:自定义函数计算
sex_mapDict = {'male':1,
              'female':0}
full['Sex'] = full['Sex'].map(sex_mapDict)
full.head()

Titanic生存率预测_第9张图片
登船港口

#查看登船港口这一列的数据
full['Embarked'].head()

0 S
1 C
2 S
3 S
4 S
Name: Embarked, dtype: object

#使用get_dummies进行one_hot编码
embarkedDf = pd.DataFrame()
embarkedDf = pd.get_dummies(full['Embarked'],prefix='Embarked')
embarkedDf.head()

Titanic生存率预测_第10张图片

#将one_hot编码产生的虚拟变量添加到数据集full中
#并把原有的登船港口(Embarked)数据列删除
full = pd.concat([full,embarkedDf],axis= 1)
full.drop('Embarked',axis = 1,inplace = True)
full.head()

Titanic生存率预测_第11张图片
客舱等级

#使用get_dummies进行one_hot编码
pclassDf = pd.DataFrame()
pclassDf = pd.get_dummies(full['Pclass'],prefix='Pclass')
pclassDf.head()

Titanic生存率预测_第12张图片

#将one_hot编码产生的虚拟变量添加到数据集full中
#并把原有的客舱等级(Pclass)数据列删除
full = pd.concat([full,pclassDf],axis=1)
full.drop('Pclass',axis = 1,inplace = True)
full.head()

Titanic生存率预测_第13张图片
对字符串类型的数据列进行分类

  • 乘客姓名(Name)
  • 客舱号(Cabin)
  • 船票编号(Ticket)

乘客姓名

#查看姓名这一列的数据
full['Name'].head()

Titanic生存率预测_第14张图片

#从姓名中提取出头衔
#定义函数
def getTitle(name):
    str1 = name.split(',')[1]
    str2 = str1.split('.')[0]
    str3 = str2.strip()
    return str3
#对数据列进行自定义函数计算
titleDf = pd.DataFrame()
titleDf['Title'] = full['Name'].map(getTitle)
titleDf.head()

Titanic生存率预测_第15张图片

#姓名头衔与定义头衔的映射
title_mapDict = {
                    "Capt":       "Officer",
                    "Col":        "Officer",
                    "Major":      "Officer",
                    "Jonkheer":   "Royalty",
                    "Don":        "Royalty",
                    "Sir" :       "Royalty",
                    "Dr":         "Officer",
                    "Rev":        "Officer",
                    "the Countess":"Royalty",
                    "Dona":       "Royalty",
                    "Mme":        "Mrs",
                    "Mlle":       "Miss",
                    "Ms":         "Mrs",
                    "Mr" :        "Mr",
                    "Mrs" :       "Mrs",
                    "Miss" :      "Miss",
                    "Master" :    "Master",
                    "Lady" :      "Royalty"
                    }

#对数据列进行自定义函数计算
titleDf ['Title'] = titleDf['Title'].map(title_mapDict)
#进行one_hot编码
titleDf = pd.get_dummies(titleDf['Title'])
titleDf.head()

Titanic生存率预测_第16张图片

#将one_hot编码产生的虚拟变量添加到数据集full中
#并把原有的姓名(Name)数据列删除
full = pd.concat([full,titleDf],axis=1)
full.drop('Name',axis = 1,inplace = True)
full.head()

Titanic生存率预测_第17张图片
客舱号

#查看客舱号这一列的内容
full['Cabin'].head()

Titanic生存率预测_第18张图片

#客舱号映射为首字母
cabinDf = pd.DataFrame()
full['Cabin'] = full['Cabin'].map(lambda c:c[0])
#进行get_dummies编码
cabinDf = pd.get_dummies(full['Cabin'],prefix = 'Cabin')
cabinDf.head()

Titanic生存率预测_第19张图片

#将one_hot编码产生的虚拟变量添加到数据集full中
#并把原有的客舱号(Cabin)数据列删除
full = pd.concat([full,cabinDf],axis=1)
full.drop('Cabin',axis = 1,inplace = True)
full.head()

Titanic生存率预测_第20张图片
家庭人数和家庭类别

#划分家庭类别
#家庭人数=同代直系亲属数+不同代直系亲属数+乘客自己
familyDf = pd.DataFrame()
familyDf['FamilySize'] = full['Parch']+full['SibSp']+1
familyDf['Family_Single'] = familyDf['FamilySize'].map(lambda s:1 if s == 1 else 0)
familyDf['Family_Small'] = familyDf['FamilySize'].map(lambda s:1 if 2 <= s <= 4 else 0)
familyDf['Family_Large'] = familyDf['FamilySize'].map(lambda s:1 if 5 <= s else 0)

familyDf.head()

Titanic生存率预测_第21张图片

#将one_hot编码产生的虚拟变量添加到数据集full中
full = pd.concat([full,familyDf],axis=1)
full.head()

Titanic生存率预测_第22张图片

full.shape

(1309, 33)

3.2.2特征选择

#相关系数矩阵计算各个特征的相关系数
corrDf = full.corr()
corrDf

Titanic生存率预测_第23张图片
Titanic生存率预测_第24张图片

#按降序排列相关系数
corrDf['Survived'].sort_values(ascending = False)

Titanic生存率预测_第25张图片
根据各个特征与生成情况(Survived)的相关系数大小,选择以下特征作为模型的输入:

头衔(titleDf)、客舱等级(pclassDf)、家庭大小(familyDf)、船票价格(Fare)

船舱号(cabinDf)、登船港口(embarkedDf)、性别(Sex)

full_X = pd.concat([titleDf,
                   pclassDf,
                   familyDf,
                   full['Fare'],
                   cabinDf,
                   embarkedDf,
                   full['Sex']
                   ],axis=1)
full_X.head()

Titanic生存率预测_第26张图片
Titanic生存率预测_第27张图片

4.构建模型

运用训练数据和机器学习算法得到机器学习模型,再用测试数据评估模型

4.1建立训练数据集和测试数据集

  • 将Kaggle泰坦尼克号项目给我们的测试数据,记为预测数据集(pred)。也就是我们使用机器学习模型来对其生存情况就那些预测。

  • Kaggle泰坦尼克号项目给的训练数据集,记为原始数据集(记为source)。从这个原始数据集中拆分出训练数据集(记为train:用于模型训练)和测试数据集(记为test:用于模型评估)。

#原始数据集有891行,有890行数据
sourceRow = 891
source_X = full_X.loc[0:sourceRow-1,:]
source_y = full.loc[0:sourceRow-1,'Survived']
pred_X = full_X.loc[sourceRow:,:]

print('原始数据集有多少行:',source_X.shape[0])
print('预测数据集有多少行:',pred_X.shape[0])

原始数据集有多少行: 891
预测数据集有多少行: 418

#从原始数据集中拆分出训练数据集和测试数据集
from sklearn.cross_validation import train_test_split
train_X,test_X,train_y,test_y = train_test_split(source_X,
                                                source_y,
                                                train_size=.8)
print('原始数据集特征:',source_X.shape,
     '训练数据集特征:',train_X.shape,
     '测试数据集特征:',test_X.shape)
print('原始数据集标签:',source_y.shape,
     '训练数据集标签:',train_y.shape,
     '预测数据集标签:',test_y.shape)

原始数据集特征: (891, 27) 训练数据集特征: (712, 27) 测试数据集特征: (179, 27)
原始数据集标签: (891,) 训练数据集标签: (712,) 预测数据集标签: (179,)

source_y.head()

Titanic生存率预测_第28张图片

4.2选择机器学习算法

#逻辑回归
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()

4.3训练模型

model.fit(train_X,train_y)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class=‘ovr’, n_jobs=1,
penalty=‘l2’, random_state=None, solver=‘liblinear’, tol=0.0001,
verbose=0, warm_start=False)

5.评估模型

#得到模型的准确率
model.score(test_X,test_y)

0.82681564245810057

6.方案实施

6.1预测结果

pred_Y = model.predict(pred_X)
pred_Y=pred_Y.astype(int)
#乘客id
passenger_id = full.loc[sourceRow:,'PassengerId']
predDf = pd.DataFrame( 
    { 'PassengerId': passenger_id , 
     'Survived': pred_Y } )
predDf.shape
predDf.head()
#保存结果
predDf.to_csv( 'titanic_pred.csv' , index = False )

6.2结论

泰坦尼克号生存率与很多特征相关,根据已知的数据可知,女性和儿童比男性生存率更高。
未来如果能挖掘出更多特征,采用合适的机器学习算法,可以提高模型的预测率。

参考博客:https://www.cnblogs.com/star-zhao/p/9801196.html..

你可能感兴趣的:(学习笔记)