当前位置: 首页 > 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中配置…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...