当前位置:   article > 正文

机器学习入门:Kaggle -titanic(泰坦尼克)生存预测_kaggle泰坦尼克号生存预测得分

kaggle泰坦尼克号生存预测得分

        作为kaggle最最入门的新手村长期比赛之一,通过参考大佬们的作业,自己尝试了一下这个demo,可以很好的让萌新体验一次传统机器学习的大体流程。

        首先附上这篇博客参考大佬的原文地址,欢迎大家去捧场:

Kaggle平台Titanic生存率预测项目(TOP3%) - 知乎https://zhuanlan.zhihu.com/p/50194676

        作为萌新向入门记录,我会提及一些当时自己遇到的一些细节,还有一些个人理解的暴论(不是),不足之处还请多多指教。

一、数据获取

        kaggle注册这方面我就先不说了,这里附上网址,可以根据这里的下载图标进行数据集下载

Kaggle-Titanichttps://www.kaggle.com/competitions/titanic/overview 

        当然也可以通过代码的方式直接下载到本地,但是可能对萌新不友好,这里不多赘述,大家可以自行查找方法。

        一共三个csv文件,训练集和测试集,还有一个提交版本的csv样例。我们最终提交的文件是根据测试集预测出来的文件,该文件格式需要与gender_submission相一致。网络不好的同学可以根据文末链接下载对应数据。

 

 二、数据观察

        这个部分也不是必要的,只是可以让我们大概理解一下数据,有一定基础的小伙伴们可以跳过直接到第三部分。

  1. import warnings
  2. import numpy as np
  3. import pandas as pd
  4. import seaborn as sns
  5. import matplotlib.pyplot as plt
  1. # 忽略部分版本警告
  2. warnings.filterwarnings('ignore')
  3. #设置sns样式
  4. sns.set(style='white',context='notebook',palette='muted')
  5. #导入数据
  6. train=pd.read_csv('./train.csv')
  7. test=pd.read_csv('./test.csv')
  1. # 合并数据集
  2. full = train.append(test, ignore_index=True)
  3. full.describe()
  4. # full.info()

         可以看到一些数据的大致分布以及比例,但是这几列的意义不大。

        这里可以看出港口不同对生存率的影响,也可以试试其他参数,将‘Embarked’以及S、C、Q等相应参数进行替换即可。

  1. # 计算不同类型embarked的乘客,其生存率为多少
  2. # S:南安普顿港southampton;Q:皇后镇 Queentown;C:瑟堡 Cherbourg
  3. print('Embarked为"S"的乘客,其生存率为%.2f' % full['Survived'][full['Embarked'] == 'S'].value_counts(normalize=True)[1])
  4. print('Embarked为"C"的乘客,其生存率为%.2f' % full['Survived'][full['Embarked'] == 'C'].value_counts(normalize=True)[1])
  5. print('Embarked为"Q"的乘客,其生存率为%.2f' % full['Survived'][full['Embarked'] == 'Q'].value_counts(normalize=True)[1])

         法国登船乘客生存率较高原因可能与其头等舱乘客比例较高有关。

sns.catplot('Pclass', col='Embarked', data=train, kind='count', height=3)

         Parch与Survived:当乘客同行的父母及子女数量适中时,生存率较高。

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

         同理可以将不同的数据进行比较,这里就不放结果图了。

  1. # SibSp与Survived:当乘客同行的同辈数量适中时生存率较高
  2. sns.barplot(data=train, x='SibSp', y='Survived')
  3. # Pclass与Survived:乘客客舱等级越高,生存率越高
  4. sns.barplot(data=train, x='Pclass', y='Survived')
  5. # Sex与Survived:女性的生存率远高于男性
  6. sns.barplot(data=train, x='Sex', y='Survived')

         Age与Survived:当乘客年龄段在0-10岁期间时生存率会较高。

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

         Fare与Survived:当票价低于18左右时乘客生存率较低,票价越高生存率一般越高。

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

         查看fare(票价)分布。

  1. farePlot = sns.distplot(full['Fare'][full['Fare'].notnull()], label='skewness:%.2f' % (full['Fare'].skew()))
  2. farePlot.legend(loc='best')

        上面的查看方式在其他的基础机器学习数据集中也同样适用,可以尝试更改一下参数,更好的观察数据的关联性,为后续构建特征工程、同组识别做准备。

