SelectByInformationValue#

SelectByInformationValue() 根据特征的信息值分数是否大于用户传递的阈值来选择特征。

IV 的计算公式为:

\[IV = ∑ (正样本比例 - 负样本比例) * WoE\]

哪里:

  • 正例的比例是类别1的观测值在所有类别1观测值中的比例。

  • 负样本的比例是类别0的观测值占类别0总观测值的比例。

  • WoE 是证据的权重。

WoE 的计算公式为:

\[WoE = ln(阳性案例比例 / 阴性案例比例)\]

信息价值 (IV) 用于评估一个特征对二分类因变量的预测能力。要得出特征的 IV,必须首先为构成该特征的每个唯一类别或分箱计算证据权重 (WoE)。如果一个类别或分箱包含的正标签比例远高于负标签比例,那么该类别或分箱将具有较高的 WoE 值。

一旦 WoE 被导出,SelectByInformationValue() 计算每个变量的 IV。一个变量的 IV 本质上是该变量内每个类别或分箱的单个 WoE 值的加权和,其中权重包含了分子和分母之间的绝对差异。这个值评估了特征在捕捉二元因变量时的预测能力。

下表展示了一个使用工具变量(IV)来确定变量预测能力的一般框架:

信息价值

预测能力

< 0.02

无用的

0.02 到 0.1

0.1 到 0.3

中等

0.3 到 0.5

> 0.5

可疑的,好得令人难以置信

表格取自 listendata

示例#

让我们看看如何使用这个转换器从UC Irvine的信用审批数据集中选择变量,该数据集可以在 这里 找到。这个数据集涉及信用卡申请。所有属性名称和值都已更改为无意义的符号以保护机密性。

数据由数值数据和分类数据组成。

让我们导入所需的库和类:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from feature_engine.selection import SelectByInformationValue

现在让我们加载并准备信用审批数据:

# load data
data = pd.read_csv('crx.data', header=None)

# name variables
var_names = ['A' + str(s) for s in range(1,17)]
data.columns = var_names
data.rename(columns={'A16': 'target'}, inplace=True)

# preprocess data
data = data.replace('?', np.nan)
data['A2'] = data['A2'].astype('float')
data['A14'] = data['A14'].astype('float')
data['target'] = data['target'].map({'+':1, '-':0})

# drop rows with missing data
data.dropna(axis=0, inplace=True)

data.head()

现在让我们查看数据集的前5行:

  A1     A2     A3 A4 A5 A6 A7    A8 A9 A10  A11 A12 A13    A14  A15  target
0  b  30.83  0.000  u  g  w  v  1.25  t   t    1   f   g  202.0    0       1
1  a  58.67  4.460  u  g  q  h  3.04  t   t    6   f   g   43.0  560       1
2  a  24.50  0.500  u  g  q  h  1.50  t   f    0   f   g  280.0  824       1
3  b  27.83  1.540  u  g  w  v  3.75  t   t    5   t   g  100.0    3       1
4  b  20.17  5.625  u  g  w  v  1.71  t   f    0   f   s  120.0    0       1

现在让我们将数据分为训练集和测试集:

# separate train and test sets
X_train, X_test, y_train, y_test = train_test_split(
    data.drop(['target'], axis=1),
    data['target'],
    test_size=0.2,
    random_state=0)

X_train.shape, X_test.shape

我们看到了以下数据集的大小。

((522, 15), (131, 15))

现在,我们设置 SelectByInformationValue()。我们将传递六个分类变量给参数 variables。我们将参数 threshold 设置为 0.2。从上述提到的表格中我们可以看到,IV 分数为 0.2 表示中等预测能力。

sel = SelectByInformationValue(
    variables=['A1', 'A6', 'A9', 'A10', 'A12', 'A13'],
    threshold=0.2,
)

sel.fit(X_train, y_train)

使用 fit() 方法,转换器:

  • 计算每个变量的 WoE

  • 计算每个变量的IV值

  • 识别IV分数低于阈值的变量

在属性 variables_ 中,我们找到被评估的变量:

['A1', 'A6', 'A7', 'A9', 'A10', 'A12', 'A13']

在属性 features_to_drop_ 中,我们找到未被选择的变量:

sel.features_to_drop_

['A1', 'A12', 'A13']

属性 information_values_ 显示了每个变量的 IV 分数。

{'A1': 0.0009535686492270659,
 'A6': 0.6006252129425703,
 'A9': 2.9184484098456807,
 'A10': 0.8606638171665587,
 'A12': 0.012251943759377052,
 'A13': 0.04383964979386022}

我们看到,转换器正确地选择了IV分数大于 阈值 的特征,该阈值设置为0.2。

转换器也有 get_support 方法,其功能与 Scikit-learn 的选择器方法类似。如果你执行 sel.get_support(),你将得到:

[False, True, True, True, True, True, True,
 True, True, True, True, False, False, True,
 True]

使用 transform(),我们可以继续删除不满足阈值的特征:

Xtr = sel.transform(X_test)

Xtr.head()
        A2     A3 A4 A5  A6 A7      A8 A9 A10  A11    A14  A15
564  42.17   5.04  u  g   q  h  12.750  t   f    0   92.0    0
519  39.17   1.71  u  g   x  v   0.125  t   t    5  480.0    0
14   45.83  10.50  u  g   q  v   5.000  t   t    7    0.0    0
257  20.00   0.00  u  g   d  v   0.500  f   f    0  144.0    0
88   34.00   4.50  u  g  aa  v   1.000  t   f    0  240.0    0

请注意,Xtr 包含了所有数值特征 - 即 A2, A3, A8, A11 和 A14 - 因为我们只评估了少数几个分类特征。

最后,我们还可以获取最终转换后的数据集中特征的名称:

sel.get_feature_names_out()

['A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A14', 'A15']

如果我们想从分类变量和数值变量中进行选择,我们也可以通过先将数值变量排序到箱子中来实现。让我们将它们排序到5个等频箱中:

sel = SelectByInformationValue(
    bins=5,
    strategy="equal_frequency",
    threshold=0.2,
)

sel.fit(X_train.drop(["A4", "A5", "A7"], axis=1), y_train)

如果我们现在检查信息值:

sel.information_values_

我们看到以下内容:

{'A1': 0.0009535686492270659,
 'A2': 0.10319123021570434,
 'A3': 0.2596258749173557,
 'A6': 0.6006252129425703,
 'A8': 0.7291628533346297,
 'A9': 2.9184484098456807,
 'A10': 0.8606638171665587,
 'A11': 1.0634602064399297,
 'A12': 0.012251943759377052,
 'A13': 0.04383964979386022,
 'A14': 0.3316668794040285,
 'A15': 0.6228678069374612}

如果我们检查要删除的功能:

sel.features_to_drop_

我们看到以下内容:

['A1', 'A2', 'A12', 'A13']

注意#

WoE 由一个分数的对数给出。因此,如果对于任何类别或区间,类别 0 的观测值比例为 0,则 WoE 未定义,转换器将引发错误。

如果你遇到这个问题,尝试将数值变量分组到更少的区间,或者如果是分类变量,使用 RareLabelEncoder 将稀有类别分组。

其他资源#

有关此方法和其他特征选择方法的更多详细信息,请查看以下资源:

../../_images/fsml.png

机器学习的特征选择#











或者阅读我们的书:

../../_images/fsmlbook.png

机器学习中的特征选择#















我们的书籍和课程都适合初学者和更高级的数据科学家。通过购买它们,您正在支持 Feature-engine 的主要开发者 Sole。