当前位置: 首页 > news >正文

05- 泰坦尼克号海难生死预测 (机器学习集成算法) (项目五)

  1. Kaggle:  一个数据建模和数据分析竞赛平台
  2. sns画柱状图sns.barplot(data=train,x='Pclass',y='Survived')
  3. 查看数据分布(survived 和 fare): sns.FacetGrid(train,hue='Survived',aspect=3)
ageFacet=sns.FacetGrid(train,hue='Survived',aspect=3)
ageFacet.map(sns.kdeplot,'Fare',shade=True)
ageFacet.set(xlim=(0,150))
ageFacet.add_legend()
  • Cabin(船舱)缺失值填充:

full['Cabin']=full['Cabin'].fillna('U')  # 利用U(Unknown)填充缺失值
  • 比较各种模型
# 不同机器学习交叉验证结果汇总
cv_results=[]
for classifier in classifiers:cv_results.append(cross_val_score(classifier,experData_X,experData_y,scoring='accuracy',cv=kfold,n_jobs=-1))
# 求出模型得分的均值和标准差
cv_means=[]
cv_std=[]
for cv_result in cv_results:cv_means.append(cv_result.mean())cv_std.append(cv_result.std())
# 汇总数据
cvResDf=pd.DataFrame({'cv_mean':cv_means,'cv_std':cv_std,'algorithm':['SVC','DecisionTreeCla','RandomForestCla','ExtraTreesCla','GradientBoostingCla','KNN','LR','LDA']})
cvResDf
  • 建立模型
