kaggle——泰坦尼克之災(zāi)3(基于stacking)

之前有寫過兩篇關(guān)于Titanic比賽的簡書,這幾天上kaggle-Titanic的kernels在MostVost找了一篇排第一的kernels來看惠呼,參考鏈接,這個Kernels在模型方面做得特別好宋舷,所以,另寫一篇簡書作為總結(jié)袍嬉。

流程

  1. 觀察數(shù)據(jù)颁井,我們要對數(shù)據(jù)有所了解厅贪,可以參考簡書
  2. 特征工程以及數(shù)據(jù)清洗
  3. 介紹模型
  4. 跑模型
  5. 修改第二層模型
  6. 總結(jié)

1.代碼分析

首先,導(dǎo)入我們需要用到的庫

import pandas as pd
import numpy as np
from sklearn.cross_validation import KFold
import re
import plotly.graph_objs as go
import plotly.offline as py
from sklearn.ensemble import (RandomForestClassifier, AdaBoostClassifier,
                              GradientBoostingClassifier, ExtraTreesClassifier)
from sklearn.svm import SVC
import xgboost as xgb
import warnings
warnings.filterwarnings('ignore')  # 忽略warning
pd.set_option('display.max_columns', None)  # 輸出結(jié)果顯示全部列

然后雅宾,導(dǎo)入數(shù)據(jù)

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
PassengerId = test['PassengerId']
full_data = [train, test]

接下來养涮,我們可以查看我們的數(shù)據(jù)

# 查看train集的數(shù)據(jù)
print(train.describe())  # 查看描述性統(tǒng)計,只能看數(shù)值型數(shù)據(jù)。
print(train.info())  # 查看數(shù)據(jù)的信息
# print(train.head())  # 查看train的前n行數(shù)據(jù)眉抬,默認(rèn)為前5行

1.1
1.2

從圖上我們可以看到贯吓,其中有5列不是數(shù)值型的,我們需要對其進(jìn)行轉(zhuǎn)換成數(shù)值蜀变,而且Age悄谐、Cabin這兩列是有缺失值的,我們要對其進(jìn)行填充或者丟棄库北。

2.特征工程以及數(shù)據(jù)清洗

添加一些新的特征

# 添加新的特征爬舰,名字的長度
train['Name_length'] = train['Name'].apply(len)
test['Name_length'] = test['Name'].apply(len)

# 乘客在船上是否有船艙
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)

# 結(jié)合SibSp和Parch創(chuàng)建新的特性FamilySize
for dataset in full_data:
    dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1

基于特征FamilySize創(chuàng)建新的特征IsAlone,因?yàn)橐粋€人的話寒瓦,顧慮沒有那么多情屹,只需要管好自己,生存的幾率會大點(diǎn)杂腰,其中又分‘male’和‘female’垃你,因?yàn)槲矣浀秒娪爸惺怯羞@樣的一句臺詞“讓女人和小孩先走”,所以颈墅,我們有理由相信蜡镶,女性的生存率會比男性的要高。

for dataset in full_data:
    dataset['IsAlone'] = 0
    dataset.loc[dataset['FamilySize'] == 1), 'IsAlone'] = 1

通過name恤筛,添加特征Title

# 定義從乘客名中提取新的特征[Title]的函數(shù)
def get_title(name):
    title_search = re.search(' ([A-Za-z]+)\.', name)
    # 如果title存在,提取并返回它芹橡。
    if title_search:
        return title_search.group(1)
    return ""

# 創(chuàng)建一個新的特征[Title]
for dataset in full_data:
    dataset['Title'] = dataset['Name'].apply(get_title)
# 將所有不常見的Title分組為一個“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')

缺失值填充

  1. Embarked只缺了兩個毒坛,所以通過統(tǒng)計三個登船地點(diǎn),選出了登船人數(shù)最多的登船地點(diǎn)(s)來填充林说。
  2. Test集的Fare只有一個缺失,所以用了中位數(shù)來填充
  3. Age缺失的比較多煎殷,所以在[age_avg - age_std, age_avg + age_std]這個范圍取值來填充(其中age_avg是Age的平均值,age_std是Age的標(biāo)準(zhǔn)差)
# 通過統(tǒng)計三個登船地點(diǎn)人數(shù)最多的填充缺失值
for dataset in full_data:
    dataset['Embarked'] = dataset['Embarked'].fillna('S')

# 缺失值填充腿箩,Test集的Fare有一個缺失豪直,按中位數(shù)來填充,以及創(chuàng)建一個新的特征[CategoricalFare]
for dataset in full_data:
    dataset['Fare'] = dataset['Fare'].fillna(train['Fare'].median())
train['CategoricalFare'] = pd.qcut(train['Fare'], 4)

# 缺失值填充,以及創(chuàng)建新的特征[CategoricalAge]
for dataset in full_data:
    age_avg = dataset['Age'].mean()
    age_std = dataset['Age'].std()
    age_null_count = dataset['Age'].isnull().sum()
    age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size=age_null_count)
    dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
    dataset['Age'] = dataset['Age'].astype(int)

通過Age,創(chuàng)建新的特征珠移,一會用來給Age分組

train['CategoricalAge'] = pd.cut(train['Age'], 5)
print(train['CategoricalAge'])

2.1

從圖片可以看出弓乙,年齡分為了5個范圍末融,所以一會把年齡分為5組(0-4)。

分組以及轉(zhuǎn)換數(shù)值

Sex:把性別轉(zhuǎn)為0和1.
Embarked:把登船地點(diǎn)轉(zhuǎn)為0暇韧、1勾习、2.
Fare:把費(fèi)用分為4組
Age:把年齡分為5組

for dataset in full_data:
    dataset['Sex'] = dataset['Sex'].map({'female': 0, 'male': 1}).astype(int)

    title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
    dataset['Title'] = dataset['Title'].map(title_mapping)
    dataset['Title'] = dataset['Title'].fillna(0)

    dataset['Embarked'] = dataset['Embarked'].map({'S': 0, 'C': 1, 'Q': 2}).astype(int)

    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
    dataset['Fare'] = dataset['Fare'].astype(int)

    dataset.loc[dataset['Age'] <= 16, 'Age'] = 0
    dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
    dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
    dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
    dataset.loc[dataset['Age'] > 64, 'Age'] = 4

特征選擇,丟棄一些不必要的特征

PassengerID懈玻、Name巧婶、Ticket、Cabin涂乌、Sibsp等特征丟棄的原因是都已組合成新的特征艺栈,所以給予丟棄
CategorcalAge、CategoricalFare這些特征創(chuàng)建時是用來查看Age湾盒、Fare的分組區(qū)間湿右,已使用,所以給予丟棄

drop_elements = ['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp']
train = train.drop(drop_elements, axis=1)
train = train.drop(['CategoricalAge', 'CategoricalFare'], axis=1)
test = test.drop(drop_elements, axis=1)
# print(train.head())
print(train.describe())
# print(train.head())

2.2

3.模型介紹

在跑模型之前历涝,先提及一下本次kernels的基礎(chǔ)知識诅需,本次使用的
是Stacking融合模型,stacking集成模型與《機(jī)器學(xué)習(xí)》提及Bagging與Boosting不同荧库,Bagging與Boosting是用弱模型的結(jié)果經(jīng)過投票加權(quán)等方法集成一個新的強(qiáng)模型堰塌。而stacking翻譯成中文叫做模型堆疊,接下來我們將對stacking進(jìn)行介紹分衫,是如何將模型堆疊在一起的场刑。

stacking定義

stacking是一種分層模型集成框架。以兩層為例蚪战,第一層由多個基學(xué)習(xí)器組成牵现,其輸入為原始訓(xùn)練集,第二層的模型則是以第一層基學(xué)習(xí)器的輸出作為訓(xùn)練集進(jìn)行再訓(xùn)練邀桑,從而得到完整的stacking模型瞎疼。

