自然语言处理高级指南

自然语言处理高级指南' can be condensed to 'NLP高级指南'.

介绍

欢迎来到自然语言处理(NLP)的变革世界。在这里,人类语言的优雅与机器智能的精准相结合。NLP这个看不见的力量驱动着我们所依赖的许多数字交互。各种应用程序都使用了这个自然语言处理指南,例如回答你的问题的聊天机器人,根据语义定制结果的搜索引擎,以及为你设置提醒的语音助手。

在这个全面的指南中,我们将深入探讨NLP的多个领域,同时重点介绍正在改变业务和提高用户体验的最新应用。

理解上下文嵌入:单词不仅仅是离散的单位,它们的意义会随着上下文的变化而改变。我们将从静态嵌入(如Word2Vec)到需要上下文的交互式嵌入的演变来探讨。

Transformer和文本摘要的艺术:摘要是一项困难的工作,不仅仅是简单的文本截断。了解Transformer架构以及像T5这样的模型如何改变成功摘要的标准。

在深度学习时代,由于层次和复杂性,分析情感是具有挑战性的。了解深度学习模型,特别是基于Transformer架构的模型,如何熟练解释这些复杂的层次,以提供更详细的情感分析。

我们将使用Kaggle数据集“Airline_Reviews”来获取实用信息。该数据集充满了真实世界的文本数据。

学习目标

  • 认识从基于规则的系统到深度学习架构的转变,特别强调关键时刻。
  • 了解从静态词表示(如Word2Vec)到动态上下文嵌入的转变,强调上下文对语言理解的重要性。
  • 详细了解Transformer架构的内部工作原理,以及T5和其他模型如何改变文本摘要。
  • 了解深度学习,特别是基于Transformer的模型如何提供对文本情感的具体洞察。

本文是Data Science Blogathon的一部分。

深入探索NLP

自然语言处理(NLP)是人工智能的一个分支,专注于教会机器理解、解释和响应人类语言。这项技术连接人类和计算机,实现更自然的交互。可以在各种应用中使用NLP,从简单的拼写检查和关键词搜索到更复杂的操作,如机器翻译、情感分析和聊天机器人功能。它是允许语音激活的虚拟助手、实时翻译服务甚至内容推荐算法正常运行的技术。作为一个多学科领域,自然语言处理(NLP)结合了语言学、计算机科学和机器学习的见解,创建了能够理解文本数据的算法,成为当今人工智能应用的基石。

NLP技术的演变

NLP在多年的发展中取得了显著进步,从基于规则的系统发展到统计模型,最近又发展到深度学习。从传统的词袋模型(BoW)到Word2Vec,再到上下文嵌入,可以看到捕捉语言细节的旅程。随着计算能力和数据可用性的增加,NLP开始使用复杂的神经网络来理解语言的细微差别。现代的迁移学习技术使得模型能够在特定任务上取得改进,确保在实际应用中的效率和准确性。

Transformer的崛起

Transformer是一种神经网络架构,成为许多前沿NLP模型的基础。与之前严重依赖循环或卷积层的模型相比,Transformer使用一种称为“注意力”的机制来建立输入和输出之间的全局依赖关系。

Transformer的架构由编码器和解码器组成,每个组件都有多个相同的层。编码器将输入序列压缩成“上下文”或“记忆”,解码器使用该上下文或记忆生成输出。Transformer的独特之处在于其“自注意力”机制,在生成输出时对输入的各个部分进行加权,使模型能够关注重要的内容。

它们在NLP任务中被广泛使用,因为它们在各种数据转换任务中表现出色,包括但不限于机器翻译、文本摘要和情感分析。

使用BERT进行高级命名实体识别(NER)

命名实体识别(NER)是自然语言处理中的重要部分,涉及将文本中的命名实体识别并分类到预定义的类别中。传统的NER系统主要依赖基于规则和特征的方法。然而,随着深度学习的出现,特别是BERT(双向编码器表示来自Transformer的代表)这样的Transformer架构,NER的性能显著提高。

谷歌的BERT在大量文本上进行了预训练,并且可以为单词生成上下文嵌入。这意味着BERT可以理解单词出现的上下文,对于NER等需要上下文关键的任务非常有帮助。

使用BERT实现高级命名实体识别

  • 我们将通过使用BERT嵌入作为NER中的一种能力来受益于BERT理解上下文的能力。
  • SpaCy的NER系统基本上是一个序列标注机制。我们将使用BERT嵌入和spaCy架构来训练它,而不是使用常见的词向量。
