Titanic数据分析:哪种类型的乘客存活率更高?| Python

Titanic的沉没是历史上最严重的海难之一。1912年4月15日,Titanic第一次航行,与冰山相撞后沉没。不幸的是,船上没有足够的救生艇供所有人使用,导致2224名船员和乘客中的1502人死亡。幸存的人有运气的成份,但也有其他比别人更可能存活的成份存在。那就有一个问题了:哪一类人更容易存活?
有两个数据集,训练集和测试集,都包含乘客的个人信息,比如姓名,性别,年龄,社会经济阶层等,训练集包含乘客是否存活这一信息,而测试集中没有这一信息,本篇文章的目的是预测测试集的乘客是否存活。
训练集的数据形式如下:
在这里插入图片描述
变量描述如下:
PassengerId:乘客编号
Survived:是否存活,1代表存活,0代表死亡
Pclass:船票舱位,可以代表社会经济地位,1代表上等,2代表中等,3代表下等
Name:乘客姓名
Sex:乘客性别
Age:乘客年龄
SibSp:乘客的兄弟姐妹/配偶数
Parch:乘客的父母/子女数
Ticket:票号
Fare:票价
Cabin:舱号
Embarked:登船港口,C代表Ckerbourg,Q代表Queenstown,S代表Southampton
本文将按以下内容进行阐述:
1. 导入库
2. 导入数据
3. 异常值处理
4. 特征分析
5. 缺失值处理
6. 特征工程
7. 数据预处理
8. 建立模型
9. 模型调参
10. 预测输出

导入库

import pandas as pd
import numpy as np
from collections import Counter
import seaborn as sns
import matplotlib.pyplot as plt 
from sklearn.preprocessing import LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier,AdaBoostClassifier,GradientBoostingClassifier,ExtraTreesClassifier,VotingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn import metrics
from sklearn.model_selection import KFold,cross_val_score,GridSearchCV,learning_curve

导入数据

train_data=pd.read_csv(r'C:\Users\****\Desktop\data\Titanic\train.csv')
test_data=pd.read_csv(r'C:\Users\****\Desktop\data\Titanic\test.csv')
train_data.head()

异常值处理

异常值对预测的结果会产生一定的影响,这里采用箱线图判别法来判断数值型数据的样本值是否异常,如果样本有两个以上的值显示异常,则删除该样本。
箱线图判别法是怎么判别的?假设Q1是下四分位数(25%),Q3是上四分位数(75%),IQR是四分位差,则异常值outlier<Q1-1.5IQR或者outlier>Q3+1.5IQR.
为什么要有2个以上的值显示异常才删除样本呢?因为有1个以上异常值的样本有62个,全部删掉不合适,而有3个以上异常值的样本有0个,有2个以上异常值的样本有10个,所以删除有2个以上异常值的样本比较合适。

def detect_outliers(df,n,features):
    outlier_indices=[]
    for col in features:
        Q1=np.percentile(df[col],25)
        Q3=np.percentile(df[col],75)
        IQR=Q3-Q1
        outlier_list_col=df[(df[col] < Q1 - 1.5 * IQR)|(df[col] > Q3 + 1.5 * IQR)].index
        outlier_indices.extend(outlier_list_col)
    outlier_indices=Counter(outlier_indices)
    multiple_outliers=list(k for k,v in outlier_indices.items() if v>n)
    return multiple_outliers
outliers=detect_outliers(train_data,2,['Age','SibSp','Parch','Fare'])
print(train_data.loc[outliers])

检测出来的异常值如下:
在这里插入图片描述

train_data=train_data.drop(outliers,axis=0).reset_index(drop=True)
print(train_data.shape)
(880, 12)

对于这些异常值,直接删除,删除完之后的训练集有880个样本。

特征分析

首先将训练集和测试集合并在一起,记为dataset,并检测dataset的缺失值状况:

dataset=pd.concat(objs=[train_data,test_data],axis=0).reset_index(drop=True)
dataset.shape
(1298, 12)

dataset.isnull().sum()
Age             263
Cabin          1006
Embarked          2
Fare              1
Name              0
Parch             0
PassengerId       0
Pclass            0
Sex               0
SibSp             0
Survived        418
Ticket            0
dtype: int64

合并后的数据集一共有1298个样本,其中变量Age,Cabin,Embarked,Fare有缺失值。

Sex
train_data.groupby(['Sex','Survived'])['Survived'].count()
Sex     Survived
female  0            79
        1           231