首先,我們來看一下下面這個圖(兩層基礎(chǔ))壁畸,并進(jìn)行步驟分解


3.1

步驟:

  1. 首先將數(shù)據(jù)分為5份贼急,
  2. 在stacking的第一層定義5個基模型,其中每個模型選擇做一下5折的交叉驗(yàn)證的預(yù)測捏萍,這樣就相當(dāng)于每個模型將所有數(shù)據(jù)預(yù)測了一遍
  3. 將第一層5個基模型的輸出預(yù)測向量太抓,作為第二層模型的特征做訓(xùn)練,
  4. 做test時令杈,直接將test的數(shù)據(jù)喂給之前第一層訓(xùn)練好的5個基模型走敌,5個模型預(yù)測出的至平均后作為第二層模型的輸入
  5. 第二層使用一個分類器,將前面得出的特征逗噩,進(jìn)行一次分類掉丽,因?yàn)橹饕Y(jié)果在第一層已經(jīng)預(yù)測完成跌榔,第二層要求不大(xgboost、LGBM等)即可机打。

Stacking注意事項(xiàng)

  • 第一層的基模型最好是強(qiáng)模型矫户,而第二層的基模型可以放一個簡單的分類器,防止過擬合残邀。

  • 第一層基模型的個數(shù)不能太小皆辽,因?yàn)橐粚幽P蛡€數(shù)等于第二層分類器的特征維度。大家可以把勉強(qiáng)將其想象成神經(jīng)網(wǎng)絡(luò)的第一層神經(jīng)元的個數(shù)芥挣,當(dāng)然這個值也不是越多越好驱闷。

  • 第一層的基模型必須“準(zhǔn)而不同”,如果有一個性能很差的模型出現(xiàn)在第一層空免,將會嚴(yán)重影響整個模型融合的效果

本次比賽中部分模型的準(zhǔn)確率:

- 樸素貝葉斯(Gaussian Naive Bays):72.2%
- 隨機(jī)梯度下降(Stochastic Gradient Descent):76.8%
- 感知器(Perceptron):78%
- Linear SVC:79.12%
- 邏輯回歸(Ligistic Regression):80.3%
- SVC(support Vector Machines):83.4%
- ExtraTreesClassifie: 84.5%
- AdaBoostClassifier: 85.6%
- 決策樹(Decision tree):86.7%
- 隨機(jī)森林(Random Forest):86.7%

4. 跑模型

這部分是這個kernels的重點(diǎn)空另,用的是Stacking。Stacking使用第一級分類器的預(yù)測作為對第二級模型的訓(xùn)練輸入蹋砚。我們使用了(RandomForestClassifier, AdaBoostClassifier,GradientBoostingClassifier, ExtraTreesClassifier扼菠,Support Vector Classifier)這5個分類器的預(yù)測作為下一個分類器(xgboost)的特征。

為什么使用的是這5個模型坝咐,其他需求還是這5個模型嗎循榆?為什么不用其他如神經(jīng)網(wǎng)絡(luò)等強(qiáng)模型呢?

  • 這5個模型是當(dāng)前比賽排名準(zhǔn)度率最好的5個強(qiáng)模型墨坚,而其他的模型準(zhǔn)度較低如邏輯回歸(準(zhǔn)確率0.80左右秧饮,而強(qiáng)模型均在0.83以上),這樣會影響堆疊后的準(zhǔn)確率泽篮,決策樹準(zhǔn)確率雖然達(dá)到86%盗尸,但是和隨機(jī)森林相關(guān)性過高,且屬于單樹模型帽撑,容易過擬合泼各,所以選取隨機(jī)森林。

注意:當(dāng)碰到其他需求的時候亏拉,不一定還是這5個模型历恐,需要進(jìn)行對其他模型的準(zhǔn)確率測試,相關(guān)性確認(rèn)等专筷。