import spacy
import torch
from transformers import BertTokenizer, BertModel
import pandas as pd

# 将航空公司评论数据集加载到DataFrame中
df = pd.read_csv('/kaggle/input/airline-reviews/Airline_Reviews.csv')

# 初始化BERT tokenizer和模型
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
model = BertModel.from_pretrained("bert-base-uncased")

# 初始化NER的spaCy模型
nlp = spacy.load("en_core_web_sm")

# 定义一个使用spaCy从文本中获取命名实体的函数
def get_entities(text):
    doc = nlp(text)
    return [(ent.text, ent.label_) for ent in doc.ents]

# 从DataFrame的前4条评论中提取并打印命名实体
for i, review in df.head(4).iterrows():
    entities = get_entities(review['Review'])
    print(f"评论 #{i + 1}:")
    for entity in entities:
        print(f"实体: {entity[0]}, 类别: {entity[1]}")
    print("\n")

'''这段代码加载了一个航空公司评论的数据集,初始化了BERT和spaCy模型,
然后从前四条评论中提取并打印命名实体。
'''
输出

上下文嵌入及其重要性

在传统的Word2Vec或GloVe等嵌入中,一个词在任何上下文中总是具有相同的向量表示。这并不能准确地表示词的多个含义。上下文嵌入已成为绕过这个限制的一种流行方式。

与Word2Vec相比,上下文嵌入根据其上下文来捕捉词的含义,允许灵活的词表示。例如,在句子“I sat by the river bank”和“I went to the bank”中,“bank”这个词的含义是不同的。不断变化的描绘产生更准确的理论,特别是对于需要细致理解的任务。模型理解常用短语、同义词和其他语言结构的能力正在提高,而这些以前对机器来说很难理解。

使用BERT和T5进行Transformer和文本摘要

Transformer架构从根本上改变了自然语言处理的领域,使得BERT、GPT-2和T5等模型的发展成为可能。这些模型使用注意机制来评估序列中不同词语的相对权重,从而对文本进行高度的上下文和细致的理解。

T5(文本到文本转换Transformer)通过将每个NLP问题视为文本到文本问题来概括这个思想,而BERT是一种有效的摘要模型。例如,翻译涉及将英文文本转换为法文文本,而摘要则涉及对长文本进行减少。因此,T5非常适应各种任务。可以使用T5的统一系统进行各种任务的训练,可能利用一个任务的信息来训练另一个任务。

使用T5进行实现

import pandas as pd
from transformers import T5Tokenizer, T5ForConditionalGeneration

# 将航空公司评论数据集加载到DataFrame中
df = pd.read_csv('/kaggle/input/airline-reviews/Airline_Reviews.csv')

# 初始化T5 tokenizer和模型(此处使用't5-small'作为示例)
model_name = "t5-small"
model = T5ForConditionalGeneration.from_pretrained(model_name)
tokenizer = T5Tokenizer.from_pretrained(model_name)

# 定义一个使用T5模型进行文本摘要的函数
def summarize_with_t5(text):
    input_text = "summarize: " + text
    # 对输入文本进行分词并生成摘要
    input_tokenized = tokenizer.encode(input_text, return_tensors="pt", max_length=512, truncation=True)
    summary_ids = model.generate(input_tokenized, max_length=100, min_length=5, length_penalty=2.0, num_beams=4, early_stopping=True)
    return tokenizer.decode(summary_ids[0], skip_special_tokens=True)

# 对DataFrame中的前5条评论进行摘要并打印
for i, row in df.head(5).iterrows():
    summary = summarize_with_t5(row['Review'])
    print(f"摘要 {i+1}:\n{summary}\n")
    print("-" * 50)

''' 此代码加载了一个航空公司评论数据集,初始化了T5模型和tokenizer,
然后为前五条评论生成并打印了摘要。
'''
输出

代码成功执行后,可以明显看到生成的摘要既简洁又成功地传达了原始评论的主要观点。这显示了T5模型理解和评估数据的能力。由于其在文本摘要方面的有效性和能力,该模型是自然语言处理领域中最受追捧的模型之一。

深度学习的高级情感分析洞察

除了将情感简单地分类为正面、负面或中性,我们还可以深入挖掘更具体的情感,并甚至确定这些情感的强度。将BERT的能力与额外的深度学习层结合起来,可以创建出一种提供更深入洞察的情感分析模型。

现在,我们将研究数据集中情感如何在各个评论中变化,以发现评论特征中的模式和趋势。

使用BERT实现高级情感分析

数据准备

在开始建模过程之前,对数据进行准备是至关重要的。这包括加载数据集、处理缺失值,并将未处理的数据转换为适合进行情感分析的格式。在这个例子中,我们将航空公司评论数据集中的Overall_Rating列转换为情感类别。在训练情感分析模型时,我们将使用这些类别作为目标标签。

import pandas as pd

# 加载数据集
df = pd.read_csv('/kaggle/input/airline-reviews/Airline_Reviews.csv')

# 将'n'值转换为NaN,然后将列转换为数值数据类型
df['Overall_Rating'] = pd.to_numeric(df['Overall_Rating'], errors='coerce')

# 删除Overall_Rating列中的NaN值行
df.dropna(subset=['Overall_Rating'], inplace=True)

# 将评分转换为多类别类别
def rating_to_category(rating):
    if rating <= 2:
        return "非常负面"
    elif rating <= 4:
        return "负面"
    elif rating == 5:
        return "中性"
    elif rating <= 7:
        return "正面"
    else:
        return "非常正面"

# 应用函数创建一个'Sentiment'列
df['Sentiment'] = df['Overall_Rating'].apply(rating_to_category)

分词

通过分词过程,将文本转化为标记。模型使用这些标记作为输入。我们将使用DistilBERT tokenizer进行分词处理,以提高准确性和性能。借助这个分词器,我们的评论将被转换为DistilBERT模型能理解的格式。

from transformers import DistilBertTokenizer

# 使用'distilbert-base-uncased'预训练模型初始化DistilBert tokenizer
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')

数据集和数据加载器

我们必须实现PyTorch的Dataset和DataLoader类,以便有效地训练和评估我们的模型。DataLoader将允许我们对数据进行分批处理,加速训练过程,而Dataset类将帮助我们组织数据和标签。

from torch.utils.data import Dataset, DataLoader
from sklearn.model_selection import train_test_split

# 为情感分析定义自定义的Dataset类
class SentimentDataset(Dataset):
    def __init__(self, reviews, labels):
        self.reviews = reviews
        self.labels = labels
        self.label_dict = {"非常消极": 0, "消极": 1, "中性": 2,
                           "积极": 3, "非常积极": 4}
    
    # 返回样本总数
    def __len__(self):
        return len(self.reviews)
    
    # 获取给定索引处的样本和标签
    def __getitem__(self, idx):
        review = self.reviews[idx]
        label = self.label_dict[self.labels[idx]]
        tokens = tokenizer.encode_plus(review, add_special_tokens=True,
        max_length=128, pad_to_max_length=True, return_tensors='pt')
        return tokens['input_ids'].view(-1), tokens['attention_mask'].view(-1),
         torch.tensor(label)

# 将数据集拆分为训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)

# 创建训练集的DataLoader
train_dataset = SentimentDataset(train_df['Review'].values, train_df['Sentiment'].values)
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)

# 创建测试集的DataLoader
test_dataset = SentimentDataset(test_df['Review'].values, test_df['Sentiment'].values)
test_loader = DataLoader(test_dataset, batch_size=16, shuffle=False)

'''该代码定义了一个用于情感分析的自定义PyTorch Dataset类,并为训练和测试数据集创建了DataLoader。
'''

模型初始化和训练

我们现在可以使用准备好的数据初始化DistilBERT模型,进行序列分类。根据我们的数据集,我们将训练这个模型,并修改其权重以预测航空评论的情感。

from transformers import DistilBertForSequenceClassification, AdamW
from torch.nn import CrossEntropyLoss

# 使用5个标签初始化DistilBERT序列分类模型
model = DistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased',
num_labels=5)

# 初始化AdamW优化器进行训练
optimizer = AdamW(model.parameters(), lr=1e-5)

# 定义交叉熵损失函数
loss_fn = CrossEntropyLoss()

# 进行3轮训练
for epoch in range(3):
    for batch in train_loader:
        # 从DataLoader批次中解包输入和标签张量
        input_ids, attention_mask, labels = batch
        
        # 梯度归零
        optimizer.zero_grad()
        
        # 前向传播:获取模型的预测结果
        outputs = model(input_ids, attention_mask=attention_mask)
        
        # 计算预测结果和实际标签之间的损失
        loss = loss_fn(outputs[0], labels)
        
        # 反向传播:计算梯度
        loss.backward()
        
        # 更新模型参数
        optimizer.step()

'''该代码初始化了一个DistilBERT序列分类模型,设置了AdamW优化器和交叉熵损失函数,
然后对模型进行了3轮训练。
'''