三、数据预处理

        这里新开一个jupyter,需要导入的包如下(调包侠是我了)。

  1. import warnings
  2. import numpy as np
  3. import pandas as pd
  4. import seaborn as sns
  5. import matplotlib.pyplot as plt
  6. from sklearn.ensemble import RandomForestRegressor
  7. from sklearn.metrics import roc_curve, auc
  8. from sklearn.ensemble import RandomForestClassifier,GradientBoostingClassifier,ExtraTreesClassifier
  9. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  10. from sklearn.linear_model import LogisticRegression
  11. from sklearn.neighbors import KNeighborsClassifier
  12. from sklearn.tree import DecisionTreeClassifier
  13. from sklearn.svm import SVC
  14. from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold
  1. # 忽略部分版本警告
  2. warnings.filterwarnings('ignore')
  3. #设置sns样式
  4. sns.set(style='white',context='notebook',palette='muted')
  5. #导入数据
  6. train=pd.read_csv('./train.csv')
  7. test=pd.read_csv('./test.csv')
  8. full = train.append(test, ignore_index=True)

3.1对cabin船舱标签进行缺失值填充

        这里要引入几种缺失值处理方式,我们会先后用到。

        第一种就是直接填“不造啊”,我愿称之为“摆烂型数据”,一般意义不大的数据可以尝试这样填写。而且就算让咱们好好填,也填不上啊(捂脸)。

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

3.2对Embarked登船港口标签进行缺失值填充

        第二种:填入众数、平均值,或者可能性最大的某一个标签。

  1. #对Embarked缺失值进行处理,查看缺失值情况
  2. full[full['Embarked'].isnull()]

         查看Embarked数据分布情况,可知在英国南安普顿登船可能性最大,因此以此填充缺失值。

  1. full['Embarked']=full['Embarked'].fillna('S')
  2. full['Embarked'].value_counts()

         fare票价同样的处理方式,不过这次采取的是平均值。

  1. # 利用3等舱,登船港口为英国,舱位未知旅客的平均票价来填充缺失值。
  2. full['Fare']=full['Fare'].fillna(full[(full['Pclass']==3)&(full['Embarked']=='S')&(full['Cabin']=='U')]['Fare'].mean())

         第三种:预测后填充

        某种数据太关键了,我们难以使用常规方式直接添加,比如本案例的年龄数据,脑补一下就可以感觉到,对最终生存率预测的影响至关重要,我们可以尝试根据现有数据“预测年龄”,之后再填充。但我们在预测年龄之前还需要对数据进行进一步处理,这里先挖个坑。

四、特征工程

        首先我们愿意相信,某些标签下的数据只有几条,那预测效果肯定不会太好,我们可以尝试“暴力更改”他们的部分标签,合并类型大致相同的标签 ,本案例中以姓名头衔为例。

4.1name中头衔信息提取

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

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

         可以看到头衔实在太多了,我们有选择的合并部分头衔

  1. # 将相近的特征整合在一起
  2. TitleDict={}
  3. TitleDict['Mr']='Mr'
  4. TitleDict['Mlle']='Miss'
  5. TitleDict['Miss']='Miss'
  6. TitleDict['Master']='Master'
  7. TitleDict['Jonkheer']='Master'
  8. TitleDict['Mme']='Mrs'
  9. TitleDict['Ms']='Mrs'
  10. TitleDict['Mrs']='Mrs'
  11. TitleDict['Don']='Royalty'
  12. TitleDict['Sir']='Royalty'
  13. TitleDict['the Countess']='Royalty'
  14. TitleDict['Dona']='Royalty'
  15. TitleDict['Lady']='Royalty'
  16. TitleDict['Capt']='Officer'
  17. TitleDict['Col']='Officer'
  18. TitleDict['Major']='Officer'
  19. TitleDict['Dr']='Officer'
  20. TitleDict['Rev']='Officer'
  21. full['Title']=full['Title'].map(TitleDict)
  22. full['Title'].value_counts()

         合并结果如下,数量较少标签被合并到其余大类中。

 4.2FamilyNum及FamilySize信息提取

        脑补时间又到了,如果沉船发生,那种一家七八个人的和普通一家三口的生存率应该会出现明显差别,人数越多可能生存率越低,人数过少也可能因为没有帮助的原因而导致生存率较低。

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

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

        可以看出,家庭成员人数在2-4人时,乘客的生存率较高,当没有家庭成员同行或家庭成员人数过多时生存率较低,脑补成功。

 

        但是这里我们虽然挖掘到了数据中本不存在的信息,但是凭空增加了一类标签,而且观察发现,2-4类别的生存率可能不会有太大差别,在这里可以尝试将类别合并,按照家庭成员人数多少,将家庭规模分为“小、中、大”三类:

  1. # 按照家庭成员人数多少,将家庭规模分为“小、中、大”三类:
  2. def familysize(familyNum):
  3. if familyNum==1:
  4. return 0
  5. elif (familyNum>=2)&(familyNum<=4):
  6. return 1
  7. else:
  8. return 2
  9. full['familySize']=full['familyNum'].map(familysize)
  10. full['familySize'].value_counts()
  11. # 查看familySize与Survived
  12. sns.barplot(data=full,x='familySize',y='Survived')
  13. # 当家庭规模适中时,乘客的生存率更高。

         看图说话,有理有据,令人信服。

