【RapidAI】P1 中文文本切割程序

这篇具有很好参考价值的文章主要介绍了【RapidAI】P1 中文文本切割程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基本信息

文件名: chinese_text_splitter.py
文件地址: E:\Code\Knowledge-QA-LLM\Knowledge-QA-LLM-main\knowledge_qa_llm\text_splitter\chinese_text_splitter.py
Author: @SWHL、@omahs
CSDN Author: me(脚踏实地的大梦想家)
Original Code: url


代码解析

相关包

import re
from pathlib import Path
from typing import List

re 正则表达式。在文本处理中,正则表达式可用于验证、搜索、提取和替换文本中的特定模式。

re.sub(pattern, replacement, string, count=0, flags=0)
# pattern:要被替换的字符串。
# replacement:要替换的字符串。
# string:被操作的字符串的名称。
# count(可选):指定最大替换次数,默认为0,表示替换所有匹配项。
# flags(可选):可以对字符串加以限制,比如忽略大小写等。

import re

text = "Hello, my name is Alice. Nice to meet you, Alice!"
new_text = re.sub(r'Alice', 'Bob', text)

>>> Hello, my name is Bob. Nice to meet you, Bob!

Path 负责路径,通过使用 Path 类,可以创建、连接、分解和操作文件系统路径,而无需直接使用字符串拼接或分割。

# 当前脚本文件的路径
Path(__file__)
# resolve()方法会返回规范化的绝对路径,解析出符号链接和相对路径,使其变为绝对路径
Path(__file__).resolve()
# root_dir为当前脚本的绝对路径下的上级目录的上级目录
root_dir = Path(__file__).resolve().parent.parent

List 用于表示一个列表类型。

# 表明函数的参数或返回值应该是一个字符串类型的列表
List[str]

获取 yaml 关键文件

root_dir = Path(__file__).resolve().parent.parent
config_path = root_dir / "config.yaml"
config = read_yaml(config_path)

上述代码获取了重要描述文件 config.yaml 文件的路径地址信息,然后通过 read_yaml() 函数读取到其中信息。关于 read_yaml() 函数的代码提取如下:

# 首先 read_yaml() 函数在 ..util.util.py 文件中
from ..utils.utils import read_yaml

# 提取出 read_yaml() 函数如下:
def read_yaml(yaml_path: Union[str, Path]):
    with open(str(yaml_path), "rb") as f:
        data = yaml.load(f, Loader=yaml.Loader)
    return data

上述代码讲打开 str 字符串类型的地址信息,或者 Path 对象的地址信息;通过代码读取到该地址文件,以二进制的形式返回读取到的结果。


类的构造函数

def __init__(
    self,
    pdf: bool = False,
    sentence_size: int = config.get("SENTENCE_SIZE"),
):
    self.pdf = pdf
    self.sentence_size = sentence_size

上述 __init__ 为类 ChineseTextSplitter 的构造函数;
pdf: bool = False 这是一个布尔型参数,默认为False。它用于表示文本是否来自PDF文档。如果设置为True,则表示文本来自PDF,否则为其他来源。
sentence_size: int = config.get("SENTENCE_SIZE"): 从 yaml 文件中获取 SENTENCE_SIZE 的值,作为 sentence_size 的默认值。


切分语句部分

特殊处理 PDF

切分语句 split_text 是定义在 ChineseTextSplitter 类中的一个成员方法,用于将输入的文本分割成句子的列表。

切分语句部分过长,将首先切分开介绍,附录附完整的切分函数代码;

def split_text(self, text: str) -> List[str]:  ##此处需要进一步优化逻辑
    if self.pdf:
        text = re.sub(r"\n{3,}", r"\n", text)
        text = re.sub("\s", " ", text)
        text = re.sub("\n\n", "", text)

text 为待分割的文本,字符串格式;
-> List[str] 是方法的返回类型标注,表示该方法返回一个字符串列表;
re.sub(r"\n{3,}", "\n", text) 将连续三个以上的换行符替换称为单个换行符;
re.sub("\s", " ", text) 将单个/连续的空白字符串替换为单个空格;
text = text.replace("\n\n", "") 将连续两个换行符移除;


