kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting

顺利注册完kaggle之后,终于可以开始上手撸项目啦!
先从大名鼎鼎的泰坦尼克号开始吧!
尽管网上有很多大神进行了“入门级别”的代码分享讲解,但我看了一轮仍然觉得对新手不够友好。
愿此文能给新手入门一些帮助。

声明在前:
我的代码有参考某些大神的帖子,在文末会贴上作者及链接;
我的代码和文章仅做学习研究分享,如需转载请注明作者(笨小孩)和出处
https://blog.csdn.net/CC_Cynthia/article/details/104278690;
转载请知会作者;
此文仅供非商业用途,谢谢。
那么闲话不多说,上干货。

一、 数据准备

我在这里使用的是Jupyter Notebook,Python语言
首先先导入需要使用到的包

%matplotlib inline
#使得图像即时显示
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
#引用warinings 是为了美观的看代码及运行结果,不然Jupyter会爆红提示版本更新后用法过时问题

然后导入数据

train = pd.read_csv('C:/Users/笨小孩/Desktop/泰坦尼克/train.csv')
test= pd.read_csv('C:/Users/笨小孩/Desktop/泰坦尼克/test.csv')
PassengerId=test['PassengerId']
all_data= pd.concat([train, test], ignore_index=True)
all_data

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第1张图片
这里有2个细节:
1.导入数据的时候,我的是windows系统,所以引用路径需要使用“/”而非ios的“\”,大家可以根据自己的系统而做出调整,路径直接去文件夹上方复制粘贴。见下图。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第2张图片
2.函数pd.concat( )是拼接函数
代码all_data= pd.concat([train, test], ignore_index=True)的含义是,将train, test合并拼接,参数ignore_index=True 是test的原来索引洗去,强制赋予新的索引。我们来看一下,如果没有这个参数会怎么样。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第3张图片
我们发现其索引并未改变,沿用了原来的索引

二、 数据观察

1. 宏观观察数据整体情况

现在我们来观察下表头,或许直接打开csv文件观察更直观一些。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第4张图片
可以看到,表头分别有Passenger(唯一标识),Survived(是否获救),Pclass(舱位等级),Name(名字),Sex(性别),Age(年龄),SibSp(同上船的兄弟姐妹+配偶),Parch(同上船的父母子女),Ticket(票号),Fare(船票价格),Cabin(船舱),Embarked(上船地点)。随便滚动下鼠标就会发现,Age, Cabin存在缺失值,但是具体的,我们需要调用函数来看。
在这里,我们可以调用pandas的info( )或者是pandas的describe( )来看,下面对比下优劣。
使用describe( )
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第5张图片
我们就会发现貌似少了一些特征的描述,比如Name, Sex, Embarked…因为这些特征都是字符串,无法进行简单的数字统计,比如mean, std等等,所以被略过了。
我们再用info( )观察下
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第6张图片
这时候就能直观的看出来Age, Cabin, Embarked存在缺失值。但是比起describe少了简单的数据统计。

2. 可视化理解特征与标签之间的关系

单看数据是无法建立起特征之间的有效联系的。所以我们需要运用统计学及可视化来了解数据之间的相关性,挖掘出潜藏在数字背后的关联,必要时可以创造一个新的特征。

(1) 女性存活数多于男性

这里说明一下,barplot是条形图,传入的参数用于设定x轴,y轴,还有数据源。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第7张图片

(2) 船舱等级越高,存活率越高

极有可能高等级的船舱更接近逃生出口,易于逃生。

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第8张图片

(3) 同船兄弟姐妹+配偶的数量为1-2个的乘客存活率高于40%

所以说人越多反而是累赘吗?数量为5和8的人都没能活下来。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第9张图片

(4) 同船父母+子女数为1-3个的乘客存活率高于50%

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第10张图片

