当前位置:   article > 正文

数据分析-项目实战:Kaggle泰坦尼克号(Titanic)沉船幸存者预测(易懂快速上手版)-二元分类-自读_kaggle 沉船估计

kaggle 沉船估计

#前言
Kaggle上的泰坦尼克项目,对于初学机器学习的朋友来说,是一个很好的练手机会,能大概了解整个机器学习的全过程。下面我把自己做这个项目的经验分享一下,希望对想了解机器学习的朋友有所帮助,里面结合很多前辈的智慧,大家可以参考最后的链接。
在文章最开头,我分享一下实际应用项目和竞赛项目的区别,实际应用中,训练的样本相对于实际的数据集总是少的,而它的评分标准,是以实际的数据集的准确度作为参考的,而在竞赛项目中,用于检验结果的测试集相对于训练集是偏少的,但是竞赛的评估结果,是以测试集的匹配度作为依据的,所以有可能会出现实际应用中比较好的模型,但是在竞赛项目中,因为测试集特有的偏差,而导致竞赛的结果并不好,这是很正常的现象。而泰坦尼克号这个项目,就存在这个问题,因为我们最后的标准是那个测试集,所以要达到最好的竞赛结果,需要去迎合那个测试集的分布特征。因为这点差异,所以竞赛项目中要想获得好名次,所要采取的战略是不一样的,泰坦尼克号适合你熟悉整个的机器学习流程,但是对于要想获得好的结果,就需要不断的去调整特征工程,模型和超参数,而且最关键的是要有一个参考点,类似于A/B测试,发现哪些特征适用于这个测试集,不能盲目的尝试。
一般的机器学习分为以下几个步骤:
1、定义问题
2、导入数据
3、理解分析数据
4、清洗转换数据
5、特征工程
6、模型选择及超参数调优
7、模型融合
8、获得问题的答案
在这几个步骤中,有一些操作是会反复出现的,比如说交叉验证,网格搜索,特征选择,管道(算法链),评估指标等等。我会在具体的步骤中解释。
对于一个具体的项目,如何去评估这个项目的优劣很重要,因为每一个项目都是基于真实场景的,我举一个简单的例子,比如说测试癌症的患病率,如果没有患癌症,却被误断出来癌症,对于病人的损失可能是多做几次治疗和所花的费用,这种情况的评估指标就是测准度(precision),也就是预测的结果中,实际存在不正确的例子。另外一种情况,如果一个人患癌了,但是却检测出来没患病,那对于患者的损失可能就是生命了,衡量这种情况的指标,就是测全度(recall)。回到泰坦尼克号的例子,我们判别的指标其实相对比较简单,就是判断预测出来的存活情况是否正确,不存在说,实际是存活了,我们却预测他遇难了,会带来什么实质的影响,这个就叫做精度。当然,精度对于相对平衡(0:1在0.5~2之间)的二分类数据集还是很好的指标,但是对于不平衡的数据集,那么精度就不是很好的度量了,这个时候要用到f-分数。只是给大家开一个头,具体的信息,大家需要到相关统计学或者机器学习的书籍中查找。
对于泰坦尼克号这个项目,我们的指标选择精度就够了。
那么有哪些因素是影响最后的指标的呢,主要是以下四个方面:
1、特征工程的质量
2、样本的数量
3、模型的类型和结合方式
4、模型的超参数
其实就是上面8个步骤的5-7。
下面我就从上面讲的8个步骤,4个要点,来详细演示一下这个项目。
#1、定义问题
这个项目的目的,是预测测试集中人员是否生还,也就是肯定当作二元分类的预测问题,因为是相对平衡的数据集,可以用精度作为衡量指标,而且生还和遇难并没有实质的区别(在数据层面上),所以不考虑准确度和召回率。
简单点说,就是利用训练数据集,训练模型,然后用测试数据集预测模型的精度。
#2、导入数据
该项目的数据源可以在这个链接下载,点这里下载项目数据

##导入需要用到的模块(我写这篇分享,是基于一个脚本写的,所以会把模块一次性全部导入,这样的好处是,所有的过程复现程度很快,实际挖掘过程中,刚开始是探索型的,很多子模块是根据需求加进去的)
#基础模块
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import warnings
warnings.filterwarnings('ignore')


#模型预处理
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder

from sklearn.pipeline import Pipeline

from sklearn.feature_selection import RFECV

from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV


#回归模型模块
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor


#分类模型模块
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LogisticRegressionCV
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
from sklearn.linear_model import PassiveAggressiveClassifier

from sklearn.neighbors import KNeighborsClassifier

from sklearn.svm import SVC, LinearSVC

from sklearn.gaussian_process import GaussianProcessClassifier

from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import BernoulliNB

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier


##导入数据
train_raw=pd.read_csv('train.csv')
test_raw=pd.read_csv('test.csv')
#创建新的整体列表
alldata=pd.concat([train_raw,test_raw],ignore_index=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

#3、理解分析数据
理解分析数据包括两个方面:
1、检查数据是否有缺失,异常,大体的描述统计情况
2、理解数据在实际场景中的含义

##info()和describe()两个方法是对数据大体了解的不错选择,还可以用head(),tail(),或者loc,都是不错的方式

train_raw.info()
<class 'pandas.core.frame.DataFrame'>
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

test_raw.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId    418 non-null int64
Pclass         418 non-null int64
Name           418 non-null object
Sex            418 non-null object
Age            332 non-null float64
SibSp          418 non-null int64
Parch          418 non-null int64
Ticket         418 non-null object
Fare           417 non-null float64
Cabin          91 non-null object
Embarked       418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB

##还可以用isnull直接得到所有的缺失值,这种方式比较容易发现缺失值,方式其实很多啦,大家可以多试试。

train_raw.isnull().sum(0)
Out[23]: 
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

test_raw.isnull().sum(0)
Out[24]: 
PassengerId      0
Pclass           0
Name             0
Sex              0
Age             86
SibSp            0
Parch            0
Ticket           0
Fare             1
Cabin          327
Embarked         0
dtype: int64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

接下来我们来讲讲,各数据的真实场景含义。
PassengerId:客户的编号,可以当作SQL中的键值,没有实际的含义;
Pclass:船舱的等级,一般和票价是成正比的,但是我发现不少船票价格是0英镑的乘客,可能还有一些其他的因素;
Name:乘客的姓名,最基本的就是姓名加一个称呼;
Sex:性别;
Age:乘客的年龄;
SibSp:乘客的非直系亲戚数量;
Parch:乘客的直系亲戚数量(父母和孩子);
Ticket:船票号码,有连号的说明是一起购买的;
Fare:船票的价格;
Cabin:具体的船舱位置;
Embarked:登陆的港口位置。
我们先对这些数据有一个感性的认识,具体的影响,还要在数据的图像化中发现。

#4、清洗转换数据
##4.1、清洗数据
数据清洗的第一步,先是处理缺失值,因为很多模型在缺失值存在的情况下,是无法运算的,而缺失值处理,一般先从缺的最少的开始,因为其他的缺失字段,比如年龄,我们可以考虑用回归的方式预测,比简单的分组平均要更准确。

##清洗转换数据
#Embarked:用众数处理空缺值
alldata.Embarked.fillna(alldata.Embarked.mode()[0],inplace=True)

#Ticket和Fare:计算重票的人数,仔细点会发现,原数据中的票价,其实是和自己同票的人的总票价,所以需要重新整理一下。
alldata['NTickets']=alldata.groupby('Ticket')['Ticket'].transform('count')
alldata['Fare_S']=alldata.Fare/alldata.NTickets
#用平均值填补空缺
alldata.Fare_S.fillna(alldata.Fare_S.mean(),inplace=True)
#Fare_S:根据每个价位段,合理的分配各价位,我选择的分配方式如下:
alldata['Fare_0']=np.where(alldata.Fare_S==0,1,0)
alldata['Fare_0_10']=np.where(((alldata.Fare_S>0)&(alldata.Fare_S<=10)),1,0)
alldata['Fare_10_15']=np.where(((alldata.Fare_S>10)&(alldata.Fare_S<=15)),1,0)
alldata['Fare_15_45']=np.where(((alldata.Fare_S>15)&(alldata.Fare_S<=45)),1,0)
alldata['Fare_45']=np.where(alldata.Fare_S>45,1,0)
#NTickets:查看NTickets和存活率之间的关系,按照1张,2-4张,5张以上分成三组
def NTickets_grouping(x):
    if x==1:
        x='Single'
    elif 1<x<5:
        x='Little_Group'
    else:
        x='Large_Group'
    return x
alldata['NTickets']=alldata.NTickets.map(NTickets_grouping)
#查看下船票数字的长度对于存活率的影响,发现,船票数字为5时,存活率更高,所以将船票数字是否为5作为一个评判的标准
alldata['Ticket_Number_Len']=alldata.Ticket.str.extract('([0-9]+$)')
alldata['Ticket_Number_Len']=alldata.Ticket_Number_Len.str.len()
alldata['Ticket_Num5']=(alldata.Ticket_Number_Len==5).astype(int)

#Name处理
#提取出名字中的title
alldata['Title']=alldata.Name.str.extract('([A-Za-z]+)\.')
mapping_title={'Capt':'Rare','Lady':'Mrs', 'Countess':'Miss', 'Col':'Rare','Don':'Rare', 'Dr':'Rare', 'Major':'Rare', 'Rev':'Rare', 'Sir':'Rare','Jonkheer':
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/142727
推荐阅读
相关标签
  

闽ICP备14008679号