Press "Enter" to skip to content

用双向LSTM掌握下一个单词预测:全面指南

介绍

识别下一个单词是下一个单词预测的任务,也被称为语言建模。自然语言处理的基准任务之一就是语言建模。在其最基本的形式中,它涉及根据给定的一串词语选择最有可能出现的下一个单词。语言建模在许多不同领域都有各种各样的应用。

学习目标

  • 认识统计分析、机器学习和数据科学中使用的各种模型背后的思想和原则。
  • 学习如何创建预测模型,包括回归、分类、聚类等,以根据数据生成精确的预测和类型。
  • 了解过拟合和欠拟合的原理,并学习如何使用准确率、精确度、召回率等指标评估模型性能。
  • 学习如何预处理数据并确定建模的相关特征。
  • 学习如何使用网格搜索和交叉验证调整超参数并优化模型。

本文作为数据科学博客马拉松的一部分发布。

语言建模的应用

以下是一些值得注意的语言建模应用:

手机键盘文本推荐

智能手机键盘上的一个功能称为手机键盘文本推荐,或者预测文本或自动建议,在您输入时建议单词或短语。它旨在加快输入速度,减少错误,并提供更准确和与上下文相关的建议。

也可阅读:构建基于内容的推荐系统

谷歌搜索自动完成

每次我们使用谷歌等搜索引擎搜索任何内容时,我们会得到许多想法,随着我们不断添加短语,推荐会变得越来越好,与当前搜索更相关。那么,这是如何实现的呢?

自然语言处理(NLP)技术使其成为可能。在这里,我们将使用自然语言处理(NLP)来创建一个预测模型,利用双向LSTM(长短期记忆)模型来预测句子的剩余部分。

了解更多:什么是LSTM?长短期记忆简介

导入必要的库和包

最好导入构建下一个单词预测模型所需的必要库和包。下面是你通常需要的一些库的示例:

import pandas as pd
import os
import numpy as np

import tensorflow as tf
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, LSTM, Dense, Bidirectional
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam

数据集信息

了解你正在处理的数据集的特征和属性需要知识。该数据集包含以下七篇2019年随机选择并发布的VoAGI文章:

  • Towards Data Science
  • UX Collective
  • The Startup
  • The Writing Cooperative
  • Data Driven Investor
  • Better Humans
  • Better Marketing

数据集链接:https://www.kaggle.com/code/ysthehurricane/next-word-prediction-bi-lstm-tutorial-easy-way/input

VoAGI_data = pd.read_csv('../input/medium-articles-dataset/medium_data.csv')
VoAGI_data.head()

在这里,我们有十个不同的字段和6508条记录,但我们只会使用标题字段来预测下一个单词。

print("记录数:", VoAGI_data.shape[0])
print("字段数:", VoAGI_data.shape[1])

通过查看和理解数据集信息,您可以为下一个单词预测挑战选择预处理过程、模型和评估指标。

显示各种文章的标题并对其进行预处理

让我们来看一些示例标题,以说明文章标题的准备工作:

VoAGI_data['title']

去除标题中不需要的字符和词语

对于预测任务中的文本数据预处理,有时需要从标题中删除不需要的字母和短语。不需要的字母和词语可能会给数据中带来噪音,增加不必要的复杂性,从而降低模型的性能和准确性。

  1. 不需要的字符:
    1. 标点符号:应该删除感叹号、问号、逗号和其他标点符号。通常情况下,可以安全地丢弃它们,因为它们通常对预测任务没有帮助。
    2. 特殊字符:删除非字母数字符号,如美元符号、@符号、井号和其他不必要的特殊字符,这些字符对于预测任务是不必要的。
    3. HTML标签:如果标题中有HTML标记或标签,请使用适当的工具或库来删除它们并提取文本。
  2. 不需要的词语:
    1. 停用词:删除常见的停用词,如“a”,“an”,“the”,“is”,“in”和其他频繁出现但不具有重要含义或预测能力的词语。
    2. 无关词汇:识别并删除与预测任务或领域无关的特定词汇。例如,如果要预测电影类型,则像“电影”或“影片”这样的词语可能不提供有用的信息。
VoAGI_data['title'] = VoAGI_data['title'].apply(lambda x: x.replace(u'\xa0',u' '))
VoAGI_data['title'] = VoAGI_data['title'].apply(lambda x: x.replace('\u200a',' '))

分词

分词将文本分割为标记、单词、子词或字符,并为每个标记分配一个唯一的ID或索引,从而创建一个词索引或词汇表。

分词过程包括以下步骤:

文本预处理:通过消除标点符号、将其转换为小写以及处理任何特定任务或领域需求来预处理文本。

分词:通过预定的规则或方法将预处理的文本分割成单独的标记。正则表达式、按空格分割和使用专门的分词器都是常见的分词技术。

增加词汇量:通过为每个标记分配一个唯一的ID或索引来创建一个词典,也称为词索引。在这个过程中,每个标题都被映射到相应的索引值。

tokenizer = Tokenizer(oov_token='<oov>') # 对于在word_index中找不到的单词
tokenizer.fit_on_texts(VoAGI_data['title'])
total_words = len(tokenizer.word_index) + 1

print("总单词数:", total_words)
print("单词:ID")
print("------------")
print("<oov>:", tokenizer.word_index['<oov>'])
print("强:", tokenizer.word_index['strong'])
print("和:", tokenizer.word_index['and'])
print("消费:", tokenizer.word_index['consumption'])

通过将文本转换为词汇表或词索引,可以创建一个查找表,将文本表示为一系列数字索引。文本中的每个唯一单词都会得到一个对应的索引值,从而可以进行进一步的处理或需要数值输入的建模操作。

将标题文本转换为序列并创建n-gram模型。

可以使用这些步骤构建基于标题序列的n-gram模型进行准确的预测:

  1. 将标题转换为序列:使用分词器将每个标题转换为标记字符串,或手动将每个滑块分隔为其组成的单词。为词典中的每个单词分配一个不同的编号。
  2. 生成n-gram:从序列中生成n-gram。连续的n个标题标记称为一个n-gram。
  3. 计算频率:确定每个n-gram在数据集中出现的频率。
  4. 构建n-gram模型:使用n-gram频率创建n-gram模型。该模型会跟踪给定前n-1个标记的每个标记的概率。这可以显示为查找表或字典。
  5. 预测下一个单词:可以使用n-gram模型识别n-1个标记序列中预期的下一个标记。为了做到这一点,需要在算法中找到概率,并选择具有最大可能性的标记。

了解更多:什么是N-grams以及如何在Python中实现它们?

您可以使用以下步骤构建一个n-gram模型,该模型利用标题序列来预测下一个单词或标记。根据训练数据,该方法可以生成准确的预测结果,因为它捕捉了标题语言使用中的统计关系和趋势。

input_sequences = []
for line in VoAGI_data['title']:
    token_list = tokenizer.texts_to_sequences([line])[0]
    #print(token_list)
    
    for i in range(1, len(token_list)):
        n_gram_sequence = token_list[:i+1]
        input_sequences.append(n_gram_sequence)

# print(input_sequences)
print("总输入序列数:", len(input_sequences))

使用填充使所有标题具有相同的长度

您可以按照以下步骤使用填充来确保每个标题具有相同的大小:

  • 通过比较所有其他标题,找到数据集中最长的标题。
  • 对每个标题重复此过程,将每个标题的长度与整体限制进行比较。
  • 当标题太短时,应使用特定的填充标记或字符进行扩展。
  • 对数据集中的每个标题再次进行填充过程。

填充将确保所有标题具有相同的长度,并为后处理或模型训练提供一致性。

