根据自定义字典对字符串进行标记

时间:2019-03-22 16:44:50

标签: python nlp nltk tokenize gensim

我想根据自己定义的字典对字符串列表进行标记。

字符串列表如下:

lst = ['vitamin c juice', 'organic supplement'] 

自定义词典:

dct = {0: 'organic', 1: 'juice', 2: 'supplement', 3: 'vitamin c'}

我的预期结果:

维生素C汁-> [(3,1), (1,1)] 有机补品-> [(0,1), (2,1)]

我当前的代码:

import gensim
import gensim.corpora as corpora
from gensim.utils import tokenize
dct = corpora.Dictionary([list(x) for x in tup_list]) 
corpus = [dct.doc2bow(text) for text in [s for s in lst]]

我收到的错误消息是TypeError: doc2bow expects an array of unicode tokens on input, not a single string,但是,我不想简单地将“维生素c”标记为vitaminc。相反,我想基于现有的dct单词进行标记化。也就是说,它应该是vitamin c

2 个答案:

答案 0 :(得分:1)

我只能想到关于如何实现识别包括空白在内的子字符串的标记器的效率很低的方法。但是,如果您不坚持使用空格,这是一种简单的方法,将vitamin c更改为vitamin_c


lst = ['vitamin_c juice', 'organic supplement']
dct = {0: 'organic', 1: 'juice', 2: 'supplement', 3: 'vitamin_c'}

word2index = {key: val for val, key in dct.items()}

tokenized = [[word2index[word] for word in text.split()] for text in lst]

如果您不坚持使用预定义的映射dct,也可以使用以下方法创建它:

vocab = set([word for text in lst for word in text.split()])
word2index = {word: ind for ind, word in enumerate(sorted(vocab))}

答案 1 :(得分:1)

您首先必须将字典反向,以使关键字成为关键。然后,您可以使用正则表达式将列表的条目分解为关键字。然后在反向字典中使用关键字来找到相应的令牌

例如:

lst = ['vitamin c juice', 'organic supplement'] 
dct = {0: 'organic', 1: 'juice', 2: 'supplement', 3: 'vitamin c'}

import re
from collections import Counter
keywords      = { keyword:token for token,keyword in dct.items() }  # inverted dictionary
sortedKw      = sorted(keywords,key=lambda x:-len(x))               # keywords in reverse order of size
pattern       = re.compile( "|".join(sortedKw) )                    # regular expression
lstKeywords   = [ pattern.findall(item) for item in lst ]           # list items --> keywords
tokenGroups   = [ [keywords[word] for word in words] for words in lstKeywords ]  # keyword lists to lists of indexes
result        = [ list(Counter(token).items()) for token in tokenGroups ] # lists of token indexes to (token,count) 
print(result) # [[(3, 1), (1, 1)], [(0, 1), (2, 1)]]

正则表达式的形式为:keyword1 | keyword2 | keyword3

因为“ |”正则表达式中的运算符永远不要贪婪,较长的关键字必须首先出现在列表中。这就是在构建表达式之前对它们进行排序的原因。

之后,仅需将列表项转换为关键字列表(re.findall()即可),然后使用倒排字典将每个关键字转换为令牌索引。

[UPDATE] 为了计算令牌出现的次数,将转换为令牌索引列表的关键字列表加载到Counter对象中(从收集模块中执行)专业词典中的计数操作。