上篇中我们用常规方法分析了泰坦尼克号事件中乘客的生存情况,最后得出结论,已知某人的资料并不能判断他或她是生存或死亡。
上篇链接:https://blog.csdn.net/wuzlun/article/details/80189766
那么接下来我们用机器学习的方法来分析。
# 再次导入本次用到的工具
# 使用该魔法,不用写plt.show()
%matplotlib inline
import warnings
# 忽略警告提示
warnings.filterwarnings('ignore')
warnings.filterwarnings('ignore', category=DeprecationWarning)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# seaborn作为matplotlib的补充及扩展
import seaborn as sns
二、机器学习
首先,还是对数据的处理。
# 导入下载的训练数据(train.csv)和测试数据集(test.csv)
# 合并数据集,方便同时对两个数据集进行清洗
train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/test.csv')
print('训练数据集',train.shape, '测试数据集',test.shape)
# 合并后再删除干扰列“Survived/PassengerId”
full = train.append( test , ignore_index = True )
full.drop('PassengerId', 1,inplace=True)
print('合并后的数据集', full.shape, '\n\n合并后表格结构如下:')
full.head()
训练数据集 (891, 12) 测试数据集 (418, 11) 合并后的数据集 (1309, 11) 合并后表格结构如下:
Age | Cabin | Embarked | Fare | Name | Parch | Pclass | Sex | SibSp | Survived | Ticket | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 22.0 | NaN | S | 7.2500 | Braund, Mr. Owen Harris | 0 | 3 | male | 1 | 0.0 | A/5 21171 |
1 | 38.0 | C85 | C | 71.2833 | Cumings, Mrs. John Bradley (Florence Briggs Th… | 0 | 1 | female | 1 | 1.0 | PC 17599 |
2 | 26.0 | NaN | S | 7.9250 | Heikkinen, Miss. Laina | 0 | 3 | female | 0 | 1.0 | STON/O2. 3101282 |
3 | 35.0 | C123 | S | 53.1000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 0 | 1 | female | 1 | 1.0 | 113803 |
4 | 35.0 | NaN | S | 8.0500 | Allen, Mr. William Henry | 0 | 3 | male | 0 | 0.0 | 373450 |
#获取数据类型列的描述统计信息
full.describe()
Age | Fare | Parch | Pclass | SibSp | Survived | |
---|---|---|---|---|---|---|
count | 1046.000000 | 1308.000000 | 1309.000000 | 1309.000000 | 1309.000000 | 891.000000 |
mean | 29.881138 | 33.295479 | 0.385027 | 2.294882 | 0.498854 | 0.383838 |
std | 14.413493 | 51.758668 | 0.865560 | 0.837836 | 1.041658 | 0.486592 |
min | 0.170000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 |
25% | 21.000000 | 7.895800 | 0.000000 | 2.000000 | 0.000000 | 0.000000 |
50% | 28.000000 | 14.454200 | 0.000000 | 3.000000 | 0.000000 | 0.000000 |
75% | 39.000000 | 31.275000 | 0.000000 | 3.000000 | 1.000000 | 1.000000 |
max | 80.000000 | 512.329200 | 9.000000 | 3.000000 | 8.000000 | 1.000000 |
# 查看每一列的数据类型,和数据总数
full.info()
我们发现合并后的总表有1309行记录。
其中数据类型列:
1)年龄(Age)里面数据总数是1046条,缺失了1309-1046=263,缺失率263/1309=20%
2)船票价格(Fare)里面数据总数是1308条,缺失了1条数据
3) 生存或死亡(Survived) 这个不用处理
字符串列:
1)登船港口(Embarked)里面数据总数是1307,只缺失了2条数据,缺失比较少
2)船舱号(Cabin)里面数据总数是295,缺失了1309-295=1014,缺失率1014/1309=77.5%,缺失比较大
这为我们下一步数据清洗指明了方向,只有知道哪些数据缺失数据,我们才能有针对性的处理。
数据清理
很多机器学习算法为了训练模型,要求所传入的特征中不能有空值,所以首先要做的就是对缺失值处理。
1、缺失值处理
缺失值处理的原则:
1. 如果是数值类型,用平均值取代。
PS: 上篇分析知道乘客年龄分布很分散,这里用中位数取代。
2. 如果是分类数据,用最常见的类别取代
3. 使用模型预测缺失值,例如:K-NN
(1)、数值类型处理
# 数值类型处理
# 训练表和测试表分开处理
sRow=891 # 原始数据集有891行
# 年龄处理
full[0:sRow]['Age'].fillna(train['Age'].median(), inplace=True)
full[sRow:]['Age'].fillna(test['Age'].median(), inplace=True)
# 船票价格处理
full[0:sRow]['Fare'].fillna(train['Fare'].mean(), inplace=True)
full[sRow:]['Fare'].fillna(test['Fare'].mean(), inplace=True)
full.describe()
Age | Fare | Parch | Pclass | SibSp | Survived | |
---|---|---|---|---|---|---|
count | 1309.000000 | 1309.000000 | 1309.000000 | 1309.000000 | 1309.000000 | 891.000000 |
mean | 29.437487 | 33.297261 | 0.385027 | 2.294882 | 0.498854 | 0.383838 |
std | 12.915275 | 51.738919 | 0.865560 | 0.837836 | 1.041658 | 0.486592 |
min | 0.170000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 |
25% | 22.000000 | 7.895800 | 0.000000 | 2.000000 | 0.000000 | 0.000000 |
50% | 28.000000 | 14.454200 | 0.000000 | 3.000000 | 0.000000 | 0.000000 |
75% | 35.000000 | 31.275000 | 0.000000 | 3.000000 | 1.000000 | 1.000000 |
max | 80.000000 | 512.329200 | 9.000000 | 3.000000 | 8.000000 | 1.000000 |
(2)、字符类型处理
# 查看登船港口(Embarked)人数
print('训练表统计\n',full[0:sRow]['Embarked'].value_counts())
print('测试表统计\n',full[sRow:]['Embarked'].value_counts())
训练表统计
S 644
C 168
Q 77
Name: Embarked, dtype: int64
测试表统计
S 270
C 102
Q 46
Name: Embarked, dtype: int64
# 用S替换登船港口(Embarked)缺失值
full['Embarked'].fillna('s', inplace=True)
# 船舱号(Cabin)缺失数据比较多,缺失值填充为U,表示未知(Uknow)
full['Cabin'].fillna( 'U', inplace=True)
缺失值处理已经完成,我们查看数据处理情况,及完整的表格
# 缺失处理后的表格
full.info()
full.head()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 11 columns):
Age 1309 non-null float64
Cabin 1309 non-null object
Embarked 1309 non-null object
Fare 1309 non-null float64
Name 1309 non-null object
Parch 1309 non-null int64
Pclass 1309 non-null int64
Sex 1309 non-null object
SibSp 1309 non-null int64
Survived 891 non-null float64
Ticket 1309 non-null object
dtypes: float64(3), int64(3), object(5)
memory usage: 112.6+ KB
Age | Cabin | Embarked | Fare | Name | Parch | Pclass | Sex | SibSp | Survived | Ticket | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 22.0 | U | S | 7.2500 | Braund, Mr. Owen Harris | 0 | 3 | male | 1 | 0.0 | A/5 21171 |
1 | 38.0 | C85 | C | 71.2833 | Cumings, Mrs. John Bradley (Florence Briggs Th… | 0 | 1 | female | 1 | 1.0 | PC 17599 |
2 | 26.0 | U | S | 7.9250 | Heikkinen, Miss. Laina | 0 | 3 | female | 0 | 1.0 | STON/O2. 3101282 |
3 | 35.0 | C123 | S | 53.1000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 0 | 1 | female | 1 | 1.0 | 113803 |
4 | 35.0 | U | S | 8.0500 | Allen, Mr. William Henry | 0 | 3 | male | 0 | 0.0 | 373450 |
看上表,通过缺失值处理,现在的表格已经很完整了。但通过上篇的分析,这个表格维度太高,还不能直接分析。所以接下来我们要对表格进行特征工程处理。
2、特征提取
(1)、数据分类
查看数据类型,分为3种数据类型。并对类别数据处理:用数值代替类别,并进行One-hot编码。
1.数值类型:
年龄(Age),船票价格(Fare),同代直系亲属人数(SibSp),不同代直系亲属人数(Parch)
2.时间序列:无
3.分类数据:
1)有直接类别的
乘客性别(Sex):男性male,女性female
登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱
2)字符串类型:可能从这里面提取出特征来,也归到分类数据中
乘客姓名(Name)
客舱号(Cabin)
船票编号(Ticket)
先从简单的开始处理
性别(Sex)
# 将性别的值映射为数值
# 男(male)对应数值1,女(female)对应数值0
sex_mapDict={
'male':1, 'female':0}
# map函数:对Series每个数据应用自定义的函数计算
full['Sex']=full['Sex'].map(sex_mapDict)
full.head()
Age | Cabin | Embarked | Fare | Name | Parch | Pclass | Sex | SibSp | Survived | Ticket | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 22.0 | U | S | 7.2500 | Braund, Mr. Owen Harris | 0 | 3 | 1 | 1 | 0.0 | A/5 21171 |
1 | 38.0 | C85 | C | 71.2833 | Cumings, Mrs. John Bradley (Florence Briggs Th… | 0 | 1 | 0 | 1 | 1.0 | PC 17599 |
2 | 26.0 | U | S | 7.9250 | Heikkinen, Miss. Laina | 0 | 3 | 0 | 0 | 1.0 | STON/O2. 3101282 |
3 | 35.0 | C123 | S | 53.1000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 0 | 1 | 0 | 1 | 1.0 | 113803 |
4 | 35.0 | U | S | 8.0500 | Allen, Mr. William Henry | 0 | 3 | 1 | 0 | 0.0 | 373450 |
登船港口(Embarked)
将维方法:
通过get_dummies进行one-hot编码,产生虚拟变量表,再将此表添加到full表中。
登船港口(Embarked)的值是:
出发地点:S=英国南安普顿Southampton
途径地点1:C=法国 瑟堡市Cherbourg
途径地点2:Q=爱尔兰 昆士敦Queenstown
# 存放提取后的特征
embarkedDf = pd.DataFrame()
embarkedDf = pd.get