# 填充序列
max_sequence_len = max([len(x) for x in input_sequences])
input_sequences = np.array(pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre'))
input_sequences[1]

准备特征和标签

在给定的场景中,如果我们将每个输入序列的最后一个元素视为标签,我们可以对标题进行独热编码,将其表示为与唯一单词总数相对应的向量。

# 创建特征和标签
xs,labels = input_sequences[:,:-1],input_sequences[:,-1]
ys = tf.keras.utils.to_categorical(labels,num_classes=total_words)


print(xs[5])
print(labels[5])
print(ys[5][14])

双向LSTM神经网络的架构

具有长短时记忆(LSTM)的循环神经网络(RNN)可以收集和保存跨广泛序列的信息。 LSTM网络使用专门的存储单元和门控技术来克服常规RNN的限制,常规RNN经常遇到梯度消失问题,并且难以保持长期依赖性。

LSTM网络的关键特征是细胞状态,它作为存储信息的单元可以随时间保留信息。细胞状态由三个主要的门控制:遗忘门、输入门和输出门。这些门控制着信息在LSTM细胞内的流动,允许网络在不同的时间步骤中有选择地记住或忘记信息。

了解更多:长短时记忆 | LSTM的架构

双向LSTM

双向LSTM神经网络模型训练

在训练双向LSTM(Bi-LSTM)神经网络模型时,必须遵循许多关键步骤。第一步是编译一个训练数据集,其中包含与之对应的输入和输出序列,指示下一个单词。文本数据必须经过预处理,分成单独的行,删除标点符号,并将大小写更改为小写。

model = Sequential()
model.add(Embedding(total_words, 100, input_length=max_sequence_len-1))
model.add(Bidirectional(LSTM(150)))
model.add(Dense(total_words, activation='softmax'))
adam = Adam(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])
history = model.fit(xs, ys, epochs=50, verbose=1)
#print model.summary()
print(model)

通过调用fit()方法,模型进行训练。训练数据包括输入序列(xs)和匹配的输出序列(ys)。模型通过50次迭代完成整个训练集的训练。在训练过程中,显示训练进度(verbose=1)。

绘制模型准确度和损失

绘制模型在训练过程中的准确性和损失可以提供有关其性能和训练进展的有见地的信息。预测值与实际值之间的错误或差异被称为损失。而模型生成的准确预测的百分比则被称为准确性。

import matplotlib.pyplot as plt


def plot_graphs(history, string):
    plt.plot(history.history[string])
    plt.xlabel("Epochs")
    plt.ylabel(string)
    plt.show()

plot_graphs(history, 'accuracy')

plot_graphs(history, 'loss')

预测标题的下一个单词

自然语言处理中一个有趣的挑战是猜测标题中的下一个单词。通过查找文本数据中的模式和相关性,模型可以提出最有可能的词语。这种预测能力使得文本建议系统和自动补全等应用成为可能。像RNN和基于Transformer的复杂方法可以提高准确性并捕捉上下文关系。

seed_text = "implementation of"
next_words = 2
  
for _ in range(next_words):
    token_list = tokenizer.texts_to_sequences([seed_text])[0]
    token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
    predicted = model.predict_classes(token_list, verbose=0)
    output_word = ""
    for word, index in tokenizer.word_index.items():
        if index == predicted:
            output_word = word
            break
    seed_text += " " + output_word
print(seed_text)

结论

总之,训练模型以预测一系列单词中的下一个单词是一项令人兴奋的自然语言处理挑战,被称为下一个单词预测。以下是结论的要点:

  • 强大的深度学习架构BI-LSTM用于顺序数据处理可以捕捉长距离关系和短语上下文。
  • 为了对BI-LSTM进行训练,需要对原始文本数据进行准备工作,包括标记化、词汇生成和文本向量化。
  • 创建损失函数、使用优化器构建模型、将其适配到预处理数据并在验证集上评估其性能是训练BI-LSTM模型的步骤。
  • BI-LSTM下一个单词预测需要结合理论知识和实践实验才能掌握。
  • 下一个单词预测模型的应用包括自动补全、语言生成和文本建议算法。

下一个单词预测的应用包括聊天机器人、机器翻译和文本补全。通过进一步的研究和改进,您可以创建更精确和上下文感知的下一个单词预测模型。

常见问题

本文中展示的媒体不属于Analytics Vidhya所有,仅由作者自行决定使用。

Leave a Reply

Your email address will not be published. Required fields are marked *