基于Kaggle入门项目预测Titanic乘客的获救的数据进行的模型探究(一)

一日三省

基于XGboost快速搭建分类模型



前言

知道Kaggle已经好长时间了,账号也建立4年了,但是一直没有真正的动手来写过项目. 这个titanic的项目数据前前后后下载了太多次了,现在终于有点时间可以做了. 这个数据应该是比较简单的一个数据集了,所以我想通过这个数据集来对常用的一些方法和模型进行探究对比. 打磨一下自己的知识库. 本次先基于简单处理数据和XGBoost,先在Kaggle得出一个参考分数Score. 后续基于这个分数来作为参照物,看看常用的处理方法对于结果上到底有什么样的影响.


一、数据的基本情况

Titanic的数据分为一个train.csv和一个test.cv. 我们的目的就是通过train.csv的数据来训练模型,再给test进行预测并将结果上传. 其中train的数据集的shape是(891,12),test数据集的大小是(418,11). 其中各个字段名及含义如下:

VariableDefinitionKeytype
PassengerIdPassenger Idint
survivalSurvival0 = No, 1 = Yesint
pclassTicket class1 = 1st, 2 = 2nd, 3 = 3rdint
sexSexobj
AgeAge in yearsfloat
sibsp# of siblings /
spouses aboard the Titanic
int
parch# of parents /
children aboard the Titanic
int
ticketTicket numberobj
farePassenger farefloat
cabinCabin numberobj
embarkedPort of EmbarkationC = Cherbourg,
Q = Queenstown,
S = Southampton
obj

二、数据处理(简单处理)

1.数据清洗及缺失值填充

这个数据集中数据还算干净,除了有一些填充值需要填充,其他就没有什么. 因为我是要准备使用xgboost的,所以对于里面的离散变量进行特征编码. 对于离散型变量的特征编码一般使用onehot和哑变量. 但是我为了简单直接对其中一些数据进行了编码,如性别直接赋予1和2之类的,其中担心会有缺失值,所以就多加了一个0.

df['Sex_code]=df['Sex'].apply(lambda x:
				 (1 if x=='female' else 2) if pd.notna(x) else 0)

2.特征工程

分析了训练数据中的各个字段的含义,我决定从Cabin(船舱) 这个字段开始入手来做衍生变量。而其他变量目前也没有什么可以衍生的方向。Cabin衍生出Cabin_level(船舱的区域), Cabin_num(船舱号), Cabin_count(购买船舱的数量)。因为特征工程还需要在test集上再次加工,所以我把特征工程部分做成了一个类,以便后续继续调用,也方便处理数据.

# 1. 特征工程
# 1.1 构造衍生变量,对离散型变量自定义类型
class feature():
    features=['Cabin_level','Cabin_num','Cabin_count','Sex_code','Embarked_code']
    def __init__(self,df):
        self.df=df
        
    def add_f(self,which_one='Cabin_level'):
        d={'A':1,'B':2,'C':3,'D':4,'E':5,'F':6,'G':7,'T':8,'N':-1}
        d1={'S':3, 'C':2, 'Q':1,-1:-1}
        if which_one=='Cabin_level':
            self.df[which_one]=self.df['Cabin'].apply(lambda x: d[x[0]] if pd.notna(x) else d['N'])
        elif which_one=='Cabin_num':
            self.df[which_one]=self.df['Cabin'].apply(lambda x: ((( x.split(' ')[0][1:] if len(x.split(' ')[0])>1 else 0) if ' ' in x else x[1:]) if len(x)>1 else 0) if pd.notna(x) else -1)
            self.df[which_one]=self.df[which_one].apply(lambda x: int(x) if type(x)!='int' else x)
        elif which_one=='Cabin_count':
            self.df[which_one]=self.df['Cabin'].apply(lambda x: x.count(' ')+1 if pd.notna(x) else 1)
        elif which_one=='Sex_code':
            self.df[which_one]=self.df['Sex'].apply(lambda x: (1 if x=='female' else 2) if pd.notna(x) else 0)
        elif which_one=='Embarked_code':
            self.df[which_one]=self.df['Embarked'].apply(lambda x: d1[x] if pd.notna(x) else -1)
            
    def add_all(self):
        features=[i for i in self.features if i not in self.df.columns]
        for i in features:
            self.add_f(i)
        l=[i for i in self.df.columns if i in ['PassengerId','Name','Sex','Ticket','Cabin','Embarked']]
        if len(l)!=0:
            self.df.drop(l,1,inplace=True)
        self.df.fillna(-1,inplace=True)

