深入解析文本分割工具:utils.py
在自然语言处理(NLP)领域,文本分割是一个基础且关键的步骤。它涉及将长文本拆分成更小的单元,以便于进一步处理和分析。今天,我们将深入探讨一个名为 utils.py
的文本分割工具,它提供了多种文本分割方法,包括按字符、按句子、按特定分隔符等。这些方法在处理不同类型的文本时尤为有用,因为它们可以帮助我们更好地理解文本的结构和上下文。
前置知识
在深入了解 utils.py
之前,我们需要掌握以下几个概念:
- 文本分割(Text Splitting):将长文本拆分成更小的单元,如句子、段落或词语。
- 正则表达式(Regular Expression):一种用于匹配字符串中字符组合的模式。
- NLTK(Natural Language Toolkit):一个用于自然语言处理的Python库。
utils.py 的实现
utils.py
提供了多种文本分割方法,下面是其实现的详细解析:
导入必要的模块
首先,我们需要导入一些必要的模块和函数:
import logging
from typing import Callable, List
from llama_index.core.node_parser.interface import TextSplitter
定义日志记录器
接下来,我们定义一个日志记录器,用于记录程序的运行信息:
logger = logging.getLogger(__name__)
定义文本分割函数
现在,我们定义一些文本分割函数,并为其添加必要的属性和方法:
def truncate_text(text: str, text_splitter: TextSplitter) -> str:
"""Truncate text to fit within the chunk size."""
chunks = text_splitter.split_text(text)
return chunks[0]
def split_text_keep_separator(text: str, separator: str) -> List[str]:
"""Split text with separator and keep the separator at the end of each split."""
parts = text.split(separator)
result = [separator + s if i > 0 else s for i, s in enumerate(parts)]
return [s for s in result if s]
def split_by_sep(sep: str, keep_sep: bool = True) -> Callable[[str], List[str]]:
"""Split text by separator."""
if keep_sep:
return lambda text: split_text_keep_separator(text, sep)
else:
return lambda text: text.split(sep)
def split_by_char() -> Callable[[str], List[str]]:
"""Split text by character."""
return lambda text: list(text)
def split_by_sentence_tokenizer_internal(text: str, tokenizer) -> List[str]:
"""Get the spans and then return the sentences.
Using the start index of each span
Instead of using end, use the start of the next span if available
"""
spans = list(tokenizer.span_tokenize(text))
sentences = []
for i, span in enumerate(spans):
start = span[0]
if i < len(spans) - 1:
end = spans[i + 1][0]
else:
end = len(text)
sentences.append(text[start:end])
return sentences
def split_by_sentence_tokenizer() -> Callable[[str], List[str]]:
import nltk
tokenizer = nltk.tokenize.PunktSentenceTokenizer()
return lambda text: split_by_sentence_tokenizer_internal(text, tokenizer)
def split_by_regex(regex: str) -> Callable[[str], List[str]]:
"""Split text by regex."""
import re
return lambda text: re.findall(regex, text)
def split_by_phrase_regex() -> Callable[[str], List[str]]:
"""Split text by phrase regex.
This regular expression will split the sentences into phrases,
where each phrase is a sequence of one or more non-comma,
non-period, and non-semicolon characters, followed by an optional comma,
period, or semicolon. The regular expression will also capture the
delimiters themselves as separate items in the list of phrases.
"""
regex = "[^,.;。]+[,.;。]?"
return split_by_regex(regex)
详细解析
函数解析
- truncate_text:截断文本以适应块大小。
- split_text_keep_separator:按分隔符拆分文本,并保留分隔符在每个拆分的末尾。
- split_by_sep:按分隔符拆分文本,可以选择是否保留分隔符。
- split_by_char:按字符拆分文本。
- split_by_sentence_tokenizer_internal:使用NLTK的句子标记器拆分文本。
- split_by_sentence_tokenizer:返回一个按句子拆分文本的可调用对象。
- split_by_regex:按正则表达式拆分文本。
- split_by_phrase_regex:按短语正则表达式拆分文本。
实际应用示例
为了更好地理解 utils.py
的工作原理,我们来看一个实际的应用示例:
# 示例文本
text = "这是一个示例文本。它包含多个句子。每个句子都将被拆分成一个节点。"
# 按句子拆分文本
split_by_sentence = split_by_sentence_tokenizer()
sentences = split_by_sentence(text)
# 输出句子
for sentence in sentences:
print(sentence)
在这个示例中,我们首先定义了一个包含多个句子的文本,然后使用 split_by_sentence_tokenizer
将其拆分成句子,并输出每个句子。
输出结果
假设文本被拆分成以下三个句子:
- “这是一个示例文本。”
- “它包含多个句子。”
- “每个句子都将被拆分成一个节点。”
那么,输出的句子信息可能如下:
这是一个示例文本。
它包含多个句子。
每个句子都将被拆分成一个节点。
总结
utils.py
是一个高效的文本分割工具,它提供了多种文本分割方法,包括按字符、按句子、按特定分隔符等。通过这种方式,我们可以更好地理解文本的结构和上下文,从而提高NLP任务的准确性。希望这篇博客能够帮助你全面理解 utils.py
的工作原理及实际应用。