知識匯總
前面已講了7節(jié),為方便大家學(xué)習(xí),我總結(jié)在一起,無論是日常實踐還是面試使用,都非常方便,喜歡記得收藏
- 用通俗易懂的方式講解:邏輯回歸模型及案例(Python 代碼)
- 用通俗易懂的方式講解:決策樹模型及案例(Python 代碼)
- 用通俗易懂的方式講解: 隨機森林及案例(Python 代碼)
- 用通俗易懂的方式講解: xgboost 算法及案例(Python 代碼)
- 用通俗易懂的方式講解: GBDT算法及案例(Python 代碼)
- 用通俗易懂的方式講解:lightGBM 算法及案例(Python 代碼)
- 用通俗易懂的方式講解:主成分分析(PCA)算法及案例(Python 代碼)
CatBoost(categorical boosting)是一種能夠很好地處理類別型特征的梯度提升算法庫。本文中,我們對 CatBoost 基本原理及應(yīng)用實例做個詳細介紹。
后面我還將針對其中幾個重要特性做專門介紹,如 CatBoost 對類別型特征處理、特征選擇、文本特征處理、超參數(shù)調(diào)整以及多標(biāo)簽?zāi)繕?biāo)處理,感興趣記得收藏、點贊、關(guān)注。
解惑答疑
本文來自技術(shù)群小伙伴分享的,技術(shù)交流歡迎入群
目前開通了技術(shù)交流群,群友已超過3000人,添加時最好的備注方式為:來源+興趣方向,方便找到更快獲取資料、入群
方式①、添加微信號:dkl88191,備注:來自CSDN+加群
方式②、微信搜索公眾號:Python學(xué)習(xí)與數(shù)據(jù)挖掘,后臺回復(fù):加群
1、梯度提升概述
要理解 boosting
,我們首先理解集成學(xué)習(xí),為了獲得更好的預(yù)測性能,集成學(xué)習(xí)結(jié)合多個模型(弱學(xué)習(xí)器)的預(yù)測結(jié)果。它的策略就是大力出奇跡,因為弱學(xué)習(xí)器的有效組合可以生成更準(zhǔn)確和更魯棒的模型。集成學(xué)習(xí)方法分為三大類:
-
Bagging:該技術(shù)使用隨機數(shù)據(jù)子集并行構(gòu)建不同的模型,并聚合所有預(yù)測變量的預(yù)測結(jié)果。
-
Boosting:這種技術(shù)是可迭代的、順序進行的和自適應(yīng)的,因為每個預(yù)測器都是針對上一個模型的錯誤進行修正。
-
Stacking:這是一種元學(xué)習(xí)技術(shù),涉及結(jié)合來自多種機器學(xué)習(xí)算法的預(yù)測,例如 bagging 和 boosting。
2、什么是 CatBoost
CatBoost(categorical boosting)
是 Yandex 開源的機器學(xué)習(xí)算法。它可以與深度學(xué)習(xí)框架輕松集成。它可以處理多種數(shù)據(jù)類型,以幫助解決企業(yè)今天面臨的各種問題。CatBoost 和 XGBoost、LightGBM 并稱為 GBDT 的三大主流神器,都是在 GBDT 算法框架下的一種改進實現(xiàn)。XGBoost 被廣泛的應(yīng)用于工業(yè)界,LightGBM 有效的提升了 GBDT 的計算效率,而 Yandex 的 CatBoost 號稱是比 XGBoost 和 LightGBM 在算法準(zhǔn)確率等方面表現(xiàn)更為優(yōu)秀的算法。
CatBoost 是一種基于 對稱決策樹(oblivious trees)
為基學(xué)習(xí)器實現(xiàn)的參數(shù)較少、支持類別型變量和高準(zhǔn)確性的GBDT框架,主要解決的痛點是高效合理地處理類別型特征,這一點從它的名字中可以看出來,CatBoost 是由 Categorical
和 Boosting
組成。此外,CatBoost 還解決了梯度偏差(Gradient Bias)
以及預(yù)測偏移(Prediction shift)
的問題,從而減少過擬合的發(fā)生,進而提高算法的準(zhǔn)確性和泛化能力。
此外,CatBoost 梯度提升算法庫中的學(xué)習(xí)算法基于 GPU 實現(xiàn),打分算法基于 CPU 實現(xiàn)。
3、CatBoost 的主要特點
CatBoost 優(yōu)于同類產(chǎn)品的一些關(guān)鍵特性:
01 對稱樹
與 XGBoost 和 LightGBM 不同,CatBoost 構(gòu)建對稱(平衡)樹。在每一步中,前一棵樹的葉子都使用相同的條件進行拆分。選擇損失最低的特征分割對并將其用于所有級別的節(jié)點。這種平衡的樹結(jié)構(gòu)有助于高效的 CPU 實現(xiàn),減少預(yù)測時間,模型結(jié)構(gòu)可作為正則化以防止過度擬合。
在對稱決策樹中,只使用一個特性來構(gòu)建每個樹級別上的所有分支。我們使用圖示方法更加清晰地觀察三種類型的拆分:"FloatFeature"、"OneHotFeature" 和 "OnlineCtr"
。
FloatFeature
模型沒有類別型特征時,在可視化的樹中只有 "FloatFeature"
節(jié)點。"FloatFeature"
拆分對應(yīng)的節(jié)點包含特征索引和邊界值,用于拆分對象。
boston = load_boston()
y = boston['target']
X = boston['data']
pool = catboost.Pool(data=X, label=y)
model = CatBoostRegressor(depth=2, verbose=False, iterations=1).fit(X, y)
model.plot_tree(tree_idx=0,
# pool=pool, )
在這個例子中,深度為0的節(jié)點表示對象被它們的第0個帶邊界值的特征分割。類似地,深度1的節(jié)點通過其具有邊界值的第二個特征來分割對象。
OneHotFeature
titanic_df = titanic()
X = titanic_df[0].drop('Survived',axis=1)
y = titanic_df[0].Survived
# 分類變量的缺失值用"NAN"填充,代碼略
pool = Pool(X, y, cat_features=cat_features_index, feature_names=list(X.columns))
model = CatBoostClassifier(
max_depth=2, verbose=False, max_ctr_complexity=1, random_seed=42, iterations=2).fit(pool)
model.plot_tree(
tree_idx=0,
pool=pool # 對于一個需要使用獨熱編碼的特征,"pool" 是一個必須的參數(shù)
)
第一棵樹只包含一個由"OneHotFeature"
特征產(chǎn)生的分裂。這種分割將"Sex=female"
的對象放在左邊,而"other"
的對象放在右邊。
OnlineCtr
model.plot_tree(tree_idx=1, pool=pool)
02 Ordered Boosting
經(jīng)典提升算法存在預(yù)測偏移的問題,容易在小的/嘈雜的數(shù)據(jù)集上過度擬合。在計算數(shù)據(jù)實例的梯度估計時,這些算法使用與構(gòu)建模型相同的數(shù)據(jù)實例,因此沒有機會遇到看不見的數(shù)據(jù)。
另一方面,CatBoost 使用排序提升的概念,這是一種置換驅(qū)動的方法,在數(shù)據(jù)子集上訓(xùn)練模型,同時在另一個子集上計算殘差,從而防止目標(biāo)泄漏和過度擬合。
03 魯棒性
它減少了對大量超參數(shù)調(diào)整的需求,并降低了過度擬合的機會,這也導(dǎo)致了更通用的模型。雖然,CatBoost 有多個參數(shù)需要調(diào)整,它包含樹的數(shù)量、學(xué)習(xí)率、正則化、樹深度、折疊大小、裝袋溫度等參數(shù)。您可以在此處閱讀所有這些參數(shù)。
04 原生特征支持,易于使用
CatBoost 支持數(shù)字、分類或文本的各種特征,節(jié)省了預(yù)處理的時間和精力??梢詮拿钚惺褂?CatBoost,使用 Python 和 R 的用戶友好 API。
4、CatBoost 的基本使用
導(dǎo)入基本數(shù)據(jù)
我們使用 CatBoost 庫里自帶的經(jīng)典數(shù)據(jù)集 titanic。
from catboost.datasets import titanic
import numpy as np
train_df, test_df = titanic()
# 用一些超出分布范圍的數(shù)字來填充缺失值
train_df.fillna(-999, inplace=True)
test_df.fillna(-999, inplace=True)
# 拆分特征變量及標(biāo)簽變量
X = train_df.drop('Survived', axis=1)
y = train_df.Survived
# 劃分訓(xùn)練集和測試集
from sklearn.model_selection import train_test_split
X_train, X_validation, y_train, y_validation = train_test_split(X, y, train_size=0.75, random_state=42)
X_test = test_df
Titanic 數(shù)據(jù)集中的特征變量具有不同的類型—有些是數(shù)值類型,有些是分類類型,甚至有些只是字符串類型,通常應(yīng)該以某種特定的方式進行處理(例如使用詞袋表示進行編碼)。但這里我們可以將這些字符串特征視為分類特征——所有繁重的工作都是在 CatBoost 中完成的。
創(chuàng)建一個baseline模型
我們首先從一個基礎(chǔ)baseline模型開始,認識如何使用catboost進行預(yù)測目標(biāo)。
# !pip install catboost
from catboost import CatBoostClassifier, Pool, metrics, cv
from sklearn.metrics import accuracy_score
model = CatBoostClassifier(
custom_loss=[metrics.Accuracy()], # 該指標(biāo)可以計算logloss,并且在該規(guī)模的數(shù)據(jù)集上更加光滑
random_seed=42,
logging_level='Silent'
)
# 模型訓(xùn)練
model.fit(
X_train, y_train,
cat_features=categorical_features_indices,
eval_set=(X_validation, y_validation),
# logging_level='Verbose', # you can uncomment this for text output
plot=True
);
可以通過詳細輸出或使用漂亮的繪圖來觀察我們的模型學(xué)習(xí),我們使用CatBoost自帶的可交互模型過程可視化,查看模型的學(xué)習(xí)過程。
特征變量統(tǒng)計
Float feature
feature = 'Fare'
res = model.calc_feature_statistics(
X_train, y_train, feature, plot=True)
One-hot feature
feature = 'Sex'
res = model.calc_feature_statistics(X_train, y_train, feature, plot=True)
模型交叉驗證
驗證模型是否是性能最佳的,使用交叉驗證,可能甚至?xí)玫礁玫哪P汀?/p>
cv_params = model.get_params()
cv_params.update({
'loss_function': metrics.Logloss()
})
cv_data = cv(
Pool(X, y, cat_features=categorical_features_indices),
cv_params,
plot=True
)
現(xiàn)在我們得到了每個 boosting 步驟 3folds 平均的損失函數(shù)值,這提供了更準(zhǔn)確的模型性能估計。
print('Best validation accuracy score: {:.2f}±{:.2f} on step {}'.format(
np.max(cv_data['test-Accuracy-mean']),
cv_data['test-Accuracy-std'][np.argmax(cv_data['test-Accuracy-mean'])],
np.argmax(cv_data['test-Accuracy-mean'])
))
print('Precise validation accuracy score: {}'.format(np.max(cv_data['test-Accuracy-mean'])))
Best validation accuracy score:
0.83±0.02 on step 355
Precise validation accuracy score:
0.8294051627384961
如上所示,最初對單次驗證的性能估計并不是特別理想,而經(jīng)過交叉驗證后會有所提升。
模型應(yīng)用
模型訓(xùn)練結(jié)束后,可以保存模型,以供預(yù)測使用。
predictions = model.predict(X_test)
predictions_probs = model.predict_proba(X_test)
print(predictions[:10])
print(predictions_probs[:10])
[0 0 0 0 1 0 1 0 1 0]
[[0.85473931 0.14526069]
[0.76313031 0.23686969]
[0.88972889 0.11027111]
[0.87876173 0.12123827]
[0.3611047 0.6388953 ]
[0.90513381 0.09486619]
[0.33434185 0.66565815]
[0.78468564 0.21531436]
[0.39429048 0.60570952]
[0.94047549 0.05952451]]
5、CatBoost 應(yīng)用案例
出于演示目的,我們同樣使用 catboost 自帶的 amazon 數(shù)據(jù)集。
import pandas as pd
import os
import numpy as np
np.set_printoptions(precision=4)
import catboost
from catboost import *
from catboost import datasets
(train_df, test_df) = catboost.datasets.amazon()
train_df.head()
數(shù)據(jù)預(yù)處理
數(shù)據(jù)標(biāo)簽提取
y = train_df.ACTION
X = train_df.drop('ACTION', axis=1)
檢查數(shù)據(jù)集中標(biāo)簽平衡性
print('Labels: {}'.format(set(y)))
print('Zero count = {}, One count = {}'.format(len(y) - sum(y), sum(y)))
abels: {0, 1}
Zero count = 1897, One count = 30872
保存數(shù)據(jù)
dataset_dir = './amazon'
if not os.path.exists(dataset_dir):
os.makedirs(dataset_dir)
train_df.to_csv(
os.path.join(dataset_dir, 'train.csv'),
index=False, sep=',', header=True
)
test_df.to_csv(
os.path.join(dataset_dir, 'test.csv'),
index=False, sep=',', header=True
)
創(chuàng)建 Pool 類
from catboost.utils import create_cd
feature_names = dict()
for column, name in enumerate(train_df):
if column == 0:
continue
feature_names[column - 1] = name
create_cd(
label=0,
cat_features=list(range(1, train_df.columns.shape[0])),
feature_names=feature_names,
output_path=os.path.join(dataset_dir, 'train.cd')
)
!cat amazon/train.cd
0 Label
1 Categ RESOURCE
2 Categ MGR_ID
3 Categ ROLE_ROLLUP_1
4 Categ ROLE_ROLLUP_2
5 Categ ROLE_DEPTNAME
6 Categ ROLE_TITLE
7 Categ ROLE_FAMILY_DESC
8 Categ ROLE_FAMILY
9 Categ ROLE_CODE
這里展示了幾種創(chuàng)建Pool的不同方法,實際中你選中其中一種創(chuàng)建方法即可。
pool1 = Pool(data=X, label=y, cat_features=cat_features)
pool2 = Pool(
data=os.path.join(dataset_dir, 'train.csv'),
delimiter=',',
column_description=os.path.join(dataset_dir, 'train.cd'),
has_header=True
)
pool3 = Pool(data=X, cat_features=cat_features)
# 創(chuàng)建Pool的最快方法是從numpy矩陣創(chuàng)建它。
# 如果你想要快速的預(yù)測或者以最快的方式在python中加載數(shù)據(jù),就應(yīng)該使用這種方式。
X_prepared = X.values.astype(str).astype(object)
# 對于FeaturesData類,類別特性必須具有str類型
pool4 = Pool(
data=FeaturesData(
cat_feature_data=X_prepared,
cat_feature_names=list(X)
),
label=y.values
)
print('Dataset shape')
print('dataset 1:' + str(pool1.shape) +
'\ndataset 2:' + str(pool2.shape) +
'\ndataset 3:' + str(pool3.shape) +
'\ndataset 4:' + str(pool4.shape))
print('\n')
print('Column names')
print('dataset 1:')
print(pool1.get_feature_names())
print('\ndataset 2:')
print(pool2.get_feature_names())
print('\ndataset 3:')
print(pool3.get_feature_names())
print('\ndataset 4:')
print(pool4.get_feature_names())
Dataset shape
dataset 1:(32769, 9)
dataset 2:(32769, 9)
dataset 3:(32769, 9)
dataset 4:(32769, 9)
Column names
dataset 1:
['RESOURCE', 'MGR_ID', 'ROLE_ROLLUP_1',
'ROLE_ROLLUP_2', 'ROLE_DEPTNAME',
'ROLE_TITLE', 'ROLE_FAMILY_DESC',
'ROLE_FAMILY', 'ROLE_CODE']
dataset 2:
['RESOURCE', 'MGR_ID', 'ROLE_ROLLUP_1',
'ROLE_ROLLUP_2', 'ROLE_DEPTNAME',
'ROLE_TITLE', 'ROLE_FAMILY_DESC',
'ROLE_FAMILY', 'ROLE_CODE']
dataset 3:
['RESOURCE', 'MGR_ID', 'ROLE_ROLLUP_1',
'ROLE_ROLLUP_2', 'ROLE_DEPTNAME',
'ROLE_TITLE', 'ROLE_FAMILY_DESC',
'ROLE_FAMILY', 'ROLE_CODE']
dataset 4:
['RESOURCE', 'MGR_ID', 'ROLE_ROLLUP_1',
'ROLE_ROLLUP_2', 'ROLE_DEPTNAME',
'ROLE_TITLE', 'ROLE_FAMILY_DESC',
'ROLE_FAMILY', 'ROLE_CODE']
拆分訓(xùn)練集和測試集
這一步大家應(yīng)該比較熟悉,就不做過多的介紹。
from sklearn.model_selection import train_test_split
X_train, X_validation, y_train, y_validation = train_test_split(
X, y, train_size=0.8, random_state=1234)
選擇目標(biāo)函數(shù)
對于二分類數(shù)據(jù)集,目標(biāo)函數(shù)可以選擇Logloss
,如果要預(yù)測目標(biāo)標(biāo)簽的概率值,推薦使用交叉熵CrossEntropy
。
from catboost import CatBoostClassifier
model = CatBoostClassifier(
iterations=5,
learning_rate=0.1,
# loss_function='CrossEntropy'
)
model.fit(
X_train, y_train,
cat_features=cat_features,
eval_set=(X_validation, y_validation),
verbose=False
)
print('Model is fitted: ' + str(model.is_fitted()))
print('Model params:')
print(model.get_params())
Model is fitted: True
Model params:
{'iterations': 5, 'learning_rate': 0.1}
訓(xùn)練模型
模型訓(xùn)練與通常sklearn模型訓(xùn)練差異不大,先實例化模型 model,然后直接 fit
訓(xùn)練即可。
from catboost import CatBoostClassifier
model = CatBoostClassifier(
iterations=15,
# verbose=5,
)
model.fit(
X_train, y_train,
cat_features=cat_features,
eval_set=(X_validation, y_validation),
)
評估模型
Catboost 做模型評估時,同一般模型少有區(qū)別,該模型在 model.fit()
時,傳遞給參數(shù) eval_set
相應(yīng)的驗證子集,設(shè)置參數(shù) plot
為 True
,即可在訓(xùn)練模型的同時,用驗證集評估模型,并且輸出過程可視化結(jié)果,可謂是非常方便與驚艷。
from catboost import CatBoostClassifier
model = CatBoostClassifier(
iterations=50,
random_seed=63,
learning_rate=0.5,
custom_loss=['AUC', 'Accuracy']
)
model.fit(
X_train, y_train,
cat_features=cat_features,
eval_set=(X_validation, y_validation),
verbose=False,
plot=True
)
模型比較
與模型評估一樣,使用相同 CatBoostClassifier 分類器,僅僅設(shè)置不同的 learning_rate
,并設(shè)置train_dir
分別為 'learing_rate_0.7'
及 'learing_rate_0.01'
。
model1 = CatBoostClassifier(
learning_rate=0.7,
iterations=100,
random_seed=0,
train_dir='learing_rate_0.7'
)
model2 = CatBoostClassifier(
learning_rate=0.01,
iterations=100,
random_seed=0,
train_dir='learing_rate_0.01'
)
model1.fit(
X_train, y_train,
eval_set=(X_validation, y_validation),
cat_features=cat_features,
verbose=False
)
model2.fit(
X_train, y_train,
eval_set=(X_validation, y_validation),
cat_features=cat_features,
verbose=False
)
然后使用catboost的MetricVisualizer
方法比較兩個模型。該方法在單個圖表上繪制有關(guān)訓(xùn)練、指標(biāo)評估或交叉驗證運行的信息。根據(jù)輸入信息,一個圖表可以包含有關(guān)一次或多次運行的信息。圖表既可以在訓(xùn)練進行時實時繪制,也可以在訓(xùn)練結(jié)束后繪制。
from catboost import MetricVisualizer
MetricVisualizer(['learing_rate_0.01', 'learing_rate_0.7']).start()
交叉驗證
在前面已經(jīng)提到,使用交叉驗證可以得到性能更好的模型,進而得到更好的預(yù)測結(jié)果。相對使用sklearn 中的交叉驗證方法,Catboost 模型自帶的交叉驗證方法簡單、靈活,還可以直接顯示可視化交叉驗證過程及結(jié)果。下面小猴子錄制了動畫,展示交叉驗證過程。
from catboost import cv
# 設(shè)置參數(shù)空間
params = {}
params['loss_function'] = 'Logloss'
params['iterations'] = 80
params['custom_loss'] = 'AUC'
params['random_seed'] = 63
params['learning_rate'] = 0.5
# 直接使用catboost中自帶的cv參數(shù)。
cv_data = cv(
params = params,
pool = Pool(X, label=y, cat_features=cat_features), # 設(shè)置Pool類。
fold_count=5,
shuffle=True,
partition_random_seed=0,
plot=True, # 設(shè)置可視化過程
stratified=False,
verbose=False
)
交叉驗證過程中所有數(shù)據(jù)都記錄下來并以DataFrame格式返回,可以直接查看,或后續(xù)使用,非常方便!
cv_data.head()
其實,我們只關(guān)系最佳得分,使用如下方法可以輕松獲得:
best_value = np.min(cv_data['test-Logloss-mean'])
best_iter = np.argmin(cv_data['test-Logloss-mean'])
print('Best validation Logloss score, not stratified: {:.4f}±{:.4f} on step {}'.format(
best_value,
cv_data['test-Logloss-std'][best_iter],
best_iter)
)
Best validation Logloss score,
not stratified: 0.1581±0.0104 on step 52
過擬合檢驗
在創(chuàng)建CatBoostClassifier實例時,設(shè)置參數(shù)early_stopping_rounds=20
(根據(jù)實際情況設(shè)置),模型可以在 early_stopping_rounds
所設(shè)置的迭代輪數(shù)內(nèi)尋找模型效果最好的,這個模型效果評價指標(biāo)可以通過eval_metric
設(shè)置,默認 Logloss
,也可以設(shè)置為"AUC"
。還可以通過設(shè)置custom_metric
參數(shù),使用自定義評價指標(biāo)函數(shù)。
model_with_early_stop = CatBoostClassifier(
eval_metric='AUC',
iterations=200,
random_seed=63,
learning_rate=0.5,
early_stopping_rounds=20
)
model_with_early_stop.fit(
X_train, y_train,
cat_features=cat_features,
eval_set=(X_validation, y_validation),
verbose=False,
plot=True
)
print(model_with_early_stop.tree_count_)
30
可以使用tree_count_
屬性查看在何時停止的。
選擇概率決策邊界
繪制 ROC 曲線
首先使用catboost的工具函數(shù)get_roc_curve
獲取到在驗證池中的數(shù)據(jù)fpr
和 tpr
值,然后將其輸入到 sklearn 中的 auc
函數(shù)中,計算得到 roc_auc
面積大小。為了更加直觀,我們繪制如下曲線。
from catboost.utils import get_roc_curve
import sklearn
from sklearn import metrics
eval_pool = Pool(X_validation, y_validation, cat_features=cat_features)
curve = get_roc_curve(model, eval_pool)
(fpr, tpr, thresholds) = curve
roc_auc = sklearn.metrics.auc(fpr, tpr)
lw = 2
plt.plot(fpr, tpr, color='darkorange',
lw=lw, label='ROC curve (area = %0.2f)' % roc_auc, alpha=0.5)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--', alpha=0.5)
除了上面上面用于ROC曲線的FPR,TPR,另外還可以繪制FPR,F(xiàn)NR曲線。
from catboost.utils import get_fpr_curve
from catboost.utils import get_fnr_curve
(thresholds, fpr) = get_fpr_curve(curve=curve)
(thresholds, fnr) = get_fnr_curve(curve=curve)
lw = 2
plt.plot(thresholds, fpr, color='blue', lw=lw, label='FPR', alpha=0.5)
plt.plot(thresholds, fnr, color='green', lw=lw, label='FNR', alpha=0.5)
返回實現(xiàn)指定FNR或FPR所需的概率邊界。
from catboost.utils import select_threshold
print(select_threshold(model=model, data=eval_pool, FNR=0.01))
print(select_threshold(model=model, data=eval_pool, FPR=0.01))
0.48689529945049076
0.9899713850692811
模型預(yù)測
CatBoost預(yù)測有四種方式,predict、staged_predict、predict_proba 及 staged_predict_prob
。我們看下他們之間的區(qū)別。
首先 predict
和 predict_proba
,將模型應(yīng)用于給定數(shù)據(jù)集,預(yù)測得到結(jié)果,predict
是直接得到計算后的結(jié)果,如果是二分類,就是0或1。predict_proba
結(jié)果是歸屬于哪種類別的概率值。
print(model.predict_proba(X=X_validation))
[[0.0608 0.9392]
[0.0141 0.9859]
[0.0126 0.9874]
...
[0.0148 0.9852]
[0.0215 0.9785]
[0.0333 0.9667]]
print(model.predict(data=X_validation))
[1 1 1 ... 1 1 1]
與常規(guī)預(yù)測不同,Predict()
函數(shù)中有個 prediction_type
參數(shù),支持的預(yù)測類型包含多種:
-
Probability
-
Class
-
RawFormulaVal
-
Exponent
-
LogProbability
raw_pred = model.predict(
data=X_validation,
prediction_type='RawFormulaVal'
)
print(raw_pred)
[2.7374 4.2445 4.3614 ... 4.1992 3.8198 3.3681]
可以通過 Sigmoid 函數(shù)將上面結(jié)果轉(zhuǎn)換為概率。
from numpy import exp
sigmoid = lambda x: 1 / (1 + exp(-x))
probabilities = sigmoid(raw_pred)
print(probabilities)
[0.9392 0.9859 0.9874 ... 0.9852 0.9785 0.9667]
另一個就是 staged_predict 及 staged_predict_prob,他是階段預(yù)測,僅考慮 trees 在range[0; i) 內(nèi)的計算結(jié)果值。這個范圍是通過參數(shù)
eval_period
控制的:
要在應(yīng)用模型或計算指標(biāo)時減少要使用的樹的數(shù)量,將樹索引的范圍設(shè)置為[ntree_start; ntree_end)
并將要使用的樹的步長設(shè)置為eval_period
。
此參數(shù)定義迭代范圍的步驟[ntree_start; ntree_end)
。例如,假設(shè)設(shè)置了以下參數(shù)值:
-
ntree_start
設(shè)置為 0 -
ntree_end
設(shè)置為 N(總樹數(shù)) -
eval_period
設(shè)置為 2
在這種情況下,將返回以下樹范圍的結(jié)果:[0, 2), [0, 4), ... , [0, N)
。
predictions_gen = model.staged_predict_proba(
data=X_validation,
ntree_start=0,
ntree_end=5,
eval_period=1
)
try:
for iteration, predictions in enumerate(predictions_gen):
print('Iteration ' + str(iteration) + ', predictions:')
print(predictions)
except Exception:
pass
Iteration 0, predictions:
[[0.3726 0.6274]
...
[0.3726 0.6274]]
...
Iteration 4, predictions:
[[0.1388 0.8612]
...
[0.175 0.825 ]]
在未知數(shù)據(jù)集上評估模型
我們使用 eval_metrics
方法計算指定數(shù)據(jù)集的指定指標(biāo)。
metrics = model.eval_metrics(
data=pool1,
metrics=['Logloss','AUC'],
ntree_start=0,
ntree_end=0,
eval_period=1,
plot=True
)
從可視化結(jié)果看,eval_metrics
只包含 Eval 結(jié)果曲線,我們設(shè)置了 metrics=['Logloss','AUC']
,因此包含'Logloss'
和'AUC'
兩條評估曲線。
print('AUC values:')
print(np.array(metrics['AUC']))
特征重要性
使用模型自帶的get_feature_importance
方法。
model.get_feature_importance(prettified=True)
使用第三方解釋庫 Shap
。與一般模型直接使用 Shap
有所不同,使用 model.get_feature_importance()
方法,并設(shè)置參數(shù) type='ShapValues'
, 直接輸出 shap_values
值,該值可直接用戶輸出結(jié)果值及繪制相應(yīng)可視化圖形。
shap_values = model.get_feature_importance(
pool1, type='ShapValues')
expected_value = shap_values[0,-1]
shap_values = shap_values[:,:-1]
print(shap_values.shape)
(32769, 9)
import shap
shap.initjs()
shap.force_plot(expected_value, shap_values[3,:], X.iloc[3,:])
shap.initjs()
shap.force_plot(expected_value, shap_values[91,:], X.iloc[91,:])
shap.summary_plot(shap_values, X)
X_small = X.iloc[0:200]
shap_small = shap_values[:200]
shap.force_plot(expected_value, shap_small, X_small)
特征評估
CatBoost還有個很厲害的功能,就是對指定特征進行評估,給出評估結(jié)果,是好是壞
from catboost.eval.catboost_evaluation import *
learn_params = {'iterations': 20, # 2000
'learning_rate': 0.5, # we set big learning_rate,
# because we have small
# #iterations
'random_seed': 0,
'verbose': False,
'loss_function' : 'Logloss',
'boosting_type': 'Plain'}
evaluator = CatboostEvaluation(
'amazon/train.tsv',
fold_size=10000, # <= 50% of dataset
fold_count=20,
column_description='amazon/train.cd',
partition_random_seed=0,
#working_dir=...
)
result = evaluator.eval_features(
learn_config=learn_params,
eval_metrics=['Logloss', 'Accuracy'],
features_to_eval=[6, 7, 8])
以上設(shè)定用來評估的特征是[6, 7, 8],從以下結(jié)果看到特征6得到正向結(jié)論,而特征8得到負向結(jié)論,特征7從各項指標(biāo)中得不到確切的指標(biāo)。
from catboost.eval.evaluation_result import *
logloss_result = result.get_metric_results('Logloss')
logloss_result.get_baseline_comparison(
ScoreConfig(ScoreType.Rel, overfit_iterations_info=False)
)
模型保存和導(dǎo)入
當(dāng)我們得到一個較為理想的模型后,需要保存模型,以后期使用模型,因此,該步驟還是非常重要的。而CatBoost保存模型非常方便,無需借助第三方庫如pickle等,直接使用其save_model
方法,即可保存模型。
save_model
保存模型,可以保存為各種格式:
-
cbm — CatBoost 二進制格式。
-
coreml — Apple CoreML 格式(目前僅支持沒有分類特征的數(shù)據(jù)集)。
-
json — JSON 格式。有關(guān)格式詳細信息,請參閱CatBoost JSON 模型教程[1]。
-
python — 獨立的 Python 代碼(目前不支持多分類模型)。有關(guān)應(yīng)用結(jié)果模型的詳細信息,請參閱 Python[2]部分。
-
cpp — 獨立 C++ 代碼(當(dāng)前不支持多分類模型)。有關(guān)應(yīng)用結(jié)果模型的詳細信息,請參閱 C++[3]部分。
-
onnx — ONNX-ML 格式(目前僅支持沒有分類特征的數(shù)據(jù)集)。詳情請參閱 https://onnx.ai/。有關(guān)應(yīng)用結(jié)果模型的詳細信息,請參閱 ONNX[4]部分。
-
pmml — PMML 4.3 版[5]格式。如果訓(xùn)練數(shù)據(jù)集中存在分類特征,則必須在訓(xùn)練期間將其解釋為 one-hot 編碼。這可以通過將
--one-hot-max-size
/one_hot_max_size
參數(shù)設(shè)置為大于數(shù)據(jù)集中所有分類特征中唯一分類特征值的最大數(shù)量的值來實現(xiàn)。有關(guān)應(yīng)用結(jié)果模型的詳細信息,請參閱PMML[6]部分。
my_best_model.save_model('catboost_model.bin')
my_best_model.save_model('catboost_model.json', format='json')
當(dāng)然,導(dǎo)入模型也是非常方便,直接使用load_model
方法
my_best_model.load_model('catboost_model.bin')
print(my_best_model.get_params())
print(my_best_model.random_seed_)
參考資料
[1]CatBoost JSON 模型教程: https://github.com/catboost/tutorials/blob/master/model_analysis/model_export_as_json_tutorial.ipynb
[2]Python: https://catboost.ai/en/docs/concepts/python-reference_apply_catboost_model
[3]C++: https://catboost.ai/en/docs/concepts/c-plus-plus-api_applycatboostmodel
[4]ONNX: https://catboost.ai/en/docs/concepts/apply-onnx-ml
[5]PMML 4.3 版: http://dmg.org/pmml/pmml-v4-3.html文章來源:http://www.zghlxwxcb.cn/news/detail-849039.html
[6]PMML: https://catboost.ai/en/docs/concepts/apply-pmml文章來源地址http://www.zghlxwxcb.cn/news/detail-849039.html
到了這里,關(guān)于用通俗易懂的方式講解:CatBoost 算法原理及案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!