likes
comments
collection
share

如何在Python中使用Tokenize模块

作者站长头像
站长
· 阅读数 6

本文将介绍Python中 "标记化 "模块的使用指南。tokenize模块可以用来以各种方式将文本分段或分成小块。你可以在使用机器学习、自然语言处理和人工智能算法的Python应用程序中使用这些片段。本文中所有的代码样本都是在Ubuntu 21.04上用Python 3.9.5测试的。

关于标记化模块

顾名思义,tokenize模块可以用来从一段或一大块文本中创建 "tokens"。在标记化过程中返回的每一个单独的碎块被称为一个标记。一旦你将文本标记化,你就可以在你的Python程序中实现你自己的逻辑,根据你的用例来处理这些标记物。tokenize模块提供了一些有用的方法,可以用来创建令牌。这些方法的用法可以通过例子得到最好的理解。下面将对其中的一些方法进行解释。

对一个段落或句子进行标记

你可以使用下面解释的代码样本对一个段落或句子进行符号化,并使用空格分隔的单词。

import tokenize

from io import BytesIO

 

text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

tokens = tokenize.tokenize(BytesIO(text.encode('utf-8')).readline)

for t in tokens:

        print (t)

前两个语句导入了将一段文本转换为单个标记所需的Python模块。一个叫做 "text "的变量包含了一个示例字符串。接下来,调用 tokenize 模块中的 "tokenize" 方法。它使用 "readline "方法作为一个强制参数。由于text变量是 "str "类型的,直接使用它将会产生一个错误。readline参数是一个可调用的方法,它必须返回字节而不是字符串,这样tokenize方法才能正确工作。所以使用 "BytesIO "类,通过指定编码类型将文本转换为字节流。

tokenize方法生成一个命名的元组,包含五种类型:type(标记的类型)、string(标记的名称)、start(标记的起始位置)、end(标记的结束位置)和line(用于创建标记的行)。因此,在运行上述代码示例后,你应该得到一个类似于这样的输出。

TokenInfo(type=62 (ENCODING), string='utf-8', start=(0, 0), end=(0, 0), line='')

TokenInfo(type=1 (NAME), string='Lorem', start=(1, 0), end=(1, 5), line='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')





TokenInfo(type=54 (OP), string='.', start=(1, 122), end=(1, 123), line='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')

TokenInfo(type=4 (NEWLINE), string='', start=(1, 123), end=(1, 124), line='')

TokenInfo(type=0 (ENDMARKER), string='', start=(2, 0), end=(2, 0), line='')

正如你在上面的输出中看到的,tokenize方法生成了一个具有上述五种类型的 "TokenInfo"对象。如果你想单独访问这些类型,可以使用点符号(如下面的代码示例所示)。

import tokenize

from io import BytesIO

 

text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

tokens = tokenize.tokenize(BytesIO(text.encode('utf-8')).readline)

for t in tokens:

        print (t.string, t.start, t.end, t.type)

运行上述代码样本后,你应该得到以下输出。


utf-8 (0, 0) (0, 0) 62

Lorem (1, 0) (1, 5) 1

ipsum (1, 6) (1, 11) 1




请注意,"t.type"调用会返回一个标记类型的常数。如果你想要一个更容易被人理解的标记类型,请使用 "token"模块和其中的 "tok_name"字典。

import tokenize

from io import BytesIO

import token

 

text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

tokens = tokenize.tokenize(BytesIO(text.encode('utf-8')).readline)

for t in tokens:

        print (t.string, t.start, t.end, token.tok_name[t.type])

通过向 "tok_name "字典提供 "t.type "常数,你可以得到一个人类可读的标记类型名称。运行上述代码示例后,你应该得到以下输出。

utf-8 (0, 0) (0, 0) ENCODING

Lorem (1, 0) (1, 5) NAME

ipsum (1, 6) (1, 11) NAME

dolor (1, 12) (1, 17) NAME




所有标记类型及其名称的完整列表可在此获得。请注意,第一个令牌总是输入流的编码类型,它没有开始和结束值。

你可以使用for循环语句或列表理解法很容易地得到一个仅仅是令牌名称的列表,如下面的代码示例所示。

import tokenize

from io import BytesIO

 

text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

tokens = tokenize.tokenize(BytesIO(text.encode('utf-8')).readline)

token_list = [t.string for t in tokens]

        print (token_list)

运行上述代码样本后,你应该得到以下输出。

['utf-8', 'Lorem', 'ipsum', 'dolor', 'sit', 'amet', ',', 'consectetur', 'adipiscing', 'elit', ',', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua', '.', '', '']

如果你想对一个字符串进行标记而不将其转换为字节,你可以使用tokenize模块中的 "generate_tokens "方法。它仍然需要一个可调用的readline方法作为强制参数,但它只处理readline方法返回的字符串,而不是字节(与上面解释的tokenize方法不同)。下面的代码示例说明了generate_tokens方法的用法。现在使用的是 "StringIO "类,而不是BytesIO类。

import tokenize

from io import StringIO

 

text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

tokens = tokenize.generate_tokens(StringIO(text).readline)

token_list = [t.string for t in tokens]

print (token_list)

运行上述代码样本后,你应该得到以下输出。

['Lorem', 'ipsum', 'dolor', 'sit', 'amet', ',', 'consectetur', 'adipiscing', 'elit', ',', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua', '.', '', '']

对文件的内容进行标记

你可以在 "rb "模式下使用 "with open "语句来直接读取一个文件的内容,然后对其进行标记。rb模式中的 "r "代表只读模式,而 "b "代表二进制模式。下面的代码示例打开一个 "sample.txt "文件,并使用tokenize和readline方法对其内容进行标记。

import tokenize

with open("sample.txt", "rb") as f:

        tokens = tokenize.tokenize(f.readline)

        token_list = [t.string for t in tokens]

        print (token_list)

你也可以使用 "open",一个在tokenize模块中可用的方便方法,然后调用generate_tokens和readline方法,直接从文件中创建令牌。

import tokenize

 

with tokenize.open("sample.txt") as f:

        tokens = tokenize.generate_tokens(f.readline)

        token_list = [t.string for t in tokens]

        print (token_list)

假设sample.txt文件包含相同的例子字符串,在运行上面解释的两个代码样本后,你应该得到以下输出。

['Lorem', 'ipsum', 'dolor', 'sit', 'amet', ',', 'consectetur', 'adipiscing', 'elit', ',', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua', '.', '', '']

结论

Python中的tokenize模块提供了一种有用的方法来标记包含空格分隔的单词的文本块。它还创建了一个标记的起始和结束位置的地图。如果你想对文本中的每一个词进行标记,tokenize方法比 "split "方法更好,因为它还负责对标点符号/其他符号进行标记,并推断出标记的类型。