【发布时间】:2020-10-13 10:02:50
【问题描述】:
python 新手——我需要一些帮助来弄清楚如何在 python 中编写一个标记器方法,而不使用任何像 Nltk 这样的库。我将如何开始?谢谢!
【问题讨论】:
-
您的输入看起来如何?一般来说,您可以使用
example_string.split()来检索单词列表(没有参数,这是由空格分隔的)。
python 新手——我需要一些帮助来弄清楚如何在 python 中编写一个标记器方法,而不使用任何像 Nltk 这样的库。我将如何开始?谢谢!
【问题讨论】:
example_string.split() 来检索单词列表(没有参数,这是由空格分隔的)。
根据复杂程度,您可以简单地使用字符串split 函数。
# Words independent of sentences
words = raw_text.split(' ')
# Sentences and words
sentences = raw_text.split('. ')
words_in_sentences = [sentence.split(' ') for sentence in sentences]
如果你想做一些更复杂的事情,你可以使用像 re 这样的包,它提供了对正则表达式的支持。 [Related question]
【讨论】:
我假设您正在谈论编译器的标记器。这样的标记通常可以由正则表达式/有限状态自动机是自然解决方案的正则语言定义。一个例子:
import re
from collections import namedtuple
Token = namedtuple('Token', ['type','value'])
def lexer(text):
IDENTIFIER = r'(?P<IDENTIFIER>[a-zA-Z_][a-zA-Z_0-9]*)'
ASSIGNMENT = r'(?P<ASSIGNMENT>=)'
NUMBER = r'(?P<NUMBER>\d+)'
MULTIPLIER_OPERATOR = r'(?P<MULTIPLIER_OPERATOR>[*/])'
ADDING_OPERATOR = r'(?P<ADDING_OPERATOR>[+-])'
WHITESPACE = r'(?P<WHITESPACE>\s+)'
EOF = r'(?P<EOF>\Z)'
ERROR = r'(?P<ERROR>.)' # catch everything else, which is an error
tokenizer = re.compile('|'.join([IDENTIFIER, ASSIGNMENT, NUMBER, MULTIPLIER_OPERATOR, ADDING_OPERATOR, WHITESPACE, EOF, ERROR]))
seen_error = False
for m in tokenizer.finditer(text):
if m.lastgroup != 'WHITESPACE': #ignore whitespace
if m.lastgroup == 'ERROR':
if not seen_error:
yield Token(m.lastgroup, m.group())
seen_error = True # scan until we find a non-error input
else:
yield Token(m.lastgroup, m.group())
seen_error = False
else:
seen_error = False
for token in lexer('foo = x12 * y / z - 3'):
print(token)
打印:
Token(type='IDENTIFIER', value='foo')
Token(type='ASSIGNMENT', value='=')
Token(type='IDENTIFIER', value='x12')
Token(type='MULTIPLIER_OPERATOR', value='*')
Token(type='IDENTIFIER', value='y')
Token(type='MULTIPLIER_OPERATOR', value='/')
Token(type='IDENTIFIER', value='z')
Token(type='ADDING_OPERATOR', value='-')
Token(type='NUMBER', value='3')
Token(type='EOF', value='')
上面的代码将IDENTIFIER、ASSIGNMENT等每个标记定义为简单的正则表达式,然后使用|运算符将它们组合成一个正则表达式模式,并将表达式编译为变量tokenizer .然后,它使用正则表达式 finditer 方法并将输入文本作为其参数来创建一个“扫描器”,该“扫描器”尝试将连续的输入标记与 tokenizer 正则表达式进行匹配。只要存在匹配项,lexer 生成器函数就会生成由类型和值组成的 Token 实例。在这个例子中,WHITESPACE 标记不会被解析器忽略并仅用于分隔其他标记的假设。
有一个包罗万象的 ERROR 标记定义为最后一个标记,如果没有其他标记正则表达式匹配,则匹配单个字符(. 用于此,除非标志,否则它将不匹配换行符使用了re.S,但不需要匹配换行符,因为换行符正在与WHITESPACE 令牌正则表达式匹配,因此是“合法”匹配)。添加了特殊代码以防止生成连续的ERROR 令牌。实际上,lexer 会生成一个 ERROR 令牌,然后丢弃输入,直到它可以再次匹配一个合法令牌。
【讨论】:
改用 gensim。
tokenized_word = gensim.utils.simple_preprocess(str(sentences ), deacc=True) # deacc=True removes punctuations
【讨论】: