在 sklearn 逻辑回归中使用分类数据作为特征

Posted

技术标签:

【中文标题】在 sklearn 逻辑回归中使用分类数据作为特征【英文标题】:Using categorical data as features in sklean LogisticRegression 【发布时间】:2016-03-02 19:18:37 【问题描述】:

我正在尝试了解如何将分类数据用作sklearn.linear_modelLogisticRegression 中的特征。

我明白我当然需要对其进行编码。

    我不明白的是如何将编码的特征传递给 Logistic 回归,以便将其作为分类特征处理,而不是解释它在编码为标准可量化特征时得到的 int 值。

    (不太重要)有人可以解释使用preprocessing.LabelEncoder()DictVectorizer.vocabulary 还是仅使用简单的字典自己对分类数据进行编码之间的区别? Alex A.'s comment here 涉及主题但不是很深入。

尤其是第一个!

【问题讨论】:

【参考方案1】:
    将分类特征转换为数字的标准方法 - OneHotEncoding

    这是完全不同的类:

    [DictVectorizer][2].vocabulary_

    将特征名称映射到特征索引的字典。

    i.e After fit() DictVectorizer 具有所有可能的特征名称,现在它知道它将在哪个特定列中放置特征的特定值。所以DictVectorizer.vocabulary_ 包含特征的indicies,但不包含值。

    LabelEncoder 将每个可能的标签(标签可以是字符串或整数)映射到某个整数值,并返回这些整数值的一维向量。

【讨论】:

感谢回复。转换本身问题不大(我认为),我主要关心的是逻辑reg会将数值视为标准数值,所以如果Cat被编码作为 1 和 Dog 作为 2,它将假设具有“Dog”的观察具有“更多”该属性,而我们知道分配的值是无意义的。 @Optimesh,“编码”是什么意思?如果您在谈论目标变量 - 目标 [1,2,3] 没有任何问题,LogisticRegression 将简单地构建 3 个(在这种特殊情况下)分类器并将它们组合在 OneVsRest 方案中。如果您在谈论特征 - OneHotEncoder 将以二进制格式对每个分类特征进行编码,即它将创建新的二进制特征而不是分类特征的每个可能值,即生成的数据集将具有值 Dog=1 的单独的二进制特征(列), Dog=2、Dog=3、Cat=1等。看官方文档中的例子。【参考方案2】:

您可以为不同的类别创建指标变量。例如:

animal_names = 'mouse';'cat';'dog'

Indicator_cat = strcmp(animal_names,'cat')
Indicator_dog = strcmp(animal_names,'dog')

那么我们有:

                [0                         [0
Indicator_cat =  1        Indicator_dog =   0
                 0]                         1]

您可以将这些连接到您的原始数据矩阵中:

X_with_indicator_vars = [X, Indicator_cat, Indicator_dog]

请记住,如果数据矩阵中包含常数项,则保留一个没有指示符的类别!否则,您的数据矩阵将不会是全列排名(或在计量经济学术语中,您有多重共线性)。

[1  1  0  0         
 1  0  1  0         
 1  0  0  1]        

注意常数项、鼠标指示符、猫指示符和狗指示符如何导致小于满列的秩矩阵:第一列是最后三列的总和。

【讨论】:

感谢您的回复。想到了这一点,但我想到的特征有 40 多个分类值(猫、狗、大象、狮子……)。必须有更好的方法。 我不确定你想要什么?您可以将它们分成更大的类别吗?或者将类别映射到某个n 维向量空间? (例如,将动物名称映射到二维向量空间(高度、重量))。但是,如果您想将每个类别视为自己独特的类别,这就是您(通常用于回归)必须做的事情。如果您假设效果可以因类别而异,那么您的类别中的所有交互项也必须与其他回归量相同。也许sklearn会在幕后为你做这件事(我不知道),但这可能就是会发生的事情。 @Optimesh,没有更好的方法,但你可以通过 FeatureHashing 或更复杂的技术如 PCA 等来降低维度。此外,这篇文章提出了相同的 One Hot Encoding 技术。【参考方案3】:

假设每个分类变量的类型是“对象”。首先,您可以创建一个分类列名称的panda.index

import pandas as pd    
catColumns = df.select_dtypes(['object']).columns

然后,您可以使用下面的 for 循环创建指标变量。对于二元分类变量,使用LabelEncoder() 将其转换为01。对于超过两个类别的分类变量,使用pd.getDummies()获取指标变量,然后删除一个类别(避免多重共线性问题)。

from sklearn import preprocessing
le = preprocessing.LabelEncoder()

for col in catColumns:
    n = len(df[col].unique())
    if (n > 2):
       X = pd.get_dummies(df[col])
       X = X.drop(X.columns[0], axis=1)
       df[X.columns] = X
       df.drop(col, axis=1, inplace=True)  # drop the original categorical variable (optional)
    else:
       le.fit(df[col])
       df[col] = le.transform(df[col])

【讨论】:

在最近的 sklearn 版本中,您现在可以将 le.fit 用于具有两个以上类的分类变量。

以上是关于在 sklearn 逻辑回归中使用分类数据作为特征的主要内容,如果未能解决你的问题,请参考以下文章

sklearn 逻辑回归中的特征选择

Python SKLearn 逻辑回归中的虚拟变量

使用 sklearn - python 具有分类特征的多元线性回归

解释 sklearn 中的逻辑回归特征系数值

sklearn机器学习——逻辑回归

在sklearn python中处理逻辑回归分类器中的极端不平衡多类