动手学深度学习(Pytorch版)代码实践 -循环神经网络-52文本预处理

52文本预处理

"""
我们将解析文本的常见预处理步骤。 
这些步骤通常包括:
1.将文本作为字符串加载到内存中。
2.字符串拆分为词元(如单词和字符)。
3.建立一个词表,将拆分的词元映射到数字索引。
4.将文本转换为数字索引序列,方便模型操作。
"""
import collections
import re
from d2l import torch as d2l

# 读取数据集
# 从H.G.Well的时光机器中加载文本
# d2l.DATA_HUB['time_machine'] = (d2l.DATA_URL + 'timemachine.txt',
#                                 '090b5e7e70c295757f55df93cb0a180b9691891a')
# d2l.download('time_machine')

time_machine_dir = '../data/timemachine.txt'

def read_time_machine():
    """将时间机器数据加载到文本行的列表中"""
    with open(time_machine_dir, 'r') as f:
        lines = f.readlines()
    return [
        re.sub('[^A-Za-z]+', ' ', line).strip().lower() 
        for line in lines
    ]
"""
re.sub 是正则表达式模块 re 中的一个函数,用于替换字符串中的匹配项。
[^A-Za-z] 表示匹配任何不是大写字母(A-Z)或小写字母(a-z)的字符。
+表示匹配一个或多个非字母字符
' ' 是替换字符串,表示将所有匹配的非字母字符替换为空格。

strip() 方法用于移除字符串首尾的空白字符。
lower() 方法将字符串中的所有字符转换为小写。
"""

lines = read_time_machine()
# print(f'# 文本总行数: {len(lines)}')
# print(lines[0])
# print(lines[10])
# # 文本总行数: 3221
# the time machine by h g wells
# twinkled and his usually pale face was flushed and animated the


# 词元化
def tokenize(lines, token='word'):  #@save
    """将文本行拆分为单词或字符词元"""
    if token == 'word': # 拆成单词
        return [line.split() for line in lines]
    elif token == 'char': # 拆成单个字符
        return [list(line) for line in lines]
    else:
        print('错误:未知词元类型:' + token)

tokens = tokenize(lines)
# print(tokens[0])
# ['the', 'time', 'machine', 'by', 'h', 'g', 'wells']

# 词表
# 构建一个字典,通常也叫做词表(vocabulary)
# 用来将字符串类型的词元映射到从0开始的数字索引中
class Vocab:
    """文本词表"""
    def __init__(self, tokens=None, min_freq=0, reserved_tokens=None) -> None:
        if tokens is None:
            tokens = []
        if reserved_tokens is None:
            reserved_tokens = []
        
        # 词元频率
        counter = count_corpus(tokens)
        # print(counter)
        # Counter({'the': 1, 'time': 1, 'machine': 1, 'by': 1, 'h': 1, 'g': 1, 'wells': 1})

        # 按出现频率排序
        self._token_freqs = sorted(counter.items(), key=lambda x: x[1],
                                   reverse=True)
        # 未知词元的索引为0
        self.idx_to_token = ['<unk>'] + reserved_tokens
        """
        这里,self.idx_to_token 是一个列表,包含所有词元及其对应的索引。
        '<unk>' 是一个特殊的词元,表示未知词元(unknown token)。
        reserved_tokens 是一个列表,包含预留的词元,可以是其他特殊词元,
        如 '<pad>'、'<bos>'(句子开始)和 '<eos>'(句子结束)。
        ['<unk>'] + reserved_tokens 将 '<unk>' 添加到 reserved_tokens 的前面,
        创建一个包含未知词元和预留词元的列表。
        """
        self.token_to_idx = {token: idx
                             for idx, token in enumerate(self.idx_to_token)}
        # enumerate(self.idx_to_token) 会生成一个迭代器,
        # 产生一系列的 (idx, token) 元组,其中 idx 是索引,token 是词元。
        
        for token, freq in self._token_freqs:
            if freq < min_freq:
                break
            if token not in self.token_to_idx:
                self.idx_to_token.append(token)
                self.token_to_idx[token] = len(self.idx_to_token) - 1

    def __len__(self):
        return len(self.idx_to_token)

    def __getitem__(self, tokens):
        if not isinstance(tokens, (list, tuple)): # 检查 tokens 是否是列表或元组
            # 尝试获取词元 tokens 对应的索引。
            # 如果词元不在字典中,返回 self.unk,表示未知词元的索引
            return self.token_to_idx.get(tokens, self.unk)
        return [self.__getitem__(token) for token in tokens]

    def to_tokens(self, indices):
        if not isinstance(indices, (list, tuple)):
            return self.idx_to_token[indices]
        return [self.idx_to_token[index] for index in indices]
    
    @property
    def unk(self):  # 未知词元的索引为0
        return 0

    @property
    def token_freqs(self):
        return self._token_freqs

def count_corpus(tokens):  #@save
    """统计词元的频率"""
    # 检查 tokens 是否为空或是二维列表
    # len(tokens) == 0, 二维的tokens如果没有元素的话tokens[0]会报错,需要单独处理
    if len(tokens) == 0 or isinstance(tokens[0], list):
        # 将词元列表展平成一个列表
        # tokens = [token for line in tokens for token in line]
        flat_tokens = []
        for line in tokens:
            for token in line:
                flat_tokens.append(token)
        tokens = flat_tokens

    return collections.Counter(tokens) # 得到词元的频率

vocab = Vocab(tokens)
# print(list(vocab.token_to_idx.items())[:10])
# [('<unk>', 0), ('the', 1), ('i', 2), ('and', 3), ('of', 4),
#  ('a', 5), ('to', 6), ('was', 7), ('in', 8), ('that', 9)]


# 整合所有功能
"""
在使用上述函数时,我们将所有功能打包到load_corpus_time_machine函数中, 
该函数返回corpus(词元索引列表)和vocab(时光机器语料库的词表)。 
我们在这里所做的改变是:
1.为了简化后面章节中的训练,我们使用字符(而不是单词)实现文本词元化;
2.时光机器数据集中的每个文本行不一定是一个句子或一个段落,还可能是一个单词,
因此返回的corpus仅处理为单个列表,而不是使用多词元列表构成的一个列表。
"""
def load_corpus_time_machine(max_tokens=-1):  #@save
    """返回时光机器数据集的词元索引列表和词表"""
    lines = read_time_machine()
    tokens = tokenize(lines, 'char')
    vocab = Vocab(tokens)
    # 因为时光机器数据集中的每个文本行不一定是一个句子或一个段落,
    # 所以将所有文本行展平到一个列表中
    corpus = [vocab[token] for line in tokens for token in line]
    if max_tokens > 0:
        corpus = corpus[:max_tokens]
    return corpus, vocab

corpus, vocab = load_corpus_time_machine(10)
print(corpus)  # 输出: [对应的词元索引列表]
print(vocab.token_to_idx)  # 输出: 词元到索引的映射字典

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/776503.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面向物联网行业的异常监控追踪技术解决方案:技术革新与运维保障

在现代高度数字化和互联的环境中&#xff0c;物联网技术已经深入到我们生活的方方面面。特别是在家庭和工业环境中&#xff0c;物联网系列通讯作为连接各类设备的关键枢纽&#xff0c;其稳定性和可靠性显得尤为重要。本文将介绍一种创新的监控系统&#xff0c;旨在实时跟踪和分…

用Python轻松转换PDF为CSV

数据的可访问性和可操作性是数据管理的核心要素。PDF格式因其跨平台兼容性和版面固定性&#xff0c;在文档分享和打印方面表现出色&#xff0c;尤其适用于报表、调查结果等数据的存储。然而&#xff0c;PDF的非结构化特性限制了其在数据分析领域的应用。相比之下&#xff0c;CS…

DFS之剪枝与优化——AcWing 165. 小猫爬山

DFS之剪枝与优化 定义 DFS之剪枝与优化指的是在执行深度优先搜索(DFS, Depth-First Search)时&#xff0c;采取的一系列策略来减少搜索空间&#xff0c;避免无效计算&#xff0c;从而加速找到问题的解。剪枝是指在搜索过程中&#xff0c;当遇到某些条件不符合解的要求或者可以…

Day05-02-Jenkins-pipeline

Day05-02-Jenkins-pipeline 1. Jenkins-Pipeline概述1) pipeline? 2. pipeline格式3. 小试牛刀4. Java上线的项目4.1 流程汇总4.2 根据流程书写pipeline架构4.3 分步实现1&#xff09;拉取代码2&#xff09;检查,编译,部署 4.4 完整pipeline代码 5. 根据tag标签拉取代码(了解自…

FreeBSD@ThinkPad x250因电池耗尽关机后无法启动的问题存档

好几次碰到电池耗尽FreeBSD关机&#xff0c;再启动&#xff0c;网络通了之后到了该出Xwindows窗体的时候&#xff0c;屏幕灭掉&#xff0c;网络不通&#xff0c;只有风扇在响&#xff0c;启动失败。关键是长按开关键后再次开机&#xff0c;还是启动失败。 偶尔有时候重启到单人…

温州网站建设方案及报价

随着互联网的发展&#xff0c;网站建设已经成为企业推广和营销的重要手段。温州作为中国经济发达地区之一&#xff0c;各行各业企业纷纷意识到网站建设的重要性&#xff0c;纷纷加大网站建设工作的投入。那么&#xff0c;温州网站建设方案及报价是怎样的呢&#xff1f;下面我们…

深入理解C# log4Net日志框架:功能、使用方法与性能优势

文章目录 1、log4Net的主要特性2、log4Net框架详解配置日志级别 3、log4Net的使用示例4、性能优化与对比5、总结与展望 在软件开发过程中&#xff0c;日志记录是一个不可或缺的功能。它可以帮助开发者追踪错误、监控应用程序性能&#xff0c;以及进行调试。在C#生态系统中&…

C#运算符重载