4.3共票号乘客数量TickCot及TickGroup

        这里思路与上方思路一致,同一票号的乘客数量可能不同,可能也与乘客生存率有关系。我们构建这一关系,并且发现当TickCot大小适中时,乘客生存率较高。并且为了降低数据的复杂性,可以按照TickCot大小,将TickGroup分为三类。在代码中进行了详细说明,此处不在赘述。

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

        到这里大伙儿还记得我们的年龄一直没有补全这件事吗,我们在进行了以上的数据处理和特征工程后,数据变得更加“立体”,就可以着手预测年龄了,但是这毕竟不是直接预测生存率,我们只挑去部分数据和一种模型即可。

        查看Age与Parch、Pclass、Sex、SibSp、Title、familyNum、familySize、Deck、TickCot、TickGroup等变量的相关系数大小,筛选出相关性较高的变量构建预测模型。

full[full['Age'].isnull()].head()

        这里可以大致看一下前五条没年龄的数据,选择几个有良好对应特征的数据用于后续预测,列数较多,这里没有截全。

 4.4.1筛选数据

  1. #筛选数据集
  2. AgePre=full[['Age','Parch','Pclass','SibSp','Title','familyNum','TickCot']]
  3. #进行one-hot编码
  4. AgePre=pd.get_dummies(AgePre)
  5. ParAge=pd.get_dummies(AgePre['Parch'],prefix='Parch')
  6. SibAge=pd.get_dummies(AgePre['SibSp'],prefix='SibSp')
  7. PclAge=pd.get_dummies(AgePre['Pclass'],prefix='Pclass')
  8. #查看变量间相关性
  9. AgeCorrDf=pd.DataFrame()
  10. AgeCorrDf=AgePre.corr()
  11. AgeCorrDf['Age'].sort_values()

 

         根据相关性,拼接相关数据,并查看前五条,因为前面进行了独热编码,列数明显增加。

  1. AgePre=pd.concat([AgePre,ParAge,SibAge,PclAge],axis=1)
  2. AgePre.head()

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

  1. #拆分实验集和预测集
  2. AgeKnown=AgePre[AgePre['Age'].notnull()]
  3. AgeUnKnown=AgePre[AgePre['Age'].isnull()]
  4. #生成实验数据的特征和标签
  5. AgeKnown_X=AgeKnown.drop(['Age'],axis=1)
  6. AgeKnown_y=AgeKnown['Age']
  7. #生成预测数据的特征
  8. AgeUnKnown_X=AgeUnKnown.drop(['Age'],axis=1)
  9. #利用随机森林构建模型
  10. rfr=RandomForestRegressor(random_state=None,n_estimators=500,n_jobs=-1)
  11. rfr.fit(AgeKnown_X,AgeKnown_y)

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

  1. #预测年龄
  2. AgeUnKnown_y=rfr.predict(AgeUnKnown_X)
  3. #填充预测数据
  4. full.loc[full['Age'].isnull(),['Age']]=AgeUnKnown_y
  5. full.info()

         此时已无缺失值,数据处理大功告成。