(5) 12岁以下的儿童生还率较高

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第11张图片
年龄不是简单的分类值,而是回归数值,所以这里用到了Seaborn的FacetGrid(结构化多绘图网格)。在我们想要可视化变量的分布或者多个变量之间的关系时,使用FacetGrid非常有用。
我们来看:
facet=sns.FacetGrid(train, hue=‘Survived’, aspect=2)
FacetGrid( )里面设置了参数,data=train, hue(颜色显示为)Survived, aspect是长宽比,这里设置为2;
facet.map(sns.kdeplot, ‘Age’, shade=True)
这里的kdeplot是核密度估计图,通过这个图我们可以比较直观的看出数据样本本身的分布特征,我们对Age进行处理。shade若为True,则在kde曲线下面的区域进行阴影处理。除此之外还可以设置参数color,g代表绿色,r 代表红色,y代表黄色;
facet.set(xlim=(0, train[‘Age’].max()))
是对图像x轴的数据范围进行设定,从0到Age的最大值;
facet.add_legend()
plt.xlabel(‘Age’)
plt.ylabel(‘Density’)
这一段代码很明了,设置图例,横坐标是Age,纵坐标是Density;
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第12张图片
从上图可以看出来,大约在12岁左侧,生还率有明显的差异,密度图非交叉面积很大。

(6) 票价越低,越不容易生还

举一反三,我们也可以通过上述代码对票价进行分析:
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第13张图片
这个陡峭的曲线告诉我们,票价越低,越不容易生还。

(7) 登案港口中,C地上船的存活率更高

countplot是以bar的形式展示每个类别的数量。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第14张图片

(8) 名字中提取Title

现在特征还剩Name, Tickect, Cabin,SlibSp,Parch没有进行可视化观察。先观察下Name,似乎有身份职业的提示信息。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第15张图片
我们调用函数再仔细看看:

all_data['Title']=all_data['Name'].apply(lambda x:x.split(',')[1].split('.')[0].strip())
all_data['Title'].value_counts()


Out[13]:
Mr              757
Miss            260
Mrs             197
Master           61
Dr                8
Rev               8
Col               4
Mlle              2
Major             2
Ms                2
Capt              1
Dona              1
Jonkheer          1
Mme               1
Sir               1
Don               1
the Countess      1
Lady              1
Name: Title, dtype: int64

all_data[‘Title’]=all_data[‘Name’].apply(lambda x:x.split(’,’)[1].split(’.’)[0].strip())
这段代码表示,我们基于all_data(train+test的总数据集)创建一个新的特征【Title】,【Title】是从Name中提取出来的,apply(lambda x:x.split(’,’)[1].split(’.’)[0].strip()),我们截取【,】之后的第一个字母,到【.】之前的字母,并将选取的字符串去除空格。
仔细观察下提取出来的抬头称呼,可以进行大致分类,比如像Lady, Jonkheer这些典型的贵族称呼。
对于抬头的划分,目前只能基于我的英语知识储备+感性直觉进行,如果有更加可信的分类方法,烦请告知。
第一类Mr(先生)
第二类Mrs(已婚或未知婚姻状况)Mme, Ms, Mrs
第三类Miss(未婚女子)Mlle, Miss
划分完最容易识别的三类之后,我们来看剩下的:
‘Master’(表示某一专业领域的专家,也可能是学院的老师);
‘Rev’(这个是reverend的缩写,就是牧师);
‘Dr’(医生或者博士);
‘Col’(上校的缩写);
‘Major’(少校);
‘Jonkheer’(年轻贵族的称呼)
‘Lady’(贵族女性)
‘the Countess’(女公爵);
‘Sir’(爵士);
‘Don’(也是一种贵族称呼)
‘Dona’(Don的夫人)
‘Capt’(上尉)
直观感受下就可以分类了。
第四类Nobility(贵族),Jonkheer, Lady, the Countess, Sir, Don, Dona
第五类Offiecer(军官), Cpl, Major, Capt
第六类Master(某一领域专家),Master, Dr, Rev

Title_Dict={}
Title_Dict.update(dict.fromkeys(['Mr'], 'Mr'))
Title_Dict.update(dict.fromkeys(['Mme', 'Ms', 'Mrs'], 'Mrs'))
Title_Dict.update(dict.fromkeys(['Mlle', 'Miss'], 'Miss'))
Title_Dict.update(dict.fromkeys(['Jonkheer','Lady','the Countess','Sir','Don',  'Dona'], 'Nobility'))
Title_Dict.update(dict.fromkeys(['Capt', 'Col', 'Major'], 'Officer'))
Title_Dict.update(dict.fromkeys(['Master','Dr','Rev'], 'Master'))

