在字典上使用标签编码器

时间:2016-08-08 22:04:39

标签: python dictionary scikit-learn text-classification multilabel-classification

我正在使用sklearn LabelEncoder。我知道如何将它用于一维数组,但我的用例是这样的:

我有多个这样的dicts数组(这实际上是我在分类器中分配每个文本标签u'a'u'b'等的成本),所有都在dict中:

{'open_model':    
[
    {u'a': 47502.125, u'c': 45.3, u'd': 2.3, u'e': 0.45},
    {u'b': 121, u'a': 1580.5625, u'c': 12, u'e': 62,u'd':0.343},
    {u'e': 12321, u'b': 4, u'a': 0.1112}
    ],
 'closed_model':
 [
    {u'a': 1231.22, u'c': 43.1},
    {u'b': 342.2, u'a': 121.1, u'c': 343},
    {u'b': 14.2, u'a': 53.2}
    ]
}

我需要能够将其编码为数字标签,然后将其全部解码回来,例如:

[
    {1: 47502.125, 3: 45.3, 4: 2.3, 5: 0.45},
    {2: 121, 1: 1580.5625, 3: 12, 5: 62, 4: 0.343},
    {5: 12321, 2: 4, 1: 0.1112}
    ]

我有效地使用它来生成每行最佳标签的预测,所以:

[5, 4, 1] perhaps in this case.

我需要做的是能够将其解码回:

[u'e',u'd', u'a'] perhaps in this case.

如何在dict键是我的标签的一系列dicts上获得相同的LabelEncoder功能,但fit_transform

注意,dicts数组中的dict是不同的长度,但我确实有所有潜在标签的列表,即open_model标签,set([u'a',u'b',u'c',u'd',u'e'])和closed_model标签:set([u'a',u'b',u'c'])

2 个答案:

答案 0 :(得分:1)

似乎你总是有'a','b','c','d','e'。如果是这种情况,为什么不使用pandas数据帧而忘记编码器呢?你需要重写你使用的词典的键,所以无论如何它都会变得混乱!

import pandas as pd
i = [
{u'a': 47502.125, u'b': 1580.5625, u'c': 45.3, u'd': 2.3, u'e': 0.45},
{u'b': 121, u'a': 1580.5625, u'c': 12, u'e': 62, u'd': 0.343},
{u'e': 12321, u'b': 4, u'd': 5434, u'c': 2.3, u'a': 0.1112}
]
# transform to data frame
df = pd.DataFrame(i)
print df
            a          b     c         d         e
0  47502.1250  1580.5625  45.3     2.300      0.45
1   1580.5625   121.0000  12.0     0.343     62.00
2      0.1112     4.0000   2.3  5434.000  12321.00

# create a mapping between columns and encoders
mapping = dict((k, v) for k, v in enumerate(df.columns))

# rename columns
df.columns = range(len(df.columns))

# print your new input data
print df.to_dict(orient='records)
[{0: 47502.125, 1: 1580.5625, 2: 45.3, 3: 2.3, 4: 0.45},
 {0: 1580.5625, 1: 121.0, 2: 12.0, 3: 0.343, 4: 62.0},
 {0: 0.1112, 1: 4.0, 2: 2.3, 3: 5434.0, 4: 12321.0}]

# translate prediction
prediction = [3, 4, 1]
print [mapping[k] for k in prediction]
[u'd', u'e', u'b']

这不是直截了当的,但我想它比使用编码器花费的时间更少:)

答案 1 :(得分:1)

尽管使用已经实现的功能是一种很好的做法,但您可以使用几行代码轻松实现此功能。鉴于您的列表输入:

dico = [
{u'a': 47502.125, u'b': 1580.5625, u'c': 45.3, u'd': 2.3, u'e': 0.45},
{u'b': 121, u'a': 1580.5625, u'c': 12, u'e': 62, u'd': 0.343},
{u'e': 12321, u'b': 4, u'd': 5434, u'c': 2.3, u'a': 0.1112}
]

您可以通过以下方式获取标签集:

keyset = set(dico[0].keys()) #Get the set of keys assuming they all appear in each list item. 
mapping = { val:key+1 for key,val in enumerate(list(keyset))} # Create a mapping from int -> str
inv_mapping = { key+1:val for key,val in enumerate(list(keyset))} # Create a mapping from str:int. 

拥有mappinginv_mapping,您可以通过以下方式更改数据的表示形式:

for inner_dict in dico:
    for key in inner_dict.keys():
        inner_dict[mapping[key]] = inner_dict.pop(key)
print dico

将为您提供[{1: 47502.125, ...}],然后根据需要提供:

for inner_dict in dico:
    for key in inner_dict.keys():
        inner_dict[inv_mapping[key]] = inner_dict.pop(key)
print dico

获取初始版本。

此外,也许与您的问题更密切相关,输出[5, 4, 1]您可以轻松地将其转换为:

print [inv_mapping[i] for i in x]