缺失值填充是特征工程之后才做的,因为这样的话在衍生变量的时候不容易出错。

3. 模型的搭建(XGboost)

因为想比较快速的产出一个结果,所以就使用了效果好,兼容好的XGBoost,也是我之前比较熟悉的一个算法模型。这块其实就是一个调参的过程,其中用了CV来不断地尝试产出了相对好的参数。代码如下:

def modelfit(alg, dtrain,dtrain_l, predictors,x_v,y_v,target='Survived',useTrainCV=True, cv_folds=5, early_stopping_rounds=50,):

    if useTrainCV:
        xgb_param = alg.get_params()
        xgtrain = xgb.DMatrix(dtrain[predictors].values, label=dtrain_l.values)
        cvresult = xgb.cv(xgb_param, xgtrain, num_boost_round=alg.get_params()['n_estimators'], nfold=cv_folds,
            metrics='auc', early_stopping_rounds=early_stopping_rounds)
        alg.set_params(n_estimators=cvresult.shape[0])

    #Fit the algorithm on the data
    alg.fit(dtrain[predictors], dtrain_l,eval_metric='auc')

    #Predict training set:
    dtrain_predictions = alg.predict(dtrain[predictors])
    dtrain_predprob = alg.predict_proba(dtrain[predictors])[:,1]

    #Print model report:
    print("\nModel Report")
    print("Accuracy : %.4g" % metrics.accuracy_score(dtrain_l.values, dtrain_predictions))
    print("AUC Score (Train): %f" % metrics.roc_auc_score(dtrain_l, dtrain_predprob))
    feat_imp = pd.Series(alg.feature_importances_)
    feat_imp.index=predictors
    feat_imp.sort_values(ascending=False,inplace=True)
    feat_imp.plot(kind='bar', title='Feature Importances')
    plt.ylabel('Feature Importance Score')
    dtest_predictions = xgb1.predict(x_val[predictors])
    dtest_predprob = xgb1.predict_proba(x_val[predictors])[:,1]
    #Print model report:
    print("\nModel Report")
    print("Accuracy : %.4g" % metrics.accuracy_score(y_val.values, dtest_predictions))
    print("AUC Score (Test): %f" % metrics.roc_auc_score(y_val, dtest_predprob))
    print('AUC fall percent : %f'% (metrics.roc_auc_score(dtrain_l, dtrain_predprob)-metrics.roc_auc_score(y_val, dtest_predprob)))

代码比较乱,就是自己用的,没有整体的优化。其中还有从其他人借鉴的代码部分,但是由于大同小异,也就没有改了。如果作者看到后觉得侵权啦,我可以删掉自己再写一个 😃.

4. 模型预测

最后模型跑下来的结果呢,不足够令人满意。首先训练集和验证集的结果,通过AUC和准确率来看,分别是:

AccAUC
Train0.88440.934160
Validation0.81720.867952

其中各个变量的重要性中,性别占了很大的比重
在这里插入图片描述


总结

最终上传到Kaggle上后,这个结果的得分为0.76315,排名4w开外 😦 .不过虽然如此,但是我还是会继续不断的尝试的,因为这次做的里面还是有一些改进空间。后面要做的就是特征编码换成onehot或者哑变量,各个变量做woe转码,分箱,更换其他的模型算法,如LR,SVM,RF, GBDT等。就是不断地尝试,来判断这样做的每一次操作都会相对应的带来哪些结果。

*在今天结束前,我又用LightGBM在这个训练集上跑了一下结果。这样下来的结果就是,真香 *😂😂😂😂😂😂😂在这里插入图片描述
呵呵~ 😶😶😶😶😶😶

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值