如何在sklearn中编码分类变量?
machine-learning
python
scikit-learn
5
0

我正在尝试使用UCI存储库中的汽车评估数据集,并且想知道是否存在方便的方法来对sklearn中的分类变量进行二值化。一种方法是使用LabelBinarizer的DictVectorizer,但在这里我得到了k个不同的特征,而您应该只有k-1个,以避免共线性。我想我可以编写自己的函数并删除一列,但是这种记账是乏味的,是否有一种简单的方法来执行这种转换并得到一个稀疏矩阵?

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

建议使用DictVectorizer生成分类变量的单编码。您可以使用sparse参数创建一个稀疏的CSR矩阵,而不是一个密集的numpy数组。我通常不关心多重共线性,也没有注意到我倾向于使用的方法(即LinearSVC,SGDClassifier,基于树的方法)存在问题。

修补DictVectorizer以便为每个分类功能删除一列不是问题-您只需在fit方法的结尾从DictVectorizer.vocabulary中删除一个术语DictVectorizer.vocabulary 。 (随时欢迎提出要求!)

收藏
评论

基本方法是

import numpy as np
import pandas as pd, os
from sklearn.feature_extraction import DictVectorizer

def one_hot_dataframe(data, cols, replace=False):
    vec = DictVectorizer()
    mkdict = lambda row: dict((col, row[col]) for col in cols)
    vecData = pd.DataFrame(vec.fit_transform(data[cols].apply(mkdict, axis=1)).toarray())
    vecData.columns = vec.get_feature_names()
    vecData.index = data.index
    if replace is True:
        data = data.drop(cols, axis=1)
        data = data.join(vecData)
    return (data, vecData, vec)

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

df = pd.DataFrame(data)

df2, _, _ = one_hot_dataframe(df, ['state'], replace=True)
print df2

这是稀疏格式的操作方法

import numpy as np
import pandas as pd, os
import scipy.sparse as sps
import itertools

def one_hot_column(df, cols, vocabs):
    mats = []; df2 = df.drop(cols,axis=1)
    mats.append(sps.lil_matrix(np.array(df2)))
    for i,col in enumerate(cols):
        mat = sps.lil_matrix((len(df), len(vocabs[i])))
        for j,val in enumerate(np.array(df[col])):
            mat[j,vocabs[i][val]] = 1.
        mats.append(mat)

    res = sps.hstack(mats)   
    return res

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': ['2000', '2001', '2002', '2001', '2002'],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

df = pd.DataFrame(data)
print df

vocabs = []
vals = ['Ohio','Nevada']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))
vals = ['2000','2001','2002']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))

print vocabs

print one_hot_column(df, ['state','year'], vocabs).todense()
收藏
评论

如果您的数据是熊猫DataFrame,则只需调用get_dummies。假设您的数据帧为df,并且您希望每个级别的变量“键”都有一个二进制变量。您可以简单地致电:

pd.get_dummies(df['key'])

然后删除其中一个虚拟变量,以避免多重共线性问题。我希望这有帮助 ...

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号