我有一个类似如下的列表:
list = ['Opinion, Journal, Editorial',
'Opinion, Magazine, Evidence-based',
'Evidence-based']其中逗号在类别之间拆分,例如。观点和期刊是两个不同的类别。真正的列表要大得多,并且有更多可能的类别。我想使用one-hot编码来转换列表,这样它就可以用于机器学习。例如,我想从该列表中生成一个包含以下数据的稀疏矩阵:
list = [[1, 1, 1, 0, 0],
[1, 0, 0, 0, 1],
[0, 0, 0, 0, 1]]理想情况下,我希望使用scikit-learn's one hot encoder,因为我认为这将是最有效的。
在回应@nbrayns评论时:
其思想是将类别列表从文本转换为向量,如果它属于该类别,将被分配1,否则为0。对于上面的示例,标题将是:
headings = ['Opinion', 'Journal', 'Editorial', 'Magazine', 'Evidence-based']发布于 2017-02-04 08:00:18
如果您能够使用Pandas,则此功能本质上是内置的:
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']。
发布于 2017-02-04 07:29:47
另一种方法:
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]])发布于 2017-02-04 07:14:44
这可能不是最有效的方法,但可能很容易掌握。
如果您还没有所有可能单词的列表,则需要创建该列表。在下面的代码中,它被称为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.]]https://stackoverflow.com/questions/42034338
复制相似问题