先建立一个Title_Dict的空字典,然后我们使用dict.fromkeys往字典里面添加键值,在这个函数里第一个参数是键,第二个参数是值。比如Title_Dict.update(dict.fromkeys([‘Mme’, ‘Ms’, ‘Mrs’], ‘Mrs’))这行代码中,Mme, Ms, Mrs都是键(key),对应的是Mrs(Value)。
下面来可视化一下
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第16张图片
怎么感觉什么头衔都没有的普普通通Mr最惨啊,存活率好低,不到2成。Master和Officer存活率虽然相对于Mr高,但是仍然低于5成。
我们来分析下代码:
之前我们已经赋值过all_data[‘Title’],即下面这些提取出来的Title字符串。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第17张图片
all_data[‘Title’]=all_data[‘Title’].map(Title_Dict),这一步实现了什么,我们取all_data的前20行看下。
all_data.head(20)
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第18张图片
结果发现Title都被赋予了Title_Dict的value值,这样就可以为分类统计做好准备。

(9) 创建新特征Cabin_type

我们再看Cabin,似乎存在很多缺失值,但是如果直接弃之不用又有些可惜。
调用个函数观察下

all_data['Cabin'].value_counts()

Out[17]:
C23 C25 C27        6
G6                 5
B57 B59 B63 B66    5
B96 B98            4
D                  4
                  ..
C50                1
B4                 1
A14                1
A11                1
B39                1
Name: Cabin, Length: 186, dtype: int64

我们来处理下看看。先将缺失值补为Unknown,然后提取首字母。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第19张图片
似乎船舱类别不一样也是对存活率有影响的。

(10) 舍弃Ticket特征

最后看下Ticket……感觉一团糟,没有头绪,我决定舍弃。有的大神对同票号的人数进行了统计。最后得出同行人数对于存活率的影响,这个思路很很厉害,不过对于小白的我,有些复杂,我就跳过啦。

(11) SlibSp+Parch数据的合并

一家人就要整整齐齐在一起,数据也是。这里加多了个1是因为还有乘客自己,我们得到一个新的特征——Family_size(家庭大小)。

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第20张图片
但是类别太多,无法有效分析,我们需要进一步细化。仔细看来,family_size=2,3,4可以归为高生存率(超过5成),family_size=1,5,6,7为低生存率(低于5成),其他生存率为0。这么一想,我们可以封装个函数,函数里面使用if分类。代码如下:

def Family_type(s):
    if (s>=2)&(s<=4):
    #高生存率
        return 2
    elif ((s>4)&(s<=7)|(s==1)): 
    #低于40%的生存率
        return 1
    else:
    #无生存率
        return 0
all_data['Family_type']=all_data['Family_size'].map(Family_type)
sns.barplot(x='Family_type',y='Survived',data=all_data)

kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第21张图片

三、 数据清洗

到这里,我们终于可以进行数据清洗了。

1. 缺失值处理

我们先来观察下all_data的缺失值:
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第22张图片
一共三个Age, Embarked, Fare
再来粗略看下统计数据
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第23张图片

(1) Age用均值填充。

all_data['Age']=all_data['Age'].fillna(all_data['Age'].mean())

(2) Fare缺失值处理

Fare虽然缺失值只有1个,可以简单粗暴的使用mean填充,但是不同的路程和舱位等级票价肯定是不一样的,直接使用mean值就不科学。我们调取这条缺失数据看一下
在这里插入图片描述
我们可以看到登船地点是S,舱位等级是3等舱
代码如下

fare=all_data[(all_data['Embarked']=='S')&(all_data['Pclass']==3)].Fare.mean()
all_data['Fare']=all_data['Fare'].fillna(fare)

(3) Embarked缺失值处理

好了,现在就剩下Embarked这个没处理了。
我们当然可以采用登船人数多的那一个口岸作为填充数。先调取数据看一下。

all_data['Embarked'].value_counts()
Out[26]:
S    914
C    270
Q    123
Name: Embarked, dtype: int64

S港口登船的人数最多,所以我们可以选择填‘S’,但是我们可以效仿Fare的处理方式,先观察下数据。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第24张图片
与登船口岸数据相关的就是Fare(票价),除了距离票价也受到舱位等级影响。这里可以看到票价80,1等舱。
我们可以看一下大概在哪个区间:kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第25张图片
这样一看,S最接近,好的,就是S了。

all_data['Embarked']=all_data['Embarked'].fillna('S')

再来看下数据状态,很好,缺失值处理完成。

