如何处理我们的文本数据成构建词表

我们拿到在拿到一堆语料数据,或者是在网络中爬取下来的文本数据如何处理成为模型能够训练的数据呢?这里有我们先经过停用词和按字分词的处理之后,得到的问答对文本数据,input_by_word.txt target_by_word.txt 。其中,input_by_word.txt 里面存放问题,如下:

target_by_word.txt 里面存放回答,如下:

对应行组成一个问答对(qa_pair)。

我们的目的是把一行中文句子转换为对应的一行数字,每一个字对应的数字都应该是独一无二的,比如,['不', '是'] 会对应的转换为 [ 6, 4 ]这样的形式。那么我们可以通过构建字典来完成这种映射关系,即 {..., '不': 6, '是': 4 ,...},另外,我们还需要将模型的输出转换回原本的句子的形式,即将 [ 6, 4 ] 转换为 ['不', '是'] ,所以我们还需要实现反转字典,即 {... , 6 : 不', 4 : '是' , ...} 

我们可以把每个字作为一个词元,统计这个词元在 input_by_word.txt target_by_word.txt 里出现的频率,根据词元的频率排序得到一个词典,或者是分别对input_by_word.txt target_by_word.txt 里面词元出现的频率,根据频率排序,得到 input_by_word.txt 对应的词典 和 target_by_word.txt 对应的词典。另外,我们的词典中还包含几个特殊词元应对不同情况的需要,如未知词元<"UNK">等。假设我们通过按行遍历的方式,拿到了每一行的句子(sentence),通过对每一行句子进行处理,即目前待处理的数据是这种形式为 list :['是', '王', '若', '猫', '的' ] 。

class Wordsequence():PAD_TAG = "PAD"PAD = 0UNK_TAG = "UNK"UNK = 1SOS_TAG = "SOS"SOS = 2EOS_TAG = "EOS"EOS = 3def __init__(self):self.dict = {self.PAD_TAG: self.PAD,self.UNK_TAG: self.UNK,self.SOS_TAG: self.SOS,self.EOS_TAG: self.EOS}self.inverse_dict = {}  # 反转字典self.count = {} # 用于记录词频def fit(self, sentence):"""词频统计:param sentence: list:return:"""for word in sentence:self.count[word] = self.count.get(word, 0) + 1

记录完所有词元的出现次数,我们着手构建词表,可以规定词元的最大频率 max_count 和最小频率 min_count ,以及词表最大容量 max_features ,通常我们最大词频对最大词频不做限制,对小于最小词频的词元不记录在字典,统一用 <'UNK'> 替代,另外还可以按照词频降序排序。下面我们实现了构建词典和反转词典的方法:

    def build_vocab(self, min_count=5, max_count=None, max_features=None):"""构建词典:param min_count: 最小词频:param max_count: 最大词频:param max_features: 最大词元数:return:"""# 字典在遍历的过程中无法改变temp = self.count.copy()for key in temp:cur_count = self.count.get(key, 0)if min_count is not None:if cur_count < min_count:del self.count[key]if max_count is not None:if cur_count > max_count:del self.count[key]if max_features is not None:self.count = (sorted(self.count.items(), key=lambda x: x[1], reverse=True)[:max_features])for key in self.count:self.dict[key] = len(self.dict)self.inverse_dict = zip(self.dict.values(), self.dict.keys())

我们构建的两个词典分别如下:

input :{'PAD': 0, 'UNK': 1, 'SOS': 2, 'EOS': 3, '呵': 4, '不': 5, '是': 6, '怎': 7, '么': 8, '了': 9, ...}

target:{'PAD': 0, 'UNK': 1, 'SOS': 2, 'EOS': 3, '是': 4, '王': 5, '若': 6, '猫': 7, '的': 8, '。': 9,  ...}

        在我们得到了词典之后我们就可以依次把每个句子映射为序列了。

在这里我们把句子转换为序列

    def transform(self, sentence, max_len, add_eos=False):"""把sentence转化为数值序列当add_eos=False时,sentence长度会是max_len当add_eos=True时,sentence长度会是max_len+1:param sentence::param max_len::param add_eos: add_eos=True使用 --> 也就是说输出长度会是max_len+1add_eos=False中使用 --> 也就是说输出长度会是max_len:return:"""# 把sentence长度固定为一致if len(sentence) > max_len:sentence = sentence[:max_len]sentence_len = len(sentence)  # 提前计算句子长度,实现add_eos后,句子长度还是一致if add_eos:sentence = sentence+[self.EOS_TAG]if sentence_len < max_len:sentence = sentence + [self.PAD_TAG]*(max_len-sentence_len)result = [self.dict.get(i, self.UNK) for i in sentence]  # 若在字典中未出现则用UNK字符替代return result

以及将序列反转回句子的形式和整个词典的大小:

    def inverse_transform(self, indices):"""把序列转为sentence:param indices: 序列:return: list 不包含有EOS的词元"""result = []for i in indices:if i == self.EOS:breakresult.append(self.inverse_dict.get(i, self.UNK_TAG))return resultdef __len__(self):return len(self.dict)  # 返回词典大小

至此我们完成了构建词典和序列化句子所需要的函数。并通过 pickle 保存把词典保存为pkl文件,在重新加载pkl的时候需要把该类重新导入一下。

def save_ws():ws = Wordsequence()for line in open(config.chatbot_input_by_word_path, encoding="utf-8").readlines():ws.fit(line.strip().split())ws.build_vocab()print(ws.dict, len(ws))pickle.dump(ws, open(config.chatbot_ws_input_by_word_path, "wb"))ws = Wordsequence()for line in open(config.chatbot_target_by_word_path, encoding="utf-8").readlines():ws.fit(line.strip().split())ws.build_vocab()print(ws.dict, len(ws))pickle.dump(ws, open(config.chatbot_ws_target_by_word_path, "wb"))

我们现在要将文本数据变成这种形式为 list :['是', '王', '若', '猫', '的' ] 。我们在构建 dataset 的时候处理:

class ChatbotDataset(Dataset):def __init__(self):self.input_path = config.chatbot_input_by_word_pathself.target_path = config.chatbot_target_by_word_pathself.input_lines = open(self.input_path, encoding="utf-8").readlines()self.target_lines = open(self.target_path, encoding="utf-8").readlines()# 确保文本数据input 和 target数量一致assert len(self.input_lines) == len(self.target_lines), "input和target长度一致"def __getitem__(self, idx):input = self.input_lines[idx].strip().split()  # 按空格切分为列表target = self.target_lines[idx].strip().split()input_length = len(input)  # input的句子真实长度target_length = len(target)  # target的句子真实长度return input, target, input_length, target_lengthdef __len__(self):return len(self.input_lines)

然后重写DataLoader的 collate_fn 函数:

def collate_fn(batch):"""重写cllate_fn:param batch: [(input, target, input_length, target_length),(input, target, input_length, target_length),...]:return:"""# 对input的句子,按句子长度降序排序sorted(batch, key=lambda x: x[2], reverse=True)input, target, input_length, target_length = zip(*batch)input = [config.chatbot_ws_by_word_input.transform(i, max_len=config.chatbot_input_max_seq_len) for i in input]target = [config.chatbot_ws_by_word_target.transform(i, max_len=config.chatbot_target_max_seq_len, add_eos=True) for i in target]input = torch.LongTensor(input)target = torch.LongTensor(target)input_length = torch.LongTensor(input_length)target_length = torch.LongTensor(target_length)return input, target, input_length, target_length
train_data_loader = DataLoader(ChatbotDataset(),batch_size=config.chatbot_batch_size,shuffle=True, collate_fn=collate_fn)
if __name__ == '__main__':for idx, (input, target, input_length, target_length) in enumerate(train_data_loader):print(idx)print(input, target, input_length, target_length)break

最后我们可以的到序列化后的数据:

0
tensor([[ 22,  59, 311,  ...,   0,   0,   0],[ 19, 482,   9,  ...,   0,   0,   0],[617, 807,   0,  ...,   0,   0,   0],...,[670, 671,  17,  ...,   0,   0,   0],[ 30, 349, 764,  ...,   0,   0,   0],[220, 955,   6,  ...,   0,   0,   0]]) 
tensor([[ 582,  218,  386,  ...,    0,    0,    0],[1740,    3,    0,  ...,    0,    0,    0],[ 304,  578,  859,  ...,    0,    0,    0],...,[1852,   25,  131,  ...,    0,    0,    0],[  70,  265,   23,  ...,    0,    0,    0],[ 297,    4,   56,  ...,   74, 1362,    3]]) 
tensor([ 9,  3,  2, 11, 18,  3,  3,  5, 10,  7, 10,  1,  9,  4,  2,  5,  7, 77,45,  2, 15,  2,  3, 12, 11,  4,  5,  4, 45,  3, 12,  2,  5,  9,  7, 13,5,  9,  4, 11, 21,  6,  7,  5,  5,  3,  7,  6, 10,  4, 18, 19, 10,  4,2,  5,  3,  5,  4,  7,  6,  7,  4,  9,  9,  3,  3,  8,  6, 19,  6, 14,3, 10,  7,  4,  5,  5,  2,  5,  5, 11,  2,  7,  9,  6,  6, 18,  8,  4,4, 12,  3,  8,  9, 10, 19,  7,  5,  3,  8,  9,  9, 13, 10,  3,  6,  5,4,  4, 34, 11, 12,  7,  5,  6, 20,  2,  8,  3, 16,  5,  3,  4,  7, 12,6,  4]) 
tensor([ 4,  1,  6, 10,  3, 12, 15,  2,  5,  4, 11,  3,  6,  6,  8,  7,  4,  7,4, 12,  9,  8,  6,  5,  5,  5, 18,  4,  5,  1,  9, 13,  8,  1,  5,  1,6,  4, 13,  4,  9, 14, 12,  2,  5, 13, 12,  9,  9,  9,  4,  2,  4, 14,4,  4,  9,  6,  6,  5,  5,  2,  7,  6, 10, 14,  6, 10,  4,  7,  6,  7,2,  6,  7,  7,  3,  3,  4,  4,  4, 10,  4,  6,  5,  3, 13,  6,  3,  5,16,  2,  7, 10,  2,  3,  6,  9,  6,  3,  9, 13, 12,  8,  7, 10,  7, 12,4,  8,  2,  3,  7,  5,  4, 14,  2,  6,  4,  1,  5,  9, 14,  2,  3,  4,5, 79])Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024美赛预测算法 | 回归预测 | Matlab基于RIME-LSSVM霜冰算法优化最小二乘支持向量机的数据多输入单输出回归预测

2024美赛预测算法 | 回归预测 | Matlab基于RIME-LSSVM霜冰算法优化最小二乘支持向量机的数据多输入单输出回归预测 目录 2024美赛预测算法 | 回归预测 | Matlab基于RIME-LSSVM霜冰算法优化最小二乘支持向量机的数据多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效…

5、DSP28335 串口发送接收FIFO中断,自定义printf函数

#include "uart.h"unsigned char data[8];void MyUartInit(Uint32 baud) {unsigned char scihbaud 0;unsigned char scilbaud 0;Uint16 scibaud 0;EALLOW;InitSciaGpio();EDIS;EALLOW;//0&#xff1a;一位停止位&#xff1b;1&#xff1a;两位停止位SciaRegs.SCIC…

Docker进阶篇-Docker网络

一、描述 1、docker不启动&#xff0c;默认网络情况 查看网卡情况使用&#xff0c;ifconfig或者ip addr ens33&#xff1a;本机网卡 lo&#xff1a;本机回环网络网卡 virbr0:在CentoS 7的安装过程中如果有选择相关虚拟化的的服务安装系统后&#xff0c;启动网卡时会发现 …

Web实战丨基于Django的简单网页计数器

文章目录 写在前面Django简介主要程序运行结果系列文章写在后面 写在前面 本期内容 基于django的简单网页计数器 所需环境 pythonpycharm或vscodedjango 下载地址 https://download.csdn.net/download/m0_68111267/88795604 Django简介 Django 是一个用 Python 编写的高…

游戏找不到d3dcompiler_43.dll怎么办?多种5种解决方法分享

在运行游戏的过程中&#xff0c;系统遇到了一个关键性的问题&#xff0c;即无法成功找到名为“d3dcompiler_43.dll”的动态链接库文件。这一特定的dll文件对于游戏的正常启动和图形渲染至关重要&#xff0c;它的缺失可能会导致游戏无法运行或者画面无法正确显示。通常情况下&am…

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…

10秒搞定!隔壁奶奶都能搞定的幻兽帕鲁、雾锁王国开服指南

最近《幻兽帕鲁》和《雾锁王国》非常火热&#xff0c;玩过的小伙伴们都说非常上头&#xff01;有跟朋友对战需求的小伙伴们可以通过本文拥有一台高性价比的专用服务器&#xff0c;随时可以用来跟朋友一起玩游戏&#xff01; 敲重点&#xff01;&#xff01;&#xff01; 步骤…

2021-10-14 51蛋骗鸡1秒变动0-9按键控制并蜂鸣器响

缘由单片机程序设计与应用-Python-CSDN问答 #include "REG52.h" sbit K1 P3^0; sbit K2 P3^1; sbit K3 P3^2; sbit K4 P3^3; sbit bpP3^4; bit k1,wk0; unsigned char code SmZiFu[]{63,6,91,79,102,109,125,7,127,111,128,255,64};//0-9.消隐- unsigned char J…

【深度学习: 计算机视觉】如何改进计算机视觉数据集

【深度学习&#xff1a; 计算机视觉】如何改进计算机视觉数据集 训练模型并评估性能确定数据集需要改进的原因和位置收集或创建新的图像或视频数据重新训练机器学习模型并重新评估&#xff0c;直到达到所需的性能标准 机器学习算法需要大量数据集来训练、提高性能并生成组织所需…

基于SpringBoot+Vue的高校在线答疑管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

代码随想录算法训练营day38 || 509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯

视频讲解&#xff1a; 手把手带你入门动态规划 | LeetCode&#xff1a;509.斐波那契数_哔哩哔哩_bilibili 带你学透动态规划-爬楼梯&#xff08;对应力扣70.爬楼梯&#xff09;| 动态规划经典入门题目_哔哩哔哩_bilibili 动态规划开更了&#xff01;| LeetCode&#xff1a;746.…

P8598 [蓝桥杯 2013 省 AB] 错误票据--2024蓝桥杯冲刺省一

点击跳转例题 思路: 直接进行模拟即可,需要注意的是有很多细节. 首先输入的问题:每个例子没有给出数量,那么我们怎么办呢? 当然是直接读入一整行! 那么我们如何分割呢?这里引入stringstream(知识总结); 利用getline()读入一整行,stringstream来过滤掉空格; #include <b…

springwebflux高性能服务

场景&#xff1a; 分别使用springwebmvc 使用tomcat &#xff08;tomcat 9&#xff09;和springwebflux 做一个简单的接口 &#xff0c;该接口返回一个随机数 压测环境&#xff1a; 4C 8G ECS 使用tomcat 压测结果 Max 抖动的厉害 保持压测的参数不变 使用webflux 压测结果 …

Power Designer的使用 创建数据库表模型

几年前用过PowerDesigner&#xff0c;好几年没用&#xff0c;有点忘记了&#xff0c;在这里记个笔记&#xff0c;需要的时候翻一翻 PowerDesigner版本16.5 下面的例子是以MySQL数据库为准 生成C#实体类 一 安装 1.1 安装 不让放网盘链接&#xff0c;审核通不过。。。。 …

【常见的Web前端框架——详细介绍】

常见的Web前端框架——详细介绍 常见的Web前端框架介绍 常见的Web前端框架介绍 Web前端开发工具和技术可以快速地发展和变化&#xff0c;但截至2023年&#xff0c;以下是一些常见和受欢迎的Web前端框架&#xff0c;每个都有自己独特的功能和用例。 React 由Facebook开发和维护…

react 之 zustand

zustand可以说是redux的平替 官网地址&#xff1a;https://zustand-demo.pmnd.rs/ 1.安装 npm i zustand2.基础使用 // zustand import { create } from zustand// 1. 创建store // 语法容易出错 // 1. 函数参数必须返回一个对象 对象内部编写状态数据和方法 // 2. set是用来…

Maven高级知识——分模块开发、继承与聚合

目录 一、分模块设计与开发 1.1 不分模块的问题 1.2 分模块设计 二、 继承与聚合 2.1 继承 2.1.1 继承关系 2.1.2 版本锁定 2.1.2.1 场景 2.1.2.2 介绍 2.1.2.3 实现 2.1.2.4 属性配置 2.2 聚合 2.2.1 介绍 2.2.2 实现 2.3 继承与聚合对比 三、Maven打包方式&#xff08;jar、w…

应对手机数据丢失的5大安卓数据恢复软件

我们都去过那里。您的手机上的数据丢失了&#xff0c;现在无法恢复。这尤其令人恐惧&#xff0c;因为我们的手机上都有如此多的信息。从图片、应用程序、个人信息&#xff0c;甚至是来自可能已不复存在的亲人的短信和语音邮件。这种情况确实发生了&#xff0c;而且也不仅仅是An…

Leetcode—382. 链表随机节点【中等】(水塘抽样法)

2024每日刷题&#xff08;一零九&#xff09; Leetcode—382. 链表随机节点 算法思想 我们可以在初始化时&#xff0c;用一个数组记录链表中的所有元素&#xff0c;这样随机选择链表的一个节点&#xff0c;就变成在数组中随机选择一个元素 实现代码 /*** Definition for si…

C++笔记(七)

递增运算符重载 //前置递增运算符重载&#xff1a; Integer& operator() { this->integer; return *this; } //后置递增运算符重载&#xff1a; Integer operator(int) { Integer temp *this; this->integ…