泰坦尼克是Kaggle上非常经典的一个项目,首先我们从Kaggle上下载数据集(https://www.kaggle.com/c/titanic)。数据集已经帮我们分好了训练集和测试集,其中训练集中包含了部分乘客名单、各种特征以及是否幸存的标签,而在测试集中是我们需要预测的乘客名单和相应的特征,我们需要做的就是通过对训练集数据进行探索,然后构建机器学习模型,利用这个模型来预测测试集中的乘客生存情况,最后我们将预测结果提交给Kaggle就可以啦。
本次项目说明:
- 编程语言:Python
- 编译工具:jupyter notebook
- 涉及到的库:pandas,numpy,matplotlib,sklearn
1. 数据概览
首先我们导入相关的库以及读取数据,
# 导入相关库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
data_train = pd.read_csv('train.csv')
data_test = pd.read_csv('test.csv')
我们来看下数据的整体特征
data_train[:5]
部分字段解释:
- PassengerID:乘客ID
- Survied:是否获救
- Pclass:船舱等级
- SibSp:同行堂兄妹个数
- Parch:同行父母与小孩个数
- Ticket:船票编号
- Fare:票价
- cabin:客舱
- Embarked:登船港口
data_train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
从上面的数据我们可以发现,训练集数据一共891行,其中Age和Cabin这两列缺失值较多,Embarked列有2行缺失。
然后我们分别来来看下数值型和字符型数据的情况。
# 数值型数据的情况
data_train.describe()
从上面对数值列的统计可以发现:
- 一共891名乘客,获救的概率是38%(Survived列的均值)
- Pclass的均值是2.3就意味着2,3等级船舱的人数要多于1等仓
- 整个船的乘客年龄均值是29.6岁,最大的乘客80岁,最小的才4个月
- 最贵的票512美金,最便宜的0元,票的均价是32美金
# 字符型数据的情况
data_train.describe(include=['O'])
从上面对字符数据统计可以发现:
- 891名乘客中没有同名同姓的
- 男性乘客有577名,比女性多
- S港口登船的人最多,共计644人
2. 数据分析与可视化
每个乘客都有N项属性,那哪些属性和最后获救的结果有关,这些属性和最后获救结果(Survived)之间的关系又是怎样的?
所以我们要对数据进行分析,同时进行可视化更直观的来认识这些数据。
2.1 乘客属性分布
首先我们来粗略的看下乘客的各个属性分布,比如说获救与遇难的人数比例,各个港口的登船比例,乘客船舱分布,不同船舱的年龄分布等,来对数据有一个更加深刻的认知!
%matplotlib notebook
fig = plt.figure()
plt.subplot2grid((2,3),(0,0))
data_train.Survived.value_counts().plot(kind='bar')
plt.ylabel(u'人数',fontproperties='SimHei')
plt.title(u'获救/遇难人数对比',fontproperties='SimHei')
plt.subplot2grid((2,3),(0,1))
data_train.Pclass.value_counts().plot(kind='bar')
plt.ylabel(u'人数',fontproperties='SimHei')
plt.title(u'乘客船舱分布',fontproperties='SimHei')
plt.subplot2grid((2,3),(0,2))
plt.scatter(data_train.Survived,data_train.Age)
plt.ylabel(u'年龄',fontproperties='SimHei')
plt.title(u'按年龄看获救分布',fontproperties='SimHei')
plt.subplot2grid((2,3),(1,0),colspan=2)
data_train.Age[data_train.Pclass==1].plot(kind='kde')
data_train.Age[data_train.Pclass==2].plot(kind='kde')
data_train.Age[data_train.Pclass==3].plot(kind='kde')
plt.legend((u'1',u'2',u'3'),loc='best',)
plt.ylabel(u'密度',fontproperties='SimHei')
plt.title(u'各等级船舱的乘客年龄分布',fontproperties='SimHei')
plt.subplot2grid((2,3),(1,2))
data_train.Embarked.value_counts().plot(kind='bar')
plt.ylabel(u'人数',fontproperties='SimHei')
plt.title(u'各登船口岸的上船人数',fontproperties='SimHei')
可以发现:
- 整个泰坦尼克号中,遇难人数要多于获救人数,获救人数只要350人不到
- 3等舱的乘客最多,让人意外的是1等舱的乘客比2等舱的乘客还要多
- 船舱等级越高,平均年龄也越高,这个也是符合财富分布与年龄之间的关系的
- S港口登船人数最多,比其他两个港口登船人数加一起还多
2.2 各个属性与获救结果之间的关系
数据集中有很多列,哪些列是影响最后获救结果的特征呢?这些属性具体又是怎么影响获救的呢?
从直觉上来说,乘客的ID、姓名、船票编号这些和最后是否被获救关系不大,所以在这里我们排除PaddengerID,Name,Ticket这几列,然后一个一个的来看每个属性与获救与否是否之间的关系。
2.2.1 船舱等级与获救结果之间的关系
%matplotlib notebook
pclass_0=data_train.Pclass[data_train.Survived==0].value_counts()
pclass_1=data_train.Pclass[data_train.Survived==1].value_counts()
df=pd.DataFrame({'Victim':pclass_0,'Survival':pclass_1})
df.plot(kind='bar',stacked=True)
plt.title('不同等级船舱的获救/遇难人数',fontproperties='SimHei')
plt.xlabel('船舱等级',fontproperties='SimHei')
plt.ylabel('人数',fontproperties='SimHei')
1等舱的人总数很少,但是获救的人数确实最多的,可能觉得这样看不是很明显,那么我们将每个船舱的获救的概率画出来,就更明显了。
%matplotlib notebook
df=pd.DataFrame({'Victim':pclass_0,'Survival':pclass_1})
df = df.div(df.sum(axis=1),axis=0)
df.plot(kind='bar',stacked=True)
plt.title('不同等级船舱的获救比例',fontproperties='SimHei')
plt.xlabel('船舱等级',fontproperties='SimHei')
船舱的等级越高,获救的概率越大,在1等舱,有60%以上的乘客获救了,而在2等舱,稍微低一些,大概45%左右,而在3等舱,则只有25%不到的乘客获救,所以船舱等级一定是影响最后是否获救的一个特征。
2.2.2 性别与获救结果之间的关系
%matplotlib notebook
df=(data_train.Sex[data_train.Survived==1].value_counts()/data_train.Sex.value_counts())
df.plot(kind='bar')
plt.ylabel(u'在对应性别中的比例',fontproperties='SimHei')
plt.title(u'获救者中的性别情况',fontproperties='SimHei')
可以发现有女性中有70%以上获救了,而只有20%不到的男性获救,所以性别也是影响最后是否获救的一个特征。
我们再来看下获救与遇难的人数中性别的比例!
%matplotlib notebook
survived_f = data_train.Survived[data_train.Sex=='female'].value_counts()
survived_m = data_train.Survived[data_train.Sex=='male'].value_counts()
df = pd.DataFrame({'female':survived_f,'male':survived_m})
df.plot(kind='bar',stacked=True)
plt.ylabel(u'人数',fontproperties='SimHei')
plt.title(u'按性别看获救情况',fontproperties='SimHei')
在获救的乘客中,女性的人数要明显多于男性乘客的人数,而在遇难乘客中,男性乘客远多于女性乘客。
那么我们再进一步,来看下不同船舱中的性别获救情况。
#不同船舱的女性获救情况
%matplotlib notebook
fig = plt.figure()
plt.subplot2grid((1,3),(0,0))
data_train.Survived[data_train.Sex=='female'][data_train.Pclass==1].value_counts()[[0,1]].plot(kind='bar')
plt.title(u'1等舱女性获救情况',fontproperties='SimHei')
plt.subplot2grid((1,3),(0,1))
data_train.Survived[data_train.Sex=='female'][data_train.Pclass==2].value_counts()[[0,1]].plot(kind='bar')
plt.title(u'2等舱女性获救情况',fontproperties='SimHei')
plt.subplot2grid((1,3),(0,2))
data_train.Survived[data_train.Sex=='female'][data_train.Pclass==3].value_counts()[[0,1]].plot(kind='bar')
plt.title(u'3等舱女性获救情况',fontproperties='SimHei')
在所有的船舱,女性获救的人数都是大于等于遇难的女性,尤其是在1/2等舱女性的获救概率很高,而到了3等舱,获救的概率就明显下降,获救率和死亡率各占50%。
#不同船舱的男性获救情况
%matplotlib notebook
fig = plt.figure()
plt.subplot2grid((1,3),(0,0))
data_train.Survived[data_train.Sex=='male'][data_train.Pclass==1].value_counts().plot(kind='bar')
plt.title(u'1等舱男性获救情况',fontproperties='SimHei')
plt.subplot2grid((1,3),(0,1))
data_train.Survived[data_train.Sex=='male'][data_train.Pclass==2].value_counts().plot(kind='bar')
plt.title(u'2等舱男性获救情况',fontproperties='SimHei')
plt.subplot2grid((1,3),(0,2))
data_train.Survived[data_train.Sex=='male'][data_train.Pclass==3].value_counts().plot(kind='bar')
plt.title(u'3等舱男性获救情况',fontproperties='SimHei')
在所有的船舱中,男性遇难的人数都是多于获救的人数,而且3等舱中遇难的男性人数非常多,远多于其他两个船舱。
2.2.3 年龄与获救结果之间的关系
由于年龄这个字段缺失值很多(缺失值处理这块我们后面数据预处理时再说),所以我们可以先来看下有年龄记录和没有年龄记录之间是否存在获救概率的差异,然后我们再来看下有年龄数据的乘客中获救与遇难乘客的分布是怎样的。
%matplotlib notebook
survived_y = data_train.Survived[data_train.Age.notnull()].value_counts()
survived_n = data_train.Survived[data_train.Age.isnull()].value_counts()
df = pd.DataFrame({'yes':survived_y,'no':survived_n})
df = df.T
df.plot(kind='bar',stacked=True)
plt.title(u'有无年龄数据与是否获救之间的关系',fontproperties='SimHei')
好像这里我们并没有看到很明显的关系,所以下面就来看下有年龄数据的乘客中获救/遇难乘客的年龄分布。
%matplotlib notebook
data_train.Age[data_train.Survived==0].plot(kind='kde')
data_train.Age[data_train.Survived==1].plot(kind='kde')
plt.xticks(range(-40,125,10))
plt.legend([0,1],loc='best')
plt.title('获救与遇难乘客的年龄的分布',fontproperties='SimHei')
从上面的密度图可以看到,对13岁以下的小朋友来说,获救的概率要高于死亡概率,这个可能还是和“女士和小孩先走”的口号有关,而在13-30这个年龄段,死亡率要明显高于获救率,到了30-57岁,获救与死亡概率基本差不太多,而在57岁-78之间,死亡率要大于获救概率。
所以从这里可以看到其实年龄和最后获救结果是直接相关的。
2.2.4 同行堂兄妹个数与获救结果之间的关系
%matplotlib notebook
sibsp_0 = data_train.SibSp[data_train.Survived==0].value_counts()
sibsp_1 = data_train.SibSp[data_train.Survived==1].value_counts()
df = pd.DataFrame({'遇难':sibsp_0,'获救':sibsp_1})
df.plot(kind='bar')
plt.legend(('Victim',u'Survival'),loc='best')
plt.title('不同堂兄妹个数的获救人数',fontproperties='SimHei')
可以发现同行有1-2名堂兄妹的时候,获救率是最高的,再多的话,获救率又开始下降了。
我们可以更加形象一点,画出获救乘客在其对应的堂兄妹数量分组中的占比。
%matplotlib notebook
arr = (data_train.SibSp[data_train.Survived==1].value_counts()/df.sum(axis=1))
arr.plot(kind='bar')
plt.title('获救乘客在其对应堂兄妹个数下的占比',fontproperties='SimHei')
可以看到这个图表有点像正偏态分布,当只有1-2名同行唐兄妹时,获救的概率最高,人数再多的话,获救率又开始下降了。
2.2.5 同行父母/小孩的数量与获救结果之间的关系
%matplotlib notebook
parch_0 = data_train.Parch[data_train.Survived==0].value_counts()
parch_1 = data_train.Parch[data_train.Survived==1].value_counts()
df = pd.DataFrame({'遇难':parch_0,'获救':parch_1})
df.plot(kind='bar')
plt.legend(('Victim',u'Survival'),loc='best')
plt.title('不同父母/子女个数的获救人数',fontproperties='SimHei')
%matplotlib notebook
arr = (data_train.Parch[data_train.Survived==1].value_counts()/df.sum(axis=1))
arr.plot(kind='bar')
plt.title('获救乘客在其对应父母/子女个数下的占比',fontproperties='SimHei')
父母/子女个数和获救概率的关系和堂兄妹和获救率的关系有点像,都是呈一个类似于正态分布的关系,当1-3名父母/子女个数时,获救概率最高,过多和过少,获救概率都呈下降趋势。
2.2.5 票价的数量与获救结果之间的关系
票价和船舱一样,也是反应乘客身份的信息之一,既然不同的船舱乘客的获救率不同,那么不同票价的乘客获救率也肯定不同。
我们可以先来看下整个船的票价分布情况以及不同船舱的船票价格情况。
%matplotlib notebook
data_train.Fare.plot(kind='hist',bins=70)
plt.xticks(range(0,600,50))
plt.title(u'船票价格分布',fontproperties='SimHei')
%matplotlib notebook
data_train.boxplot(column='Fare', by='Pclass',showfliers=False,grid=False,showmeans=True)
plt.title('不同船舱的票价情况',fontproperties='SimHei')
可以发现,绝大多数乘客的票价都是在0-100之间,而且2等舱和3等舱的价格相差的不是特别多,均值都在25以下,而1等舱的价格,不管是均值还是中位数都要明显高于2/3等舱。
那么获救乘客与遇难乘客的船票价格分布又是怎样的呢?是否和船舱一样,高票价意味着更高的获救概率?
%matplotlib notebook
data_train.boxplot(column='Fare', by='Survived',showfliers=False,grid=False,showmeans=True)
和船舱一样,获救乘客的票价不论是均值还是中位数都要明显高于遇难乘客,我们可以通过密度图来更进一步观察。
%matplotlib notebook
data_train.Fare[data_train.Survived==0].plot(kind='kde')
data_train.Fare[data_train.Survived==1].plot(kind='kde')
plt.xlim((0,600))
plt.xticks(range(0,600,50))
plt.legend([0,1],loc='best')
plt.title('获救与遇难乘客的年龄的分布',fontproperties='SimHei')
当票价在30左右时是一个分水岭,小于30,死亡率高于获救率,大于30,获救的概率就要高于死亡的概率,所以和船舱等级一样,票价也是影响最后获救结果很重要的一个特征。
2.2.6 客舱与获救结果之间的关系
由于客舱这一列的缺失数据非常多,而且这是数据很不集中,所以在这里我们将数据分为有无客舱信息,来看下有无客舱信息与获救结果之间的关系。
%matplotlib notebook
survived_y = data_train.Survived[data_train.Cabin.notnull()].value_counts()
survived_n = data_train.Survived[data_train.Cabin.isnull()].value_counts()
df = pd.DataFrame({'yes':survived_y,'null':survived_n})
df = df.T
df.plot(kind='bar',stacked=True)
plt.title('按有无客舱信息查看获救情况',fontproperties='SimHei')
%matplotlib notebook
df.div(df.sum(axis=1),axis=0).plot(kind='bar',stacked=True)
plt.title('按有无客舱查看获救/遇难的人数比例',fontproperties='SimHei')
发现如果有客舱信息的话,获救的概率确实要大一点,在有客舱信息的乘客中有超过60%都获救了,而在没有客舱信息的组中,只有20%多获救了。
2.2.7 登船港口与获救结果之间的关系
%matplotlib notebook
embarked_0 = data_train.Embarked[data_train.Survived==0].value_counts()
embarked_1 = data_train.Embarked[data_train.Survived==1].value_counts()
df = pd.DataFrame({0:embarked_0,1:embarked_1})
df.plot(kind='bar')
plt.title('不同港口登船的乘客获救情况',fontproperties='SimHei')
可以发现S港口登船的乘客最多,但是只有C港口登船的乘客中获救人数要多于遇难人数,而其他两个港口登船乘客中遇难人数都要多于获救乘客人数。
3. 数据预处理
终于到我们最重要的一步:数据预处理,在这一步中,我们需要对数据进行清洗(处理空值/重复值),分类数据(也就是特征因子化)以及特征缩放。
我们之前在数据概览中看到,Name这一列没有重复,所以在这里我们就不用处理重复值了,那么第一步,我们来处理缺失值。
3.1缺失数据处理
对缺损的数据的处理可以选择的处理可以选择以下几种方式:
- 直接删除此特征(缺损数据太多的情况,防止引入噪声)
- 直接删除缺损数据的样本(只用于训练数据集,且样本量较大,缺损数据样本较少的情况)
- 直接将有无数值作为新的特征(数据缺失较多,且数据有无本身是对预测是一个有用的特征)
- 中值或均值回补(缺失数据较多,不想损失此较多训练数据,特征又比较重要的情况,是比较常用的方法)
- 参考其他特征,利用与此特征的相关性编写算法回补数据(回补的准确性可能会比较高一些,但实现过程复杂)
这几种方法具体使用哪一个需要根据实际情况决定,选用复杂的方法得到的结果不一定就好。
在这里我们一共有3列数据存在缺失值,分别是Age,Cabin,Embarked。这三列我们的处理方式分别是:
- Embarked列由于缺失值很少,只有2行,所以对于Embarked列,我们选择用众数来填充缺失值
- Carbin列我们选择将有无数值作为新的特征
- Age列采取最复杂的方法,使用随机森林进行数据回补(不是说使用算法回补,准确性就一定高哈)
另外我们将Age和Fare列根据上方与获救结果之间的关系图表进行离散化处理,所以也不需要特征缩放了。
# 这里我们将data_train复制一份,后面的数据处理/建模就用这个复制的变量,原始数据不去动他
train_data = data_train.copy()
Embarked列处理
train_data['Embarked'].fillna(train_data['Embarked'].mode().iloc[0],inplace=True)
Carbin列处理
def func_one(x):
if type(x)==str:
return 'yes'
else:
return 'no'
train_data['Cabin'] = train_data['Cabin'].map(func_one)
Age列处理
# 导入随机森林的回归器
from sklearn.ensemble import RandomForestRegressor
# 将已有的数值型特征都喂给随机森林的回归器
age_df = train_data[['Age','SibSp','Fare','Parch','Pclass']]
# 乘客分为已知年龄和未知年龄两组
know_age = age_df[age_df['Age'].notnull()].iloc[:,:].values
unknow_age = age_df[age_df['Age'].isnull()].iloc[:,:].values
# y就是已知的年龄,x就是已知年龄的特征属性
y = know_age[:,0]
x = know_age[:,1:]
# 生成回归器并进行拟合
regressor = RandomForestRegressor(random_state=0,n_estimators=2000)
regressor.fit(x,y)
# 用得到的模型对未知年龄进行预测
age_predict = regressor.predict(unknow_age[:,1:])
# 将预测得到的数据填充给原缺失数据
train_data.Age[train_data['Age'].isnull()]=age_predict
# Age列离散化处理
def func_two(x):
if x<13:
return 'child'
elif x<30:
return 'young'
elif x<57:
return 'adult'
else:
return 'old'
train_data.Age = train_data.Age.map(func_two)
Fare列处理
# Fare列离散化处理
def func_three(x):
if x<29:
return 'poor'
else:
return 'rich'
train_data.Fare = train_data.Fare.map(func_three)
3.2 分类数据
dummies_Pclass = pd.get_dummies(train_data['Pclass'],prefix='Pclass')
dummies_Sex = pd.get_dummies(train_data['Sex'],prefix='Sex')
dummies_Carbin = pd.get_dummies(train_data['Cabin'],prefix='Carbin')
dummies_Embarked = pd.get_dummies(train_data['Embarked'],prefix='Embarked')
dummies_Age = pd.get_dummies(train_data['Age'],prefix='Age')
dummies_Fare = pd.get_dummies(train_data['Fare'],prefix='Fare')
train_data = pd.concat([train_data,dummies_Carbin,dummies_Embarked,dummies_Pclass,dummies_Sex,dummies_Age,dummies_Fare],axis=1)
train_data = train_data.drop(['Name','Ticket','Pclass','Sex','Cabin','Embarked','Age','Fare'],axis=1)
3.4 测试集数据处理
我们对训练集进行处理之后,测试集也要记得进行预处理。
数据清洗
test_data = data_test.copy()
test_data.info()
output:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId 418 non-null int64
Pclass 418 non-null int64
Name 418 non-null object
Sex 418 non-null object
Age 332 non-null float64
SibSp 418 non-null int64
Parch 418 non-null int64
Ticket 418 non-null object
Fare 417 non-null float64
Cabin 91 non-null object
Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
和训练集一样,训练集中Age,Cabin列缺失值较多,Fare列有1行缺失。
测试集中Fare列进行处理
test_data.Fare.fillna(test_data.Fare.mode().iloc[0],inplace=True)
test_data.Fare = test_data.Fare.map(func_three)
测试集Carbin列处理
def func_one(x):
if type(x)==str:
return 'yes'
else:
return 'no'
test_data['Cabin'] = test_data['Cabin'].map(func_one)
测试集Age列处理
# 找到测试集中未知年龄数据的特征
tmp_df = test_data[['Age','SibSp','Fare','Parch','Pclass']]
unknow_age_test = tmp_df[tmp_df['Age'].isnull()].iloc[:,:].values
x = unknow_age_test[:,1:]
# 用训练集中的模型直接对测试集中的年龄进行预测
age_predict_test = regressor.predict(x)
# 将预测得到的数据填充给测试集缺失数据
test_data.Age[test_data['Age'].isnull()] = age_predict_test
test_data.Age = test_data.Age.map(func_two)
分类数据
dummies_Pclass = pd.get_dummies(test_data['Pclass'],prefix='Pclass')
dummies_Sex = pd.get_dummies(test_data['Sex'],prefix='Sex')
dummies_Carbin = pd.get_dummies(test_data['Cabin'],prefix='Carbin')
dummies_Embarked = pd.get_dummies(test_data['Embarked'],prefix='Embarked')
dummies_Age = pd.get_dummies(test_data['Age'],prefix='Age')
dummies_Fare = pd.get_dummies(test_data['Fare'],prefix='Fare')
test_data = pd.concat([test_data,dummies_Carbin,dummies_Embarked,dummies_Pclass,dummies_Sex,dummies_Age,dummies_Fare],axis=1)
test_data = test_data.drop(['Name','Ticket','Pclass','Sex','Cabin','Embarked','Age','Fare'],axis=1)
4. 建模与调参
4.2 Kernel SVM
# 导入Kernel svm
from sklearn.svm import SVC
train_df = train_data.iloc[:,1:]
X_train = train_df.iloc[:,1:].values
y_train = train_df.iloc[:,0].values
classifier = SVC(kernel='rbf',random_state=0)
classifier.fit(X_train,y_train)
交叉验证
from sklearn.model_selection import GridSearchCV, cross_val_score
svc_classifier = cross_val_score(estimator=classifier,X=X_train,y=y_train,cv=10)
print(svc_classifier.mean())
output:
0.8215438088752695
网格搜索调参
param = {
'C': [0.1,0.8,0.9,1,1.1,1.2,1.3,1.4,1.6,1.8,2.0],
'kernel':['rbf'],
'gamma' :[0.1,0.8,0.9,1,1.1,1.2,1.3,1.4,1.6,1.8,2.0]
}
grid_classifier = GridSearchCV(classifier, param_grid=param, scoring='accuracy', cv=10)
grid_classifier.fit(X_train,y_train)
print(grid_classifier.best_params_)
output:
{'C': 0.9, 'gamma': 0.1, 'kernel': 'rbf'}
重新建模
svc = SVC(C=0.9,gamma=0.1,kernel='rbf')
svc.fit(X_train,y_train)
X_test = test_data.iloc[:,1:].values
y_pred = svc.predict(X_test)
result = pd.DataFrame({'PassengerId':test_data['PassengerId'],'Survived':y_pred})
result.to_csv('kernel_svm.predictions.csv',index=False)
svc_val = cross_val_score(estimator=svc,X=X_train,y=y_train,cv=10)
svc_val.mean()
output:
0.8283109181704689
提交到Kaggle,可以发现准确率0.79425,相比上此提高了0.05,排名上升到2166,说明经过网格搜索调参之后,模型的性能得到了进一步的优化。