all_data.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1309 entries, 0 to 417
Data columns (total 16 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
PassengerId    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
Title          1309 non-null object
Cabin_type     1309 non-null object
Family_size    1309 non-null int64
Family_type    1309 non-null int64
dtypes: float64(3), int64(6), object(7)
memory usage: 213.9+ KB

2. 数据类型转换

接下来就是数据的类型转换了,我们将一些为字符串形式的特征转换为数字。

all_data=all_data[['Survived','Pclass','Sex','Age','Fare','Embarked','Title','Cabin_type','Family_type']]
all_data=pd.get_dummies(all_data)

我们来看下代码
我们并不需要所有特征,这里选取我们新增的特征和原有的关键特征:
[‘Survived’,‘Pclass’,‘Sex’,‘Age’,‘Fare’,‘Embarked’,‘Title’,‘Cabin_type’,‘Family_type’]。
接下来看着一条,all_data=pd.get_dummies(all_data)。
pd.get_dummies( )是一个很简单粗暴实用的函数。我们很多时候拿到的数据特征是字符串,需要转化为虚拟变量,就是讲不能定量处理的变量量化,比如我们拿到的Sex原始数据是Female和Male,无法有效进行处理,所以可以将Female=0,Male=1来处理。通过dummies的处理之后数据就成了这个样子。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第26张图片
数据按特征类别分出了列,符合该项特征的为1,不符合为0。而要得到这个结果,并不复杂。我们在pd.get_dummies( )里面输入data这个参数行。但是大家可能已经想到了,dummies明显的缺点就是,当类别数量很多的时候,我们的特征空间会变得非常大。
然后将all_data类型转化好的数据分为X_train和X_test(我们要预测的418名乘客数据),并且将数据转化为矩阵。调用一下就了然了。

train=all_data[all_data['Survived'].notnull()]
X_test=all_data[all_data['Survived'].isnull()].drop('Survived',axis=1)
X_train=train.as_matrix()[:,1:]
X_train[0]

Out[32]:
array([ 3.  , 22.  ,  7.25,  2.  ,  0.  ,  1.  ,  0.  ,  0.  ,  1.  ,
        0.  ,  0.  ,  1.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
        0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  1.  ])

Y_train是与X_train对应的样本特征,即Survived这一栏,我们调用部分Y_train看一下,都是数字0与1。

Y_train=train.as_matrix()[:,0]
Y_train[:15]

Out[31]:
array([0., 1., 1., 1., 0., 0., 0., 0., 1., 1., 1., 1., 0., 0., 0.])

在使用算法模型之前,我们看下shape有个形象的认识。

X_train.shape,Y_train.shape,X_test.shape

Out[34]:
((891, 24), (891,), (418, 24))

四、 构建模型

1. 使用逻辑回归,k邻近算法,随机森林,决策树

好的,接下来咱们就可以开始套用算法模型啦哈哈哈哈,主要使用4种算法:逻辑回归,k邻近算法,随机森林,决策树。别问我为啥不用别的,因为我跟它们不太熟。
先粗略看下:

#Logistic Regression
from sklearn.linear_model import LogisticRegression
logreg=LogisticRegression()
logreg.fit(X_train,Y_train)
Y_pred=logreg.predict(X_test)
log_score=logreg.score(X_train,Y_train)
log_score

Out[35]:
0.8260381593714927
#k近邻算法
from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train,Y_train)
Y_pred=knn.predict(X_test)
knn_score=knn.score(X_train,Y_train)
knn_score

Out[36]:
0.8395061728395061
#随机森林
from sklearn.ensemble import RandomForestClassifier
random_forest= RandomForestClassifier(n_estimators=300)
random_forest.fit(X_train,Y_train)
Y_pred=random_forest.predict(X_test)
rf_score=random_forest.score(X_train,Y_train)
rf_score

Out[37]:
0.9876543209876543
#决策树
from sklearn.tree import DecisionTreeClassifier
decision_tree=DecisionTreeClassifier()
decision_tree.fit(X_train,Y_train)
Y_pred=decision_tree.predict(X_test)
dt_score=decision_tree.score(X_train,Y_train)
dt_score

Out[38]:
0.9876543209876543

哇,得分都挺高的啊,看到这里是不是很激动,别急,我们需要进行交叉验证。

2. 网格搜索交叉验证调整参数

给大家演示调整参数的两种办法,交叉验证手写循环和网格搜索交叉验证。
在进行交叉验证之前,先分割数据

