前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >一文速学-CatBoost算法模型实现贷款违约预测

一文速学-CatBoost算法模型实现贷款违约预测

原创
作者头像
fanstuck
发布2025-01-01 21:29:33
发布2025-01-01 21:29:33
19000
代码可运行
举报
运行总次数:0
代码可运行

前言

此篇文章为整个Boost(提升方法)集成算法模型的终章,前几篇文章依次结合详细项目案例讲解了AdaBoost、GBDT、XGBoost、LightGBT共四个常用的集成算法模型,每一篇文章都包含实战项目以及可运行代码。仅通过看一遍文章不去实践是很难掌握集成算法模型的,其中很多思想和优化参数的方法需要长期使用才能掌握,集成学习的方法在全球各大机器学习、数据挖掘竞赛中使用的非常广泛,其概念和思想也是风靡学术界和工业界,所以有此需求的朋友推荐细读实践。

​之前我们已经详细描述了AdaBoost算法模型和GBDT原理以及实践。通过这两类算法就可以明白Boosting算法的核心思想以及基本的运行计算框架,余下几种Boosting算法都是在前者的算法之上改良得到,尤其是以GBDT算法为基础改进衍生出的三种Boosting算法:XGBoost、LightGBM、CatBoost。看过之前GBDT的读者应该对GBDT模型有了一个很清楚的认知,对于理解CatBoost算法有一定的基础。

作为一个从事数据建模五年的专业人士,我参与了许多数学建模项目,了解各种模型的原理、建模流程和题目分析方法。我希望通过这个专栏让你能够快速掌握各类数学模型、机器学习和深度学习知识,并掌握相应的代码实现。每篇文章都包含实际项目和可运行的代码。我会紧跟各类数模比赛,将最新的思路和代码分享给你,保证你能够高效地学习这些知识。

一、CatBoost

CatBoost(Categorical Boosting)是由俄罗斯搜索引擎巨头Yandex开发的一种梯度提升树算法。它可以与深度学习框架轻松集成。它可以处理多种数据类型,以帮助解决企业今天面临的各种问题。CatBoost 和 XGBoost、LightGBM 并称为 GBDT 的三大主流神器,都是在 GBDT 算法框架下的一种改进实现。XGBoost 被广泛的应用于工业界,LightGBM 有效的提升了 GBDT 的计算效率,而 Yandex 的 CatBoost 号称是比 XGBoost 和 LightGBM 在算法准确率等方面表现更为优秀的算法。 CatBoost相比与其他GBDT算法系列,其特点以下表可以清楚区别:

算法差异点

GBDT

XGBoost

LightGBM

CatBoost

弱学习器

CART回归树

1.CART回归树 2.线性学习器 3.Dart树

Leaf-wise树

对称树

寻找分裂点

贪心算法

近似算法

直方图算法

预排序算法

稀疏值处理

稀疏感知算法

EFB(互斥特征捆绑)

类别特征

不直接支持,可自行编码后输入模型

同GBDT

直接支持,GS编码

直接支持,Ordered TS编码

并行支持

不可以

可以

可以

可以

CatBoost最大的特点是能够直接处理类别型特征,而不需要进行独热编码或其他转换,这点和LightGBM算法相同,但是二者采取编码的算法不同,CatBoost比LightGBM处理类别特征也更加直接。

CatBoost 是一种基于 对称决策树(oblivious trees)为基学习器实现的参数较少、支持类别型变量和高准确性的GBDT框架:GBDT,主要解决的痛点是高效合理地处理类别型特征,这一点从它的名字中可以看出来,CatBoost 是由 Categorical 和 Boosting 组成。此外,CatBoost 还解决了梯度偏差(Gradient Bias)以及预测偏移(Prediction shift)的问题,从而减少过拟合的发生,进而提高算法的准确性和泛化能力。

此外,CatBoost 梯度提升算法库中的学习算法基于 GPU 实现,打分算法基于 CPU 实现。

​1.CatBoost算法特点

1.1自动处理分类特征

CatBoost 能够直接处理分类特征,无需进行独热编码或其他预处理。这使得它在处理实际数据时更为方便。

代码语言:python
代码运行次数:0
复制
import catboost
from catboost import CatBoostClassifier, Pool

# 假设我们有一个包含分类特征的数据集
X = [[1, 'a', 0.1], [2, 'b', 0.2], [3, 'a', 0.3], [4, 'b', 0.4]]
y = [0, 1, 0, 1]

