前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文弄懂随机森林的原理和应用

一文弄懂随机森林的原理和应用

作者头像
阿黎逸阳
发布2023-12-04 14:41:46
1.8K0
发布2023-12-04 14:41:46
举报

随机森林是一种集成学习算法,属于Bagging类型,通过组合多个决策树的预测结果得出最终的预测结果。

随机森林算法的原理和实现比较简单,本文接下来将进行详细阐述。

本文目录

  1. 名词解释
  2. 随机森林算法原理详解
  3. 随机森林算法参数详解
  4. 随机森林算法在车贷领域中应用 4.1 导入基本库并设置文件存放路径 4.2 导入待建模的数据 4.3 看下数据基本情况 4.4 创建和训练分类随机森林模型 4.5 创建和训练回归随机森林模型

一、名词解释

集成学习:通过构建并结合多个机器学习模型来改善模型的性能。通过训练多个模型,并将它们的预测结果进行某种方式的结合,通常可以得到比单一模型更好的预测结果。

Bagging:是Bootstrap Aggregating的缩写,是一种通过结合多个模型的预测结果来减少模型方差的方法。在Bagging中,每个模型都是在原始数据集的随机子集上进行训练的,这些随机子集是通过有放回的抽样得到的。然后,所有模型的预测结果通过投票(对于分类问题)或平均(对于回归问题)的方式进行结合。

随机森林:一种特殊的Bagging方法,其中每个模型都是一个决策树。除了数据集的随机子集外,每个决策树还在每个节点处从随机子集中选择最佳分裂。这种额外的随机性有助于减少模型之间的相关性,进一步提高模型的性能。

二、随机森林算法原理详解

大自然中的森林是由很多的树组成的,机器学习算法中的随机森林,也是由很多决策树组成的。

对决策树原理和使用不太了解,可以看下本公众号之前的文章:决策树-ID3算法和C4.5算法CART决策树原理(分类树与回归树)、Python中调用sklearn决策树、Python中应用决策树算法预测客户等级。

随机森林的训练过程如下:

  • 从原始数据集中进行有放回的随机抽样,构建出多个子集。
  • 在每个子集上训练一个决策树。
  • 在预测阶段,让每个决策树都对输入进行预测,然后以投票的方式或求平均的方式得出最终的预测结果。

在随机森林中,有两个重要的随机性:

1.数据采集的随机性:每个决策树模型都是在随机的子数据集上进行训练的,这有助于减少过拟合的风险。

2.特征选取的随机性:在每个节点分裂时,随机选择一部分特征进行计算,这有助于增加模型的多样性。

三、随机森林算法参数详解

代码语言:javascript
复制
随机森林算法分为分类随机森林和回归随机森林,在sklearn中可以直接调用。是一个功能强大的分类器,它有很多参数可以调整。
代码语言:javascript
复制
其基本调用语法如下:
from sklearn.ensemble import RandomForestClassifier  
from sklearn.ensemble import RandomForestRegressor

RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, 
                       min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, 
                       min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, 
                       warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)
RandomForestRegressor(n_estimators=100, *, criterion='mse', max_depth=None, min_samples_split=2, min_samples_leaf=1, 
                      min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, 
                      min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, 
                      verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)
代码语言:javascript
复制

主要参数详解:
n_estimators:森林中树的数量,也就是基学习器的数量。一般来说,树越多,模型的性能就越好,但同时计算时间和内存消耗也会增加。通常可以选择一个相对较大的值,然后通过交叉验证来找到最优值。
criterion:节点分裂采用的算法,这个参数决定了每个节点分裂的质量。对于分类问题,可以选择‘gini’(基尼不纯度)或‘entropy’(信息增益)。对于回归问题,可以选择‘mse’(均方误差)或‘mae’(平均绝对误差)。选择哪一个取决于你对预测误差的敏感程度。
max_depth:树的最大深度,如果设置为None,则节点会一直分裂到所有叶子都是纯的,或者直到所有的叶子都包含少于min_samples_split个样本。如果树太深,可能会导致过拟合,因此通常需要通过交叉验证来选择一个合适的值。
min_samples_split:一个节点在被考虑分裂之前必须具有的最小样本数。这个参数可以防止树过度适应训练数据。
min_samples_leaf:在每个叶子节点上必须有的最小样本数。这个参数和min_samples_split一样,也是用来防止过拟合的。
max_features:在寻找最佳分裂时考虑的特征数量。如果设置为‘auto’,则max_features=sqrt(n_features)。如果设置为‘log2’,则max_features=log2(n_features)。更大的max_features值将会使模型考虑更多的特征,从而可能提高模型的性能,但同时也会增加计算复杂度和过拟合的风险。
bootstrap:是否使用自助采样法(bootstrap sample)来构建树。如果设置为True,则每次构建树时都会从原始数据中随机抽取样本(有放回)。如果设置为False,则会使用整个数据集来构建每棵树。
oob_score:是否使用袋外样本来评估模型的性能。只有当bootstrap=True时,这个参数才有效。
random_state:随机数生成器的种子,用于控制模型的随机性。如果设置为一个整数,则每次运行模型时都会得到相同的结果。如果设置为None,则每次运行模型时都会得到不同的结果。
verbose:控制模型训练时的输出信息,如果设置为0,则不输出任何信息。如果设置为1,则会输出进度条和其他信息。
warm_start:如果设置为True,则使用上一次调用的解决方案来初始化添加更多的树,否则完全重新开始。
class_weight:指定样本各类别的权重。对于不平衡的数据集,这个参数可能会有所帮助。
n_jobs:并行运行的作业数。如果设置为-1,则使用所有可能的处理器来训练模型。
ccp_alpha:复杂度参数(特定用于回归问题),用于最小成本复杂度剪枝。增加alpha会增加剪枝的程度,从而可能导致更小、更简单的树。


