Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在sklearn中对分类变量进行编码?_Python_Machine Learning_Scikit Learn - Fatal编程技术网

Python 如何在sklearn中对分类变量进行编码?

Python 如何在sklearn中对分类变量进行编码?,python,machine-learning,scikit-learn,Python,Machine Learning,Scikit Learn,我正在尝试使用UCI存储库中的car评估数据集,我想知道是否有一种方便的方法来对sklearn中的分类变量进行二值化。一种方法是使用LabelBinarizer的DictVectorizer,但这里我得到了k个不同的特性,而为了避免共线,您应该只有k-1。 我想我可以编写自己的函数并删除一列,但这种簿记工作很乏味,有没有一种简单的方法来执行这种转换并得到一个稀疏矩阵 建议使用DictVectorizer生成分类变量的一次热编码;可以使用sparse参数创建稀疏CSR矩阵,而不是密集numpy数组

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

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

修补DictVectorizer以删除每个分类功能的一列应该不会有问题-您只需在
fit
方法末尾从DictVectorizer.词汇表中删除一个术语即可。(拉取请求总是受欢迎的!)

基本方法是

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()

如果您的数据是熊猫数据帧,那么您可以简单地调用get_dummies。 假设您的数据帧是df,并且您希望每个级别的变量“key”有一个二进制变量。您只需拨打:

pd.get_dummies(df['key'])
然后删除其中一个虚拟变量,以避免多重共线性问题。
我希望这能有所帮助……

您喜欢k-1功能而不是k-1功能,有什么特别的原因吗?拥有k个特征使系数的解释(比如线性模型)更容易,并且可能会促进稀疏特征。我试图找到系数的相关性,但遇到了共线问题。我想我对统计方面的知识还不够了解,不知道为什么这会是个问题。我认为k功能编码在功能相关性方面比任何其他编码方法都能提供更有意义的结果。在不可识别的模型中使用k功能会产生更大的结果。您推荐DictVectorizer而不是OneHotEncoder类的原因是什么?DictVectorizer更通用-OneHotEncoder输入仅限于列表示类别的整数的集合。dictvectorier还处理文本分类值。另一方面,如果一开始只有整数类别,OneHotEncoder似乎是最简单的选择。但为了使用DictVectorizer,我需要将数组转换为字典列表,列表中的每个字典对应于数组中的一行。这看起来像是一个黑客。为什么我不能直接将一个数组传递给DictVectorizer?就个人而言,我更喜欢熊猫的get_假人,而不是sklearn的OneHotEncoder或DictVectorizer。在Pandas中使用get_假人通常会导致更精简的过程和更少的代码。就我而言,Pandas更多的是数据分析和预处理,而sklearn更多的是繁重的“学习”过程。获取_假人的缺点是,它不一定会在评分数据集上生成相同的虚拟列(在尝试评分模型时会给您带来大量的复杂性)实现这一点的一种方法是首先连接训练和测试数据帧,然后应用get_假人,最后分离训练和测试数据帧。通过这种方式,训练和测试数据将具有一致的热编码。当模型在生产中,而我们还没有看到测试数据集时会发生什么?如何使用这种方法处理新数据中看不见的值?