五、同组识别

        虽然通过分析数据已有特征与标签的关系可以构建有效的预测模型,但是部分具有明显共同特征的用户可能与整体模型逻辑并不一致。

        如果将这部分具有同组效应的用户识别出来并对其数据加以修正,就可以有效提高模型的准确率。在Titancic案例中,我们主要探究相同姓氏的乘客是否存在明显的同组效应。提取两部分数据,分别查看其“姓氏”是否存在同组效应。因为性别和年龄与乘客生存率关系最为密切,因此用这两个特征作为分类条件。

        人话版:有的数据太离谱,虽说数据摆烂了,但是我们还不舍得丢弃,可是留着会导致模型不能获得良好的结果,于是进行一波骚操作,本案例中包括但不限“暴力更改性别”,“暴力更改年龄”等方式。 

5.1    12岁以上男性:找出男性中同姓氏均获救的部分

  1. #提取乘客的姓氏及相应的乘客数
  2. full['Surname']=full['Name'].map(lambda x:x.split(',')[0].strip())
  3. SurNameDict={}
  4. SurNameDict=full['Surname'].value_counts()
  5. full['SurnameNum']=full['Surname'].map(SurNameDict)
  6. #将数据分为两组
  7. MaleDf=full[(full['Sex']=='male')&(full['Age']>12)&(full['familyNum']>=2)]
  8. FemChildDf=full[((full['Sex']=='female')|(full['Age']<=12))&(full['familyNum']>=2)]
  9. MSurNamDf=MaleDf['Survived'].groupby(MaleDf['Surname']).mean()
  10. MSurNamDf.head()
  11. MSurNamDf.value_counts()

        大多数同姓氏的男性存在“同生共死”的特点,因此利用该同组效应,对生存率为1的姓氏里的男性数据进行修正,提升其预测为“可以幸存”的概率。 

  1. MSurNamDict={}
  2. MSurNamDict=MSurNamDf[MSurNamDf.values==1].index
  3. MSurNamDict

         这里显示一下符合调教的乘客姓名:

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

 

  1. #分析女性及儿童同组效应
  2. FCSurNamDf=FemChildDf['Survived'].groupby(FemChildDf['Surname']).mean()
  3. FCSurNamDf.head()
  4. FCSurNamDf.value_counts()

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

  1. #获得生存率为0的姓氏
  2. FCSurNamDict={}
  3. FCSurNamDict=FCSurNamDf[FCSurNamDf.values==0].index
  4. FCSurNamDict

 

        下面是更改数据,可以看到进行了萌新们难以理解的操作 :

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

六、筛选子集

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

        人话版:数据太多,但是机器并不会认为年龄比客舱名更加重要,我们对某些数据进行删除,或者其他的降维处理。

        这里只展示人工去除的方式,因为在本demo中,盲目使用sklearn自带的降维函数,准确率波动太大,得不偿失,而手撕降维代码或者更改参数不在本萌新讨论范围之内(留下了菜狗的泪水)。

  1. fullSel=full.drop(['Cabin','Name','Ticket','PassengerId','Surname','SurnameNum'],axis=1)
  2. #查看各特征与标签的相关性
  3. corrDf=pd.DataFrame()
  4. corrDf=fullSel.corr()
  5. corrDf['Survived'].sort_values(ascending=True)

 

  1. # 查看Survived与其他特征间相关性大小。
  2. plt.figure(figsize=(8,8))
  3. sns.heatmap(fullSel[['Survived','Age','Embarked','Fare','Parch','Pclass',
  4. 'Sex','SibSp','Title','familyNum','familySize','Deck',
  5. 'TickCot','TickGroup']].corr(),cmap='BrBG',annot=True,
  6. linewidths=.5)
  7. # plt.xticks(rotation=45)

 

        先人工初步筛除与标签预测明显不相关或相关度很低的特征,再查看剩余特征与标签之间的相关性大小做进一步降维。

  1. fullSel=fullSel.drop(['familyNum','SibSp','TickCot','Parch'],axis=1)
  2. #one-hot编码
  3. fullSel=pd.get_dummies(fullSel)
  4. PclassDf=pd.get_dummies(full['Pclass'],prefix='Pclass')
  5. TickGroupDf=pd.get_dummies(full['TickGroup'],prefix='TickGroup')
  6. familySizeDf=pd.get_dummies(full['familySize'],prefix='familySize')
  7. fullSel=pd.concat([fullSel,PclassDf,TickGroupDf,familySizeDf],axis=1)

 七:构建预测模型

7.1模型选择