四、随机森林算法在车贷领域的应用

项目背景:由于公司发展车贷业务,需要判断新进来的申请人有多大的概率会逾期,根据逾期的概率和资金的松紧程度决定是否放贷。 现在有一批历史上是否违约的客户样本数据(由于数据涉及安全问题,也是职业操守要求,故此数据不是原始数据,是经过处理的)。 想根据这批历史数据训练随机森林模型,得到模型结果,预测未来新申请的客户逾期概率。从而决定新申请人是通过、转人工核验还是拒绝。 1 导入基本库并设置文件存放路径 首先导入基本库,并设置数据的存放的地址,代码如下: import os import numpy as np import pandas as pd from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import RandomForestRegressor os.chdir(r'F:\公众号\88_随机森林') 2 导入待建模的数据 用pandas库导入待建模的csv格式数据。 data = pd.read_csv('testtdmodel.csv', sep=',', encoding='gb18030') 注:由于数据中存在中文,如果不使用encoding对编码进行申明会报如下错误: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 2: invalid start byte 把endcoding的值设置为gb18030或gbk可以解决此类问题,成功导入数据。 3 看下数据基本情况 3.1 用head函数看下数据表头和前几行数据 我选择看前两行的数据,如果括号里为空默认展示前五行的数据,可以根据需要把2改为你想展示的行数。也可以用tail函数展示后几行数据。 data.head(2) 结果:

3.2 用value_counts函数观测因变量y的数据分布 在信贷中,有些客户因为忘记了还款日期、或者资金在短期内存在缺口(不是恶意不还),可能会导致几天的逾期,在催收后会及时还款。 故一般不把历史逾期不超过x天(根据公司的实际业务情况和数据分析结果得出)的客户定义为坏客户(这里的坏不是坏人的意思,纯粹指逾期超过x天的客户)。 在本文把逾期超过20天的客户标签y定义为1(坏客户),没有逾期和逾期不超过20天的客户标签y定义为0(好客户)。 data.y.value_counts() 得到结果:

本文总计样本数量为7252,其中7155个样本是好客户,97个样本是坏客户。说明0和1的分布很不均匀,我们统计一下占比:

发现0的占比达到了98.6%,1的占比不到2%,这是典型的样本不均衡问题。 如果我们把所有的客户都预测成好客户,模型可以达到98.6%的准确率。但是这个结果是毫无意义的,因为模型没起到区分逾期和非逾期客户的作用,没有达到建模的目的。 可以用前文提到的class_weight对权重进行调整,让标签是1的样本占更多的权重。 实际中很多问题可能都是数据分布不均匀的,比如患病的人数和不患病的人数、欺诈商户和正常商户、逾期的客户和不逾期的客户等等。 不过这些都是正常现象,想一想如果逾期客户数超过了不逾期的人数,公司早就倒闭了