不使用神經(jīng)網(wǎng)絡(luò)原因:

  1. 神經(jīng)網(wǎng)絡(luò)不太可控,調(diào)參困難蒸苇,容易出現(xiàn)過擬合等問題
  2. 較好的神經(jīng)網(wǎng)絡(luò)計算量較大磷蛹,需要很大的數(shù)據(jù)量,而本次的比賽中Data只有890行溪烤,學(xué)習(xí)速度調(diào)整困難味咳,收斂可能發(fā)生過快等問題庇勃,無法工作

在下面的代碼中,我們編寫了一個類SklearnHelper槽驶,它允許擴(kuò)展所有Sklearn分類器所共有的內(nèi)置方法(如train责嚷、predict和fit)。這消除了冗余掂铐,因?yàn)槿绻覀兿胝{(diào)用5個不同的分類器罕拂,就不需要編寫相同的方法5次。

# 一些有用的參數(shù)全陨,下面會用到
ntrain = train.shape[0]
ntest = test.shape[0]
SEED = 0
NFOLDS = 5
kf = KFold(ntrain, n_folds=NFOLDS, random_state=SEED)

class SklearnHelper(object):
    def __init__(self, clf, seed=0, params=None):
        params['random_state'] = seed
        self.clf = clf(**params)

    def train(self, x_train, y_train):
        self.clf.fit(x_train, y_train)

    def predict(self, x):
        return self.clf.predict(x)

    def fit(self, x, y):
        return self.clf.fit(x, y)

    def feature_importances(self, x, y):
        return self.clf.fit(x, y).feature_importances_

def get_oof(clf, x_train, y_train, x_test):
    oof_train = np.zeros((ntrain,))
    oof_test = np.zeros((ntest,))
    oof_test_skf = np.empty((NFOLDS, ntest))

    for i, (train_index, test_index) in enumerate(kf):
        x_tr = x_train[train_index]
        y_tr = y_train[train_index]
        x_te = x_train[test_index]

        clf.train(x_tr, y_tr)

        oof_train[test_index] = clf.predict(x_te)
        oof_test_skf[i, :] = clf.predict(x_test)

    oof_test[:] = oof_test_skf.mean(axis=0)
    return oof_train.reshape(-1, 1), oof_test.reshape(-1, 1)

現(xiàn)在讓我們準(zhǔn)備五個學(xué)習(xí)模型作為我們的第一級分類爆班。這些模型都可以通過Sklearn庫方便地調(diào)用,如下所示

1.Random Forest classifier
2.Extra Trees classifier
3.AdaBoost classifer
4.Gradient Boosting classifer
5.Support Vector Machine

輸入上述分類器的參數(shù)

# 隨機(jī)森林的參數(shù)
rf_params = {
    'n_jobs': -1,
    'n_estimators': 100,
     'warm_start': True,
     #'max_features': 0.2,
    'max_depth': 6,
    'min_samples_leaf': 2,
    'max_features': 'sqrt',
    'verbose': 0
}

# Extra Trees的參數(shù)
et_params = {
    'n_jobs': -1,
    'n_estimators': 100,
    #'max_features': 0.5,
    'max_depth': 8,
    'min_samples_leaf': 2,
    'verbose': 0
}

# AdaBoost的參數(shù)
ada_params = {
    'n_estimators': 100,
    'learning_rate': 0.01
}

# Gradient Boosting的參數(shù)
gb_params = {
    'n_estimators': 100,
     #'max_features': 0.2,
    'max_depth': 5,
    'min_samples_leaf': 2,
    'verbose': 0
}

# Support Vector Classifier的參數(shù)
svc_params = {
    'kernel': 'linear',
    'C': 0.025
}

第一級分類器
# 通過前面定義的SklearnHelper類創(chuàng)建5個對象來表示5個學(xué)習(xí)模型
rf = SklearnHelper(clf=RandomForestClassifier, seed=SEED, params=rf_params)
et = SklearnHelper(clf=ExtraTreesClassifier, seed=SEED, params=et_params)
ada = SklearnHelper(clf=AdaBoostClassifier, seed=SEED, params=ada_params)
gb = SklearnHelper(clf=GradientBoostingClassifier, seed=SEED, params=gb_params)
svc = SklearnHelper(clf=SVC, seed=SEED, params=svc_params)
# 創(chuàng)建包含train辱姨、test的Numpy數(shù)組柿菩,以提供給我們的模型
y_train = train['Survived'].ravel()
train = train.drop(['Survived'], axis=1)
x_train = train.values
# test = test.drop(['Parch', 'Embarked', 'Has_Cabin', 'IsAlone'], axis=1)
x_test = test.values

#這些將會作為新的特征被使用
et_oof_train, et_oof_test = get_oof(et, x_train, y_train, x_test)  # Extra Trees
rf_oof_train, rf_oof_test = get_oof(rf, x_train, y_train, x_test)  # Random Forest
ada_oof_train, ada_oof_test = get_oof(ada, x_train, y_train, x_test)  # AdaBoost
gb_oof_train, gb_oof_test = get_oof(gb, x_train, y_train, x_test)  # Gradient Boost
svc_oof_train, svc_oof_test = get_oof(svc, x_train, y_train, x_test)  # Support Vector Classifier

現(xiàn)在已經(jīng)獲得了我們的第一級預(yù)測,我們可以把它看作是一組新的特性雨涛,作為下一個分類器的訓(xùn)練數(shù)據(jù)枢舶。

查看各個特征對上述分類器的重要性

rf_features = rf.feature_importances(x_train, y_train)
et_features = et.feature_importances(x_train, y_train)
ada_features = ada.feature_importances(x_train, y_train)
gb_features = gb.feature_importances(x_train, y_train)

cols = train.columns.values
feature_dataframe = pd.DataFrame({'features': cols,
     'Random Forest feature importances': rf_features,
     'Extra Trees  feature importances': et_features,
      'AdaBoost feature importances': ada_features,
    'Gradient Boost feature importances': gb_features})

feature_dataframe['mean'] = feature_dataframe.mean(axis=1)  # axis = 1 computes the mean row-wise
print(feature_dataframe.head(11))

4.1

4.2
以圖形形式顯示各模型對特征的相關(guān)性,觀察
4.3

4.4

4.5

4.7

從圖中觀察可以知道替久,第一層模型特征相關(guān)性平均后凉泄,各特征的相關(guān)性相對降低,準(zhǔn)而不同”這個要求的侣肄。所以第一層五個模型融合是符合的旧困。

畫圖查看各個分類器的相關(guān)性

base_predictions_train = pd.DataFrame( {'RandomForest': rf_oof_train.ravel(),
     'ExtraTrees': et_oof_train.ravel(),
     'AdaBoost': ada_oof_train.ravel(),
      'GradientBoost': gb_oof_train.ravel()
    })
data = [
    go.Heatmap(
        z= base_predictions_train.astype(float).corr().values ,
        x=base_predictions_train.columns.values,
        y= base_predictions_train.columns.values,
          colorscale='Viridis',
            showscale=True,
            reversescale = True
    )
]
py.iplot(data, filename='labelled-heatmap')

4.8

這些模型彼此之間的相關(guān)性越低,得分越高稼锅。

第二級分類器xgboost

x_train = np.concatenate((et_oof_train, rf_oof_train, ada_oof_train, gb_oof_train, svc_oof_train), axis=1)
x_test = np.concatenate((et_oof_test, rf_oof_test, ada_oof_test, gb_oof_test, svc_oof_test), axis=1)

gbm = xgb.XGBClassifier(
 #learning_rate=0.01,
 n_estimators=2000,
 max_depth=4,
 min_child_weight=2,
 # gamma=1,
 gamma=0.9,
 subsample=0.8,
 colsample_bytree=0.8,
 objective='binary:logistic',
 nthread=-1,
 scale_pos_weight=1).fit(x_train, y_train)
predictions = gbm.predict(x_test)

xgboost參數(shù)含義

提交

StackingSubmission = pd.DataFrame({'PassengerId': PassengerId,
                            'Survived': predictions})
StackingSubmission.to_csv("StackingSubmission.csv", index=False)

提交后的分?jǐn)?shù)如下

