从字典值生成一个热编码
Generate one hot encodings from dict values
我试图根据我的字典字符制作一个单热数组:首先,我创建了一个具有 X 行列 (3x7) 的 numpy zeros,然后我搜索每个字符的 ID 并分配“1”到 numpy 数组的每一行。
我的目标是为每个角色分配一个热数组。 “1”表示 "present",“0”表示 "not present"。这里我们有 3 个字符,所以我们应该有 3 行,而 7 列作为字典中存在的字符。
但是,我收到一条错误消息,指出 "TypeError: only integer scalar arrays can be converted to a scalar index"。谁能帮我解决这个问题?谢谢
为了不让大家误解我的字典:
这是我创建 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”是虚拟的,这样我就可以显示我的预期输出。
设置索引
(内联评论。)
# 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.]])
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.]
表示该单词包含字母c
、a
、t
.
要进行一次性编码,您需要两件事,即查找具有所有可能值的词汇表(当使用单词时,这就是为什么矩阵会变得如此之大的原因,因为词汇表很大!)。但是如果编码小写字母你只需要26个。
然后您通常将样本表示为词汇表中的索引。所以这组词可能是这样的:
#bag, cab, fad
sentences = np.array([[1, 0, 6], [2, 0, 1], [5, 0, 3]])
当你对它进行单热编码时,你将得到一个 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.]])
我的解决方案和未来的读者:
我为 "sent" 列表构建字典:
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.]]
我喜欢使用 sklearn
中的 LabelEncoder
with a OneHotEncoder
。
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))
这是另一个使用 sklearn.preprocessing
线路挺长的,差别不大。我 don:t 知道为什么但产生了类似的结果。
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.]]
我试图根据我的字典字符制作一个单热数组:首先,我创建了一个具有 X 行列 (3x7) 的 numpy zeros,然后我搜索每个字符的 ID 并分配“1”到 numpy 数组的每一行。
我的目标是为每个角色分配一个热数组。 “1”表示 "present",“0”表示 "not present"。这里我们有 3 个字符,所以我们应该有 3 行,而 7 列作为字典中存在的字符。
但是,我收到一条错误消息,指出 "TypeError: only integer scalar arrays can be converted to a scalar index"。谁能帮我解决这个问题?谢谢
为了不让大家误解我的字典:
这是我创建 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”是虚拟的,这样我就可以显示我的预期输出。
设置索引
(内联评论。)
# 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.]])
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.]
表示该单词包含字母c
、a
、t
.
要进行一次性编码,您需要两件事,即查找具有所有可能值的词汇表(当使用单词时,这就是为什么矩阵会变得如此之大的原因,因为词汇表很大!)。但是如果编码小写字母你只需要26个。
然后您通常将样本表示为词汇表中的索引。所以这组词可能是这样的:
#bag, cab, fad
sentences = np.array([[1, 0, 6], [2, 0, 1], [5, 0, 3]])
当你对它进行单热编码时,你将得到一个 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.]])
我的解决方案和未来的读者:
我为 "sent" 列表构建字典:
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.]]
我喜欢使用 sklearn
中的 LabelEncoder
with a OneHotEncoder
。
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))
这是另一个使用 sklearn.preprocessing
线路挺长的,差别不大。我 don:t 知道为什么但产生了类似的结果。
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.]]