#分割训练数据集
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
a_train,a_test, b_train, b_test=train_test_split(X_train, Y_train, test_size=0.4, random_state=1)

在这里,我们将Train(X_train, Y_train)分成训练集(a_train, b_train)和测试集(a_test, b_test),测试集站40%,随机种子固定为1。到这里有的同学可能有些懵了,别怕,我画了张图,一目了然。
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第27张图片

我们先看一下只使用a_train,b_train时knn交叉验证得出的score
kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第28张图片
首先得到的是有3个元素的元组,这代表着进行了3次交叉验证,我们取平均值,最后得分71.34%左右。
接下来使用手动for循环找到最优参数。

best_score, best_p, best_k=0, 0, 0
for k in range(1,11):
    for p in range(1,11):
        knn_clf=KNeighborsClassifier(weights='distance',n_neighbors=k,p=p)
        scores=cross_val_score(knn_clf,a_train,b_train)
        score=np.mean(scores)
        if score>best_score:
            best_score,best_p,best_k =score, p, k
print('best k=',best_k)
print('best p=',best_p)
print('best score=',best_score)
>>
best k= 7
best p= 1
best score= 0.7696629213483147

将最优参数带回knn算法,此时加上a_test,b_test数据集,得到71.42,与之前的分数有所不同,但是经过新数据测试的得分可信度更高。

best_knn=KNeighborsClassifier(weights='distance',n_neighbors=7, p=1,n_jobs=-1)
best_knn.fit(a_train,b_train)
best_knn.score(a_test,b_test)

Out[41]:
0.7170868347338936

接下来对随机森林和决策树进行网格搜索最优参数,代码如下

#随机森林交叉验证
cross_val_score(random_forest,a_train,b_train).mean()

Out[43]:
0.8464419475655429
from sklearn.model_selection import GridSearchCV
param_grid={
    'n_estimators':[i for i in range(1,50)],
    'max_leaf_nodes':[i for i in range(2,50)],
    'max_depth':[i for i in range(2,10)]
}
random_forest_clf=RandomForestClassifier(random_state=1)
grid_search=GridSearchCV(random_forest_clf,param_grid, n_jobs=-1)
grid_search.fit(a_train,b_train)
grid_search.best_estimator_

Out[44]:RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
                       max_depth=9, max_features='auto', max_leaf_nodes=17,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=8,
                       n_jobs=None, oob_score=False, random_state=1, verbose=0,
                       warm_start=False)
best_random_forest=RandomForestClassifier(n_estimators=8,max_leaf_nodes=17,max_depth=9,random_state=1)
best_random_forest.fit(a_train,b_train)
best_random_forest.score(a_test,b_test)

Out[45]:
0.7955182072829131

这里注意固定一下随机种子。

#决策树交叉验证
cross_val_score(decision_tree,a_train,b_train)
cross_val_score(decision_tree,a_train,b_train).mean()

Out[46]:
0.7902621722846442
param_grid={
     'max_depth':[i for i in range(1,20)],
}
decision_tree_clf=DecisionTreeClassifier(random_state=1)
grid_search=GridSearchCV(decision_tree_clf,param_grid, n_jobs=-1,verbose=2)
grid_search.fit(a_train, b_train)
grid_search.best_estimator_

Out[47]:
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5,
                       max_features=None, max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, presort=False,
                       random_state=1, splitter='best')
best_decision_tree=DecisionTreeClassifier(random_state=1,max_depth=5)
best_decision_tree.fit(a_train, b_train)
best_decision_tree.score(a_test,b_test)

Out[48]:
0.7955182072829131

对于逻辑回归的优化需要使用梯度算法,对于我有些复杂,在这里,我们就简单的使用交叉分析看下分数。

现在,翻到前面看看,是不是得分下降了很多啊,这才是比较可信的得分。

3. 集成算法 Soft Voting

我们使用了4个算法,究竟哪个才是最适合呢,我这里选择集成算法的Soft Voting,即将所有模型预测样本为某一类别的概率的平均值作为标准,概率最高的对应的类型为最终的预测结果。简单形象的说就是把4个算法宝宝集合在一起开会,对418名乘客存活率进行预测。究竟得分多少呢?期待的搓搓手。

