【问题标题】:Generate one hot encodings from dict values从 dict 值生成一种热编码
【发布时间】:2019-02-18 18:30:40
【问题描述】:

我试图根据我的字典字符创建一个热门数组:首先,我创建了一个具有行 X 列 (3x7) 的 numpy zeros,然后我搜索每个字符的 id 并为每个字符分配“1” numpy 数组的行。

我的目标是为每个字符分配一个热数组。 “1”表示“存在”,“0”表示“不存在”。这里我们有 3 个字符,所以我们应该有 3 行,而 7 列作为字典中存在的字符。

但是,我收到一条错误消息,指出“TypeError:只有整数标量数组可以转换为标量索引”。有人可以帮我吗?谢谢

为了不让大家误会我的字典:

这是我创建 dic 的方法:

sent = ["a", "b", "c", "d", "e", "f", "g"]
aaa = len(sent)
aa = {x:i for i,x in enumerate(sent)}

我的代码:

import numpy as np
sentences = ["b", "c", "e"]
a = {}
for xx in sentences:
   a[xx] = aa[xx]
a = {"b":1, "c":2, "e":4}
aa =len(a)

for x,y in a.items():
    aa = np.zeros((aa,aaa))
    aa[y] = 1

print(aa)

当前错误:

TypeError: only integer scalar arrays can be converted to a scalar index

我的预期输出:

[[0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0.]]

-------> 因为它的字典所以索引排列应该不同,并且数组中的“1”是一个虚拟的,所以我可以显示我的预期输出。

【问题讨论】:

  • 如果是a = {"a":0, "b":1, "c":5}呢?
  • 我很抱歉造成误解,但由于我创建了基于 sent = ["a", "b", "c", "d", "e"] aa = {x: i for i,x in enumerate(sent)}................它不会变成上面提到的那样。由于您有 3 个字符,因此根据我的代码,它将是 {"a":0, "b":1, "c":2}。
  • 好的,那[a, b, a, d, c]会给我什么?
  • 我假设你的 [a,b,a,d,c] 也是一个字符列表?那么就会变成这样,对吧?b = ["a", "b", "a", "d", "c"] for x in b: print(a[x])...... ......输出[0,1,0,3,2]??但我不明白为什么我们需要找到这些?由于我还是初学者,请告诉我
  • 只是想了解如何生成一个热矩阵的原因。它是基于字典顺序吗?或者它是否与它出现的顺序有关......等等。

标签: python arrays numpy one-hot-encoding


【解决方案1】:

设置索引

(内嵌评论。)

# Sort and extract the indices.
idx = sorted(a.values())
# Initialise a matrix of zeros.
aa = np.zeros((len(idx), max(idx) + 1))
# Assign 1 to appropriate indices.
aa[np.arange(len(aa)), idx] = 1

print (aa)
array([[0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 1.]])

numpy.eye

idx = sorted(a.values())
eye = np.eye(max(idx) + 1)    
aa = eye[idx]

print (aa)
array([[0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 1.]])

【讨论】:

  • 谢谢你,我刚刚做了另一个解决方案。在这里分享给未来的读者。将 numpy 导入为 np a = {"a":0, "b":1, "c":2, "d":3, "e":4} aa =len(a) i = 0 yy = []对于 a.items() 中的 x,y:yy.append(y) yy = np.asarray(yy) b = np.zeros((aa,aa)) b[np.arange(aa),yy] = 1 print(b) 非常感谢!
  • 我敢打赌,你可以在这里使用dok_matrix,效果会很好。
  • @JJson 请发表您的评论作为答案
  • @Scott 谢谢。我只是根据措辞和示例回答了这个问题。我花了很长时间试图让 OP 澄清他们想要什么,正如您可以从问题下的 cmets 中看到的那样。如果您对标题有更好的想法,我邀请您编辑问题,以便我们都能受益。
  • @Scott。如果可能,请编辑我的问题。我仍然无法以一种可以理解的方式解释它。谢谢你,我也会把它作为答案发布。
【解决方案2】:

one hot 编码将样本视为一个序列,其中序列的每个元素都是词汇表的索引,指示该元素(如单词或字母)是否在样本中。例如,如果您的词汇表是小写字母,则工作猫的 one-hot 编码可能如下所示:

 [1, 0., 1, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0., 0., 1, 0., 0., 0., 0., 0., 0.]

表示该单词包含cat 等字母。

要进行 one-hot 编码,您需要两件事:查找具有所有可能值的词汇表(使用单词时,这就是为什么矩阵会变得如此之大,因为词汇量很大!)。但是如果对小写字母进行编码,则只需要 26 个。

