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

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

二、 数据观察

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

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

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

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

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

这里说明一下,barplot是条形图,传入的参数用于设定x轴,y轴,还有数据源。
在这里插入图片描述

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

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

在这里插入图片描述

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

所以说人越多反而是累赘吗?数量为5和8的人都没能活下来。
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
年龄不是简单的分类值,而是回归数值,所以这里用到了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;
在这里插入图片描述
从上图可以看出来,大约在12岁左侧,生还率有明显的差异,密度图非交叉面积很大。

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

举一反三,我们也可以通过上述代码对票价进行分析:
在这里插入图片描述
这个陡峭的曲线告诉我们,票价越低,越不容易生还。

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

countplot是以bar的形式展示每个类别的数量。
在这里插入图片描述

(8) 名字中提取Title

现在特征还剩Name, Tickect, Cabin,SlibSp,Parch没有进行可视化观察。先观察下Name,似乎有身份职业的提示信息。
在这里插入图片描述
我们调用函数再仔细看看:

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)。
下面来可视化一下
在这里插入图片描述
怎么感觉什么头衔都没有的普普通通Mr最惨啊,存活率好低,不到2成。Master和Officer存活率虽然相对于Mr高,但是仍然低于5成。
我们来分析下代码:
之前我们已经赋值过all_data[‘Title’],即下面这些提取出来的Title字符串。
在这里插入图片描述
all_data[‘Title’]=all_data[‘Title’].map(Title_Dict),这一步实现了什么,我们取all_data的前20行看下。
all_data.head(20)
在这里插入图片描述
结果发现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,然后提取首字母。
在这里插入图片描述
似乎船舱类别不一样也是对存活率有影响的。

(10) 舍弃Ticket特征

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

(11) SlibSp+Parch数据的合并

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

在这里插入图片描述
但是类别太多,无法有效分析,我们需要进一步细化。仔细看来,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)

在这里插入图片描述

三、 数据清洗

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

1. 缺失值处理

我们先来观察下all_data的缺失值:
在这里插入图片描述
一共三个Age, Embarked, Fare
再来粗略看下统计数据
在这里插入图片描述

(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的处理方式,先观察下数据。
在这里插入图片描述
与登船口岸数据相关的就是Fare(票价),除了距离票价也受到舱位等级影响。这里可以看到票价80,1等舱。
我们可以看一下大概在哪个区间:在这里插入图片描述
这样一看,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的处理之后数据就成了这个样子。
在这里插入图片描述
数据按特征类别分出了列,符合该项特征的为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。到这里有的同学可能有些懵了,别怕,我画了张图,一目了然。
在这里插入图片描述

我们先看一下只使用a_train,b_train时knn交叉验证得出的score
在这里插入图片描述
首先得到的是有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 在这里插入图片描述
最终存储结果就是这样的啦。在这里插入图片描述

六、总结

到这里,这个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.

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: Kaggle是一个数据科学竞赛平台,其中有一个经典的比赛题目是泰坦尼克号生存预测。逻辑回归是其中一种常用的机器学习算法,用于分类问题。下面是一个使用逻辑回归算法来预测泰坦尼克号乘客生存率的代码示例。 首先,我们导入需要使用的Python库,例如pandas、numpy和sklearn等。 ```python import pandas as pd import numpy as np from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split ``` 接着,我们读取并预处理训练数据集和测试数据集。 ```python train_data = pd.read_csv('train.csv') test_data = pd.read_csv('test.csv') # 特征选择 features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked'] train_X = train_data[features] train_y = train_data['Survived'] test_X = test_data[features] # 处理缺失值 train_X['Age'].fillna(train_X['Age'].mean(), inplace=True) train_X['Fare'].fillna(train_X['Fare'].mean(), inplace=True) train_X['Embarked'].fillna(train_X['Embarked'].mode()[0], inplace=True) test_X['Age'].fillna(test_X['Age'].mean(), inplace=True) test_X['Fare'].fillna(test_X['Fare'].mean(), inplace=True) test_X['Embarked'].fillna(test_X['Embarked'].mode()[0], inplace=True) # 特征转换 train_X = pd.get_dummies(train_X) test_X = pd.get_dummies(test_X) # 划分训练集和验证集 train_X, val_X, train_y, val_y = train_test_split(train_X, train_y, test_size=0.2, random_state=0) ``` 我们定义一个逻辑回归模型,并用训练集来训练它。 ```python model = LogisticRegression() model.fit(train_X, train_y) ``` 接下来,我们用验证集评估训练好的模型的性能。 ```python accuracy = model.score(val_X, val_y) print("Accuracy:", accuracy) ``` 最后,我们用训练好的模型来预测测试数据集的生存率。 ```python predictions = model.predict(test_X) ``` 这是一个简单的使用逻辑回归算法来预测泰坦尼克号乘客生存率的代码示例。当然,这只是其中的一种实现方式,还可以使用其他特征工程方法、模型调参等来进一步提升预测结果的准确性。 ### 回答2: Kaggle是一个以数据竞赛为主题的在线平台,提供了许多数据科学和机器学习任务。泰坦尼克号逻辑回归代码是指在Kaggle上完成的泰坦尼克号乘客生存预测问题的逻辑回归算法实现。 泰坦尼克号生存预测问题是基于泰坦尼克号船上乘客的数据来预测乘客是否生存的问题。逻辑回归是一种二分类算法,可以用来解决这个问题。 在代码实现上,我们首先要导入所需要的Python库,例如Pandas用于数据处理,Scikit-learn用于机器学习算法实现等。然后,我们需要从Kaggle上下载并导入训练数据和测试数据。 接下来,我们对数据进行预处理。这包括数据清洗、处理缺失值、进行特征工程等步骤。其中,数据清洗包括删除不需要的特征,填充缺失值等。特征工程包括对数据进行编码、标准化、创建新特征等操作。经过预处理后,我们得到可以用于训练和测试的数据集。 然后,我们使用逻辑回归算法对训练数据进行训练。我们将数据集划分为输入特征和目标变量两部分,并使用逻辑回归模型对训练集进行拟合。训练后的模型可以用来预测测试集中乘客的生存情况。 最后,我们对预测结果进行评估。通常使用混淆矩阵、准确率、精确率、召回率等指标来评估模型的性能。 总结来说,Kaggle泰坦尼克号逻辑回归代码的实现包括数据预处理、逻辑回归模型的构建和训练,以及结果评估这几个主要步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值