male    0           461
        1           109
Name: Survived, dtype: int64

sns.countplot('Sex',hue='Survived',data=train_data)


可以看出,训练集中男性的人数(570)比女性(310)多很多,但存活男性的数量(109)还不到存活女性的数量(231)的一半,女性的存活率达到了74%,而男性的存活率只有20%,这说明Sex是一个对存是否存活影响比较大的特征。

Pclass
pd.crosstab(train_data['Pclass'],train_data['Survived'],margins=True)#绘制交叉表,参数'margins'表示汇总功能的开关

在这里插入图片描述

sns.catplot('Pclass','Survived',data=train_data,kind='bar')

在这里插入图片描述
可以看出,Pclass 1 的存活率最高,高达63%,Pclass 2的存活率为47%,而Pclass 3的存活率最低,为24%,也就是说社会经济地位越高的人,存活的可能性越大。

Embarked

由于变量Embarked有缺失值,在分析前可以先将其填充:

dataset['Embarked'].value_counts()
S    905
C    269
Q    122
Name: Embarked, dtype: int64

dataset['Embarked'].fillna('S',inplace=True)

这是一个分类变量,直接用变量的众数填充即可。

sns.catplot('Embarked','Survived',data=train_data,kind='point')

在这里插入图片描述
可以看到,登船港口不同,存活率也不同,在C港口登船的人,存活率明显高于其他两个港口。

Fare

由于变量Fare存在1个缺失值,且是一个连续性变量,因此可以用其中位数填充:

dataset['Fare'].isnull().sum()
1
dataset['Fare'].fillna(dataset['Fare'].median(),inplace=True)

对于连续性变量,可以看一下其分布图:

sns.distplot(dataset['Fare'],label='Skew:%.2f'%(dataset['Fare'].skew()))
plt.legend()

在这里插入图片描述
可以发现,数据呈现右偏分布,可以通过对数变换降低其偏度系数:

dataset['Fare']=dataset['Fare'].map(lambda i:np.log(i) if i>0 else 0)
sns.distplot(dataset['Fare'],label='Skew:%.2f'%(dataset['Fare'].skew()))
plt.legend()

在这里插入图片描述
对数变换之后的偏度系数明显降低了。

SibSp/Parch
sns.catplot('SibSp','Survived',data=train_data,kind='bar')
plt.ylabel('Survival Probability')

在这里插入图片描述

sns.catplot('Parch','Survived',data=train_data,kind='bar')
plt.ylabel('Survival Probability')

在这里插入图片描述
可以看到,乘客的兄弟姐妹/配属数或者父母/子女数不同,其存活率也不同。当变量SibSp或Parch取值较小时,乘客存活率较高,而当其取值较大时,乘客存活率较小,甚至为0。

Age
g=sns.kdeplot(train_data['Age'][(train_data['Survived'] == 0)&(train_data['Age'].notnull())],color='red',shade=True)
sns.kdeplot(train_data['Age'][(train_data['Survived'] == 1)&(train_data['Age'].notnull())],ax=g,color='blue',shade=True)
g.set_xlabel('Age')
g.set_ylabel('Frequency')
g.legend(['Not Survived','Survived'])
plt.show()

在这里插入图片描述
可以看到,年龄较小的人的存活率比较大,而年龄很大的人存活率很低,甚至为0。

缺失值处理

在进行特征分析的时候,已经填充了变量Embarked和Fare的缺失值,还有变量Age和Cabin的缺失值尚未填充。对于变量Age,可以先考虑与其他变量的关系,这里考虑与变量Sex,Pclass,SibSp,Parch,Embarked,Name的关系,再进行缺失值的填充。

sns.catplot('Sex','Age',data=dataset,kind='box')
plt.title('Age of Different Sex')

在这里插入图片描述

sns.catplot('Pclass','Age',data=dataset,kind='box')
plt.title('Age of Different Pclasses')

在这里插入图片描述

sns.catplot('SibSp','Age',data=dataset,kind='box')
plt.title('Age of Different SibSp')

在这里插入图片描述

sns.catplot('Parch','Age',data=dataset,kind='box')
plt.title('Age of Different Parch')

在这里插入图片描述

sns.catplot('Embarked','Age',data=dataset,kind='box')
plt.title('Age of Different Embarked')

在这里插入图片描述
可以看到,变量Sex,Pclass,SibSp,Parch与Embarked都对变量Age有一定的影响,但变量Sex与Embarked的影响相对较小。接下来考虑变量Name的影响:首先将名字的取值中共同的部分提取出来,然后进行分类。