4.9

訓(xùn)練所用時間:

4.10

5.對模型第二層進(jìn)行修改

LGBM與XGBOOST:

XGBoost是在GBDT(梯度提升決策樹)基礎(chǔ)上發(fā)展而來,針對傳統(tǒng)GBDT算法做了很多細(xì)節(jié)改進(jìn)吼具,包括損失函數(shù)、正則化矩距、切分點(diǎn)查找算法優(yōu)化拗盒、稀疏感知算法、并行化算法設(shè)計等等

LightGBM 是一個梯度 boosting 框架锥债,使用基于學(xué)習(xí)算法的決策樹陡蝇。它可以說是分布式的,高效的
與以往的算法比較①histogram算法替換了傳統(tǒng)的Pre-Sorted哮肚,某種意義上是犧牲了精度(但是作者聲明實(shí)驗(yàn)發(fā)現(xiàn)精度影響不大)換取速度登夫,直方圖作差構(gòu)建葉子。(xgboost的分布式實(shí)現(xiàn)也是基于直方圖的允趟,利于并行)②帶有深度限制的按葉子生長 (leaf-wise) 算法代替了傳統(tǒng)的(level-wise) 決策樹生長策略恼策,提升精度,同時避免過擬合危險潮剪。

LightGBM作者對模型的一些解釋:
https://www.zhihu.com/question/51644470/answer/130946285

  • 兩者的結(jié)構(gòu)主要區(qū)別:在過濾數(shù)據(jù)樣例尋找分割值時涣楷,LightGBM 使用的是全新的技術(shù):基于梯度的單邊采樣(GOSS)分唾;而 XGBoost 則通過預(yù)分類算法和直方圖算法來確定最優(yōu)分割。