重点切分

text = re.sub(r"([;;.!?。!?\?])([^”’])", r"\1\n\2", text)
text = re.sub(r'(\.{6})([^"’”」』])', r"\1\n\2", text)	# \.{6} 代表着连续6个英文点,作为英文中省略号
text = re.sub(r'(\…{2})([^"’”」』])', r"\1\n\2", text)  # 中文省略号……
text = re.sub(r'([;;!?。!?\?]["’”」』]{0,2})([^;;!?,。!?\?])', r"\1\n\2", text)	# 其目标与第一个相反,想要筛选出以及引号为结尾的字段。
text = text.rstrip()  # 段尾如果有多余的\n就去掉它

上述代码是本文,本函数的重点部分,总结来说,就是运用 re.sub() 函数将句子按照标点的方式分割;详细阐述如下:

re.sub(r"([;;.!?。!?\?])([^”’])", r"\1\n\2", text) 重点部分拆分:

  1. 第一个捕获组:([;;.!?。!?\?])
    该部分是一个字符类,包含中英文分号,中英文句号,中英文感叹号以及中英文问号。该捕获组的作用为用来匹配句子分隔符。

  2. 第二个捕获组:([^”’])
    该部分是一个否定字符类,表示匹配除了有双引号与有单引号之外的任何字符。
    将第一个捕获组与第二个捕获组的结合,其意义在于筛选出:以第一个捕获组中字符类为结尾,且没有引号在其后的句子。(一定要注意其后,其前是另一种写法)
    e . g . e.g. e.g. 案例见替换模式后下述;

  3. 替换模式:\1\n\2
    如果捕获成功,即满足非引号作为结尾的句子,以字符类结尾,则使用替换模式。将句子通过换行分隔开。切分前的句子为 \1,加入换行符 \n,以及切分后的句子 \2

e . g . e.g. e.g.

import re

text = "你好吗?我很好!你想吃什么?“苹果。”她说。"
text = re.sub(r"([;;.!?。!?\?])([^”’])", r"\1\n\2", text)
print(text)

# 结果如下:
>>>你好吗?
我很好!
你想吃什么?
“苹果。”她说。

去除数组中空字符串

ls = [i for i in text.split("\n") if i]
# 将不为空的字符串保留在列表 ls 中。

若当前空字符串满足单句最大长度要求,则视为完成中文句子切分,返回 ls 数组。


再度切分后长度

在去除空元素后,通过调取 yaml 关键信息文件中的 SENTENCE_SIZE 属性信息,获取规定最长的单句文本长度。再根据长度进行判断,若超出规定范围,则需二次切分。

首先切分

切分除 。” 结尾的语句(逗号句号搭配引号)

for ele in ls:
    if len(ele) > self.sentence_size:
        ele1 = re.sub(r'([,,.]["’”」』]{0,2})([^,,.])', r"\1\n\2", ele)
        ele1_ls = ele1.split("\n")

其次切分

切分一个或多个连续的换行符 或 两个或多个连续的空格(后面可能跟随0到2个特定字符)后面紧跟一个非空白字符。然后在这两部分之间插入一个换行符。

for ele_ele1 in ele1_ls:
    if len(ele_ele1) > self.sentence_size:
        ele_ele2 = re.sub(r'([\n]{1,}| {2,}["’”」』]{0,2})([^\s])', r"\1\n\2", ele_ele1)		# 切分换行以及空格
        ele2_ls = ele_ele2.split("\n")

继续切分

切分查找一个0到2个特定字符后面跟着的空格,然后紧随一个非空格字符。在这两部分之间插入一个换行符。

然后将会找到 ele2_ls 列表中的元素 ele_ele2,然后用 ele_ele3 字符串中的多个行替换它。

for ele_ele2 in ele2_ls:
    if len(ele_ele2) > self.sentence_size:
        ele_ele3 = re.sub('( ["’”」』]{0,2})([^ ])', r"\1\n\2", ele_ele2)
        ele2_id = ele2_ls.index(ele_ele2)
		ele2_ls = (ele2_ls[:ele2_id] + [i for i in ele_ele3.split("\n") if i] + ele2_ls[ele2_id + 1 :])