7.1.1建立各种模型

  1. #拆分实验数据与预测数据
  2. experData=fullSel[fullSel['Survived'].notnull()]
  3. preData=fullSel[fullSel['Survived'].isnull()]
  4. experData_X=experData.drop('Survived',axis=1)
  5. experData_y=experData['Survived']
  6. preData_X=preData.drop('Survived',axis=1)

         一般到这里,萌新的入门机器学习之路可以暂时告一段落了,后面的路主要是调包,而这些包包里面的内容较为深奥,参数调教也很有讲究,我们可以暂时使用默认值(不传参)。

        这里涉及了众多没听说过的算法,可以参考一下我的这一篇小汇总,主要是从其他博主哪里汇总的(没有一滴是自己的),分别对应了这里出现的算法名,大家看看图一乐。这是链接

  1. #设置kfold,交叉采样法拆分数据集
  2. kfold=StratifiedKFold(n_splits=10)
  3. #汇总不同模型算法
  4. classifiers=[]
  5. classifiers.append(SVC())
  6. classifiers.append(DecisionTreeClassifier())
  7. classifiers.append(RandomForestClassifier())
  8. classifiers.append(ExtraTreesClassifier())
  9. classifiers.append(GradientBoostingClassifier())
  10. classifiers.append(KNeighborsClassifier())
  11. classifiers.append(LogisticRegression())
  12. classifiers.append(LinearDiscriminantAnalysis())

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

  1. #不同机器学习交叉验证结果汇总
  2. cv_results=[]
  3. for classifier in classifiers:
  4. cv_results.append(cross_val_score(classifier,experData_X,experData_y,
  5. scoring='accuracy',cv=kfold,n_jobs=-1))
  1. # 求出模型得分的均值和标准差
  2. cv_means=[]
  3. cv_std=[]
  4. for cv_result in cv_results:
  5. cv_means.append(cv_result.mean())
  6. cv_std.append(cv_result.std())
  7. #汇总数据
  8. cvResDf=pd.DataFrame({'cv_mean':cv_means,
  9. 'cv_std':cv_std,
  10. 'algorithm':['SVC','DecisionTreeCla','RandomForestCla','ExtraTreesCla',
  11. 'GradientBoostingCla','KNN','LR','LinearDiscrimiAna']})
  12. cvResDf

         以下是结果,数字太抽象,我们换张图。

  1. # 可视化查看不同算法的表现情况
  2. sns.barplot(data=cvResDf,x='cv_mean',y='algorithm',**{'xerr':cv_std})
  3. cvResFacet=sns.FacetGrid(cvResDf.sort_values(by='cv_mean',ascending=False),sharex=False,
  4. sharey=False,aspect=2)
  5. cvResFacet.map(sns.barplot,'cv_mean','algorithm',**{'xerr':cv_std},
  6. palette='muted')
  7. cvResFacet.set(xlim=(0.7,0.9))
  8. cvResFacet.add_legend()

         首先是0-1作为范围的总体图,但是某些模型的结果差不多,我们可以将坐标轴缩减至0.7-1.0

 

 7.2确定选取LR和GradientBoostingCla模型

        别问,问就是肉眼观察

八、模型调优

8.1模型对比

        综合以上模型表现,考虑选择GradientBoostingCla、LR两种模型进一步对比。分别建立GradientBoostingClassifier以及LogisticRegression模型,并进行模型调优。

  1. #GradientBoostingClassifier模型
  2. GBC = GradientBoostingClassifier()
  3. gb_param_grid = {'loss' : ["deviance"],
  4. 'n_estimators' : [100,200,300],
  5. 'learning_rate': [0.1, 0.05, 0.01],
  6. 'max_depth': [4, 8],
  7. 'min_samples_leaf': [100,150],
  8. 'max_features': [0.3, 0.1]
  9. }
  10. modelgsGBC = GridSearchCV(GBC,param_grid = gb_param_grid, cv=kfold,
  11. scoring="accuracy", n_jobs= -1, verbose = 1)
  12. modelgsGBC.fit(experData_X,experData_y)
  13. #LogisticRegression模型
  14. modelLR=LogisticRegression()
  15. LR_param_grid = {'C' : [1,2,3],
  16. 'penalty':['l1','l2']}
  17. modelgsLR = GridSearchCV(modelLR,param_grid = LR_param_grid, cv=kfold,
  18. scoring="accuracy", n_jobs= -1, verbose = 1)
  19. modelgsLR.fit(experData_X,experData_y)

 8.2 查看模型准确度

  1. #modelgsGBC模型
  2. print('modelgsGBC模型得分为:%.3f'%modelgsGBC.best_score_)
  3. #modelgsLR模型
  4. print('modelgsLR模型得分为:%.3f'%modelgsLR.best_score_)
  5. # GBC模型得分(即模型准确性)更高,继续比较其他指标的差异。

