1

我有这样一个类似的列表:类别中的一个热编码

list = ['Opinion, Journal, Editorial', 
     'Opinion, Magazine, Evidence-based', 
     'Evidence-based'] 

其中逗号类别例如之间分割。意见和期刊是两个不同的类别。真正的名单要大得多,并且有更多可能的类别。我想使用单热编码来转换列表,以便它可以用于机器学习。例如,从该列表中我想以产生含有像数据的稀疏矩阵:

list = [[1, 1, 1, 0, 0], 
     [1, 0, 0, 0, 1], 
     [0, 0, 0, 0, 1]] 

理想情况下,我想用scikit-learn's one hot encoder作为我相信这将是最有效的。

响应于@nbrayns评论:

的想法是从文本转换类别的列表给矢量wherby如果它属于该类别将被分配1,否则为0。对于上面的例子,该标题将是:

headings = ['Opinion', 'Journal', 'Editorial', 'Magazine', 'Evidence-based'] 
+0

什么值应该是1,什么应该是0? – nbryans

+0

@nbryans编辑了这个问题。 – user7347576

回答

0

这可能不是最有效的方法,但可能很容易掌握。
如果您还没有所有可能的单词列表,则需要创建该列表。在下面的代码中,它被称为unique。输出矩阵s的列将对应于那些唯一字;这些行将成为列表中的项目。

import numpy as np 

lis = ['Opinion, Journal, Editorial','Opinion, Magazine, Evidence-based','Evidence-based'] 

unique=list(set(", ".join(lis).split(", "))) 
print unique 
# prints ['Opinion', 'Journal', 'Magazine', 'Editorial', 'Evidence-based'] 

s = np.zeros((len(lis), len(unique))) 
for i, item in enumerate(lis): 
    for j, notion in enumerate(unique): 
     if notion in item: 
      s[i,j] = 1 

print s 
# prints [[ 1. 1. 0. 1. 0.] 
#   [ 1. 0. 1. 0. 1.] 
#   [ 0. 0. 0. 0. 1.]] 
-1
pandas

非常简单:

import pandas as pd 
s = pd.Series(['a','b','c']) 
pd.get_dummies(s) 

输出:

a b c 
0 1 0 0 
1 0 1 0 
2 0 0 1 
0

另一种方式:

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 

# Get list of unique classes 
classes = list(set([j for i in l for j in i.split(', ')])) 
=> ['Journal', 'Opinion', 'Editorial', 'Evidence-based', 'Magazine'] 

# Get indices in the matrix 
indices = np.array([[k, classes.index(j)] for k, i in enumerate(l) for j in i.split(', ')]) 
=> array([[0, 1], 
      [0, 0], 
      [0, 2], 
      [1, 1], 
      [1, 4], 
      [1, 3], 
      [2, 3]]) 

# Generate output 
output = np.zeros((len(l), len(classes)), dtype=int) 
output[indices[:, 0], indices[:, 1]]=1 
=> array([[ 1, 1, 1, 0, 0], 
      [ 0, 1, 0, 1, 1], 
      [ 0, 0, 0, 1, 0]]) 
3

如果你能够使用熊猫,这个功能是基本上内置在那里:

import pandas as pd 

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 
pd.Series(l).str.get_dummies(', ') 
Editorial Evidence-based Journal Magazine Opinion 
0   1    0  1   0  1 
1   0    1  0   1  1 
2   0    1  0   0  0 

如果你想坚持与sklearn生态系统,您正在寻找MultiLabelBinarizer,而不是OneHotEncoder。顾名思义,OneHotEncoder仅支持每个类别的每个样本一个级别,而您的数据集则有多个。

from sklearn.preprocessing import MultiLabelBinarizer 

mlb = MultiLabelBinarizer() # pass sparse_output=True if you'd like 
mlb.fit_transform(s.split(', ') for s in l) 
[[1 0 1 0 1] 
[0 1 0 1 1] 
[0 1 0 0 0]] 

要列映射回分类级别,您可以访问mlb.classes_。对于上面的例子,这给出['Editorial' 'Evidence-based' 'Journal' 'Magazine' 'Opinion']

+0

无论类别的顺序如何,这项工作是否会进行? – user7347576

+1

@ user7347576是的,如果您问“意见,日记”或“日记,意见”是否有所作为,那么它不会。 –