自然语言处理:文本预处理、语言模型、RNN

文本是一类序列数据,一篇文章可以看作是字符或单词的序列,本节将介绍文本数据的常见预处理步骤,预处理通常包括四个步骤:

  1. 读入文本
  2. 分词
  3. 建立字典,将每个词映射到一个唯一的索引(index)
  4. 将文本从词的序列转换为索引的序列,方便输入模型

现有的工具可以很好地进行分词,spaCyNLTK

使用示例:

text = "Mr. Chen doesn‘t agree with my suggestion."
####spaCy:
import spacy
nlp = spacy.load(‘en_core_web_sm‘)
doc = nlp(text)
print([token.text for token in doc])
[‘Mr.‘, ‘Chen‘, ‘does‘, "n‘t", ‘agree‘, ‘with‘, ‘my‘, ‘suggestion‘, ‘.‘]

####NLTK:
from nltk.tokenize import word_tokenize
from nltk import data
data.path.append(‘/home/kesci/input/nltk_data3784/nltk_data‘)
print(word_tokenize(text))
[‘Mr.‘, ‘Chen‘, ‘does‘, "n‘t", ‘agree‘, ‘with‘, ‘my‘, ‘suggestion‘, ‘.‘]

语言模型

一段自然语言文本可以看作是一个离散时间序列,给定一个长度为TT的词的序列w1,w2,…,wTw1,w2,…,wT,语言模型的目标就是评估该序列是否合理,即计算该序列的概率:

P(w1,w2,…,wT).P(w1,w2,…,wT).

N-gram语言模型

为了解决自由参数数目过多的问题,引入了马尔科夫假设:随意一个词出现的概率只与它前面出现的有限的n个词有关。基于上述假设的统计语言模型被称为N-gram语言模型。

随机采样

在随机采样中,每个样本是原始序列上任意截取的一段序列,相邻的两个随机小批量在原始序列上的位置不一定相毗邻。

import torch
import random
def data_iter_random(corpus_indices, batch_size, num_steps, device=None):
    # 减1是因为对于长度为n的序列,X最多只有包含其中的前n - 1个字符
    num_examples = (len(corpus_indices) - 1) // num_steps  # 下取整,得到不重叠情况下的样本个数
    example_indices = [i * num_steps for i in range(num_examples)]  # 每个样本的第一个字符在corpus_indices中的下标
    random.shuffle(example_indices)

    def _data(i):
        # 返回从i开始的长为num_steps的序列
        return corpus_indices[i: i + num_steps]
    if device is None:
        device = torch.device(‘cuda‘ if torch.cuda.is_available() else ‘cpu‘)

    for i in range(0, num_examples, batch_size):
        # 每次选出batch_size个随机样本
        batch_indices = example_indices[i: i + batch_size]  # 当前batch的各个样本的首字符的下标
        X = [_data(j) for j in batch_indices]
        Y = [_data(j + 1) for j in batch_indices]
        yield torch.tensor(X, device=device), torch.tensor(Y, device=device)

相邻采样

在相邻采样中,相邻的两个随机小批量在原始序列上的位置相毗邻。

def data_iter_consecutive(corpus_indices, batch_size, num_steps, device=None):
    if device is None:
        device = torch.device(‘cuda‘ if torch.cuda.is_available() else ‘cpu‘)
    corpus_len = len(corpus_indices) // batch_size * batch_size  # 保留下来的序列的长度
    corpus_indices = corpus_indices[: corpus_len]  # 仅保留前corpus_len个字符
    indices = torch.tensor(corpus_indices, device=device)
    indices = indices.view(batch_size, -1)  # resize成(batch_size, )
    batch_num = (indices.shape[1] - 1) // num_steps
    for i in range(batch_num):
        i = i * num_steps
        X = indices[:, i: i + num_steps]
        Y = indices[:, i + 1: i + num_steps + 1]
        yield X, Y

循环神经网络

模型示意图:

循环神经网络引入一个隐藏变量HH,用HtHt表示HH在时间步tt的值。HtHt的计算基于XtXt和Ht−1Ht−1,可以认为HtHt记录了到当前字符为止的序列信息,利用HtHt对序列的下一个字符进行预测。

循环神经网络的构造

def rnn(inputs, state, params):
    # inputs和outputs皆为num_steps个形状为(batch_size, vocab_size)的矩阵
    W_xh, W_hh, b_h, W_hq, b_q = params
    H, = state
    outputs = []
    for X in inputs:
        H = torch.tanh(torch.matmul(X, W_xh) + torch.matmul(H, W_hh) + b_h)
        Y = torch.matmul(H, W_hq) + b_q
        outputs.append(Y)
    return outputs, (H,)

解决循环神经网络梯度爆炸问题:梯度裁剪

裁剪梯度(clip gradient)是一种应对梯度爆炸的方法。假设我们把所有模型参数的梯度拼接成一个向量 g,并设裁剪的阈值是θ。裁剪后的梯度

裁剪梯度代码:

def grad_clipping(params, theta, device):
    norm = torch.tensor([0.0], device=device)
    for param in params:
        norm += (param.grad.data ** 2).sum()
    norm = norm.sqrt().item()
    if norm > theta:
        for param in params:
            param.grad.data *= (theta / norm)

使用RNN模型进行预测:

def predict_rnn(prefix, num_chars, rnn, params, init_rnn_state,
                num_hiddens, vocab_size, device, idx_to_char, char_to_idx):
    state = init_rnn_state(1, num_hiddens, device)
    output = [char_to_idx[prefix[0]]]   # output记录prefix加上预测的num_chars个字符
    for t in range(num_chars + len(prefix) - 1):
        # 将上一时间步的输出作为当前时间步的输入
        X = to_onehot(torch.tensor([[output[-1]]], device=device), vocab_size)
        # 计算输出和更新隐藏状态
        (Y, state) = rnn(X, state, params)
        # 下一个时间步的输入是prefix里的字符或者当前的最佳预测字符
        if t < len(prefix) - 1:
            output.append(char_to_idx[prefix[t + 1]])
        else:
            output.append(Y[0].argmax(dim=1).item())
    return ‘‘.join([idx_to_char[i] for i in output])

原文地址:https://www.cnblogs.com/bianque/p/12307730.html

时间: 2024-08-30 14:15:29

自然语言处理:文本预处理、语言模型、RNN的相关文章

文本聚类&mdash;&mdash;文本预处理

文本是非结构化的数据,我们无法直接对文本进行聚类处理.在此之前,应该对文本进行一些预处理操作,将文本信息转化成统一的结构化的形式.再对这些结构化的数据进行聚类. 文本预处理对于聚类的效果有着重要的作用,预处理的质量高低影响着聚类结果的好坏.对于英文文本的预处理一般包含以下几个步骤: 分词 去除非英文文本 拼写检查,转换小写 词干化处理 去停用词 词频统计 特征选择 分词--tokenize 分句:tokenize segment NLTK中使用nltk.sent_tokenize(text) #

文本预处理常用操作

这里介绍一下文本预处理中常用的操作: 1.英文统一小写 text = text.lower() 2.分词 def cut(text): # return list(jieba.cut(text)) return [item for item in jieba.cut(text.lower())] if text != "" else [] 3.去噪 两种方式 (1)去停用词 包括中英文标点符号.以及噪音词,参考附录[1] stopwords = set([line.strip() fo

中文文本预处理流程(带你分析每一步)

标签:中文文本预处理 作者:炼己者 --- 欢迎大家访问我的简书以及我的博客,大家如果感觉格式看着不舒服,也可以去看我的简书,里面也会有发布 本博客所有内容以学习.研究和分享为主,如需转载,请联系本人,标明作者和出处,并且是非商业用途,谢谢! 摘要 机器学习我的理解就是把各种原始的东西变成机器可以理解的东西,然后再用各种机器学习算法来做操作.机器可以理解的东西是什么呢?--向量 .所以不管是图片还是文字,要用机器学习算法对它们进行处理,就要把它们转为向量. 网上大部分都是处理英文文本的资料,本文

机器学习(ML)四之文本预处理

文本预处理 读入文本 分词 建立字典,将每个词映射到一个唯一的索引(index) 将文本从词的序列转换为索引的序列,方便输入模型 读入文本 import collections import re def read_time_machine(): with open('/home/kesci/input/timemachine7163/timemachine.txt', 'r') as f: lines = [re.sub('[^a-z]+', ' ', line.strip().lower()

文本预处理

文本预处理 文本是一类序列数据,一篇文章可以看作是字符或单词的序列,本节将介绍文本数据的常见预处理步骤,预处理通常包括四个步骤: 读入文本 可以直接利用open读入文本 分词 对每个句子进行分词,也就是将一个句子划分成若干个词(token),转换为一个词的序列 分词的时候很多时候需要一份停用词表 建立字典,将每个词映射到一个唯一的索引(index) 为了方便模型处理,我们需要将字符串转换为数字.因此我们需要先构建一个字典(vocabulary),将每个词映射到一个唯一的索引编号. 在模型处理的时

DataWhale 动手学深度学习PyTorch版-task3+4+5:文本预处理;语言模型;循环神经网络基础

课程引用自伯禹平台:https://www.boyuai.com/elites/course/cZu18YmweLv10OeV <动手学深度学习>官方网址:http://zh.gluon.ai/ ——面向中文读者的能运行.可讨论的深度学习教科书. 第二次打卡: Task03: 过拟合.欠拟合及其解决方案:梯度消失.梯度爆炸:循环神经网络进阶 Task04:机器翻译及相关技术:注意力机制与Seq2seq模型:Transformer Task05:卷积神经网络基础:leNet:卷积神经网络进阶 有

【NLP】Tika 文本预处理:抽取各种格式文件内容

Tika常见格式文件抽取内容并做预处理 作者 白宁超 2016年3月30日18:57:08 摘要:本文主要针对自然语言处理(NLP)过程中,重要基础部分抽取文本内容的预处理.首先我们要意识到预处理的重要性.在大数据的背景下,越来越多的非结构化半结构化文本.如何从海量文本中抽取我们需要的有价值的知识显得尤为重要.另外文本格式常常不一,诸如:pdf,word,excl,xml,ppt,txt等常见文件类型你或许经过一番周折还是有办法处理的.倘若遇到database,html,邮件,RTF,图像,语音

自然语言处理之初始-语言模型

文本自然语言处理的一个最最最基本的一个问题:如何用数学符号或公式表示一段文本?如何计算一段文本在某种语言下出现的概率? 语言模型(用概率论的专业术语表示):为长度为m的字符串确定其概率分布P(w1,w2,...wm),其中w1到wm依次表示文本中的各个词语.概率值计算公式如下, 但是有个问题发现没有?加入一个文本超级长,会怎么样?从第三项开始计算难度就会很大.此时,有人提出了n元模型(n-gram model).那么n元模型是什么呢?它就是在估算条件概率时,忽略距离大于等于n的上文词的影响.则此

深度学习与自然语言处理之五:从RNN到LSTM

/* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 大纲如下: 1.RNN 2.LSTM 3.GRN 4.Attention Model 5.应用 6.探讨与思考 扫一扫关注微信号:"布洛卡区" ,深度学习在自然语言处理等智能应用的技术研讨与科普公众号.