python 基于卡方值分箱算法的实现示例

1. 简介

在机器学习领域的数据预处理过程中,离散化(discretization)是一个常用的方法。其作用是将连续型变量转换为离散型变量,便于建模处理。分箱(binning)是离散化中的一种方法,其作用是将一段范围连续的数据划分为若干个区间,每个区间成为一个箱子,相当于将原来的连续区间离散化成了若干个离散的项,称为离散化、分箱或者分桶。本文将介绍 python 中基于卡方值分箱算法的实现示例。

2. 卡方值分箱算法

2.1 基本思想

卡方值分箱算法,顾名思义,是基于卡方值的一种分箱方法。其基本思想是首先进行最优分割点的搜索,然后按照分割点的位置,将连续的数据分成多个箱子。在搜索最优分割点的过程中,采用了卡方检验的方法,即判断样本分布与预期分布之间的差异是否足够显著,从而确定最优分割点。

2.2 分箱步骤

卡方值分箱算法的具体步骤如下:

对于连续型变量,我们需要先对其进行排序

将连续型变量分成若干个初始区间,例如 $n$ 个等分点,作为初始区间

计算每个区间的实际值分布以及预期分布,并计算卡方值

合并相邻卡方值最小的区间

重新计算每个区间的实际值分布以及预期分布,并计算卡方值

递归执行步骤4~5,直到满足停止条件(例如分成 $k$ 个区间,或者卡方值达到一定阈值等)

2.3 代码实现

基于上述思路,我们来看一下卡方值分箱算法的 python 实现。

def chiMerge(df, col, target_col, confidence_val=3.841, bin_num=10):

"""

df: 待分箱数据集

col: 待分箱列名

target_col: 标签列名

confidence_val: 卡方值显著性水平,默认为 0.05(自由度为 1,置信度为 95% 时的卡方值)

bin_num: 初始分箱数量

"""

# 创建初始分箱

data = df[[col, target_col]]

n = data.shape[0]

data[col] = pd.qcut(data[col], q=bin_num, duplicates='drop')

co_tab1 = pd.crosstab(data[col], data[target_col])

# 开始迭代

while True:

# 计算相邻区间卡方值

chi_val = [] # 表示相邻区间卡方值

for i in range(len(co_tab1) - 1):

chi = stats.chi2_contingency(co_tab1.iloc[i:i + 2])[0]

chi_val.append(chi)

if min(chi_val) >= confidence_val: # 如果不需要合并,则退出循环

break

# 合并卡方值最小的相邻区间

min_chi_index = chi_val.index(min(chi_val))

co_tab1.iloc[min_chi_index:min_chi_index + 2, :]\

= co_tab1.iloc[min_chi_index:min_chi_index + 2, :].sum()

# 最终分箱结果

bins = co_tab1.index.map(lambda x: x.right).tolist()

return bins

3. 示例

3.1 数据准备

我们使用 Kaggle 上的 titanic 数据集来演示卡方值分箱算法的使用。首先,我们需要将连续型变量 Age 进行分箱处理。

import pandas as pd

df = pd.read_csv('train.csv')

age_bins = chiMerge(df, 'Age', 'Survived')

运行上述代码,即可得到分好箱的结果:

[2.0, 15.0, 28.0, 36.0, 45.0, 55.0, 65.0, 80.0]

我们看到,原来的连续区间被离散化成了若干个离散的项,共分成了 7 个箱子。

3.2 可视化分箱结果

我们可以通过绘图来直观地展示分箱结果。

import seaborn as sns

sns.histplot(data=df, x='Age', hue='Survived', bins=age_bins[:-1], kde=True)

运行上述代码,即可得到下图:

3.3 模型建立

通过卡方值分箱方法,我们成功地将连续型变量进行了离散化,使之便于建模。下一步是使用分好箱的数据训练模型。

train_data = df.copy()

train_data['Age'] = pd.cut(train_data['Age'], bins=age_bins, right=True, include_lowest=True)

# 选择特征

cols = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare']

X = pd.get_dummies(train_data[cols])

y = train_data['Survived']

# 训练模型

from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier(random_state=0)

model.fit(X, y)

运行上述代码,即可得到训练好的决策树模型。

4. 总结

本文介绍了 python 中基于卡方值分箱算法的实现示例。通过使用卡方值分箱方法,我们将连续型变量进行了离散化,使之便于建模。卡方值分箱算法简单易懂,实现也比较容易,非常适合数据挖掘初学者使用。

后端开发标签