選擇LGBM替換XGBOOST的理由:
1.在速度上LGBM比XGBOOST的快十倍甚至百倍以上
2.LGBM與xgboost的精度不相上下

將stacking第二層xgboost替換成LGBM


lgbm_train = lgbm.Dataset ( data=x_train ,
                            label=y_train)
lgbm_params = {
    'boosting': 'dart' ,
    'application': 'binary' ,
    'learning_rate': 0.01 ,
    'feature_fraction': 0.5 ,
    'verbose' : -1,
    'drop_rate': 0.02
}

cv_results = lgbm.cv ( train_set=lgbm_train ,
                       params=lgbm_params ,
                       nfold=5 ,
                       num_boost_round=600 ,
                       early_stopping_rounds=50 ,
                       verbose_eval=50 ,

                       metrics=['auc'] )

optimum_boost_rounds = np.argmax ( cv_results['auc-mean'] )
print ( 'Optimum boost rounds = {}'.format ( optimum_boost_rounds ) )
print ( 'Best CV result = {}'.format ( np.max ( cv_results['auc-mean'] ) ) )

clf = lgbm.train ( train_set=lgbm_train ,
                   params=lgbm_params ,
                   num_boost_round=optimum_boost_rounds
)
##預(yù)測結(jié)果為浮點(diǎn)數(shù)狮斗,而本次比賽的預(yù)測結(jié)果需要0绽乔,1,所以將其轉(zhuǎn)換
predictions = clf.predict ( x_test )
predictions = predictions + 0.5
predictions = predictions.astype(int)

LGBM的重要參數(shù)用法:

學(xué)習(xí)控制參數(shù) 含義 用法
max_depth 樹的最大深度 當(dāng)模型過擬合時,可以考慮首先降低 max_depth
min_data_in_leaf 葉子可能具有的最小記錄數(shù) 默認(rèn)20碳褒,過擬合時用
feature_fraction 例如 為0.8時折砸,意味著在每次迭代中隨機(jī)選擇80%的參數(shù)來建樹 boosting 為 random forest 時用
bagging_fraction 每次迭代時用的數(shù)據(jù)比例 用于加快訓(xùn)練速度和減小過擬合
early_stopping_round 如果一次驗(yàn)證數(shù)據(jù)的一個度量在最近的early_stopping_round 回合中沒有提高,模型將停止訓(xùn)練 加速分析骤视,減少過多迭代
lambda 指定正則化 0~1
min_gain_to_split 描述分裂的最小 gain v控制樹的有用的分裂
max_cat_group 在 group 邊界上找到分割點(diǎn) 當(dāng)類別數(shù)量很多時鞍爱,找分割點(diǎn)很容易過擬合時
核心參數(shù) 含義 用法
Task 數(shù)據(jù)的用途 選擇 train 或者 predict
application 模型的用途 選擇 regression: 回歸時,binary: 二分類時专酗,multiclass: 多分類時
boosting 要用的算法 gbdt睹逃, rf: random forest, dart: Dropouts meet Multiple Additive Regression Trees祷肯, goss: Gradient-based One-Side Sampling
num_boost_round 迭代次數(shù) 通常 100+
learning_rat e 如果一次驗(yàn)證數(shù)據(jù)的一個度量在最近的 early_stopping_round 回合中沒有提高沉填,模型將停止訓(xùn)練 常用 0.1, 0.001, 0.003…
num_leaves 默認(rèn) 31
device cpu 或者 gpu
metric mae: mean absolute error , mse: mean squared error 佑笋, binary_logloss: loss for binary classification 翼闹, multi_logloss: loss for multi classification
IO參數(shù) 含義
max_bin 表示 feature 將存入的 bin 的最大數(shù)量
categorical_feature 如果 categorical_features = 0,1,2, 則列 0蒋纬,1猎荠,2是 categorical 變量
ignore_column 與 categorical_features 類似,只不過不是將特定的列視為categorical蜀备,而是完全忽略
save_binary 這個參數(shù)為 true 時关摇,則數(shù)據(jù)集被保存為二進(jìn)制文件,下次讀數(shù)據(jù)時速度會變快

調(diào)參

IO parameter 含義
num_leaves 取值應(yīng) <= 2 ^(max_depth)碾阁, 超過此值會導(dǎo)致過擬合
min_data_in_leaf 將它設(shè)置為較大的值可以避免生長太深的樹输虱,但可能會導(dǎo)致 underfitting,在大型數(shù)據(jù)集時就設(shè)置為數(shù)百或數(shù)千
max_depth 這個也是可以限制樹的深度

下表對應(yīng)了 Faster Speed 脂凶,better accuracy 宪睹,over-fitting 三種目的時,可以調(diào)的參數(shù)

Faster Speed better accuracy over-fitting
將 max_bin 設(shè)置小一些 用較大的 max_bin max_bin 小一些
num_leaves 大一些 num_leaves 小一些
用 feature_fraction 來做 sub-sampling 用 feature_fraction
用 bagging_fraction 和 bagging_freq 設(shè)定 bagging_fraction 和 bagging_freq
training data 多一些 training data 多一些
用 save_binary 來加速數(shù)據(jù)加載 直接用 categorical feature 用 gmin_data_in_leaf 和 min_sum_hessian_in_leaf
用 parallel learning 用 dart 用 lambda_l1, lambda_l2 蚕钦,min_gain_to_split 做正則化
num_iterations 大一些亭病,learning_rate 小一些 用 max_depth 控制樹的深度

