logit 和 sklearn 管道的一种热编码

Posted

技术标签:

【中文标题】logit 和 sklearn 管道的一种热编码【英文标题】:One hot encoding for logit and the sklearn pipeline 【发布时间】:2021-07-12 06:41:19 【问题描述】:

我正在尝试使用 Python 中的 Dalex 包来可视化二进制 logit 模型的某些特征。

我从示例书中复制了一段代码here (整个第五个代码单元)但现在我不太确定应该如何解释结果......

在我使用statsmodels 创建的基本 logit 模型中,我为每个类别手动选择了一个参考级别变量,以避免多重共线性(这意味着模型的所有结果都根据参考水平)。

但是当我使用上面链接中的一段代码(也复制到这篇文章下面)时,它首先在sklearn 中创建了一些管道对象,one-hot 对分类变量进行编码,然后将管道对象拟合到数据并在 Dalex 解释器中用作要解释的模型。

问题是当我在 Dalex 中使用像 model_profile() 这样的函数时,它应该输出一个图表,显示变量对预测的其他条件影响,我不知道如何解释结果,因为似乎一个分类变量中的所有值都包含在图表中。

例如,模型显示了“性别”分类变量对男性和女性的平均预测的影响......

这也显示了一条名为“平均预测”的水平线,但“平均预测”是什么?是以男性为参考水平,还是以女性为标准计算?

我对结果的含义感到非常困惑......有人可以澄清一下吗?我正在尝试使用的函数model_profile() 在笔记本中也有说明。谢谢!

我复制的一段代码:

    numerical_features = ['age', 'fare', 'sibsp', 'parch']
    numerical_transformer = Pipeline(
        steps=[
            ('imputer', SimpleImputer(strategy='median')),
            ('scaler', StandardScaler())
        ]
    )
    
    categorical_features = ['gender', 'class', 'embarked']
    categorical_transformer = Pipeline(
        steps=[
            ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
            ('onehot', OneHotEncoder(handle_unknown='ignore'))
        ]
    )
    
    preprocessor = ColumnTransformer(
        transformers=[
            ('num', numerical_transformer, numerical_features),
            ('cat', categorical_transformer, categorical_features)
        ]
    )
    
    classifier = MLPClassifier(hidden_layer_sizes=(150,100,50), max_iter=500, random_state=0)
    
    clf = Pipeline(steps=[('preprocessor', preprocessor),
                          ('classifier', classifier)])
    clf.fit(X, y)
    exp = dx.Explainer(clf, X, y)

【问题讨论】:

【参考方案1】:

为什么会这样?

这是因为默认情况下,sklearnOneHotEncoder 会对数据中的每个类别进行一次热转换。然而,对于像 logit 这样的线性模型,通常最好将其中一个类别排除在外,以避免多重共线性,并使您的结果可以相对于参考点进行解释。在这种情况下,您需要更改编码器的默认设置。

示例

您可以通过设置drop="first" 来实现这一点,它会删除一个热编码过程的第一个类别。下面的示例说明了这将如何在一个简单的示例中起作用。在这里,“女性”类别从一个热门编码中删除,只有“男性”类别被编码,这将返回您期望的结果。请注意,这也适用于非二进制特征。

from sklearn.preprocessing import OneHotEncoder
X = pd.DataFrame("gender":["male","female","female","male"])
OHE = OneHotEncoder(drop="first")
OHE.fit_transform(X).toarray()
#[[1.],
# [0.],
# [0.],
# [1.]]
OHE.get_feature_names()
#['x0_male']

你需要做什么

因此,您需要在代码中更改的只是管道定义中的以下行:

'onehot', OneHotEncoder(drop='first', handle_unknown='ignore')

【讨论】:

谢谢你,但恐怕我解释得不好。现在我知道如何从变量中省略一个类别,以免将其包含在模型中。但是,对于 Dalex,我试图了解分类变量(其所有级别)如何影响因变量。看看我在原始问题中发布的笔记本/链接。他们使用了性别,并计算了男性和女性对预测的影响。这怎么可能?如果在模型中使用这两个类别进行预测,平均预测值是如何计算的?

以上是关于logit 和 sklearn 管道的一种热编码的主要内容,如果未能解决你的问题,请参考以下文章

大型数据集的一种热编码

如何对变体长度特征进行一种热编码?

字符串分类特征的一种热编码

keras中多标签图像的一种热编码

使用 numpy 的一种热编码 [重复]

一种热编码及其与 DecisionTreeClassifier 的组合