# 创建一个 Pool 对象,它会自动识别分类特征
dataset = Pool(data=X, label=y, cat_features=[1])

# 初始化并训练一个 CatBoost 分类器
model = CatBoostClassifier(iterations=100, depth=6, learning_rate=0.1, loss_function='Logloss', verbose=200)
model.fit(dataset)

# 进行预测
preds = model.predict(dataset)

# 输出预测结果
print(preds)

在这个示例中,我们使用了一个简单的数据集 X,其中包含了一个整数特征、一个字符串特征和一个浮点数特征。我们将分类特征的索引传递给 cat_features 参数,CatBoost 将会自动识别并处理这些特征。我们创建了一个 Pool 对象,它会自动将分类特征编码为数字。接着,我们初始化了一个 CatBoost 分类器,并对其进行训练。

最后,我们使用训练好的模型进行预测。CatBoost 可以自动处理分类特征,无需进行额外的独热编码等预处理步骤。

1.2自动处理缺失值

数据存在缺失值是很正常的,一般来说我们会采取很多方法去填充这些空值,可以使用均值或者统计指标,也可以使用机器学习算法去学习再填充,而CatBoost会在训练过程中学习如何处理缺失值。它会自动将缺失值的处理纳入模型中,而无需进行显式的填充或处理。CatBoost会将缺失值视为一个特定的数值,这个数值在内部被用作缺失值的标识符。

对分类特征的处理:对于分类特征,CatBoost会将缺失值作为一个额外的类别,不需要对其进行特殊处理。

对数值特征的处理:对于数值特征,CatBoost会将缺失值视为一个额外的分支,因此不会影响其他分支的计算。

对目标变量的处理:在目标变量中也可以包含缺失值。CatBoost会自动处理这些缺失值,并在训练过程中进行适当的计算。

1.3特征重要性评估

CatBoost可以通过内置的get_feature_importance()方法来获取特征重要性评估。这个方法返回一个包含特征重要性得分的数组,可以用来衡量每个特征对于模型预测的贡献程度。这大大增加了模型的可解释性,帮助理解模型。

1.4可交互模型过程可视化

CatBoost自带的可交互模型过程可视化,查看模型的学习过程。

2.CatBoost算法计算原理

首先基础的流程还是和GBDT一致的:

相较于GBDT、XGBoost、LightGBM算法,CatBoost算法有很多特点,但最引人注目的还是这两个:

  • 对分类型特征的处理。这使得我们在训练模型之前可以考虑不用再通过特征工程去处理分类型特征
  • 预测偏移处理。这可以减少模型的过拟合,提升模型预测效果

2.1ordered TS编码

这是基于TS编码改进的一种编码方式。对于一些类别基数比较小的特征,例如2~3类,可以直接使用one-hot编码,但对于类别基数较大的特征,one-hot编码会产生特征维度问题,这种情况下TS编码会合适一些。

CatBoost算法中采用了ordered TS编码方法来解决Greedy TS编码的目标泄露问题。ordered TS编码是基于排序的,在CatBoost算法中,会对样本进行多次洗牌,每次得到不同排序状态的样本集。

排序的目的产生一种随机性,减少过拟合。每一轮迭代、构建一个树时,都会选择一种排序状态的样本集,这样在不同轮次迭代中,不同排序状态的样本集综合起来,会使模型的方差更小,越不容易过拟合。

主要有以下几个步骤:

  1. 产生一个随机排列顺序 并对数据集进行编号
  2. 对于训练样本:
  3. 对于测试样本:
  4. 根据带先验概率的Greedy TS计算

这样计算得到的 Ordered TS能够满足P1,同时也能够使用所有的训练样本。且比在线学习的划窗(sliding window)处理能够进一步减小 的方差。需要注意的是,CatBoost在不同的迭代上会采用不同的排列顺序。 下面是Ordered TS与其它各种TS在不同数据集上面在logloss/zero-one loss上面的效果比较:

2.2 特征组合

CatBoost的另一个重要实现是在构建决策树时,动态地考虑了不同类别型特征的组合,从而获取了高阶依赖关系。例如,在广告点击预测中,考虑了用户ID与广告话题之间的联合信息,或者在音乐推荐中,结合了用户ID和音乐流派的信息。

这一实现涉及到了对特征组合的动态考虑。在树的第一次分割时,不考虑任何特征的组合。然而,在下一个分割时,CatBoost会将当前树的所有组合特征、类别型特征与数据集中的所有类别型特征相结合。这种方法能够动态地将新的组合类别型特征转换为数值型特征,以便在树的构建过程中考虑到更多的信息。