然后,您通常将样本表示为词汇表中的索引。所以这组词可能看起来像这样:

#bag, cab, fad
sentences = np.array([[1, 0, 6], [2, 0, 1], [5, 0, 3]])

当你 one-hot 编码时,你会得到一个 3 x 26 的矩阵:

vocab = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

#bag, cab, fad
sentences = np.array([[1, 0, 6], [2, 0, 1], [5, 0, 3]])

def onHot(sequences, dimension=len(vocab)):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
      results[i, sequence] = 1
    return results

onHot(sentences)

这会导致你的 one-hot 编码样本具有 26 个字母的词汇表,准备好输入神经网络:

array([[1., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
   [1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
   [1., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

【讨论】:

  • 你说得对!我已经发布了我的答案,但我忘记了我必须将索引更改为 numpy 数组才能将其加载到 numpy 数组中。非常感谢您指出问题,请检查我的回答,让我知道我这次的理解是否正确。
【解决方案3】:

我的解决方案和未来的读者:

我为“已发送”列表构建字典:

sent = ["a", "b", "c", "d", "e", "f", "g"]
aaa = len(sent)
aa = {x:i for i,x in enumerate(sent)}

然后我根据字典找到我自己句子的索引,并为这些句子分配数值。

import numpy as np
sentences = ["b", "c", "e"]
a = {}
for xx in sentences:
   a[xx] = aa[xx]
a = {"b":1, "c":2, "e":4}
aa =len(a)

我从“a”的新赋值中提取索引:

index = []
for x,y in a.items():
    index.append(y)

然后我为这些从 a 中提取的索引创建另一个 numpy 数组。

index = np.asarray(index)

现在我创建 numpy zeros 来存储每个字符的存在:

new = np.zeros((aa,aaa))
new[np.arange(aa), index] = 1

打印(新)

输出:

[[0. 1. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0.]]

【讨论】:

    【解决方案4】:

    这是另一个使用 sklearn.preprocessing 的方法

    线条很长,差别不大。我不知道为什么,但产生了类似的结果。

    import numpy as np
    from sklearn.preprocessing import OneHotEncoder
    sent = ["a", "b", "c", "d", "e", "f", "g"]
    aaa = len(sent)
    aa = {x:i for i,x in enumerate(sent)}
    
    
    sentences = ["b", "c", "e"]
    a = {}
    for xx in sentences:
       a[xx] = aa[xx]
    a = {"a":0, "b":1, "c":2, "d":3, "e":4, "f":5, "g":6}
    aa =len(a)
    
    index = []
    for x,y in a.items():
        index.append([y])
    
    index = np.asarray(index)
    
    enc = OneHotEncoder()
    enc.fit(index)
    
    print(enc.transform([[1], [2], [4]]).toarray())
    

    输出

    [[0. 1. 0. 0. 0. 0. 0.]
     [0. 0. 1. 0. 0. 0. 0.]
     [0. 0. 0. 0. 1. 0. 0.]]
    

    【讨论】:

      【解决方案5】:

      我喜欢将LabelEncoder 与来自sklearnOneHotEncoder 一起使用。

      import sklearn.preprocessing
      import numpy as np
      
      texty_data = np.array(["a", "c", "b"])
      le = sklearn.preprocessing.LabelEncoder().fit(texty_data)
      integery_data = le.transform(texty_data)
      ohe = sklearn.preprocessing.OneHotEncoder().fit(integery_data.reshape((-1,1)))
      onehot_data = ohe.transform(integery_data.reshape((-1,1)))
      

      存储它稀疏,所以很方便。您还可以使用LabelBinarizer 来简化此操作:

      import sklearn.preprocessing
      import numpy as np
      
      texty_data = np.array(["a", "c", "b"])
      lb = sklearn.preprocessing.LabelBinarizer().fit(texty_data)
      onehot_data = lb.transform(texty_data)
      print(onehot_data, lb.inverse_transform(onehot_data))
      

      【讨论】:

      • 好的,谢谢,我收到了这个错误:“ValueError: Expected 2D array, got 1D array instead: array=[0. 2. 1.]. reshape your data or using array.reshape(-1 , 1) 如果您的数据具有单个特征或 array.reshape(1, -1) 如果它包含单个样本。"
      • 根据您的建议,我尝试使用 sklearn 来实现。我重新发布另一个解决方案。请检查并就如何将转换包含在字符串中给我建议。谢谢
      猜你喜欢
      • 2020-05-01
      • 2016-03-19
      • 2019-08-26
      • 2016-03-19
      • 1970-01-01
      • 2018-10-25
      • 2019-02-06
      • 1970-01-01
      • 2015-12-31
      相关资源
      最近更新 更多