• 循环神经网络-02文本预处理


    https://zh-v2.d2l.ai/chapter_recurrent-neural-networks/text-preprocessing.html
    本节中,我们将解析文本的常见预处理步骤。 这些步骤通常包括:

    1. 将文本作为字符串加载到内存中。

    2. 字符串拆分为词元(如单词和字符)。

    3. 建立一个词表,将拆分的词元映射到数字索引。

    4. 文本转换为数字索引序列,方便模型操作。

    代码

    """
    将文本作为字符串加载到内存中。
    
    将字符串拆分为词元(如单词和字符)。
    
    建立一个词表,将拆分的词元映射到数字索引。
    
    将文本转换为数字索引序列,方便模型操作。
    """
    
    import collections
    import re
    from d2l import torch as d2l
    
    d2l.DATA_HUB['time_machine'] = (d2l.DATA_URL + 'timemachine.txt','090b5e7e70c295757f55df93cb0a180b9691891a')
    
    def read_time_machine():
        """将时间机器数据集加载到文本行的列表中"""
        with open(d2l.download('time_machine'),'r') as f:
            lines = f.readlines()
        return [re.sub('[^A-Za-z]+',' ',line).strip().lower() for line in lines]  # 将非A-Z a-z的字符变成,头和尾的空格去掉,大写变小写
    
    lines = read_time_machine()
    print(f'文本总行数:{len(lines)}')
    print(lines[0])
    print(lines[10])
    
    
    ## 词元化 token
    '''下面的tokenize函数将文本行列表(lines)作为输入, 列表中的每个元素是一个文本序列(如一条文本行)。
    每个文本序列又被拆分成一个词元列表,词元(token)是文本的基本单位。 最后,返回一个由词元列表组成的列表,其中的每个词元都是一个字符串(string)'''
    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)
    for i in range(11):
        print(tokens[i])
    
    ## 词表 vocab
    class Vocab:
        """文本词表"""
        def __init__(self, tokens=None, min_freq=0, reserved_tokens=None):
            if tokens is None:
                tokens = []
            if reserved_tokens is None:
                reserved_tokens = []
            # 按出现频率排序
            counter = count_corpus(tokens)
            self._token_freqs = sorted(counter.items(), key=lambda x: x[1],
                                       reverse=True)
            # 未知词元的索引为0
            self.idx_to_token = [''] + reserved_tokens
            self.token_to_idx = {token: idx
                                 for idx, token in enumerate(self.idx_to_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)):
                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是1D列表或2D列表
        if len(tokens) == 0 or isinstance(tokens[0], list):
            # 将词元列表展平成一个列表
            tokens = [token for line in tokens for token in line]
        return collections.Counter(tokens)
    
    vocab = Vocab(tokens)
    print(list(vocab.token_to_idx.items())[:10])
    
    for i in [0, 10]:
        print('文本:', tokens[i])
        print('索引:', vocab[tokens[i]])  
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    在这里插入图片描述

    小结

    • 文本是序列数据的一种最常见的形式之一。

    • 为了对文本进行预处理,我们通常将文本拆分为词元,构建词表将词元字符串映射为数字索引,并将文本数据转换为词元索引以供模型操作。

    其他知识点

    1. re.sub()用法的详细介绍
    2. Python strip()方法
  • 相关阅读:
    制药机械行业供应链协同管理系统:全链路数字化覆盖,实现产业供应链可视化
    大数据学习(4)-hive表操作
    无涯教程-JavaScript - LCM函数
    选哪个短剧系统源码好:全面评估与决策指南
    Gitlab: PHP项目CI/CD实践
    mac 技术 如何上存项目到testFight
    公众号数据分析总结怎么做?教你玩转公众号后台数据
    如何编写一个Perl爬虫程序
    论如何直接用EF Core实现创建更新时间、用户审计,自动化乐观并发、软删除和树形查询(中)
    (针对 G1 )JVM常用参数讲解:-XX,-X,-D 的区别与常用JVM配置 +应用程序配置实例+ 调优思路
  • 原文地址:https://blog.csdn.net/weixin_39107270/article/details/133030769