替换超长字符

ele_id = ele1_ls.index(ele_ele1)
ele1_ls = (ele1_ls[:ele_id] + [i for i in ele2_ls if i] + ele1_ls[ele_id + 1 :])

id = ls.index(ele)
ls = ls[:id] + [i.strip() for i in ele1_ls if i] + ls[id + 1 :]

至此为止,数组 ls 中所有字符全部都符号长度标准。


附录

附录一:完整代码

import re
from pathlib import Path
from typing import List
from ..utils.utils import read_yaml

root_dir = Path(__file__).resolve().parent.parent
config_path = root_dir / "config.yaml"
config = read_yaml(config_path)

class ChineseTextSplitter:
    def __init__(
        self,
        pdf: bool = False,
        sentence_size: int = config.get("SENTENCE_SIZE"),
    ):
        self.pdf = pdf
        self.sentence_size = sentence_size

    def split_text(self, text: str) -> List[str]:  ## 此处需要进一步优化逻辑
        if self.pdf:
            text = re.sub(r"\n{3,}", r"\n", text)
            text = re.sub("\s", " ", text)
            text = re.sub("\n\n", "", text)

        text = re.sub(r"([;;.!?。!?\?])([^”’])", r"\1\n\2", text)
        text = re.sub(r'(\.{6})([^"’”」』])', r"\1\n\2", text)
        text = re.sub(r'(\…{2})([^"’”」』])', r"\1\n\2", text)
        text = re.sub(r'([;;!?。!?\?]["’”」』]{0,2})([^;;!?,。!?\?])', r"\1\n\2", text)
        text = text.rstrip()

        ls = [i for i in text.split("\n") if i]
        for ele in ls:
            if len(ele) > self.sentence_size:
                ele1 = re.sub(r'([,,.]["’”」』]{0,2})([^,,.])', r"\1\n\2", ele)
                ele1_ls = ele1.split("\n")
                for ele_ele1 in ele1_ls:
                    if len(ele_ele1) > self.sentence_size:
                        ele_ele2 = re.sub(
                            r'([\n]{1,}| {2,}["’”」』]{0,2})([^\s])', r"\1\n\2", ele_ele1
                        )
                        ele2_ls = ele_ele2.split("\n")
                        for ele_ele2 in ele2_ls:
                            if len(ele_ele2) > self.sentence_size:
                                ele_ele3 = re.sub(
                                    '( ["’”」』]{0,2})([^ ])', r"\1\n\2", ele_ele2
                                )
                                ele2_id = ele2_ls.index(ele_ele2)
                                ele2_ls = (
                                    ele2_ls[:ele2_id]
                                    + [i for i in ele_ele3.split("\n") if i]
                                    + ele2_ls[ele2_id + 1 :]
                                )
                        ele_id = ele1_ls.index(ele_ele1)
                        ele1_ls = (
                            ele1_ls[:ele_id]
                            + [i for i in ele2_ls if i]
                            + ele1_ls[ele_id + 1 :]
                        )

                id = ls.index(ele)
                ls = ls[:id] + [i.strip() for i in ele1_ls if i] + ls[id + 1 :]
        return ls

附录二:可继续思考问题

可继续思考的问题:

  1. 是否可以优化上述代码中对于长度的限制;
  2. 为什么要对长度进行限制?长度限制可以调整吗?
  3. 怎样对重复性的ele2,ele1与ele3的限制??

这些问题我们将在本系列博文最后的部分拓展讨论。

2023年9月5日
徐鸿铎 于 西直门文章来源地址https://www.toymoban.com/news/detail-703932.html