。 那么建模的目的就是想把钱尽可能多地贷给能按期还钱的客户,尽可能多地拒绝可能会逾期的客户。这样公司的钱才能挣得更多的利息,产生更少的坏账,总收益才能最大化。 4 创建和训练分类随机森林模型由于y的数量比较少本文就不区分训练集和测试集了,直接用全量数据训练随机森林模型,代码如下: columns_model = ['1个月内借款人身份证申请借款平台数','7天内关联P2P网贷平台数','3个月内关联P2P网贷平台数','3个月手机号关联身份证数','3个月内申请人关联融资租赁平台数','二度风险名单个数','是否命中身份证风险关注名单','原始分','一度风险名单个数'] X_train = data[columns_model] #生成入模自变量 y_train = data['y'] #生成入模因变量 # 创建随机森林分类器实例 rf = RandomForestClassifier(n_estimators=100, max_depth=None, random_state=42) # 使用训练数据进行训练 rf.fit(X_train, y_train) # 使用测试数据进行预测 y_pred = rf.predict_proba(X_train) 模型参数说明: n_estimators为100,即随机森林中用到100棵决策树做为基模型。 max_depth为None,即不限制树的深度。 random_state设置为整数,则每次运行模型时都会得到相同的结果。 由于篇幅原因,本文不对调参进行详细说明,后续文章分专题进行讲解。 用训练结果绘制KS曲线,看下模型效果,代码如下: import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams["font.sans-serif"] = ["SimHei"] def ks_plot(predictions, labels, cut_point=100): good_len = len([x for x in labels if x == 0]) # 所有好客户数量 bad_len = len([x for x in labels if x == 1]) # 所有坏客户数量 predictions_labels = list(zip(predictions, labels)) good_point = [] bad_point = [] diff_point = [] # 记录每个阈值点下的KS值 x_axis_range = np.linspace(0, 1, cut_point) for i in x_axis_range: hit_data = [x[1] for x in predictions_labels if x[0] <= i] # 选取当前阈值下的数据 good_hit = len([x for x in hit_data if x == 0]) # 预测好客户数 bad_hit = len([x for x in hit_data if x == 1]) # 预测坏客户数量 good_rate = good_hit / good_len # 预测好客户占比总好客户数 bad_rate = bad_hit / bad_len # 预测坏客户占比总坏客户数 diff = good_rate - bad_rate # KS值 good_point.append(good_rate) bad_point.append(bad_rate) diff_point.append(diff) ks_value = max(diff_point) # 获得最大KS值为KS值 ks_x_axis = diff_point.index(ks_value) # KS值下的阈值点索引 ks_good_point, ks_bad_point = good_point[ks_x_axis], bad_point[ks_x_axis] # 阈值下好坏客户在组内的占比 threshold = x_axis_range[ks_x_axis] # 阈值 plt.plot(x_axis_range, good_point, color="green", label="好企业比率") plt.plot(x_axis_range, bad_point, color="red", label="坏企业比例") plt.plot(x_axis_range, diff_point, color="darkorange", alpha=0.5) plt.plot([threshold, threshold], [0, 1], linestyle="--", color="black", alpha=0.3, linewidth=2) plt.scatter([threshold], [ks_good_point], color="white", edgecolors="green", s=15) plt.scatter([threshold], [ks_bad_point], color="white", edgecolors="red", s=15) plt.scatter([threshold], [ks_value], color="white", edgecolors="darkorange", s=15) plt.title("KS={:.3f} threshold={:.3f}".format(ks_value, threshold)) plt.text(threshold + 0.02, ks_good_point + 0.05, round(ks_good_point, 2)) plt.text(threshold + 0.02, ks_bad_point + 0.05, round(ks_bad_point, 2)) plt.text(threshold + 0.02, ks_value + 0.05, round(ks_value, 2)) plt.legend(loc=4) plt.grid() plt.show() ks_plot(y_pred[:,1], y_train) 得到结果:

可以发现分类随机森林模型的KS值为0.743。为了看得更清楚,用toad包打印一下KS表,代码如下: import toad d1 = toad.metrics.KS_bucket(y_pred[:, 1], y_train,bucket=20,method='quantile') d1 得到结果:

从上表知KS值为0.743,且当预测概率大于0.039时,能抓到75个坏客户,这一箱的lift为14。 5 创建和训练回归随机森林模型 上一节用分类随机森林模型训练了数据,为了对比,这一节用回归随机森林模型训练数据。 代码如下: rf2 = RandomForestRegressor(n_estimators=100, max_depth=None, random_state=42) # 使用训练数据进行训练 rf2.fit(X_train, y_train) # 使用测试数据进行预测 y_pred2 = rf2.predict(X_train) ks_plot(y_pred2, y_train) 得到结果:

可以发现,应用分类随机森林和回归随机森林训练数据得到的结果差不多,KS 都是0.74左右。 用toad包看下ks表,代码如下: d2 = toad.metrics.KS_bucket(y_pred2, y_train,bucket=20,method='quantile') d2 得到结果:

从上表可以发现分20箱时KS值变成了0.746,和KS图中的0.739不一样。 这是由于分箱数量不一致导致的,感兴趣的可以测试调整下分箱数,当设置为10时,结果就一致了。 机灵的小伙伴应该发现了,如果单看KS去评价模型好坏的话。在模型算法和参数没有做任何调整的前提下,计算KS时多分些箱也能提升该指标。 至此,随机森林原理和实现已讲解完毕,如想了解更多建模内容,可以翻看公众号中“风控建模”模块相关文章。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿黎逸阳的代码 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档