GBC = GradientBoostingClassifier()
gb_param_grid = {'loss' : ["deviance"],'n_estimators' : [100,200,300],'learning_rate': [0.1, 0.05, 0.01],'max_depth': [4, 8],'min_samples_leaf': [100,150],'max_features': [0.3, 0.1] }
modelgsGBC = GridSearchCV(GBC,param_grid = gb_param_grid, cv=kfold, scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsGBC.fit(experData_X,experData_y)

在参与本次kaggle项目过程中,参考学习了很多其他竞赛方案的分析思路以及数据处理技巧,如:考虑同组效应、数据对数化处理、多种模型比较结果优劣等等。在项目过程中,主要从以下三个方面对模型改进来提升准确率:

  • 模型选优:分别选取多种模型进行建模,根据模型评分进行初步比较,最终综合考虑多个性能指标来选择合适的预测模型;
  • 特征挖掘与筛选:通过挖掘新的特征并测试选择不同特征时模型预测的准确性,来选择最终训练模型的特征集合;
  • 数据整容:缺失值的填充方法以及“不合群”数据的处理也直接影响模型的最终预测结果。

  • 项目地址: Titanic - Machine Learning from Disaster | Kaggle

1、背景介绍

泰坦尼克号于1909年3月31日在爱尔兰动工建造,1911年5月31日下水,次年4月2日完工试航。她是当时世界上体积最庞大、内部设施最豪华的客运轮船,有“永不沉没”的美誉。然而讽刺的是,泰坦尼克号首航便遭遇厄运:1912年4月10日她从英国南安普顿出发,途径法国瑟堡和爱尔兰昆士敦,驶向美国纽约。在14日晚23时40分左右,泰坦尼克号与一座冰山相撞,导致船体裂缝进水。次日凌晨2时20分左右,泰坦尼克号断为两截后沉入大西洋,其搭载的2224名船员及乘客,在本次海难中逾1500人丧生。

在学习机器学习相关项目时,Titanic生存率预测项目也通常是入门练习的经典案例。Kaggle平台为我们提供了一个竞赛案例“Titanic: Machine Learning from Disaster”,在该案例中,我们将探究什么样的人在此次海难中幸存的几率更高,并通过构建预测模型来预测乘客生存率。

本项目通过数据可视化理解数据,并利用特征工程等方法挖掘更多有价值的特征,然后利用同组效应找出共性较强的群体并对其数据进行修正,在选择模型时分别比较了Gradient Boosting Classifier、Logistic Regression等多种方法,最终利用Gradient Boosting Classifier对乘客的生存率进行预测。

2、加载数据

#导入相关包
import warnings 
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import seaborn as sns
#设置sns样式
sns.set(style='white',context='notebook',palette='muted')
import matplotlib.pyplot as plt
#导入数据
train=pd.read_csv('./train.csv')
test=pd.read_csv('./test.csv')
display(train.head())

PassengerIdSurvivedPclassNameSexAge
乘客编号是否生还用户阶级姓名性别年龄
SibSpParchTicketFareCabinEmbarked
兄弟姐妹配偶数家长孩子数船票号乘客花费船舱

Survived 是否存活(label):

  • 0 - 用户死亡
  • 1- 用户存活

Pclass(用户阶级):

  • 1 - 1st class,高等用户;
  • 2 - 2nd class,中等用户;
  • 3 - 3rd class,低等用户;

SibSp:描述了泰坦尼克号上与乘客同行的兄弟姐妹(Siblings)和配偶(Spouse)数目;

Parch:描述了泰坦尼克号上与乘客同行的家长(Parents)和孩子(Children)数目;

Cabin(船舱):描述用户所住的船舱编号。由两部分组成,仓位号和房间编号,如C88中,C和88分别对应C仓位和88号房间;

Embarked(港口):

  • S:Southampton(南安普顿,英国);

  • C:Cherbourg(瑟堡,法国);

  • Q:Queenstown(昆士敦,英国);

3、数据探索

3.1、查看数据整体情况

#分别查看实验数据集和预测数据集数据
print('训练数据大小:',train.shape)   # 训练数据大小: (891, 12)
print('预测数据大小:',test.shape)    # 预测数据大小: (418, 11)#将训练数据和预测数据合并,这样便于一起处理
full=train.append(test,ignore_index=True)
full.describe()

4

  • 无明显的异常值,几乎所有数据均在正常范围内。
full.info()

  • Age/Cabin/Embarked/Fare四项数据有缺失值,其中Cabin字段缺失近四分之三的数据。

3.2、特征与标签关系

3.2.1、Embarked与Survived关系

sns.barplot(data=train,x='Embarked',y='Survived')

  • 上船港口和生存率关系较大
#计算不同类型Embarked的乘客,其生存率为多少
s = full.groupby('Embarked')['Survived'].value_counts().to_frame()
s2 = s/s.sum(level=0)
pd.merge(s,s2,left_index=True,right_index=True,suffixes=['_num','_rate'])

  •  不同的港口的幸存率,  法国登船乘客生存率较高原因可能与其头等舱乘客比例较高有关,因此继续查看不同登船地点乘客各舱位乘客数量情况。

3.2.2、Parch与Survived关系

sns.barplot(data=train,x='Parch',y='Survived')

  •  当乘客同行的父母及子女数量适中时,生存率较高 , 孩子较多较少, 死亡率较高

3.2.3、SibSp与Survived关系

sns.barplot(data=train,x='SibSp',y='Survived')

  •  当乘客同行的同辈数量适中时生存率较高

3.2.4、Pclass与Survived关系

sns.barplot(data=train,x='Pclass',y='Survived')

  •  乘客客舱等级越高,生存率越高

3.2.5、Sex与Survived关系

sns.barplot(data=train,x='Sex',y='Survived')

  •  女性的生存率远高于男性

3.2.6、Age与Survived关系

#创建坐标轴
ageFacet=sns.FacetGrid(train,hue='Survived',aspect=3)
#作图,选择图形类型
ageFacet.map(sns.kdeplot,'Age',shade=True)
#其他信息:坐标轴范围、标签等
ageFacet.set(xlim=(0,train['Age'].max()))
ageFacet.add_legend()

  •  当乘客年龄段在0-10岁期间时生存率会较高

3.2.7、Fare与Survived关系

#创建坐标轴
ageFacet=sns.FacetGrid(train,hue='Survived',aspect=3)
ageFacet.map(sns.kdeplot,'Fare',shade=True)
ageFacet.set(xlim=(0,150))
ageFacet.add_legend()

  •  当票价低时乘客生存率较低,票价越高生存率一般越高!

查看票价的分布

#查看fare分布
farePlot=sns.distplot(full['Fare'][full['Fare'].notnull()],label='skewness:%.2f'%(full['Fare'].skew()))
farePlot.legend(loc='best')

  •  fare的分布呈左偏的形态,其偏度skewness=4.37较大,说明数据偏移平均值较多,因此我们需要对数据进行对数化处理,防止数据权重分布不均匀。
# 对数化处理fare值
full['Fare']=full['Fare'].map(lambda x: np.log(x) if x > 0 else x)#处理之后票价Fare分布
farePlot=sns.distplot(full['Fare'][full['Fare'].notnull()],label='skewness:%.2f'%(full['Fare'].skew()))
farePlot.legend(loc='best')
plt.savefig('./10-Fare票价分布.png',dpi = 200)

  •  对数化处理fare值

4、数据预处理

数据预处理主要包括以下四个方面内容:

  • 数据清洗(缺失值以及异常值的处理)
  • 特征工程(基于对现有数据特征的理解构造的新特征,以挖掘数据的更多特点)
  • 同组识别(找出具有明显同组效应且违背整体规律的数据,对其进行规整)
  • 筛选子集(对数据进行降维,选择子集)

4.1、数据清洗

  • 对数据的缺失值、异常值进行处理,便于对数据进一步分析。本数据集有四个字段的数据存在缺失情况,即Cabin/Embarked/Fare/Age,未发现数据存在明显异常情况。
  • 其中Age字段缺失较多且为连续型数值,将在进行4.2特征工程章节挖取更多特征后再填充缺失值

4.1.1、Cabin(船舱)缺失值填充

# 对Cabin缺失值进行处理,利用U(Unknown)填充缺失值
full['Cabin']=full['Cabin'].fillna('U')
full['Cabin'].head()

 4.1.2、Embarked(港口)缺失值填充

# 对Embarked缺失值进行处理,查看缺失值情况
display(full[full['Embarked'].isnull()])display(full['Embarked'].value_counts())
# 查看Embarked数据分布情况,可知在英国南安普顿登船可能性最大,因此以此填充缺失值。
full['Embarked']=full['Embarked'].fillna('S')

 4.1.3、Fare缺失值填充(乘客费用)

#查看缺失数据情况,该乘客乘坐3等舱,登船港口为法国,舱位未知
display(full[full['Fare'].isnull()])# 利用3等舱,登船港口为英国,舱位未知旅客的平均票价来填充缺失值。
price = full[(full['Pclass']==3)&(full['Embarked']=='S')&(full['Cabin']=='U')]['Fare'].mean()
full['Fare']=full['Fare'].fillna(price)
full.info()

4.2、特征工程

在理解原数据特征的基础上,特征工程通过对原有数据进行整合处理,得到新特征以反映数据更多信息。

4.2.1、Name中的头衔信息-Title

旅客姓名数据中包含头衔信息,不同头衔也可以反映旅客的身份,而不同身份的旅客其生存率有可能会出现较大差异。因此我们通过Name特征提取旅客头衔Title信息,并分析Title与Survived之间的关系。

# 构造新特征Title
full['Title']=full['Name'].map(lambda x:x.split(',')[1].split('.')[0].strip())
# 查看title数据分布
full['Title'].value_counts()

将相近的Title信息整合在一起:

#将title信息进行整合
TitleDict={}
TitleDict['Mr']='Mr'
TitleDict['Mlle']='Miss'
TitleDict['Miss']='Miss'
TitleDict['Master']='Master'
TitleDict['Jonkheer']='Master'
TitleDict['Mme']='Mrs'
TitleDict['Ms']='Mrs'
TitleDict['Mrs']='Mrs'
TitleDict['Don']='Royalty'
TitleDict['Sir']='Royalty'
TitleDict['the Countess']='Royalty'
TitleDict['Dona']='Royalty'
TitleDict['Lady']='Royalty'
TitleDict['Capt']='Officer'
TitleDict['Col']='Officer'
TitleDict['Major']='Officer'
TitleDict['Dr']='Officer'
TitleDict['Rev']='Officer'full['Title']=full['Title'].map(TitleDict)
full['Title'].value_counts()

可视化观察新特征与标签间关系:

#可视化分析Title与Survived之间关系
sns.barplot(data=full,x='Title',y='Survived')

  •  头衔为'Mr'及'Officer'的乘客,生存率明显较低

4.2.2、FamilyNum及FamilySize信息

将Parch及SibSp字段整合得到一名乘客同行家庭成员总人数FamilyNum的字段,再根据家庭成员具体人数的多少得到家庭规模FamilySize这个新字段。

  • SibSp:描述了泰坦尼克号上与乘客同行的兄弟姐妹(Siblings)和配偶(Spouse)数目;

  • Parch:描述了泰坦尼克号上与乘客同行的家长(Parents)和孩子(Children)数目;

full['familyNum']=full['Parch']+full['SibSp'] + 1
#查看familyNum与Survived
sns.barplot(data=full,x='familyNum',y='Survived')

  • 家庭成员人数在2-4人时,乘客的生存率较高,当没有家庭成员同行或家庭成员人数过多时生存率较低。
# 我们按照家庭成员人数多少,将家庭规模分为小(0)、中(1)、大(2)三类:
def familysize(familyNum):if familyNum== 0 :return 0elif (familyNum>=1)&(familyNum<=3):return 1else:return 2full['familySize']=full['familyNum'].map(familysize)
full['familySize'].value_counts()

查看 familySize 与 Survived 关系:

# 查看familySize与Survived
sns.barplot(data=full,x='familySize',y='Survived')

  •  当家庭规模适中时,乘客的生存率更高

4.2.3、Cabin客舱类型信息-Deck

Cabin字段的首字母代表客舱的类型,也反映不同乘客群体的特点,可能也与乘客的生存率相关。泰坦尼克号撞击冰山时,也跟客舱位置有一定关系

# 提取Cabin字段首字母
full['Deck']=full['Cabin'].map(lambda x:x[0])
# 查看不同Deck类型乘客的生存率
sns.barplot(data=full,x='Deck',y='Survived')
plt.savefig('./14-Deck与Survived关系.png',dpi = 200)

  • 当乘客的客舱类型为B/D/E时,生存率较高;当客舱类型为U/T时,生存率较低。

4.2.4、共票号乘客数量TickCom及TickGroup

同一票号的乘客数量可能不同,可能也与乘客生存率有关系

#提取各票号的乘客数量
TickCountDict=full['Ticket'].value_counts()
TickCountDict.head()
'''
CA. 2343    11
1601         8
CA 2144      8
347077       7
PC 17608     7
Name: Ticket, dtype: int64
'''
#将同票号乘客数量数据并入数据集中
full['TickCom']=full['Ticket'].map(TickCountDict)
full['TickCom'].head()
#查看TickCom与Survived之间关系
sns.barplot(data=full,x='TickCom',y='Survived')

  •  当TickCom大小适中时,乘客生存率较高。
# 按照TickCom大小,将TickGroup分为三类。
def TickCountGroup(num):if (num>=2)&(num<=4):return 0elif (num==1)|((num>=5)&(num<=8)):return 1else :return 2
# 得到各位乘客TickGroup的类别
full['TickGroup']=full['TickCom'].map(TickCountGroup)
# 查看TickGroup与Survived之间关系
sns.barplot(data=full,x='TickGroup',y='Survived')

4.2.5、Age缺失值填充-构建随机森林模型预测缺失的数据

  • 查看AgeParch、Pclass、Sex、SibSp、Title、familyNum、familySize、Deck、TickCom、TickGroup等变量的相关系数大小,筛选出相关性较高的变量构建预测模型。
full[full['Age'].notnull()].corr()
# 筛选:Pclass、SibSp、Parch、Fare、familyNum、familySize、TickCom

1、筛选数据

#筛选数据集
agePre=full[['Age','Parch','Pclass','SibSp','familyNum','TickCom','Title']]
# 进行one-hot编码
agePre=pd.get_dummies(agePre)
ageCorrDf=agePre.corr()
ageCorrDf['Age'].sort_values()

2、拆分数据并建立模型(利用随机森林构建模型)

#拆分实验集和预测集
ageKnown=agePre[agePre['Age'].notnull()]
ageUnKnown=agePre[agePre['Age'].isnull()]#生成实验数据的特征和标签
ageKnown_X=ageKnown.drop(['Age'],axis=1)
ageKnown_y=ageKnown['Age']#生成预测数据的特征
ageUnKnown_X=ageUnKnown.drop(['Age'],axis=1)#利用随机森林构建模型
from sklearn.ensemble import RandomForestRegressor
rfr=RandomForestRegressor(random_state=None,n_estimators=500,n_jobs=-1)
rfr.fit(ageKnown_X,ageKnown_y)

3、利用模型进行预测并填入原数据集中

#模型得分
score = rfr.score(ageKnown_X,ageKnown_y)
print('模型预测年龄得分是:',score)
#预测年龄
ageUnKnown_predict = rfr.predict(ageUnKnown_X)
#填充预测数据
full.loc[full['Age'].isnull(),['Age']]=ageUnKnown_predict
full.info()  #此时已无缺失值

4.3、同组识别

虽然通过分析数据已有特征与标签的关系可以构建有效的预测模型,但是部分具有明显共同特征的用户可能与整体模型逻辑并不一致。如果将这部分具有同组效应的用户识别出来并对其数据加以修正,就可以有效提高模型的准确率。在Titanic案例中,我们主要探究相同姓氏的乘客是否存在明显的同组效应。

提取两部分数据,分别查看其“姓氏”是否存在同组效应(因为性别和年龄与乘客生存率关系最为密切,因此用这两个特征作为分类条件):

4.3.1 同姓氏的男性

12岁以上男性:找出男性中同姓氏均获救的部分; 女性以及年龄在12岁以下儿童:找出女性及儿童中同姓氏均遇难的部分。

#提取乘客的姓氏及相应的乘客数
full['Surname']=full['Name'].map(lambda x:x.split(',')[0].strip())
SurNameDict=full['Surname'].value_counts()
full['SurnameNum']=full['Surname'].map(SurNameDict)# 12岁以上男性:找出男性中同姓氏均获救的部分
MaleDf=full[(full['Sex']=='male')&(full['Age']>12)&(full['familyNum']>=2)]#分析男性同组效应
MSurNamDf=MaleDf['Survived'].groupby(MaleDf['Surname']).mean()
MSurNamDf.head()
MSurNamDf.value_counts()
'''
0.0    89
1.0    19
0.5     3'''
  • 大多数同姓氏的男性存在“同生共死”的特点,因此利用该同组效应,我们对生存率为1的姓氏里的男性数据进行修正,提升其预测为“可以幸存”的概率。

4.3.2 女性及儿童同组效应分析

#提取乘客的姓氏及相应的乘客数
full['Surname']=full['Name'].map(lambda x:x.split(',')[0].strip())
SurNameDict=full['Surname'].value_counts()
full['SurnameNum']=full['Surname'].map(SurNameDict)#将数据分为两组
FemChildDf=full[((full['Sex']=='female')|(full['Age']<=12))&(full['familyNum']>=2)]FCSurNamDf=FemChildDf['Survived'].groupby(FemChildDf['Surname']).mean()
FCSurNamDf.head()
FCSurNamDf.value_counts()
'''
1.000000    115
0.000000     27
0.750000      2
0.333333      1
0.142857      1'''

与男性组特征相似,女性及儿童也存在明显的“同生共死”的特点,因此利用同组效应,对生存率为0的姓氏里的女性及儿童数据进行修正,提升其预测为“并未幸存”的概率。

4.3.3 数据集中修改

对数据集中这些姓氏的两组数据数据分别进行修正:

男性数据修正为:1、性别改为女;2、年龄改为5;

女性及儿童数据修正为:1、性别改为男;2、年龄改为60。

#获得生存率为1的姓氏
MSurNamDict=MSurNamDf[MSurNamDf.values==1].index
MSurNamDict
#获得生存率为0的姓氏
FCSurNamDict=FCSurNamDf[FCSurNamDf.values==0].index
FCSurNamDict
#对数据集中这些姓氏的男性数据进行修正:1、性别改为女;2、年龄改为5。
full.loc[(full['Survived'].isnull())&(full['Surname'].isin(
MSurNamDict))&(full['Sex']=='male'),'Sex']='female'
full.loc[(full['Survived'].isnull())&(full['Surname'].isin(
MSurNamDict))&(full['Sex']=='male'),'Age']=5#对数据集中这些姓氏的女性及儿童的数据进行修正:1、性别改为男;2、年龄改为60。
full.loc[(full['Survived'].isnull())&(full['Surname'].isin(FCSurNamDict))&((full['Sex']=='female')|(full['Age']<=12)),'Sex']='male'
full.loc[(full['Survived'].isnull())&(full['Surname'].isin(FCSurNamDict))&((full['Sex']=='female')|(full['Age']<=12)),'Age']=60

4.4、筛选子集

在对数据进行分析处理的过程中,数据的维度更高了,为提升数据有效性需要对数据进行降维处理。通过找出与乘客生存率“Survived”相关性更高的特征,剔除重复的且相关性较低的特征,从而实现数据降维。

#人工筛选
fullSel=full.drop(['Cabin','Name','Ticket','PassengerId','Surname','SurnameNum'],axis=1)
#查看各特征与标签的相关性
corrDf=pd.DataFrame()
corrDf=fullSel.corr()
corrDf['Survived'].sort_values(ascending=True)
  • 通过热力图,查看Survived与其他特征间相关性大小
#热力图,查看Survived与其他特征间相关性大小
plt.figure(figsize=(8,8))
sns.heatmap(fullSel[['Survived','Age','Embarked','Fare','Parch','Pclass','Sex','SibSp','Title','familyNum','familySize','Deck','TickCom','TickGroup']].corr(),cmap='BrBG',annot=True,linewidths=.5)
_ = plt.xticks(rotation=45)

# 删除相关性系数低的属性
fullSel=fullSel.drop(['Age','Parch','SibSp','familyNum','TickCom'],axis=1)
#one-hot编码
fullSel=pd.get_dummies(fullSel)
fullSel.head()

5、构建模型

本项目比较了SCV/Decision Tree/Gradient Boosting/LDA/KNN/Logistic Regression等多种机器学习算法的结果,并对表现较好的算法做进一步的对比,最终选择Gradient Boosting对乘客生存率进行预测。

5.1、模型选择

5.1.1、建立模型

主要考虑使用以下常用的机器学习算法进行比较:

  • SCV
  • Decision Tree
  • Extra Trees
  • Gradient Boosting
  • Random Forest
  • KNN
  • Logistic Regression
  • Linear Discriminant Analysis
#拆分实验数据与预测数据
experData=fullSel[fullSel['Survived'].notnull()]
preData=fullSel[fullSel['Survived'].isnull()]experData_X=experData.drop('Survived',axis=1)
experData_y=experData['Survived']
preData_X=preData.drop('Survived',axis=1)#导入机器学习算法库
from sklearn.ensemble import RandomForestClassifier,GradientBoostingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold#设置kfold,交叉采样法拆分数据集
kfold=StratifiedKFold(n_splits=10)#汇总不同模型算法
classifiers=[]
classifiers.append(SVC())
classifiers.append(DecisionTreeClassifier())
classifiers.append(RandomForestClassifier())
classifiers.append(ExtraTreesClassifier())
classifiers.append(GradientBoostingClassifier())
classifiers.append(KNeighborsClassifier())
classifiers.append(LogisticRegression())
classifiers.append(LinearDiscriminantAnalysis())

5.1.2、比较各种算法结果,进一步选择模型

#不同机器学习交叉验证结果汇总
cv_results=[]
for classifier in classifiers:cv_results.append(cross_val_score(classifier,experData_X,experData_y,scoring='accuracy',cv=kfold,n_jobs=-1))#求出模型得分的均值和标准差
cv_means=[]
cv_std=[]
for cv_result in cv_results:cv_means.append(cv_result.mean())cv_std.append(cv_result.std())#汇总数据
cvResDf=pd.DataFrame({'cv_mean':cv_means,'cv_std':cv_std,'algorithm':['SVC','DecisionTreeCla','RandomForestCla','ExtraTreesCla','GradientBoostingCla','KNN','LR','LDA']})cvResDf
'''cv_mean	cv_std	algorithm
0	0.835019	0.035179	SVC
1	0.810337	0.028974	DecisionTreeCla
2	0.821548	0.034612	RandomForestCla
3	0.815955	0.028821	ExtraTreesCla
4	0.828302	0.038513	GradientBoostingCla
5	0.823808	0.040767	KNN
6	0.830549	0.038304	LR
7	0.828327	0.039658	LDA'''

可视化查看不同算法的表现情况

bar = sns.barplot(data=cvResDf.sort_values(by='cv_mean',ascending=False),x='cv_mean',y='algorithm',**{'xerr':cv_std})
bar.set(xlim = (0.7,0.9))

KNN、SVC、LR、LDA以及GradientBoostingCla 模型在该问题中表现较好。

5.1.3、模型调优

综合以上模型表现,考虑选择SVC、LDA、GradientBoostingCla、LR四种模型进一步对比。分别建立对应模型,并进行模型调优。

#GradientBoostingClassifier模型
GBC = GradientBoostingClassifier()
gb_param_grid = {'loss' : ["deviance"],'n_estimators' : [100,200,300],'learning_rate': [0.1, 0.05, 0.01],'max_depth': [4, 8],'min_samples_leaf': [100,150],'max_features': [0.3, 0.1] }
modelgsGBC = GridSearchCV(GBC,param_grid = gb_param_grid, cv=kfold, scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsGBC.fit(experData_X,experData_y)#LogisticRegression模型
modelLR=LogisticRegression()
LR_param_grid = {'C' : [1,2,3],'penalty':['l1','l2']}
modelgsLR = GridSearchCV(modelLR,param_grid = LR_param_grid, cv=kfold, scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsLR.fit(experData_X,experData_y)#SVC模型
svc = SVC()
gb_param_grid = {'C' : [0.1,0.5,1,2,3,5,10],'kernel':['rbf','poly','sigmoid']}
modelgsSVC = GridSearchCV(svc,param_grid = gb_param_grid, cv=kfold, scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsSVC.fit(experData_X,experData_y)#LDA模型
lda = LinearDiscriminantAnalysis()
gb_param_grid = {'solver' : ['svd', 'lsqr', 'eigen'],'tol':[0.000001,0.00001,0.0001,0.001,0.01]}
modelgsLDA = GridSearchCV(lda,param_grid = gb_param_grid, cv=kfold, scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsLDA.fit(experData_X,experData_y)

5.2、模型评估

5.2.1、查看模型准确率

#modelgsGBC模型
print('modelgsGBC模型得分为:%.3f'%modelgsGBC.best_score_)
#modelgsLR模型
print('modelgsLR模型得分为:%.3f'%modelgsLR.best_score_)
#modelgsSVC模型
print('modelgsSVC模型得分为:%.3f'%modelgsSVC.best_score_)
#modelgsLDA模型
print('modelgsLDA模型得分为:%.3f'%modelgsLDA.best_score_)
'''
modelgsGBC模型得分为:0.840
modelgsLR模型得分为:0.823
modelgsSVC模型得分为:0.832
modelgsLDA模型得分为:0.819'''

GBC模型得分(即模型准确性)更高,继续比较其他指标的差异。

5.2.2、查看模型ROC曲线

#查看模型ROC曲线
#求出测试数据模型的预测值
modelgsGBCtestpre_y=modelgsGBC.predict(experData_X).astype(int)
#画图
from sklearn.metrics import roc_curve, auc  ###计算roc和auc
# Compute ROC curve and ROC area for each class
#计算真正率和假正率
fpr,tpr,threshold = roc_curve(experData_y, modelgsGBCtestpre_y) 
roc_auc = auc(fpr,tpr) ###计算auc的值plt.figure()
lw = 2
plt.figure(figsize=(10,10))
# 假正率为横坐标,真正率为纵坐标做曲线
plt.plot(fpr, tpr, color='r',lw=lw, label='ROC curve (area = %0.3f)' % roc_auc) 
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Titanic GradientBoostingClassifier Model')
plt.legend(loc="lower right")
plt.show()

#查看模型ROC曲线
#求出测试数据模型的预测值
modelgsLRtestpre_y=modelgsLR.predict(experData_X).astype(int)
#画图
from sklearn.metrics import roc_curve, auc  ###计算roc和auc
# Compute ROC curve and ROC area for each class
# 计算真正率和假正率
fpr,tpr,threshold = roc_curve(experData_y, modelgsLRtestpre_y) 
roc_auc = auc(fpr,tpr) ###计算auc的值plt.figure()
lw = 2
plt.figure(figsize=(10,10))
# 假正率为横坐标,真正率为纵坐标做曲线
plt.plot(fpr, tpr, color='r',lw=lw, label='ROC curve (area = %0.3f)' % roc_auc) 
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Titanic LogisticRegression Model')
plt.legend(loc="lower right")
plt.show()

#查看模型ROC曲线
#求出测试数据模型的预测值
modelgsSVCtestpre_y=modelgsSVC.predict(experData_X).astype(int)
#画图
from sklearn.metrics import roc_curve, auc  ###计算roc和auc
# Compute ROC curve and ROC area for each class
# 计算真正率和假正率
fpr,tpr,threshold = roc_curve(experData_y, modelgsSVCtestpre_y) 
roc_auc = auc(fpr,tpr) ###计算auc的值plt.figure()
lw = 2
plt.figure(figsize=(10,10))
# 假正率为横坐标,真正率为纵坐标做曲线
plt.plot(fpr, tpr, color='r',lw=lw, label='ROC curve (area = %0.3f)' % roc_auc) 
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Titanic SVC Model')
plt.legend(loc="lower right")
plt.show()

  • GBDT、LR和SVC模型ROC曲线均左上偏,AUC分别为0.838和0.825、0.818,即GradientBoostingClassifier模型效果较好。

5.2.3、查看混淆矩阵

#混淆矩阵
from sklearn.metrics import confusion_matrix
print('GradientBoostingClassifier模型混淆矩阵为\n',confusion_matrix(experData_y,modelgsGBCtestpre_y))
print('LogisticRegression模型混淆矩阵为\n',confusion_matrix(experData_y,modelgsLRtestpre_y))
print('SVC模型混淆矩阵为\n',confusion_matrix(experData_y,modelgsSVCtestpre_y))
'''  GradientBoostingClassifier模型混淆矩阵为[[501  48][ 81 261]]
LogisticRegression模型混淆矩阵为[[480  69][ 77 265]]
SVC模型混淆矩阵为[[492  57][ 89 253]]  '''

0表示死亡,1表示存活

通过混淆矩阵可以看出:

  1. GBDT模型真正率TPR为503/(503 + 46) = 912,假正率FPR为0.236,
  2. LR模型真正率TPR为0.874,假正率FPR为0.225,
  3. SVC模型真正率TPR为0.896,假正率FPR为0.260

说明GBS找出正例能力很强,同时也不易将负例错判为正例。 综合考虑,本项目中将利用GBC方法进行模型预测。

综上所述,选择GBDT模型比较好~

6、模型预测

利用模型进行预测,并按规则导出预测结果

#TitanicGBSmodle
GBCpreData_y=modelgsGBC.predict(preData_X)
GBCpreData_y=GBCpreData_y.astype(int)
#导出预测结果
GBCpreResultDf=pd.DataFrame()
GBCpreResultDf['PassengerId']=full['PassengerId'][full['Survived'].isnull()]
GBCpreResultDf['Survived']=GBCpreData_y
GBCpreResultDf
#将预测结果导出为csv文件
GBCpreResultDf.to_csv('./TitanicGBCmodle_lufengkun.csv',index=False)

将结果上传至Kaggle中,最终预测得分为0.79186,排名约TOP3%。

在参与本次kaggle项目过程中,参考学习了很多其他竞赛方案的分析思路以及数据处理技巧,如:考虑同组效应、数据对数化处理、多种模型比较结果优劣等等。在项目过程中,主要从以下三个方面对模型改进来提升准确率:

  • 模型选优:分别选取多种模型进行建模,根据模型评分进行初步比较,最终综合考虑多个性能指标来选择合适的预测模型;
  • 特征挖掘与筛选:通过挖掘新的特征并测试选择不同特征时模型预测的准确性,来选择最终训练模型的特征集合;
  • 数据整容:缺失值的填充方法以及“不合群”数据的处理也直接影响模型的最终预测结果。

相关文章:

05- 泰坦尼克号海难生死预测 (机器学习集成算法) (项目五)

Kaggle: 一个数据建模和数据分析竞赛平台sns画柱状图: sns.barplot(datatrain,xPclass,ySurvived)查看数据分布(survived 和 fare): sns.FacetGrid(train,hueSurvived,aspect3) ageFacetsns.FacetGrid(train,hueSurvived,aspect3) ageFacet.map(sns.kdeplot,Fare,shadeTrue) …...

【python百炼成魔】python运算符的使用与输入输出函数

文章目录前言一. python 运算符1.1 算术运算符1.2 .赋值运算符1.3 比较运算符1.4. 布尔运算符二. 输入和输出函数2.1 print函数2.1.1 help函数查看帮助文档2.1.2 print的格式化输出2.2 format函数2.3 input数据接收函数写在最后前言 Python 中的运算符主要分为算术运算符、比较…...

uniapp实现app检查更新与升级-uni-upgrade-center详解

app检查更新与升级 参考链接&#xff1a; 升级中心uni-upgrade-center - App uni-admin h5 api App资源在线升级更新 uni-app使用plus注意事项 关于在线升级&#xff08;WGT&#xff09;的几个疑问 什么是升级中心uni-upgrade-center uniapp官方开发的App版本更新的插件&#…...

公司项目引入这种方式,开发应用真是又快又准!

试想一下&#xff0c;你开足马力提了一串需求&#xff0c;给开发精英团队也好&#xff0c;给外包也行&#xff0c;都要等个半年甚至更久才会给到你一个满意的产品&#xff0c;你是否还有动力&#xff1f; 这还不止&#xff0c;业务越来越复杂&#xff0c;最初的需求也在随着着…...

virtuoso数据库介绍

在国内&#xff0c;对海量 RDF 数据的管理有着迫切的实际需求&#xff1b; RDF&#xff1a;Resource Description Framework&#xff0c;是一个使用XML语法来表示的资料模型(Data model)&#xff0c;用来描述Web资源的特性&#xff0c;及资源与资源之间的关系。 Virtuoso可以对…...

linux高级命令之编辑器 vim

编辑器 vim学习目标能够说出vim的三种工作模式能够说出vim对应复制和粘贴命令1. vim 的介绍vim 是一款功能强大的文本编辑器&#xff0c;也是早年 Vi 编辑器的加强版&#xff0c;它的最大特色就是使用命令进行编辑&#xff0c;完全脱离了鼠标的操作。2. vim 的工作模式命令模式…...

分布式光伏储能系统的优化配置方法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Grafana loki部署及使用及问题处理方法(超详细)

一、下载软件 因为我是本地测试&#xff0c;所以用的windows版本的包&#xff0c;loki服务window版本的安装包下载地址&#xff1a;下载地址&#xff0c;选择 promtail-windows版本的安装包下载地址&#xff1a;下载地址 Grafana服务的下载地址&#xff1a;下载地址 二、配置…...

vue项目如何使用 SheetJS(xlsx)插件?

简言 SheetJS是一款非常好用的前端处理表格文件的工具。它分社区版和专业版&#xff0c;我们今天来介绍如何简单使用它的社区版。 SheetJS社区版官网 介绍 你应该打开官网浏览具体使用详情。 安装 打开官网在如上图的Installation板块中可以找到各种运行模块的使用方式。 …...

项目管理工具dhtmlxGantt甘特图入门教程(九):支持哪些数据格式(上篇)

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理控件应用程序的所有需求&#xff0c;是最完善的甘特图图表库这篇文章给大家讲解 dhtmlxGantt 的数据属性和数据库结构。 DhtmlxGantt正版试用下载&#xff08;qun&#xff1a;764…...

iView Table合并单元格(行、列)

行/列合并设置属性 span-method 可以指定合并行或列的算法。该方法参数为 4 个对象&#xff1a;row: 当前行column: 当前列rowIndex: 当前行索引columnIndex: 当前列索引该函数可以返回一个包含两个元素的数组&#xff0c;第一个元素代表 rowspan&#xff0c;第二个元素代表 co…...

如何用P6软件编制项目进度计划(下)

卷首语 根据项目合同包含的工作范围进行工作分解&#xff08;WBS&#xff09;&#xff0c;按照业主的要求及项目管理的需要&#xff0c;考虑不同阶段和层次&#xff0c;适时编制出项目管理所要求的的各级进度计划。 4搜集项目计划与进度控制相关信息 搜集与项目计划编制与进…...

环境配置完整指导——Installing C++ Distributions of PyTorch

目录一、前言二、动手开始做1. 安装cuda 11.42. 安装visual studio 2019 community3. 安装libtorch4. 安装mingw-w645. 配置环境变量6. 打开vscode开始写程序7. 运行程序8. 其他报错信息文章简介&#xff1a;这篇文章用于介绍在windows10 vscode中&#xff0c;跑通如下代码的全…...

深度学习——自注意力机制和位置编码(笔记)

1.自注意力&#xff1a; ①在深度学习中&#xff0c;经常使用卷积神经网络或者循环神经网络对序列进行编码 ②对于key,value和query&#xff0c;自注意力有一套自己的选法&#xff0c;因为key&#xff0c;value和query的值来自同一组输入。因此被称为自注意力或内部注意力 2…...

内网渗透(三十)之横向移动篇-利用远控工具向日葵横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…...

自动化测试中,该如何高效管理测试数据?

今晚在某个测试群&#xff0c;看到有人问了一个问题&#xff1a;把测试数据放配置文件读取和放文件通过函数调用读取有什么区别&#xff1f; 当时我下意识的这么回答&#xff1a;数据量越大&#xff0c;配置文件越臃肿&#xff0c;放在专门的数据文件&#xff08;比如excel&am…...

Qt中项目A调用另一个项目B的方法汇总

在开发一个软件项目时候&#xff0c;当涉及到一个模块&#xff0c;已经有过类似的项目开发&#xff0c;为了避免重复开发&#xff0c;涉及到在该项目的工程中调用已开发的项目作为子项目&#xff0c;有很多种方法。 一、将项目编译成库文件然后进行调用 调用库文件通常有两种…...

【项目精选】基于Javaee的影视创作论坛的设计与实现(视频+论文+源码)

点击下载源码 基于Javaee的影视创作论坛的设计与实现主要用功能包括&#xff1a; 首页推荐、用户管理、影片管理、评论管理、 预告片管理、海报管理、公告管理、数据检索、用户注册与登录等等功能、统结构如下 &#xff08;1&#xff09;后台管理: 管理模块&#xff1a;管理员…...

深入【虚拟列表】动态高度、缓冲、异步加载... Vue实现

前言&#x1f380; 在前文中我们了解到&#xff1a; 1.在某种特殊场景下&#xff0c;我们需要将 大量数据 使用不分页的方式渲染到列表上&#xff0c;这种列表叫做长列表。 2.因为事件循环的机制&#xff0c;一次性大量的渲染耗时较长&#xff0c;并且渲染期间会阻塞页面交互…...

Windows 11 + WSL(ubuntu 20.04) + CLion(2022.3) 编译OpenJDK12

编译OpenJDK12 目录编译OpenJDK12前言一、下载OpenJDK源码二、编译OpenJDK参考https://openjdk.org/groups/build/doc/building.html1&#xff1a;安装编译所需的组件2&#xff1a;执行编译命令3&#xff1a;验证编译结果三、在Clion中调试OpenJDK源码1&#xff1a;Clion中配置…...

Freemarker 语法精粹

文章目录说明基本用法宏加载宏定义宏文件写法import和include区别内置方法注册全局共享变量处理空值和默认值获得hashmap的键值从map中拿对象遍历Map其它小技巧迁移事项参考说明 Freemarker 还存在我的一些老项目中&#xff0c;比起前端框架&#xff0c;自有它的简便之处&…...

使用Benchto框架对Trino进行SQL性能对比测试

有时需要对魔改源码前后的不同版本Trino引擎进行性能对比测试&#xff0c;提前发现改造前后是否有性能变差或变好的现象&#xff0c;避免影响数据业务的日常查询任务性能。而Trino社区正好提供了一个性能测试对比框架&#xff1a;GitHub - trinodb/benchto: Framework for runn…...

Redis之哨兵模式

什么是哨兵模式&#xff1f; Sentinel(哨兵)是用于监控Redis集群中Master状态的工具&#xff0c;是Redis高可用解决方案&#xff0c;哨兵可以监视一个或者多个redis master服务&#xff0c;以及这些master服务的所有从服务。 某个master服务宕机后&#xff0c;会把这个master下…...

Selenium自动化测试Python二:WebDriver基础

欢迎阅读WebDriver基础讲义。本篇讲义将会重点介绍Selenium WebDriver的环境搭建和基本使用方法。 WebDriver环境搭建 Selenium WebDriver 又称为 Selenium2。 Selenium 1 WebDriver Selenium 2 WebDriver是主流Web应用自动化测试框架&#xff0c;具有清晰面向对象 API&…...

蓝桥杯模块学习17——AT24C02存储器(深夜学习——单片机)

一、硬件电路&#xff1a;1、引脚功能&#xff1a;&#xff08;1&#xff09;A0-A2&#xff1a;决定不同设备的地址码&#xff1a;&#xff08;2&#xff09;WP&#xff1a;写保护二、通讯方式&#xff08;IIC协议&#xff09;通讯方式与PCF8591相同&#xff0c;可参考以下文章…...

netty

Netty的介绍Netty是异步的&#xff08;指定回调处理&#xff09;、基于事件驱动的网络应用框架&#xff0c;用于快速开发高性能、高可靠性的网络IO程序。Netty本质是一个NIO框架&#xff0c;适用于服务器通讯相关的多种应用场景&#xff0c;分布式节点远程调用中Netty往往作为R…...

Django项目部署-uWSGI

Django项目部署-uWSGIDjango运维部署框架整体部署架构web服务器与web应用服务器的区别部署环境准备安装python3安装mariadb安装Django和相关模块Django托管服务器uWSGI使用uWSGI配置使用Django运维部署框架 整体部署架构 操作系统: Linux 。优势&#xff1a;生态系统丰富&…...

jhipster自动生成java代码的方法

一、前言 java springboot后台项目用到了jpa查询数据库&#xff0c;还用到了jhipster&#xff0c;这个东西可以自动生成基础的Controller、Service、Dao、JavaBean等相关代码&#xff0c;减少重复开发。 在此总结下使用方法。 二、jhipster自动生成java代码的方法 1.需要先…...

LeetCode 82. 删除排序链表中的重复元素 II

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给定一个已排序的链表的头 headheadhead &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,…...

tensorflow gpu环境安装

查看本电脑支持的最高cuda版本&#xff1a;nvidia-smi在~/.condarc修改conda 源&#xff1a;channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/- https://mirrors.tuna.tsinghua.edu.cn/…...

wordpress 链接打不开/关键词com

也许您正在为架设服务器的烦琐步骤而苦恼&#xff0c;也许您正为配置PHP,asp环境感到困惑。那么现在&#xff0c;中电云集请您放心&#xff0c;您的这些困惑苦恼&#xff0c;我们为您解决。为了服务器爱好者和使用者能更简单、快捷的架设自己的服务器,我们推出最新产品---china…...

建站网站/北京网站外包

a.如果备份的数据库可以访问&#xff0c;那么执行执行生产转化脚本&#xff1a;select set newname for datafile || file# || to ||replace( name,/old/data/path,/new/data/path ) || ; from v$datafile;b.如果备份的数据库不可以访问&#xff0c;可以trace控制文件内容&a…...

做网站和游戏是如何赚钱/百度排名服务

实现了一个简单的char二维数组函数&#xff0c;传入二维数组&#xff0c;打印二维数组的内容。 #include <cstdio>#define VEINKAPI __callback #define IN typedef int YNHANDLE;VEINKAPI void PrepareList(IN int fingercount, IN char **fingerlist, IN char** nameli…...

用户体验好网站/seo推广方法有哪些

迎接新的开始&#xff0c;2021沉淀 蜕变 静心 修炼&#xff01;...

wordpress空间租赁/网络营销的工具和方法

深入理解硬盘的Linux分区在学习Linux的过程中&#xff0c;安装Linux是每一个初学者的第一个门槛。在这个过程中间&#xff0c;最大的困惑莫过于给硬盘进行分区。虽然&#xff0c;现在各种发行版本的Linux已经提供了友好的图形交互界面&#xff0c;但是很多的人还是感觉无从下手…...

广州最新今天的消息/seo的名词解释

黑客技术点击右侧关注&#xff0c;了解黑客的世界&#xff01;推荐↓↓↓ 长按关注?【16个技术公众号】都在这里&#xff01;涵盖&#xff1a;程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Andr…...