train_data['Title']=0
for i in dataset:
    dataset['Title']=dataset.Name.str.extract('([A-Za-z]+)\.')
pd.crosstab(dataset['Sex'],dataset['Title'])

在这里插入图片描述

dataset['Title'].replace(['Countess','Lady','Mme'],'Mrs',inplace=True)
dataset['Title'].replace(['Mlle','Ms'],'Miss',inplace=True)
dataset['Title'].replace('Sir','Mr',inplace=True)
dataset['Title'].replace(['Capt','Col','Don','Dona','Dr','Jonkheer','Major','Rev'],'Other',inplace=True)
dataset['Title'].replace(['Master','Miss','Mr','Mrs','Other'],[0,1,2,3,4],inplace=True)

sns.catplot('Title','Age',data=dataset,kind='box')
plt.title('Age of Different Title')

在这里插入图片描述
可以看到,对变量Name进行处理之后得到的变量Title对变量Age的影响也比较大,接下来绘制热力图,观察这些变量之间的相关系数。

dataset['Sex'].replace(['male','female'],[0,1],inplace=True)
dataset['Embarked'].replace(['S','C','Q'],[0,1,2],inplace=True)

sns.heatmap(dataset[['Age','Fare','SibSp','Parch','Sex','Embarked','Pclass','Title']].corr(),annot=True)

在这里插入图片描述
可以看到,与变量Age的相关系数最大的两个变量是Pclass和Title,接下来用这两个变量的均值填充变量Age的缺失值。

sns.catplot('Title','Age',hue='Pclass',data=dataset,kind='bar')

在这里插入图片描述

dataset.groupby(['Pclass','Title'])['Age'].mean()
Pclass  Title
1       0         6.984000
        1        30.250000
        2        41.500000
        3        42.857143
        4        48.533333
2       0         2.757273
        1        20.865714
        2        32.346715
        3        33.518519
        4        40.700000
3       0         6.229063
        1        17.471700
        2        28.318910
        3        32.326531
Name: Age, dtype: float64

dataset.loc[(dataset['Pclass']==1)&(dataset['Title']==0)&(dataset['Age'].isnull()),'Age']=6.98
dataset.loc[(dataset['Pclass']==1)&(dataset['Title']==1)&(dataset['Age'].isnull()),'Age']=30.25
dataset.loc[(dataset['Pclass']==1)&(dataset['Title']==2)&(dataset['Age'].isnull()),'Age']=41.5
dataset.loc[(dataset['Pclass']==1)&(dataset['Title']==3)&(dataset['Age'].isnull()),'Age']=42.86
dataset.loc[(dataset['Pclass']==1)&(dataset['Title']==4)&(dataset['Age'].isnull()),'Age']=48.53
dataset.loc[(dataset['Pclass']==2)&(dataset['Title']==0)&(dataset['Age'].isnull()),'Age']=2.76
dataset.loc[(dataset['Pclass']==2)&(dataset['Title']==1)&(dataset['Age'].isnull()),'Age']=20.87
dataset.loc[(dataset['Pclass']==2)&(dataset['Title']==2)&(dataset['Age'].isnull()),'Age']=32.35
dataset.loc[(dataset['Pclass']==2)&(dataset['Title']==3)&(dataset['Age'].isnull()),'Age']=33.52
dataset.loc[(dataset['Pclass']==2)&(dataset['Title']==4)&(dataset['Age'].isnull()),'Age']=40.7
dataset.loc[(dataset['Pclass']==3)&(dataset['Title']==0)&(dataset['Age'].isnull()),'Age']=6.23
dataset.loc[(dataset['Pclass']==3)&(dataset['Title']==1)&(dataset['Age'].isnull()),'Age']=17.47
dataset.loc[(dataset['Pclass']==3)&(dataset['Title']==2)&(dataset['Age'].isnull()),'Age']=28.32
dataset.loc[(dataset['Pclass']==3)&(dataset['Title']==3)&(dataset['Age'].isnull()),'Age']=32.33
dataset['Age'].isnull().sum()
0

对于变量Cabin,缺失值太多,这里将变量Cabin的缺失值记为’X’并提取出非缺失值的第一个字母:

dataset['Cabin']=pd.Series(i[0] if not pd.isnull(i) else 'X' for i in dataset['Cabin'])
dataset['Cabin'].value_counts()
X    1006
C      92
B      64
D      46
E      41
A      22
F      21
G       5
T       1
Name: Cabin, dtype: int64

sns.catplot('Cabin','Survived',data=dataset,kind='point')

在这里插入图片描述
可以看出,Cabin取值不同,乘客的存活率不同。

特征工程

对于Parch和SibSp这两个特征,可以将其组合在一起作为变量FamilySize,分析家属人员的多少对存活的影响,并且可以再创建一个特征Alone来分析有家属陪伴和没有家属陪伴对存活的影响。

train_data['FamilySize']=train_data['SibSp']+train_data['Parch']
f,ax=plt.subplots(1,2,figsize=(16,7))
sns.barplot('FamilySize','Survived',data=train_data,ax=ax[0])
sns.catplot('FamilySize','Survived',data=train_data,kind='point',ax=ax[1])

在这里插入图片描述

train_data['Alone']=0
train_data.loc[train_data['FamilySize']==0,'Alone']=1
sns.catplot('Alone','Survived',data=train_data,kind='point')
plt.title('Alone VS Survived')

在这里插入图片描述
对训练集中Family,Alone与Survived变量的分析,可以看出,Family的不同取值以及是否孤单都对是否存活有较大的影响。

dataset['FamilySize']=dataset['SibSp']+dataset['Parch']
dataset['Alone']=0
dataset.loc[dataset['FamilySize']==0,'Alone']=1

数据预处理

对于变量Cabin,直接将其转换为数值型变量:

le=LabelEncoder()
dataset['Cabin']=le.fit_transform(dataset['Cabin'])
dataset['Cabin'].value_counts()
8    1006
2      92
1      64
3      46
4      41
0      22
5      21
6       5
7       1
Name: Cabin, dtype: int64

对于变量Ticket,进行处理之后转换为数值型变量:

Ticket=[]
for i in dataset['Ticket']:
    if not i.isdigit():
        Ticket.append(i.replace('.','').replace('/','').strip().split(' ')[0])
    else:
        Ticket.append('X')
dataset['Ticket']=Ticket
dataset['Ticket']=le.fit_transform(dataset['Ticket'])

接着,将数据集拆分为训练集和测试集,并将没用的变量删掉。

IDtest=dataset['PassengerId'][880:]
dataset.drop(['Name','Parch','SibSp','PassengerId'],axis=1,inplace=True)
train_data=dataset[:880]
test_data=dataset[880:]
test_data.drop('Survived',axis=1,inplace=True)
test_data.head()

在这里插入图片描述
最后,分出X_train和Y_train :

X_train=train_data.drop('Survived',axis=1)
Y_train=train_data['Survived']

建立模型

random_state=2
classifiers=['Logistic Regression','Radial Svm','Linear Svm','Random Forest','KNN','Gaussian','Decision Tree','AdaBoost','GradientBoost','Extra Trees']

models=[]
models.append(LogisticRegression(random_state=random_state))
models.append(SVC(kernel='rbf',random_state=random_state))
models.append(SVC(kernel='linear',random_state=random_state))
models.append(RandomForestClassifier(random_state=random_state))
models.append(KNeighborsClassifier(n_neighbors=11))
models.append(GaussianNB())
models.append(DecisionTreeClassifier(random_state=random_state))
models.append(AdaBoostClassifier(DecisionTreeClassifier(random_state=random_state),random_state=random_state))
models.append(GradientBoostingClassifier(random_state=random_state))
models.append(ExtraTreesClassifier(random_state=random_state))

cv_results=[]
for model in models:
    cv_results.append(cross_val_score(model,X_train,y=Y_train,scoring='accuracy',cv=kfold))
cv_means=[]
cv_std=[]
for cv_result in cv_results:
    cv_means.append(cv_result.mean())
    cv_std.append(cv_result.std())

result=pd.DataFrame({'CrossValMeans':cv_means,'CrossValStd':cv_std},index=classifiers)
result.sort_values(by='CrossValMeans',ascending=False,inplace=True)
print(result)
                     CrossValMeans  CrossValStd
GradientBoost             0.811364     0.056636
Random Forest             0.797727     0.030829
Logistic Regression       0.796591     0.022413
Extra Trees               0.795455     0.028748
Linear Svm                0.788636     0.039101
Gaussian                  0.786364     0.040592
AdaBoost                  0.777273     0.073504
KNN                       0.747727     0.046798
Radial Svm                0.744318     0.051639
Decision Tree             0.742045     0.095488
sns.barplot('CrossValMeans',result.index,data=result,orient='h')
plt.title('Cross Validation Scores')

