【python】使用Python和BERT进行文本择要:从数据预处理到模子训练与天生 ...

打印 上一主题 下一主题

主题 1475|帖子 1475|积分 4425

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!
解锁Python编程的无穷大概:《奥妙的Python》带你漫游代码世界
随着信息爆炸期间的到来,海量文本数据的高效处理与理解成为亟待解决的题目。文本择要作为天然语言处理(NLP)中的关键任务,旨在自动天生简明扼要的文本择要,资助用户快速获取关键信息。近年来,基于深度学习的预训练语言模子,尤其是BERT(Bidirectional Encoder Representations from Transformers),在文本理解和天生任务中取得了显着进展。本文深入探讨了怎样使用Python和BERT模子进行文本择要,包括数据预处理、模子构建与训练、择要天生及结果评估等环节。首先,先容了文本择要的基本概念及其在实际应用中的重要性。随后,详细论述了BERT模子的架构及其在文本择要任务中的应用原理。接着,通过实际案例,展示了怎样使用Python进行数据清洗与预处理,并使用Hugging Face的Transformers库构建和训练基于BERT的文本择要模子。文章还涵盖了天生择要的详细方法,包括抽取式和天生式择要技术,并联合代码示例进行详细说明。末了,探讨了模子评估指标及优化计谋,旨在为研究人员和开发者提供一套完备的基于BERT的文本择要解决方案,助力其在信息提取与内容天生领域的创新与实践。
引言

在当今信息爆炸的期间,海量的文本数据如消息报道、学术论文、交际媒体内容等以惊人的速度涌现。怎样高效地从这些海量数据中提取关键信息,成为了天然语言处理(NLP)领域的重要研究方向之一。文本择要作为NLP中的核心任务,旨在自动天生简明扼要的文本择要,资助用户快速获取所需信息,提升信息处理的效率和结果。
传统的文本择要方法主要分为抽取式择要和天生式择要两类。抽取式择要通过从原文中直接提取关键句子或片段来构建择要,而天生式择要则尝试理解原文内容,天生新的句子来表达核心信息。随着深度学习技术的迅猛发展,基于神经网络的文本择要方法渐渐成为研究热门,尤其是预训练语言模子的应用,为文本择要任务带来了革命性的突破。
BERT(Bidirectional Encoder Representations from Transformers)作为一种基于Transformer架构的双向编码器表示模子,自推出以来在多个NLP任务中表现出色。其强盛的语义理解能力使其在文本择要任务中具备巨大的潜力。然而,怎样有用地使用BERT进行文本择要,包括数据预处理、模子构建与训练、择要天生及结果评估,仍然是一个值得深入探讨的题目。
本文旨在系统地先容怎样使用Python和BERT模子进行文本择要任务。通过详细的理论解析与丰富的代码示例,展示从数据预处理到模子训练,再到择要天生的完备流程。同时,探讨模子评估与优化计谋,资助读者全面把握基于BERT的文本择要技术,推动其在实际应用中的落地与创新。
BERT模子概述

Transformer架构

Transformer架构由Vaswani等人于2017年提出,是一种完全基于留意力机制(Attention Mechanism)的神经网络模子,广泛应用于各种NLP任务。与传统的循环神经网络(RNN)相比,Transformer具有更高的并行化能力和更好的长距离依赖建模能力。Transformer主要由编码器(Encoder)和解码器(Decoder)两部分构成,每部分由多个雷同的层(Layer)堆叠而成。
每个编码器层包含两个子层:多头自留意力机制(Multi-Head Self-Attention)和前馈全连接网络(Feed-Forward Neural Network)。每个解码器层则在此底子上增长了一个编码器-解码器留意力机制(Encoder-Decoder Attention)。这种设计使得Transformer在处理序列到序列(Sequence-to-Sequence)任务时表现尤为出色。
BERT模子

BERT(Bidirectional Encoder Representations from Transformers)是Google于2018年提出的预训练语言模子,基于Transformer的编码器部分。BERT的核心创新在于其双向性,即在进行词表示学习时同时思量左右上下文信息,这一特性显着提升了模子的语义理解能力。
BERT通过两个主要任务进行预训练:掩蔽语言模子(Masked Language Model, MLM)和下一句猜测(Next Sentence Prediction, NSP)。MLM任务随机掩蔽输入句子中的一些词汇,模子需根据上下文猜测被掩蔽的词;NSP任务则要求模子判定两句话是否在原文中相邻。这两种任务共同训练出具有深厚语义理解能力的语言表示。
BERT在文本择要中的应用

在文本择要任务中,BERT可以作为编码器,用于理解输入文本的语义信息。联合解码器部分,BERT可以被扩展为天生式择要模子。此外,基于BERT的预训练模子,如BERTSUM,通过调解模子结构和训练目的,专门用于择要天生,取得了良好的结果。
然而,直接使用BERT进行文本择要存在一些挑战,包括天生的择要质量、模子的训练效率以及对大规模数据的顺应能力。本文将探讨怎样通过数据预处理、模子构建与训练、择要天生等步骤,充分发挥BERT在文本择要任务中的潜力。
数据预处理