具体来说,CatBoost会将树中选定的所有分割点都视为具有两个值的类别型特征,然后像对待普通的类别型特征一样,将它们进行组合考虑。这种策略能够在不引入过多特征组合的情况下,依然有效地捕获到特征之间的复杂关系,从而提升了模型的性能。

感兴趣的推荐阅读paper很有帮助:http://learningsys.org/nips17/assets/papers/paper_11.pdf

2.3 预测偏移处理

基础原理还是和GBDT一致:在梯度提升中,每个弱学习器的训练都是基于前一个弱学习器的预测误差,通过梯度下降的方式来最小化误差。具体来说,对于回归问题,我们可以选择平方损失函数作为损失函数。关于梯度提升算法我之前在Logistic原理详解和遗传算法里面也有详解讲过,此类最优算法最核心的一点就是对于残差的使用。而损失函数就是衡量调整每一次迭代模型算法的权重的参考功能。

这个技术的实现原理是通过在目标函数中引入PredictionValuesChange,使得模型在训练时会在最小化损失的同时,尽量保持预测值的稳定性。这样,在测试时,即使输入的数据分布与训练集有所不同,模型也能够更好地适应新的数据分布,保证了模型的泛化性能。

CatBoost的预测偏移处理通过反复对样本进行重新排序来减小预测方差。在这个过程中,模型会根据当前迭代的样本排序计算梯度,以获取一个无偏估计。然而,对于排名靠前的样本,由于它们是由较少的样本训练的,因此估计结果可能会有一定的不准确性和较大的方差。

为了解决这个问题,CatBoost在每轮迭代中都会重新对样本进行排序,然后基于新的排序计算梯度。这样做的好处是,在多轮迭代的过程中,模型可以逐步获取更为准确的梯度估计,从而降低了预测的方差。

二、实现贷款违约预测

上述的理论其实是比较复杂的,博主本人研究此算法也花了很大一部分工作去阅读原papar和其他解释文章。最重要的是我们能够使用catboost来进行一些实际案例运行,这点对我们来说更为重要。对于贷款违约预测这个比较经典的课题,我们很容易拿到现成的数据,对于建模来讲,我们最缺的就是数据,而阿里天池提供了一份开源贷款违约数据,大家直接下载即可.

1.数据背景及描述

赛题以预测用户贷款是否违约为任务,数据集报名后可见并可下载,该数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。为了保证比赛的公平性,将会从中抽取80万条作为训练集,20万条作为测试集A,20万条作为测试集B,同时会对employmentTitle、purpose、postCode和title等信息进行脱敏。

​字段表

Field

Description

id

为贷款清单分配的唯一信用证标识

loanAmnt

贷款金额

term

贷款期限(year)

interestRate

贷款利率

installment

分期付款金额

grade

贷款等级

subGrade

贷款等级之子级

employmentTitle

就业职称

employmentLength

就业年限(年)

homeOwnership

借款人在登记时提供的房屋所有权状况

annualIncome

年收入

verificationStatus

验证状态

issueDate

贷款发放的月份

purpose

借款人在贷款申请时的贷款用途类别

postCode

借款人在贷款申请中提供的邮政编码的前3位数字

regionCode

地区编码

dti

债务收入比

delinquency_2years

借款人过去2年信用档案中逾期30天以上的违约事件数

ficoRangeLow

借款人在贷款发放时的fico所属的下限范围

ficoRangeHigh

借款人在贷款发放时的fico所属的上限范围

openAcc

借款人信用档案中未结信用额度的数量

pubRec

贬损公共记录的数量

pubRecBankruptcies

公开记录清除的数量

revolBal

信贷周转余额合计

revolUtil

循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额

totalAcc

借款人信用档案中当前的信用额度总数

initialListStatus

贷款的初始列表状态

applicationType

表明贷款是个人申请还是与两个共同借款人的联合申请

earliesCreditLine

借款人最早报告的信用额度开立的月份

title

借款人提供的贷款名称

policyCode

公开可用的策略_代码=1新产品不公开可用的策略_代码=2

n系列匿名特征

匿名特征n0-n14,为一些贷款人行为计数特征的处理

数据均被处理过,详细处理过程在我的另一篇文章上有具体代码和每一个步骤的数据可视化展示.

2.划分数据集

首先每天catboost库的需要安装:

代码语言:javascript
代码运行次数:0
复制
pip installl catboost

导入sklearn帮助我们快速搭建模型和计算对应指标:

代码语言:javascript
代码运行次数:0
复制
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split  
import pandas as pd
train=pd.read_csv("df2.csv")
train=train.iloc[:10000,2:] 
# 划分特征变量与目标变量
X=train.drop(columns='isDefault')
Y=train['isDefault']
# 划分训练及测试集
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.2,random_state=0)

3.权重统计

首先我们可以尝试使用用CatBoost内置函数计算权重:

代码语言:javascript
代码运行次数:0
复制
from catboost.utils import get_roc_curve
# 创建并训练一个CatBoost分类器
model = CatBoostClassifier(iterations=100, depth=6, learning_rate=0.1, loss_function='Logloss')
model.fit(X_train, y_train)
# 假设 df 是你的 Pandas DataFrame
train_data = catboost.Pool(data=X_train, label=y_train)
# 获取特征重要性评估
feature_importance = model.get_feature_importance(data=train_data, type='LossFunctionChange')

# 打印特征重要性得分
for i, score in enumerate(feature_importance):
    print(f'Feature {i}: {score}')

4.构建分类器

代码语言:javascript
代码运行次数:0
复制
from catboost.utils import get_roc_curve
# 创建并训练一个CatBoost分类器
model = CatBoostClassifier(iterations=100, depth=6, learning_rate=0.1, loss_function='Logloss')
model.fit(X_train, y_train,plot=True)

可以通过详细输出或使用漂亮的绘图来观察我们的模型学习,我们使用CatBoost自带的可交互模型过程可视化,查看模型的学习过程。只需要在fit函数加入参数plot就可展示:

5.模型验证

Catboost 做模型评估时,同一般模型少有区别,该模型在 model.fit() 时,传递给参数 eval_set 相应的验证子集,设置参数 plotTrue,即可在训练模型的同时,用验证集评估模型,并且输出过程可视化结果,可谓是非常方便与惊艳。

代码语言:javascript
代码运行次数:0
复制
model = CatBoostClassifier(
    iterations=50,
    random_seed=63,
    learning_rate=0.5,
    custom_loss=['AUC', 'Accuracy']
)
model.fit(
    X_train, y_train,
    eval_set=(X_test, y_test),
    verbose=False,
    plot=True
)

​6.模型参数比较

与模型评估一样,使用相同 CatBoostClassifier 分类器,仅仅设置不同的 learning_rate,并设置train_dir分别为 'learing_rate_0.7''learing_rate_0.01'

代码语言:javascript
代码运行次数:0
复制
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_test, y_test),
    verbose=False,
    plot=True
)
model2.fit(
    X_train, y_train,
    eval_set=(X_test, y_test),
    verbose=False,
    plot=True
)

然后使用catboost的MetricVisualizer方法比较两个模型。该方法在单个图表上绘制有关训练、指标评估或交叉验证运行的信息。根据输入信息,一个图表可以包含有关一次或多次运行的信息。图表既可以在训练进行时实时绘制,也可以在训练结束后绘制。

编辑

7.模型交叉验证

相比sklearn的交叉验证方法,Catboost 模型自带的交叉验证方法简单、灵活,还可以直接显示可视化交叉验证过程及结果:

代码语言:javascript
代码运行次数:0
复制
from catboost import cv
# 设置参数空间
params = {}
params['loss_function'] = 'Logloss'
params['iterations'] = 80
params['custom_loss'] = 'AUC'
params['random_seed'] = 63
params['learning_rate'] = 0.01
# 直接使用catboost中自带的cv参数。
cv_data = cv(
    params = params,
    pool = Pool(X_train, label=y_train), # 设置Pool类。
    fold_count=5,
    shuffle=True,
    partition_random_seed=0,
    plot=True,   # 设置可视化过程
    stratified=False, 
    verbose=False
)

可获取最佳得分:

代码语言:javascript
代码运行次数:0
复制
import numpy as np
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.4976±0.0059 on step 79

8.过拟合检验

在创建CatBoostClassifier实例时,设置参数early_stopping_rounds=20(根据实际情况设置),模型可以在 early_stopping_rounds 所设置的迭代轮数内寻找模型效果最好的,这个模型效果评价指标可以通过eval_metric设置,默认 Logloss,也可以设置为"AUC"。还可以通过设置custom_metric参数,使用自定义评价指标函数。

代码语言:javascript
代码运行次数:0
复制
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,
    eval_set=(X_test, y_test),
    verbose=False,
    plot=True
)

编辑

9.模型预测及指标检验

通过sklearn可以快速可视化模型预测结果:

代码语言:javascript
代码运行次数:0
复制
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split  
import xgboost as xgb
from sklearn.model_selection import KFold
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt

result = []
mean_score = 0
labels=[0,1]
y_pred=model.predict_proba(X_test)[:,1]
def classify_convert(x):
    if x >0.5:
        return 1
    else:
        return 0
list_predict=[]
for i in y_pred:
    list_predict.append(classify_convert(i))
cm= confusion_matrix(y_test.values, list_predict)
sns.heatmap(cm,annot=True ,fmt="d",xticklabels=labels,yticklabels=labels)
print('验证集auc:{}'.format(roc_auc_score(y_test, y_pred)))
mean_score += roc_auc_score(y_test, y_pred)
plt.title('confusion matrix')  # 标题
plt.xlabel('Predict lable')  # x轴
plt.ylabel('True lable')  # y轴
plt.show()
# 模型评估
print('mean 验证集Auc:{}'.format(mean_score))
cat_pre=sum(result)  
from sklearn.metrics import f1_score
print('F1_socre:{}'.format(f1_score(y_test.values, list_predict, average='weighted')))
from sklearn.metrics import recall_score
print('Recall_score:{}'.format(recall_score(y_test.values, list_predict, average='weighted')))
from sklearn.metrics import precision_score
print('Percosopn:{}'.format(precision_score(y_test.values, list_predict, average='weighted')))

​编辑 模型效果比上期我们用XGBoost模型预测的效果还要优秀。

10.权重展示

对于数据集的每个特征权重,我们可以适当的丢掉一些影响准确的的特征,增加我们模型的计算速率和数据使用空间,通过get_feature_names可以或得权重数值,通过数据可视化可以轻松获取需要的特征:

代码语言:javascript
代码运行次数:0
复制
# 获取特征名称
feature_names = train_data.get_feature_names()
# 将特征重要性和特征名称结合起来,创建一个字典
feature_importance_dict = dict(zip(feature_names, feature_importance))

# 将特征重要性排序
sorted_feature_importance = sorted(feature_importance_dict.items(), key=lambda x: x[1], reverse=True)

# 提取排序后的特征名称和重要性
sorted_feature_names, sorted_feature_importance = zip(*sorted_feature_importance)

plt.figure(figsize=(10, 6))
plt.barh(sorted_feature_names[:10], sorted_feature_importance[:10])
plt.xlabel('Feature Importance')
plt.title('Top 10 Important Features')
plt.gca().invert_yaxis()  # 反转y轴以显示重要性高的特征在顶部
plt.show()

11.获取最优参数

要在指定的数据集上获取CatBoost算法模型的最优训练参数,可以使用交叉验证(Cross Validation)和网格搜索(Grid Search)的方法。CatBoost支持使用GPU进行加速,可以加快我们训练速度:

代码语言:javascript
代码运行次数:0
复制
from catboost import CatBoostClassifier, Pool, cv
from sklearn.model_selection import GridSearchCV
train=pd.read_csv("df2.csv")
train=train.iloc[:40000,2:] 
# 划分特征变量与目标变量
X=train.drop(columns='isDefault')
Y=train['isDefault']
# 划分训练及测试集
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.2,random_state=0)
train_data = Pool(X_train, label=y_train)

param_grid = {
    'depth': [4, 6, 8],
    'learning_rate': [0.1, 0.05, 0.01,0.001]
}
model = CatBoostClassifier(task_type="GPU")

grid_search = GridSearchCV(estimator=model, param_grid=param_grid, scoring='accuracy', cv=3, verbose=2, n_jobs=-1)

grid_search.fit(X_train,y_train)
best_params = grid_search.best_params_
best_model = CatBoostClassifier(depth=best_params['depth'], learning_rate=best_params['learning_rate'])
best_model.fit(train_data)

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢

以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、CatBoost
    • 1.1自动处理分类特征
    • 1.2自动处理缺失值
    • 1.3特征重要性评估
    • 1.4可交互模型过程可视化
    • 2.CatBoost算法计算原理
      • 2.1ordered TS编码
      • 2.2 特征组合
      • 2.3 预测偏移处理
  • 二、实现贷款违约预测
    • 1.数据背景及描述
    • 2.划分数据集
    • 3.权重统计
    • 4.构建分类器
    • 5.模型验证
    • ​6.模型参数比较
    • 7.模型交叉验证
    • 8.过拟合检验
    • 9.模型预测及指标检验
    • 10.权重展示
    • 11.获取最优参数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档