评估

在训练后,我们必须评估模型在未测试数据上的性能。这将帮助我们确定模型在实际情况下的工作效果如何。

correct_predictions = 0
total_predictions = 0

# 将模型设置为评估模式
model.eval()

# 关闭梯度计算,因为我们只进行推断
with torch.no_grad():
    # 在测试DataLoader中循环遍历批次
    for batch in test_loader:
        # 从DataLoader批次中解包输入和标签张量
        input_ids, attention_mask, labels = batch

        # 获取模型的预测结果
        outputs = model(input_ids, attention_mask=attention_mask)

        # 获取预测的标签
        _, preds = torch.max(outputs[0], dim=1)

        # 统计正确预测的数量
        correct_predictions += (preds == labels).sum().item()

        # 统计总的预测数量
        total_predictions += labels.size(0)

# 计算准确率
accuracy = correct_predictions / total_predictions

# 打印准确率
print(f"准确率: {accuracy * 100:.2f}%")

'''该代码片段评估了在测试数据集上训练的模型,并打印了整体准确率。
'''
  • 输出:准确率:87.23%

部署

一旦我们对模型的性能满意,我们就可以将其保存起来。这样可以在各种平台或应用程序上使用该模型。

# 将训练好的模型保存到磁盘
model.save_pretrained("/kaggle/working/")

# 将分词器保存到磁盘
tokenizer.save_pretrained("/kaggle/working/")

''' 此代码片段将训练好的模型和分词器保存到指定目录供将来使用。
'''

推理

让我们使用样本评论的情绪来训练我们的训练模型以预测它。这展示了如何使用模型进行实时情绪分析。

# 预测给定评论的情绪的函数
def predict_sentiment(review):
    # 对输入评论进行分词
    tokens = tokenizer.encode_plus(review, add_special_tokens=True, max_length=128, 
    pad_to_max_length=True, return_tensors='pt')
    
    # 运行模型进行预测
    with torch.no_grad():
        outputs = model(tokens['input_ids'], attention_mask=tokens['attention_mask'])
    
    # 获取具有最大预测值的标签
    _, predicted_label = torch.max(outputs[0], dim=1)
    
    # 定义一个将数字标签映射到字符串标签的字典
    label_dict = {0: "非常负面", 1: "负面", 2: "中性", 3: "正面", 
    4: "非常正面"}
    
    # 返回预测的标签
    return label_dict[predicted_label.item()]

# 样本评论
review_sample = "航班太棒了,工作人员非常友好。"

# 预测样本评论的情绪
sentiment_sample = predict_sentiment(review_sample)

# 打印预测的情绪
print(f"预测的情绪:{sentiment_sample}")

''' 此代码片段定义了一个预测给定评论情绪的函数,并在一个样本评论上演示了它的用法。
'''
  • 输出:预测的情绪:非常正面

自然语言处理中的迁移学习

自然语言处理(NLP)在迁移学习的推动下经历了一场革命,它使得模型能够利用一项任务的先前知识并将其应用于新的相关任务。研究人员和开发人员现在可以对预训练模型进行微调,以适应特定任务,例如情感分析或命名实体识别,而无需从头开始训练模型,这通常需要大量数据和计算资源。这些预训练模型经常在大规模语料库(如整个维基百科)上进行训练,它们捕捉到了复杂的语言模式和关系。迁移学习使得NLP应用程序能够更快地运行,需要更少的数据,并经常具有最先进的性能,为更广泛的用户和任务提供了卓越的语言模型。

结论

传统语言学方法和现代深度学习技术的融合为快速发展的NLP领域带来了前所未有的进步。我们不断推动机器理解和处理人类语言的界限。从利用嵌入来理解上下文的微妙之处,到利用BERT和T5等Transformer架构的强大能力。特别是迁移学习使得使用高性能模型更加容易,降低了门槛并促进了创新。随着提出的主题,清楚地表明人类语言能力和机器计算能力之间的不断互动有望在不久的将来使机器不仅能够理解,还能够理解人类语言的微妙之处。

主要观点

  • 上下文嵌入使得NLP模型能够理解单词与其周围环境的关系。
  • Transformer架构显著提升了NLP任务的能力。
  • 迁移学习提高了模型的性能,无需进行大量训练。
  • 深度学习技术,特别是基于Transformer的模型,为文本数据提供了细致入微的洞察力。

常见问题

本文中显示的媒体不归Analytics Vidhya所有,仅在作者的自由裁量下使用。