1、运算符重载 运算符重载是指重定义C#内置的运算符。 程序员也可以使用用户自定义类型的运算符。重载运算符是具有特殊名称的函数&#xff0c;是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样&#xff0c;重载运算符有返回类型和参数列表。 2、在Box类中定义…

C++ volatile 关键字

C volatile &#xff08;只有release下才会生效&#xff09; 1、告诉编译器volatile修饰的变量不要进行指令顺序的优化&#xff0c;以保证代码编写者的真实意图&#xff1b; int a 0;int b 10;int c 100;int* p &a;p &b;p &c;如果不加volatile修饰 p , 编译…

团队编程:提升代码质量与知识共享的利器

目录 前言1. 什么是团队编程&#xff1f;1.1 团队编程的起源1.2 团队编程的工作流程 2. 团队编程的优势2.1 提高代码质量2.2 促进知识共享2.3 增强团队协作2.4 提高开发效率 3. 团队编程的挑战3.1 开发成本较高3.2 需要良好的团队协作3.3 个人风格和习惯的差异3.4 长时间的集中…

AI时代算法面试:揭秘高频算法问题与解答策略

三种决策树算法的特点和区别 ID3算法&#xff1a;基本的决策树算法&#xff0c;适用于简单的分类问题C4.5算法&#xff1a;改进了ID3算法&#xff0c;适用于更复杂的分类问题&#xff0c;可以处理连续型数据和缺失值CART算法&#xff1a;更加通用的决策树算法&#xff0c;适用于…

【机器学习】机器学习与自然语言处理的融合应用与性能优化新探索

引言 自然语言处理&#xff08;NLP&#xff09;是计算机科学中的一个重要领域&#xff0c;旨在通过计算机对人类语言进行理解、生成和分析。随着深度学习和大数据技术的发展&#xff0c;机器学习在自然语言处理中的应用越来越广泛&#xff0c;从文本分类、情感分析到机器翻译和…

VBA常用的字符串内置函数

前言 在VBA程序中&#xff0c;常用的内置函数可以按照功能分为字符串函数、数字函数、转换函数等等&#xff0c;本节主要会介绍常用的字符串的内置函数&#xff0c;包括Len()、Left()、Mid()、Right()、Split()、String()、StrConV()等。 本节的练习数据表以下表为例&#xff…

前后端的导入、导出、模板下载等写法

导入&#xff0c;导出、模板下载等的前后端写法 文章目录 导入&#xff0c;导出、模板下载等的前后端写法一、导入实现1.1 后端的导入1.2 前端的导入 二、基础的模板下载2.1 后端的模板下载-若依基础版本2.2 前端的模板下载2.3 后端的模板下载 - 基于资源文件读取2.4 excel制作…

使用maven搭建一个SpingBoot项目

1.首先创建一个maven项目 注意选择合适的jdk版本 2.添加依赖 2.在pom.xml中至少添加依赖 spring-boot-starter-web 依赖&#xff0c;目的是引入Tomcat&#xff0c;以及SpringMVC等&#xff0c;使项目具有web功能。 <!-- 引入 包含tomcat&#xff0c;SpringMVC&#xff0c…

二维Gamma分布的激光点云去噪

目录 1、Gamma 分布简介2、实现步骤 1、Gamma 分布简介 Gamma 分布在合成孔径雷达( Synthetic Aperture &#xff32;adar&#xff0c;SA&#xff32;) 图像分割中具有广泛应用&#xff0c;较好的解决了SA&#xff32; 图像中相干斑噪声对图像分割的影响。采用二维Gamma 分布对…

配置基于不同端口的虚拟主机

更改配置文件&#xff0c;添加三个不同端口的虚拟主机 <directory /www> allowoverride none require all granted </directory><virtualhost 192.168.209.136:80> documentroot /www servername 192.168.209.136 </virtualhost><virtualhost 192.…

详解yolov5的网络结构

转载自文章 网络结构图&#xff08;简易版和详细版&#xff09; 此图是博主的老师&#xff0c;杜老师的图 网络框架介绍 前言&#xff1a; YOLOv5是一种基于轻量级卷积神经网络&#xff08;CNN&#xff09;的目标检测算法&#xff0c;整体可以分为三个部分&#xff0c; ba…

Floyd判圈算法——环形链表(C++)

Floyd判圈算法(Floyd Cycle Detection Algorithm)&#xff0c;又称龟兔赛跑算法(Tortoise and Hare Algorithm)&#xff0c;是一个可以在有限状态机、迭代函数或者链表上判断是否存在环&#xff0c;求出该环的起点与长度的算法。 …

实验四 图像增强—灰度变换之直方图变换

一&#xff0e;实验目的 1&#xff0e;掌握灰度直方图的概念及其计算方法&#xff1b; 2&#xff0e;熟练掌握直方图均衡化计算过程&#xff1b;了解直方图规定化的计算过程&#xff1b; 3&#xff0e;了解色彩直方图的概念和计算方法 二&#xff0e;实验内容&#xff1a; …