到了这里,关于【RapidAI】P1 中文文本切割程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [oneAPI] 使用Bert进行中文文本分类

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 在本次实验中,我们利用PyTorch和Intel® Optimization for PyTorch的强大功能,对PyTorch进行了精心的优化和扩展。这些优化举措极大地增强了PyTorch在各

    2024年02月12日
    浏览(33)
  • Whisper对于中文语音识别与转写中文文本优化的实践(Python3.10)

    阿里的FunAsr对Whisper中文领域的转写能力造成了一定的挑战,但实际上,Whisper的使用者完全可以针对中文的语音做一些优化的措施,换句话说,Whisper的“默认”形态可能在中文领域斗不过FunAsr,但是经过中文特殊优化的Whisper就未必了。 Whisper经常被人诟病的一点是对中文语音

    2024年01月25日
    浏览(35)
  • pytorch-textsummary,中文文本摘要实践

    pytorch-textsummary是一个以pytorch和transformers为基础,专注于中文文本摘要的轻量级自然语言处理工具,支持抽取式摘要等。 数据 使用方式 paper 参考 pytorch-textsummary: https://github.com/yongzhuo/Pytorch-NLU/pytorch_textsummary 免责声明:以下数据集由公开渠道收集而成, 只做汇总说明; 科学研究

    2024年02月21日
    浏览(35)
  • 第N2周:中文文本分类-Pytorch实现

    🍨 本文为🔗365天深度学习训练营 中的学习记录博客 🍖 原作者:K同学啊|接辅导、项目定制 环境搭建 Python 3.8 pytorch == 1.8.1 torchtext == 0.9.1

    2024年02月01日
    浏览(45)
  • Python文本分析之中文分词(jieba库)

    (1)全自动安装 (2)半自动安装 首先登入https://pypi.org/project/jieba/下载安装包 最后解压安装包: python setup py install (3)手动安装 首先登入https://pypi.org/project/jieba/下载安装包 最后把jieba目录放置在site-packages目录内 语法: jieba.cut(sentence, cut_all=False, HMM=True, use_paddle=False) 功能

    2024年02月07日
    浏览(34)
  • 基于BERT-PGN模型的中文新闻文本自动摘要生成——文本摘要生成(论文研读)

    基于BERT-PGN模型的中文新闻文本自动摘要生成(2020.07.08) 针对文本自动摘要任务中生成式摘要模型对句子的上下文理解不够充分、生成内容重复的问题,基于BERT 和指针生成网络(PGN),提出了一种面向中文新闻文本的生成式摘要模型——BERT-指针生成网络(BERTPGN)。首先,

    2024年02月01日
    浏览(42)
  • 开源(离线)中文语音识别ASR(语音转文本)工具整理

    开源(离线)中文语音识别ASR(语音转文本)工具整理 Open AI在2022年9月21日开源了号称其英文语音辨识能力已达到人类水准的Whisper神经网络,且它亦支持其它98种语言的自动语音辨识。 Whisper系统所提供的自动语音辨识(Automatic Speech Recognition,ASR)模型是被训练来运行语音辨识与翻

    2024年02月13日
    浏览(42)
  • python3使用PIL添加中文文本水印背景

    环境:Windows10_x64  Python版本 :3.9.2 Pillow版本:9.1.1   写的博客文章被转载且不注明出处的情况时有发生,甚至有部分转载者将文章配图添加自己的水印!为了保护作者劳动成果,添加水印是一个可选项。 今天记录下Windows10环境下使用python3.9简单实现批量添加中文文本水印背

    2024年02月12日
    浏览(28)
  • 高级文本编辑软件 UltraEdit mac中文版介绍说明

    UltraEdit mac是一款在Windows系统中非常出名的文本编辑器, UltraEdit for mac对于IT程序猿来说,更是必不可少,可以使用UltraEdit编辑配置文件、查看16进制文件、代码高亮显示等,虽然Mac上已经有了很多优秀的文本编辑器,但对于在Windows系统中已经习惯了UltraEdit的用户来说,使用

    2024年02月06日
    浏览(43)
  • 【LangChain】P1 LangChain 应用程序的核心构建模块 LLMChain 以及其三大部分

    LangChain 应用程序的核心构建模块 LLMChain 由三部分组成: 语言模型 - LLMs: 语言模型是这里的核心推理引擎。为了使用 LangChain,您需要了解不同类型的语言模型以及如何使用它们。 提示模板 - Prompt templates: 它为语言模型提供指令。它控制着语言模型的输出,因此了解如何构

    2024年02月12日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包