【问题标题】:Using categorical data as features in sklean LogisticRegression在 sklearn 逻辑回归中使用分类数据作为特征
【发布时间】:2026-01-26 14:15:02
【问题描述】:

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

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

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

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

尤其是第一个!

【问题讨论】:

    标签: python scikit-learn regression data-modeling logistic-regression


    【解决方案1】:
    1. 将分类特征转换为数字的标准方法 - OneHotEncoding
    2. 这是完全不同的类:

      [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 用于具有两个以上类的分类变量。