python分箱分类代码_Python实现变量分箱及应用

之前发的内容里,代码看不清,此篇为重发。

个人观点,信贷行业中,模型稳定性往往比模型效果更重要。信贷行业所做的任何规则、政策、模型的调整,都需要较长时间才能知道结果如何,模型迭代周期相较于其他行业可能更长,因此一个模型的稳定性至关重要。当然在模型迭代周期较短的场景下,可以去追求更好的模型效果,比如有些反欺诈场景,模型模型迭代快,模型可以快速及时调整。但对于大多数其他情况,无论是做评分卡还是机器学习,个人在实践中会为了稳定性牺牲掉一些效果。

提高模型的稳定性往往就是防止模型过拟合,当然不同算法中有很多防止过拟合的技术 上的细节,除去算法上的技术处理,还有一个非常重要的一点,就是对入模的特征进行处理, 其中一点就是变量分箱。分箱是将变量离散化(类别变量的分箱,也可以理解为“离散化”, 因为分箱后整理类别会变少),挖掘出变量的主要趋势,剔除变量的噪音。

之前使用SAS和R实现过分箱,学了Python后,就把R的代码翻译成python代码,因为R和 python太像了。

将代码封装在函数cut_bin里,函数中各参数分别为,df待分箱的数据集, Kvar数据集主键, Yvar数据集y值, max_depth决策树深度, p决策树叶节点数据占比。 代码如下:

该函数输出两个对象,df_bin分箱后的数据集,dict_bin为存放各变量分箱结果的字典。df_bin分箱后的数据集示例:

dict_bin示例:

某变量分箱结果,从Bad_Rate可以看出该变量风险递增,有很好的趋势和业务解释性:

在训练样本上分箱后,如何将分箱结果应用到测试样本呢?下面函数实现了将训练样本上分箱方式“套进” 测试样本里。其中df是测试样本数据集,Kvar是主键,Yvar是y值,lst_bin是训练样本上的分箱结果的字典。该函数也输出两个对象,df_bin是测试样本分箱结果,dict_bin是测试样本变量分箱结果的字典。具体示例和上面结果相似。

上面的两个函数实现了变量分箱的自动化,现在想看看训练样本和测试样本里某个变量的趋势是否一致。编了两个函数实现该功能。train_test_bindict_trend里的参数为训练和测试样本的分箱结果的字典,train_test_bin_trend参数为训练和测试样本的分箱数据集。

运行后的结果如下,左侧为该变量在训练样本上的趋势,右侧为测试样本上的趋势,从图中可以看出该变量的趋势比较稳定,但为了业务上更好解释,可以将2和3进行合并,这样趋势就更明显也更好解释,也会在某种程度上消除掉一些噪音。

现在我想改变上面这个变量的分箱,比如分箱的个数更多一些或更少一些,或改变每段的最少占比等。

如改变每段占比至少10%,看看趋势如何:

好的,关于Python实现连续变量最优分箱详解,我可以为您提供一些基础的思路和代码实现。该方法是基于CART算法实现的,具体如下: 首先,我们需要导入相关的库,包括numpy、pandas和sklearn等: ```python import numpy as np import pandas as pd from sklearn.tree import DecisionTreeRegressor ``` 然后,我们需要定义一个函数来执行最优分箱操作,该函数的输入参数包括待分箱的数据、目标变量、最小样本数、最大分箱数、以及是否需要返回分箱结果等: ```python def binning_continuous_var(data, target, min_samples_leaf=50, max_bins=10, return_bins=False): # 将数据和目标变量拼接 data = pd.concat([data, target], axis=1) # 获取连续变量的列名 cont_cols = data.select_dtypes(include=[np.number]).columns.tolist() # 循环处理每个连续变量 for col in cont_cols: # 对该变量进行分箱操作 binned_col, bins = bin_continuous_var(data, col, target, min_samples_leaf, max_bins) # 将分箱结果更新到数据集中 data[col] = binned_col # 如果需要返回分箱结果,则返回数据集和分箱边界值 if return_bins: return data, bins # 否则,仅返回数据集 else: return data ``` 接下来,我们需要定义一个子函数来执行单个连续变量分箱操作,该函数的输入参数包括待分箱的数据、连续变量的列名、目标变量、最小样本数和最大分箱数等: ```python def bin_continuous_var(data, col, target, min_samples_leaf, max_bins): # 获取该变量的取值范围 data_range = data[col].max() - data[col].min() # 如果取值范围为0,则直接返回原始变量和一个空的分箱边界值列表 if data_range == 0: return data[col], [] # 否则,使用CART算法进行分箱操作 else: # 初始化决策树模型 tree_model = DecisionTreeRegressor( criterion='mse', min_samples_leaf=min_samples_leaf, max_leaf_nodes=max_bins, random_state=42 ) # 拟合决策树模型 tree_model.fit(data[col].to_frame(), target) # 获取决策树的叶节点数目 n_leaves = tree_model.get_n_leaves() # 如果叶节点数目大于等于最大分箱数,则需要重新设置最大叶节点数目并重新拟合模型 while n_leaves >= max_bins: max_bins -= 1 tree_model = DecisionTreeRegressor( criterion='mse', min_samples_leaf=min_samples_leaf, max_leaf_nodes=max_bins, random_state=42 ) tree_model.fit(data[col].to_frame(), target) n_leaves = tree_model.get_n_leaves() # 获取叶节点的取值范围 leaves_range = [(tree_model.tree_.threshold[i - 1], tree_model.tree_.threshold[i]) for i in np.where(tree_model.tree_.children_left == -1)[0]] # 初始化分箱边界值列表,将最小值和最大值作为边界值的起点和终点 bins = [data[col].min()] + [i[1] for i in leaves_range[:-1]] + [data[col].max()] # 计算每个取值所对应的分箱编号 binned_col = np.digitize(data[col], bins) # 将分箱编号转换为分箱中心点的取值 binned_col = pd.Series(binned_col, index=data.index) binned_col = binned_col.map(lambda x: np.round(np.mean(data[target.name][binned_col == x]), 4)) # 返回分箱结果和分箱边界值列表 return binned_col, bins ``` 最后,我们可以使用上述代码实现对连续变量的最优分箱操作,例如: ```python # 生成测试数据 data = pd.DataFrame({ 'col1': np.random.rand(1000), 'col2': np.random.rand(1000), 'col3': np.random.rand(1000), 'target': np.random.randint(0, 2, 1000) }) # 执行最优分箱操作 data_binned = binning_continuous_var(data.drop('target', axis=1), data['target'], min_samples_leaf=50, max_bins=10, return_bins=False) ``` 以上就是Python实现连续变量最优分箱的基础思路和代码实现,希望可以对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值