#集成学习soft voting
from sklearn.ensemble import VotingClassifier
voting_clf=VotingClassifier(estimators=[
    ('logreg_voting',LogisticRegression()),
    ('knn_voting',KNeighborsClassifier(weights='distance',n_neighbors=7,p=1)),
    ('random_forest_voting',RandomForestClassifier(n_estimators=8,max_leaf_nodes=17,max_depth=9,random_state=1)),
   ( 'decision_tree_voting',DecisionTreeClassifier(max_depth=5,random_state=1))
], voting='soft')
voting_clf.fit(a_train, b_train)
voting_clf.score(a_test,b_test)

Out[49]:
0.8067226890756303

五、存储结果,上传搞定。

#存储预测结果
predictions=voting_clf.predict(X_test)
submission = pd.DataFrame({'PassengerId':PassengerId,'Survived':predictions.astype(np.int32)})
submission.to_csv('C:/Users/笨小孩/Desktop/泰坦尼克/submissional.csv',index=False)

因为predicions的矩阵是浮点数,所以我们需要转化为int32 kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第29张图片
最终存储结果就是这样的啦。kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting_第30张图片

六、总结

到这里,这个case就告一段落了,再继续就是不断优化代码提升排名了。
在刚开始做这个项目的时候,颇有一种无处下手的感觉,参考了很多人的代码(我都在文末贴上了网址,感兴趣的朋友可以去看看)之后,才有了一些思路。可惜的是,很多优秀的算法和代码因为现阶段掌握的知识有限,没能实现。在这里,只能提供给大家笨小孩这略显简陋稚嫩的代码。

下面分享下我对泰坦尼克项目的一些思考:

  1. 预测的准确率与特征工程有很大关系,比如我们挖掘提取出来的Title, Cabin_type等特征。很多时候,数据标签并不等同于数据特征,需要我们对于原始数据进行深度挖掘——最好进行可视化观察,找到数据之间的潜在联系,提高算法的准确率。
  2. 但挖掘出来的数据特征并不一定全部用到,这时需要对每一个特征的相关程度进行划分,把最重要的特征用在模型中。具体的代码实现还需要多研究学习。
  3. 如何对特征下的字符串进行高可信度的归类?比如本案例中对于Title的分类:网上绝大部分帖子没有说明他们归类的方法和原因,因此我只能基于我的英语知识储备+感性直觉进行分类。但是可信度存疑,这也是今后需要进一步关注学习的地方。
  4. 在调参的过程中,我只使用了网格搜索交叉检验,但这个过程并非这么简单,还需要学习曲线,决策边界等等方式来辅助进行。
  5. 对于二分类法,混淆矩阵是否应该放入这个项目中对于精确率和召回率进行判断呢?我想是有必要的,但是在代码实现部分卡壳了,还需要再进一步思考。
  6. 我在最后选择的是集成学习算法,这个算法究竟是不是最合适的算法呢?这点存疑,如果单纯的观察交叉验证平均值,似乎是随机森林的交叉验证分数最高。如何判断哪个算法最适合呢?
    在最后,给大家一些建议: kaggle竞赛可以先上传基本算法得出的结果,在这个基本排名的基础上,慢慢精修代码,实现排名上升,正向强化;作为新手不要太过纠结排名,重要的是算法知识和思路的积累;不要觉得参考别人的代码是一种耻辱,勤奋的模仿练习才能不断的提高,但也不要单纯的照抄代码而不去思考背后的逻辑思路,学而不思则罔,思而不学则殆;大家的时间和精力是有限的,不必去做完每一个竞赛项目,可以专门挑自己喜欢的专业领域进行深挖,培养对于数据特征的敏感。

结束之前推广下我的个人微信公众号:BXH_data,欢迎大家与我沟通交流,共同进步!

最后的最后,用一句话结尾吧:业精于勤荒于嬉,行成于思毁于随!与君共勉。

参考文献
[1]炼己者.kaggle入门–泰坦尼克号之灾(手把手教你) https://www.jianshu.com/p/e79a8c41cb1a,2018.07.26.
[2]起名困难症用户.Kaggle平台Titanic生存率预测项目(TOP3%) https://zhuanlan.zhihu.com/p/50194676,2019-3-2.
[3]大树先生.Kaggle Titanic 生存预测 – 详细流程吐血梳理 https://zhuanlan.zhihu.com/p/31743196,2018-1-15.

你可能感兴趣的:(kaggle 泰坦尼克项目实战(详细代码分享)——集成学习Soft voting)