8.3 查看模型ROC曲线

  1. #求出测试数据模型的预测值
  2. modelgsGBCtestpre_y=modelgsGBC.predict(experData_X).astype(int)
  3. #画图
  4. fpr,tpr,threshold = roc_curve(experData_y, modelgsGBCtestpre_y) ###计算真正率和假正率
  5. roc_auc = auc(fpr,tpr) ###计算auc的值
  6. plt.figure()
  7. lw = 2
  8. plt.figure(figsize=(10,10))
  9. plt.plot(fpr, tpr, color='r',
  10. lw=lw, label='ROC curve (area = %0.3f)' % roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线
  11. plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
  12. plt.xlim([0.0, 1.0])
  13. plt.ylim([0.0, 1.0])
  14. plt.xlabel('False Positive Rate')
  15. plt.ylabel('True Positive Rate')
  16. plt.title('Titanic GradientBoostingClassifier Model')
  17. plt.legend(loc="lower right")

         话说我总感觉这个框框是扁的(右上角低了· 。·),因为这两个模型的准确率差不多,所以这个曲线观感是基本一致的,至于该评价指标的详细内容请查阅其他博文,这里不做赘述啦。

 

  1. #求出测试数据模型的预测值
  2. testpre_y=modelgsLR.predict(experData_X).astype(int)
  3. #画图
  4. fpr,tpr,threshold = roc_curve(experData_y, testpre_y) ###计算真正率和假正率
  5. roc_auc = auc(fpr,tpr) ###计算auc的值
  6. plt.figure()
  7. lw = 2
  8. plt.figure(figsize=(10,10))
  9. plt.plot(fpr, tpr, color='r',
  10. lw=lw, label='ROC curve (area = %0.3f)' % roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线
  11. plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
  12. plt.xlim([0.0, 1.0])
  13. plt.ylim([0.0, 1.0])
  14. plt.xlabel('False Positive Rate')
  15. plt.ylabel('True Positive Rate')
  16. plt.title('Titanic LogisticRegression Model')
  17. plt.legend(loc="lower right")

 8.4 查看混淆矩阵

  1. from sklearn.metrics import confusion_matrix
  2. print('GradientBoostingClassifier模型混淆矩阵为\n',confusion_matrix(experData_y.astype(int).astype(str),modelgsGBCtestpre_y.astype(str)))
  3. print('LinearRegression模型混淆矩阵为\n',confusion_matrix(experData_y.astype(int).astype(str),testpre_y.astype(str)))

         这里涉及召回率等其他评价指标,萌新可以简单理解为,主对角线上的数字越大越好。那从这里可以看出,这个小G模型效果应该比较好。

 九、模型预测

  1. #TitanicGBSmodle
  2. GBCpreData_y=modelgsGBC.predict(preData_X)
  3. GBCpreData_y=GBCpreData_y.astype(int)
  4. #导出预测结果
  5. GBCpreResultDf=pd.DataFrame()
  6. GBCpreResultDf['PassengerId']=full['PassengerId'][full['Survived'].isnull()]
  7. GBCpreResultDf['Survived']=GBCpreData_y
  8. GBCpreResultDf
  9. #将预测结果导出为csv文件
  10. GBCpreResultDf.to_csv(r'C:\Users\demo\Titanic\TitanicGBSmodle.csv',index=False)

        这里注意更改一下保存路径,接下来我们可以在kaggle官网进行提交啦。

 

        依旧是建议萌新点击这里的上传按钮,而不选择代码提交的方式。但这里注意要搭一下梯子哦,一般科学上网才能顺利提交。 

         上面就是提交结果啦,可以看到小G结果比LR结果高出了一丢丢。

代码链接:https://pan.baidu.com/s/14F87WTGJFDHlpCF91xlt5Q 
提取码:f6x5

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/142718
推荐阅读
相关标签
  

闽ICP备14008679号