数据集选择

文本择要任务需要大量的带有择要的文本对作为训练数据。常用的数据集包括:

  • CNN/Daily Mail:包含消息文章及其择要,广泛用于文本择要任务。
  • DUC:由美国国家尺度与技术研究院(NIST)组织的文档理解评估会议提供的数据集。
  • Gigaword:包含大量的消息择要数据,适用于训练大规模择要模子。
本文以CNN/Daily Mail数据集为例,展示数据预处理的详细步骤。
数据清洗与格式化

数据预处理的主要目的是将原始数据转化为模子可以担当的格式,包括去除噪声、统一文本格式、分割训练与测试集等。以下是详细的代码实现:
  1. import os
  2. import re
  3. import json
  4. import pandas as pd
  5. from tqdm import tqdm
  6. # 定义数据集路径
  7. DATA_DIR = 'cnn_dm_dataset'
  8. TRAIN_FILE = os.path.join(DATA_DIR, 'train.json')
  9. VALID_FILE = os.path.join(DATA_DIR, 'valid.json')
  10. TEST_FILE = os.path.join(DATA_DIR, 'test.json')
  11. # 检查数据文件是否存在
  12. for file in [TRAIN_FILE, VALID_FILE, TEST_FILE]:
  13.     if not os.path.exists(file):
  14.         raise FileNotFoundError(f'文件 {
  15.      file} 不存在,请检查数据集路径。')
  16. # 加载数据
  17. def load_data(file_path):
  18.     """
  19.     加载JSON格式的数据
  20.     参数:
  21.     file_path -- 数据文件路径
  22.     返回:
  23.     texts -- 原文列表
  24.     summaries -- 摘要列表
  25.     """
  26.     texts = []
  27.     summaries = []
  28.     with open(file_path, 'r', encoding='utf-8') as f:
  29.         for line in tqdm(f, desc=f'加载 {
  30.      file_path}'):
  31.             data = json.loads(line)
  32.             text = data['article']
  33.             summary = data['highlights']
  34.             texts.append(text)
  35.             summaries.append(summary)
  36.     return texts, summaries
  37. # 加载训练、验证和测试集
  38. train_texts, train_summaries = load_data(TRAIN_FILE)
  39. valid_texts, valid_summaries = load_data(VALID_FILE)
  40. test_texts, test_summaries = load_data(TEST_FILE)
  41. # 数据示例
  42. print(f'训练集样本数: {
  43.      len(train_texts)}')
  44. print(f'验证集样本数: {
  45.      len(valid_texts)}')
  46. print(f'测试集样本数: {
  47.      len(test_texts)}')
  48. # 数据清洗函数
  49. def clean_text(text):
  50.     """
  51.     清洗文本数据,去除特殊字符和多余空格
  52.     参数:
  53.     text -- 输入文本
  54.     返回:
  55.     清洗后的文本
  56.     """
  57.     # 去除特殊字符
  58.     text = re.sub(r'[^A-Za-z0-9\s,.!?\'"-]', '', text)
  59.     # 替换多个空格为一个空格
  60.     text = re.sub(r'\s+', ' ', text)
  61.     return text.strip()
  62. # 清洗所有数据
  63. train_texts = [clean_text(text) for text in tqdm(train_texts, desc='清洗训练集')]
  64. valid_texts = [clean_text(text) for text in tqdm(valid_texts, desc='清洗验证集')]
  65. test_texts = [clean_text(text) for text in tqdm(test_texts, desc='清洗测试集')]
  66. train_summaries = [clean_text(summary) for summary in tqdm(train_summaries, desc='清洗训练集摘要')]
  67. valid_summaries = [clean_text(summary) for summary in tqdm(valid_summaries, desc='清洗验证集摘要')]
  68. test_summaries = [clean_text(summary) for summary in tqdm(test_summaries, desc='清洗测试集摘要')]
  69. # 将清洗后的数据保存为CSV文件,便于后续处理
  70. def save_to_csv(texts, summaries, file_name):
  71.     """
  72.     将文本和摘要保存为CSV文件
  73.     参数:
  74.     texts -- 原文列表
  75.     summaries -- 摘要列表
  76.     file_name -- 输出文件名
  77.     """
  78.     df = pd.DataFrame({
  79.    'text': texts, 'summary': summaries})
  80.     df.to_csv(file_name, index=False, encoding='utf-8')
  81.     print(f'已保存到 {
  82.      file_name}')
  83. # 保存数据
  84. save_to_csv(train_texts, train_summaries, 'train_clean.csv')
  85. save_to_csv(valid_texts, valid_summaries, 'valid_clean.csv')
  86. save_to_csv(test_texts, test_summaries, 'test_clean.csv')