本次比賽使用的參數(shù)解釋:

  • 'boosting': 'dart' # dart通過刪除已經(jīng)構(gòu)建好的樹,來降低模型過擬合的情況嘶居。
  • application': 'binary' # 本次比賽為一個二分類問題命贴,所以,選擇binary
  • 'learning_rate': 0.01 # 學(xué)習(xí)速率,基于數(shù)據(jù)量和精準(zhǔn)度去選擇胸蛛,本次比賽數(shù)據(jù)量小,所以選擇0.01即可以提高準(zhǔn)度樱报,也可以提高速度
  • 'verbose' : -1#取消警告No further splits with positive gain, best gain: -inf葬项,不設(shè)置為-1的話,數(shù)據(jù)量較少可能會提出警告
  • 'drop_rate': 0.02 # 解決類別不平衡所采用的的欠采樣方法迹蛤,類別不平衡就是指分類任務(wù)中不同類別的訓(xùn)練樣例數(shù)目差別很大的情況民珍,而欠采樣,即去除一些反例使得正盗飒、反例數(shù)目接近嚷量,然后再進(jìn)行學(xué)習(xí)。
  • nfold=5 #第一層有5個分類器逆趣,所以使用5折即可

提交

提交后分?jǐn)?shù)如下

5.1

訓(xùn)練所用時間:

5.2

6.總結(jié)

  1. 相比于其他的kernels蝶溶,這個kernels的特征工程方面做的不突出,突出的方面是用了新的方法Stacking宣渗,這個其他人在Titanic比賽中沒有用到過的抖所,這也是他排第一的原因。

  2. 進(jìn)一步改善的步驟
    必須指出的是痕囱,上述步驟只是顯示了一個非常簡單的方法田轧。聽說過在Kaggle的最高級別比賽中創(chuàng)建的組合,其中包括stacked classifiers的巨大組合鞍恢,以及超過2級的stacking級別傻粘。

  3. 這次嘗試修改這個模型的第二層的時候,結(jié)果得分比xgboost更高帮掉,有可能是因?yàn)樵谧鳛榉诸悓酉蚁ぃ瑇gboost需要人工去選擇權(quán)重的變化,而LGBM可以根據(jù)實(shí)際變化而修改旭寿,xgboost權(quán)重在第一層的時候應(yīng)該還可以調(diào)節(jié)警绩。但是速度上真的LGBM大約快了60倍,Xgboost由于對比LGBM屬于'元老'級模型盅称,對于調(diào)參方面在網(wǎng)上的攻略更加完善肩祥,而且優(yōu)化方面也相對突出,LGBM因?yàn)檫\(yùn)行速度的提升或許在后面會優(yōu)化并超越XGBOOST也有可能

代碼地址:
https://gitee.com/ZHBIT-MachineLearning/Machine-Learning-Base/tree/master/TItanic

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缩膝,一起剝皮案震驚了整個濱河市混狠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疾层,老刑警劉巖将饺,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡予弧,警方通過查閱死者的電腦和手機(jī)刮吧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掖蛤,“玉大人杀捻,你說我怎么就攤上這事◎就ィ” “怎么了致讥?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長器赞。 經(jīng)常有香客問我垢袱,道長,這世上最難降的妖魔是什么港柜? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任请契,我火速辦了婚禮,結(jié)果婚禮上潘懊,老公的妹妹穿的比我還像新娘姚糊。我一直安慰自己,他們只是感情好授舟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布救恨。 她就那樣靜靜地躺著,像睡著了一般释树。 火紅的嫁衣襯著肌膚如雪肠槽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天奢啥,我揣著相機(jī)與錄音秸仙,去河邊找鬼。 笑死桩盲,一個胖子當(dāng)著我的面吹牛寂纪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赌结,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捞蛋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柬姚?” 一聲冷哼從身側(cè)響起拟杉,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎量承,沒想到半個月后搬设,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穴店,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年拿穴,在試婚紗的時候發(fā)現(xiàn)自己被綠了泣洞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡贞言,死狀恐怖斜棚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情该窗,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布蚤霞,位于F島的核電站酗失,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昧绣。R本人自食惡果不足惜规肴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夜畴。 院中可真熱鬧拖刃,春花似錦、人聲如沸贪绘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽税灌。三九已至均函,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間菱涤,已是汗流浹背苞也。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粘秆,地道東北人如迟。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像攻走,于是被迫代替她去往敵國和親殷勘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容