从文本中提取单热矢量

alv*_*vas 11 python nlp numpy vector pandas

pandasnumpy,我可以做以下来获得一个热门的向量:

>>> import numpy as np
>>> import pandas as pd
>>> x = [0,2,1,4,3]
>>> pd.get_dummies(x).values
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.],
       [ 0.,  0.,  0.,  1.,  0.]])

>>> np.eye(len(set(x)))[x]
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.],
       [ 0.,  0.,  0.,  1.,  0.]])
Run Code Online (Sandbox Code Playgroud)

从文字,用gensim,我可以做:

>>> from gensim.corpora import Dictionary
>>> sent1 = 'this is a foo bar sentence .'.split()
>>> sent2 = 'this is another foo bar sentence .'.split()
>>> texts = [sent1, sent2]
>>> vocab = Dictionary(texts)
>>> [[vocab.token2id[word] for word in sent] for sent in texts]
[[3, 4, 0, 6, 1, 2, 5], [3, 4, 7, 6, 1, 2, 5]]
Run Code Online (Sandbox Code Playgroud)

然后我将不得不做同样的事情pd.get_dummiesnp.eyes得到一个热的矢量,但我得到一个错误,我的单热矢量缺少一个维度我有8个独特的单词,但单热矢量长度只有7:

>>> [pd.get_dummies(sent).values for sent in texts_idx]
[array([[ 0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.]]), array([[ 0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.]])]
Run Code Online (Sandbox Code Playgroud)

看起来它正在单独执行一个热矢量,因为它遍历每个句子,而不是使用全局词汇.

使用np.eye,我确实得到了正确的向量:

>>> [np.eye(len(vocab))[sent] for sent in texts_idx]
[array([[ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.]]), array([[ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.]])]
Run Code Online (Sandbox Code Playgroud)

此外,目前,我必须做几件事情,从使用gensim.corpora.Dictionary转换为ids然后获得单热矢量.

还有其他方法可以从文本中获得相同的单热矢量吗?

jen*_*gel 5

有各种软件包可以在单个函数中执行所有步骤,例如http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html.

或者,如果您已经为每个句子准备了词汇和文本索引,则可以通过预分配和使用智能索引来创建一个热门编码.在下面的text_idx是一个整数列表,vocab是一个将整数索引与单词相关联的列表.

import numpy as np
vocab_size = len(vocab)
text_length = len(text_idx)
one_hot = np.zeros(([vocab_size, text_length])
one_hot[text_idx, np.arange(text_length)] = 1
Run Code Online (Sandbox Code Playgroud)