Stacking 在机器学习中的应用,以kaggle titanic为例

之前自己玩了一下kaggle上的入门级别的比赛,泰坦尼克号生存预测。随便进行了简单的特征选择,直接用sklearn中的模型,直接跑结果,大概能跑到0.77左右。三千多名。

近段时间稍微闲下来了,开始着手做一些机器学习相关的比赛。然后想着提升上次的模型,或者在社区看看别人用的是什么模型。

然后看到一篇高票的文章。
Introduction to Ensembling or Stacking in Python

介绍集成学习和模型融合在泰坦尼克号上的应用。

之前只知道什么是集成,对于Stacking这个词还是比较陌生的,没有听过。

然后就查了一些资料,以下附上一些入门级的资料。






然后就是按照 Introduction to Ensembling or Stacking in Python里面的python notebook 的代码,自己敲了一遍,感觉学到了很多,特征提取方面,而且也复习了pandas的一些重要的函数。

这是我敲的notebook https://github.com/ZDstandup/titanic_notebook ,有一些简单的注释。

下面先给出学到的相关pandas的函数。用到的总结以下。

1.读取csv文件,这个csv文件里面的数据要有属性名称才行
train=pd.read_csv('train.csv')#读取数据
test=pd.read_csv('test.csv')#读取数据


2.查看dataframe数据的部分
train.head(3)    #查看前三行数据

3.添加新的属性
直接创建新的属性即可
#1,顾客name的长度
#直接增加一个属性列;直接对整个属性列进行操作;apply(function)中的函数对整体操作
train['Name_length'] =train['Name'].apply(len)


4.对整个属性列进行函数操作
apply(function)
#1,顾客name的长度
#直接增加一个属性列;直接对整个属性列进行操作;apply(function)中的函数对整体操作
train['Name_length']=train['Name'].apply(len)
    

5.apply()里面自建函数操作
#2,是否有客舱号码Cabin也是一个特征,有就为1,没有就为0
train['Has_Cabin']=train['Cabin'].apply( lambda x: 0 if type(x)==float else 1 )
test['Has_Cabin']=test['Cabin'].apply(lambda x : 0 if type(x)==float else 1)


6.相同数据格式的属性列,可以相加
dataset['FamilySize']=dataset['SibSp']+dataset['Parch']+1


7.提取具备某种条件的属性列  pd.loc()函数
#就相当于数据库sql语句的条件查询一样
dataset.loc[dataset['FamilySize']==1,'IsAlone']=1
#提取的是‘IsAlone’这一列中 dataset['FamilySize']==1的值



dataset.loc[ dataset['Fare'] <= 7.91, 'Fare']                                 = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare']   = 2
    dataset.loc[ dataset['Fare'] > 31, 'Fare']                                     = 3


8.缺失值的填充fillna()
for dataset in full_data:
    dataset['Embarked']=dataset['Embarked'].fillna('S')
#用‘S’填充‘Embarked’的缺失值

#把数据集的Fare票价这一列中为0 的填充为该列的median()中位数
for dataset in full_data:
    dataset['Fare']=dataset['Fare'].fillna(dataset['Fare'].median())


9.查看某个属性列的数据情况
train['Fare'].head(10)


10.获取中位数median()
train['Fare'].median()

常用的统计的函数:
######################## ******************************************
count 非 NA 值的数量
describe 针对 Series 或 DF 的列计算汇总统计
min , max 最小值和最大值
argmin , argmax 最小值和最大值的索引位置(整数)
idxmin , idxmax 最小值和最大值的索引值
quantile 样本分位数(0 到 1)
sum 求和
mean 均值
median 中位数
mad 根据均值计算平均绝对离差
var 方差
std 标准差
skew 样本值的偏度(三阶矩)
kurt 样本值的峰度(四阶矩)
cumsum 样本值的累计和
cummin , cummax 样本值的累计最大值和累计最小值
cumprod 样本值的累计积
diff 计算一阶差分(对时间序列很有用)
pct_change 计算百分数变化



11.统计属性列为空的样本个数
isnull()

train["Age"].isnull().sum()



12.转换属性列的数值类型
dataset['Age']=dataset['Age'].astype(int)#转换类型



13.取出为空的,并赋值新的值
dataset['Age'][np.isnan(dataset['Age'])]=age_null_random_list#把为空的取出来,再把随机的列表与之对应
#先得到bool型,在提取为True的,在进行赋值一个列表


14.把属性列的数据分成几个等份
train['CategoricalAge']=pd.qcut(train['Age'],5)
#分成5个区间,每个区间的样本数量相等



15.替换属性列里面的元素
# Group all non-common titles into one single grouping "Rare"
for dataset in full_data:
    dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
    dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')


16.对于一些属性值是离散值的,可以使用mapping操作
dataset['Sex'] = dataset['Sex'].map( {'female': 0, 'male': 1} ).astype(int)




17.删除一些属性列drop()
#现在需要的特征基本完了,现在需要把一些无用的特征属性给去掉,删除掉
drop_elements=['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp']
train=train.drop(drop_elements,axis=1)#去掉列表中的属性列
train=train.drop(['CategoricalAge', 'CategoricalFare'], axis = 1)#只删除train中这两个列,因为test没有添加,
                                                                 #这两个列其实只是为了划分一个区间出来,便于mapping到整数上去
test=test.drop(drop_elements,axis=1)




再给出自己敲的notebook,里面也有自己易懂的注释。


这里给出一个在stacking中的一个重要的部分。
#这个函数是用于交叉实验的
#clf是选择的分类模型,x_train是所有训练集,y_train是所有训练集样本的类别标签,x_test是给定的所有测试集
def get_oof(clf, x_train, y_train, x_test):
    oof_train = np.zeros((ntrain,))#长度为891的全0array
    oof_test = np.zeros((ntest,))#长度为418的全0array
    oof_test_skf = np.empty((NFOLDS, ntest))#一个用随机值填充的5*418的矩阵,用来存放5次交叉后的预测结果
    for i, (train_index, test_index) in enumerate(kf):
        #5次交叉,5次循环
        #kf实际上是一个迭代器,是从891个样本中分成了5组训练集和测试集的索引号
        x_tr = x_train[train_index]#当前循环,当前实验的训练数据
        y_tr = y_train[train_index]#当前循环的训练数据标签
        x_te = x_train[test_index]#d当前循环的测试数据
        clf.train(x_tr, y_tr)#用模型去拟合数据,也就是训练预测模型
        oof_train[test_index] = clf.predict(x_te)#把测试数据的预测标签按照对应索引,放到oof_train对应索引处
        oof_test_skf[i, :] = clf.predict(x_test)#用当前的模型,预测所有测试数据的标签,并放到oof_test_skf的一行中
        
    #5次实验做完,把5次得到的结果求平均
    oof_test[:] = oof_test_skf.mean(axis=0)
    return oof_train.reshape(-1, 1), oof_test.reshape(-1, 1)




不过按照作者的代码敲下来,感觉结果也并不是很好,大概3000多名,0.79左右。不知道那些高于0.9几得分的是怎么搞的。

不过作为一个入门的练习,了解了整个流程,以及作比赛的常用方法与套路,就可以,这个小比赛没必要做的非常好。

有时间做一个比较大的比赛。好好的研究研究。




感想:感觉看一些英文资料,挺好的。有些知识的中文资料确实比较少。还有就是逛kaggle的 kernels真的很爽。


































































































































































































































































































  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值