在 sklearn 逻辑回归中使用分类数据作为特征
Posted
技术标签:
【中文标题】在 sklearn 逻辑回归中使用分类数据作为特征【英文标题】:Using categorical data as features in sklean LogisticRegression 【发布时间】:2016-03-02 19:18:37 【问题描述】:我正在尝试了解如何将分类数据用作sklearn.linear_model
的LogisticRegression
中的特征。
我明白我当然需要对其进行编码。
我不明白的是如何将编码的特征传递给 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()
将其转换为0
和1
。对于超过两个类别的分类变量,使用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 逻辑回归中使用分类数据作为特征的主要内容,如果未能解决你的问题,请参考以下文章