复制代码
数据分词与编码

在使用BERT进行文本择要任务之前,需要对文本进行分词和编码。BERT使用WordPiece分词器,将词汇拆分为更小的子词单位,以处理未登录词和多样化的词汇形式。以下是详细的实当代码:
  1. from transformers import BertTokenizer
  2. # 加载预训练的BERT分词器
  3. tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
  4. # 定义最大序列长度
  5. MAX_INPUT_LENGTH = 512
  6. MAX_SUMMARY_LENGTH = 128
  7. # 分词和编码函数
  8. def tokenize_and_encode(texts, summaries, tokenizer, max_input_len=MAX_INPUT_LENGTH, max_summary_len=MAX_SUMMARY_LENGTH):
  9.     """
  10.     对文本和摘要进行分词和编码
  11.     参数:
  12.     texts -- 原文列表
  13.     summaries -- 摘要列表
  14.     tokenizer -- BERT分词器
  15.     max_input_len -- 原文最大长度
  16.     max_summary_len -- 摘要最大长度
  17.     返回:
  18.     input_ids -- 原文的编码
  19.     attention_masks -- 原文的注意力掩码
  20.     summary_ids -- 摘要的编码
  21.     summary_attention_masks -- 摘要的注意力掩码
  22.     """
  23.     input_ids = []
  24.     attention_masks = []
  25.     summary_ids = []
  26.     summary_attention_masks = []
  27.     for text, summary in tqdm(zip(texts, summaries), total=len(texts), desc='分词和编码'):
  28.         # 编码原文
  29.         encoded_dict = tokenizer.encode_plus(
  30.             text,
  31.             add_special_tokens=True,
  32.             max_length=max_input_len,
  33.             padding='max_length',
  34.             truncation=True,
  35.             return_attention_mask=True,
  36.             return_tensors='pt'
  37.         )
  38.         input_ids.append(encoded_dict['input_ids'])
  39.         attention_masks.append(encoded_dict['attention_mask'])
  40.         # 编码摘要
  41.         summary_encoded = tokenizer.encode_plus(
  42.             summary,
  43.             add_special_tokens=True,
  44.             max_length=max_summary_len,
  45.             padding='max_length',
  46.             truncation=True,
  47.             return_attention_mask=True,
  48.             return_tensors='pt'
  49.         )
  50.         summary_ids.append(summary_encoded['input_ids'])
  51.         summary_attention_masks.append(summary_encoded['attention_mask'])
  52.     # 将列表转换为张量
  53.     input_ids = torch.cat(input_ids, dim=0)
  54.     attention_masks = torch.cat(attention_masks, dim=0)
  55.     summary_ids = torch.cat(summary_ids, dim=0)
  56.     summary_attention_masks = torch.cat(summary_attention_masks, dim=0)
  57.     return input_ids, attention_masks, summary_ids, summary_attention_masks
  58. import torch
  59. # 进行分词和编码
  60. train_inputs, train_masks, train_summaries_ids, train_summaries_masks = tokenize_and_encode(
  61.     train_texts, train_summaries, tokenizer
  62. )
  63. valid_inputs, valid_masks, valid_summaries_ids, valid_summaries_masks = tokenize_and_encode(
  64.     valid_texts, valid_summaries, tokenizer
  65. )
  66. test_inputs, test_masks, test_summaries_ids, test_summaries_masks = tokenize_and_encode(
  67.     test_texts, test_summaries, tokenizer
  68. )
  69. # 查看编码结果
  70. print('原文编码示例:', train_inputs[0])
  71. print('摘要编码示例:', train_summaries_ids[0])
复制代码
构建数据加载器

为了高效地将数据输入模子进行训练,需要构建适当的数据加载器。以下代码展示了怎样使用PyTorch的Dataset和DataLoader类进行数据封装:
  1. from torch.utils.data import Dataset, DataLoader
  2. class SummarizationDataset(Dataset):
  3.     """
  4.     自定义数据集类,用于文本摘要任务
  5.     """
  6.     def __init__(self, input_ids, attention_masks, summary_ids, summary_attention_masks):
  7.         self.input_ids = input_ids
  8.         self.attention_masks = attention_masks
  9.         self.summary_ids = summary_ids
  10.         self.summary_attention_masks = summary_attention_masks
  11.     def __len__(self):
  12.         return len(self.input_ids)
  13.     def __getitem__(self, idx):
  14.         return {
  15.    
  16.             'input_ids': self.input_ids[idx],
  17.             'attention_mask': self.attention_masks[idx],
  18.             'summary_ids': self.summary_ids[idx],
  19.             'summary_attention_mask': self.summary_attention_masks[idx]
  20.         }
  21. # 创建数据集对象
  22. train_dataset = SummarizationDataset(train_inputs, train_masks, train_summaries_ids, train_summaries
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

光之使者

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表