在这里插入图片描述
这里将对GradientBoost,Random Forest,Logistic Regression,Extra Trees,SVM,AdaBoost六个模型的参数进行调整:

#GradientBoost
param_grid={'n_estimators':range(100,500,100),'loss':['deviance'],'learning_rate':[0.0001,0.001,0.01,0.1]}
gbc=GridSearchCV(estimator=GradientBoostingClassifier(),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
gbc.fit(X_train,Y_train)
print(gbc.best_estimator_)

在这里插入图片描述

gbc.best_score_
0.8295454545454546
#RandomForest
param_grid={'min_samples_split':[3,10,15],'n_estimators':range(100,500,100),'max_features':[8,10]}
rf=GridSearchCV(estimator=RandomForestClassifier(),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
rf.fit(X_train,Y_train)
print(rf.best_estimator_)

在这里插入图片描述

rf.best_score_
0.8272727272727273
#LogisticRegression
param_grid={'solver':['liblinear','lbfgs','newton-cg','sag'],'multi_class':['ovr']}
lr=GridSearchCV(estimator=LogisticRegression(),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
lr.fit(X_train,Y_train)
lr.best_estimator_

在这里插入图片描述

lr.best_score_
0.7965909090909091
#extratress
param_grid={'n_estimators':range(100,500,100),'min_samples_split':[5,10,15],'max_features':[6,8,10]}
extc=GridSearchCV(estimator=ExtraTreesClassifier(),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
extc.fit(X_train,Y_train)
print(extc.best_estimator_)

在这里插入图片描述

extc.best_score_
0.8193181818181818
#svm
kernel=['rbf','linear']
gamma=[0.001,0.01,0.1]
C=[0.1,0.5,1,10]
param_grid={'kernel':kernel,'gamma':gamma,'C':C}
svm=GridSearchCV(estimator=SVC(probability=True),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
svm.fit(X_train,Y_train)
print(svm.best_estimator_)

在这里插入图片描述

svm.best_score_
0.7909090909090909
#Adaboost
param_grid={'base_estimator__criterion':['gini','entropy'],'base_estimator__splitter':['best','random'],'algorithm':['SAMME'],'n_estimators':[10,50,100],'learning_rate':[0.0001,0.001,0.01,0.1]}
ada=GridSearchCV(AdaBoostClassifier(DecisionTreeClassifier(),random_state=2),param_grid=param_grid,cv=kfold,scoring='accuracy',verbose=True)
ada.fit(X_train,Y_train)
print(ada.best_estimator_)

在这里插入图片描述

ada.best_score_
0.7931818181818182

学习曲线可以用来查看模型是否过拟合,以及训练集的大小对模型准确度的影响,这里将绘制以上模型的学习曲线:

def plot_learning_curve(estimator,title,X,Y,ylim=None,cv=None,train_sizes=np.linspace(0.1,1.0,5)):
    plt.figure()
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel('Training Examples')
    plt.ylabel('Score')
    train_size,train_score,test_score=learning_curve(estimator,X,Y,cv=cv,train_sizes=train_sizes)
    train_score_mean=np.mean(train_score,axis=1)
    train_score_std=np.std(train_score,axis=1)
    test_score_mean=np.mean(test_score,axis=1)
    test_score_std=np.std(test_score,axis=1)
    plt.grid()
    plt.fill_between(train_sizes,train_score_mean-train_score_std,train_score_mean+train_score_std,alpha=0.1,color='r')
    plt.fill_between(train_sizes,test_score_mean-test_score_std,test_score_mean+test_score_std,alpha=0.1,color='g')
    plt.plot(train_sizes,train_score_mean,'o-',color='r',label='Training Score')
    plt.plot(train_sizes,test_score_mean,'o-',color='g',label='Cross-Validation Score')
    plt.legend('best')
    return plt

plot_learning_curve(gbc.best_estimator_,title='Gradient Boosting learning curve',X=X_train,Y=Y_train,cv=kfold)
plot_learning_curve(rf.best_estimator_,title='Random Forest learning curve',X=X_train,Y=Y_train,cv=kfold)
plot_learning_curve(lr.best_estimator_,title='Logistic Regression learning curve',X=X_train,Y=Y_train,cv=kfold)
plot_learning_curve(extc.best_estimator_,title='Extra Trees learning curve',X=X_train,Y=Y_train,cv=kfold)
plot_learning_curve(svm.best_estimator_,title='SVM learning curve',X=X_train,Y=Y_train,cv=kfold)
plot_learning_curve(ada.best_estimator_,title='AdaBoost learning curve',X=X_train,Y=Y_train,cv=kfold)

在这里插入图片描述
可以看出,GradientBoost的模型效果最好,而Extra Trees和AdaBoost模型都出现了较严重的过拟合现象。
为了观察最能影响乘客是否存活的因素,这里将展示基于树的分类器的特征重要性:

models=[rf.best_estimator_,gbc.best_estimator_,extc.best_estimator_,ada.best_estimator_,]
names=['Random Forest','GradientBoosting','Extra Trees','AdaBoost']
for model in models:
    indices=np.argsort(model.feature_importances_)[::-1]
    sns.barplot(y=X_train.columns[indices],x=model.feature_importances_[indices],orient='h')
    plt.xlabel('Relative Importance')
    plt.ylabel('Features')
    plt.title(names[models.index(model)]+'Feature Importance')
    plt.show()

在这里插入图片描述
可以看到,虽然每个模型的最重要的特征不完全一样,但存在一些共同的比较重要的特征,比如Sex,Age,Pclass。

预测输出

test_svm=pd.Series(svm.best_estimator_.predict(test_data),name='svm')
test_rf=pd.Series(rf.best_estimator_.predict(test_data),name='rf')
test_gbc=pd.Series(gbc.best_estimator_.predict(test_data),name='gbc')
test_extc=pd.Series(extc.best_estimator_.predict(test_data),name='extc')
test_ada=pd.Series(ada.best_estimator_.predict(test_data),name='ada')
test_lr=pd.Series(lr.best_estimator_.predict(test_data),name='lr')
results=pd.concat([test_svm,test_rf,test_gbc,test_extc,test_ada,test_lr],axis=1)
results.head()

在这里插入图片描述
绘制热力图观察预测结果之间的相似性:

sns.heatmap(results.corr(),annot=True)

在这里插入图片描述
可以看到,除了个别相似系数外,绝大部分的相似系数都大于0.7。
将以上几个模型集成在一起,使用soft voting方式进行最后的预测并写入csv文件:

voting=VotingClassifier(estimators=[('svm',svm.best_estimator_),('rf',rf.best_estimator_),('gbc',gbc.best_estimator_),('extc',extc.best_estimator_),('ada',ada.best_estimator_),('lr',lr.best_estimator_)],voting='soft')
voting=voting.fit(X_train,Y_train)
test_Survived=pd.Series(voting.predict(test_data),name='Survived')

IDtest=IDtest.reset_index(drop=True)
final_result=pd.concat([IDtest,test_Survived],axis=1)
final_result.to_csv(r'C:\Users\****\Desktop\data\Titanic\Titanic Rediction Result.csv',index=False)

最后将该文件上传至Kaggle,得分0.76555
在这里插入图片描述
得分有点低,我挑选了三个模型(这些模型在学习曲线中表现较好)重新进行集成,得分0.77511

voting=VotingClassifier(estimators=[('rf',rf.best_estimator_),('gbc',gbc.best_estimator_),('lr',lr.best_estimator_)],voting='soft')

在这里插入图片描述
之后,我又换用了hard voting集成,得分0.78947

voting=VotingClassifier(estimators=[('rf',rf.best_estimator_),('gbc',gbc.best_estimator_),('lr',lr.best_estimator_)],voting='hard')

在这里插入图片描述
这便是最终得分及排名:
在这里插入图片描述
参考文章:
[https://www.kaggle.com/yassineghouzam/titanic-top-4-with-ensemble-modeling]
[https://www.kaggle.com/ash316/eda-to-prediction-dietanic]

反思总结
  • 要慎重考虑一个变量是否可以删除。最初我的想法是,直接删除变量Cabin,Name,及Title,我的理由是Cabin中缺失值太多,Name和Ticket就像变量PassengerId一样,不具备什么分析价值,我没有意识到变量Cabin还有别的处理方式,比如将所有缺失值记为一类,变量Name和Ticket中其实还有隐藏的信息值得挖掘。
  • 特征处理很重要。我大部分的时间都用于数据的处理(包括特征分析,缺失值异常值处理,特征处理等),尝试了多种方法,最终的方法如本文所展示。
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值