从零实现诗词GPT大模型:数据集介绍和预处理

专栏规划: https://qibin.blog.csdn.net/article/details/137728228

本章将介绍该系列文章中使用的数据集,并且编写预处理代码,处理成咱们需要的格式。

一、数据集介绍

咱们使用的数据集名称是chinese-poetry,是一个在github上开源的中文诗词数据集,根据仓库中readme.md中的介绍,该数据集是最全的中华古典文集数据库,包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。诗人包括唐宋两朝近 1.4 万古诗人,和两宋时期 1.5 千古词人。
数据集的下载地址:https://github.com/chinese-poetry/chinese-poetry?tab=readme-ov-file,大家可以点击Code按钮,选择Download ZIP将该数据集下载到本地,如下图:
下载数据集
当然,作者收集数据也不易,大家可以顺手点一下star鼓励一下作者,如图:
start
如果你按照上面的步骤,把数据集下载到你本地了,解压后你可以看到如下图所示的目录结构
数据集

作者按照不同诗词类型进行了分类,并且在每个分类下提供了1个到多个的json文件,json文件里按照结构化数据组织了每一个诗词的信息,如下图
诗词结构

二、数据集预处理

上面咱们详细介绍了chinese-poetry数据集的下载方式和作者组织的结构,下面我们将提取每个诗词的标题和内容作为我们需要的部分,并聚合到一个文件中,以方便我们后续训练模型使用。
首先,我们需要把作者提供的诗词类目整理到一个数组中,方便我们后续进行目录的变量

classes = ['五代诗词', '元曲', '全唐诗', '四书五经', '宋词', '幽梦影', '御定全唐詩', '曹操诗集', '楚辞', '水墨唐诗','纳兰性德', '蒙学', '论语', '诗经']

然后,我们可以遍历该数组,拼接一个目录,遍历目录中中的文件,再进行文件处理

for cls in classes:dir = base_dir + clsfiles = os.listdir(dir)for f in files:f = f'{dir}/{f}'if os.path.isdir(f):if 'error' in f:continuefor ff in os.listdir(f):process_json(f'{f}/{ff}')else:process_json(f)

上面代码中,我们遍历每个类别的目录后,会列出该类别中所有的文件,文件如果是一个目录,则继续遍历这个目录,因为作者提供的目录结构会存在二级目录的情况。
最后,拿到每个json文件后,会调用process_json()函数处理对应的json文件。下面我们开始介绍process_json()函数。

process_json()函数会对上面代码中拿到的每个json文件进行处理,并且从json文件中提取我们需要的信息(诗词的标题和内容),重新组织结构,写入到一个新文件中;该函数还会根据一个简单的策略划分出训练集测试集(训练集用来训练我们的模型,测试集用来在训练过程中测试模型的性能)。整体代码如下

def process_json(file):if not file.endswith('.json'):returnwith open(file, 'r') as f:json_content = f.read()array = json.loads(json_content)if type(array) != list:returnif len(array) > 100:train_array = array[:-1]test_array = array[-1:]else:train_array = arraytest_array = Nonefor item in train_array:if 'title' not in item.keys() or 'paragraphs' not in item.keys():continuewrite_file(item, dst_train_file)if test_array is not None:for item in test_array:if 'title' not in item.keys() or 'paragraphs' not in item.keys():continuewrite_file(item, dst_test_file)

在代码中,首先会打开该json文件,并读取json文件中的内容;读到内容后,通过json.loads()函数将它解码成在python中可以识别的数据结构。
接下来,我们根据该分类下诗词的数据决定是否要划分出测试集,策略很简单,如果个数大于100,我们就把最后一个作为测试集的一部分,当然这个策略可以根据你的需求进行调整。
最后,我们从json中拿到titleparagraphs属性通过一个write_file()函数写到我们的新文件中。

write_file()函数的实现也很简单,作用就是拿到titleparagraphs,组织好结构写入到一个新文件中;我们预处理后的文件不会像原数据集那样提供多个文件,而是全部写到同一个文件中,所以,此时就得考虑一个问题:所有的诗词在一个文件中,怎么标识出一首诗结束了呢?办法很简单,我们在没首诗结束的时候添加一个<|endoftext|>特殊标识,该标识很重要,因为在后面我们训练模型的时候,该标识也会根据此标识学习一首诗到哪结束了(不需要结束,咱们模型就无止境的输出了)。

def write_file(item, dst_file):global error_counttitle = item['title']paragraphs = item['paragraphs']content = f'\n{title}'for p in paragraphs:content = f'{content}\n{p}'content = converter.convert(content)if '𫗋' in content:print(f'{content}----')error_count += 1returncontent = content + '<|endoftext|>'dst_file.write(content)

上面代码中,处理前面我们介绍的部分,存在两个特殊的地方

...
content = converter.convert(content)
...
if '𫗋' in content

第一个的作用是将繁体中文转换成简体字,因为原数据集中存在大量的繁体字,显然,我们不想让咱们的模型生成的诗词是繁体字形式,所以这里我选择将繁体字转换成简体字,这里借助了一个python的转换库opencc实现,大家可以通过pip3 install opencc-python-reimplemented进行安装,该库的使用方法如下

import opencc
# 繁转简
converter = opencc.OpenCC('t2s')
content = converter.convert(content)

第二个特殊的地方就是我们代码中有一个𫗋,这是因为,通过上述代码转换成简体字的时候会有一些字转换错误,所以我们这里直接将存在转换错误情况的诗过滤掉,当然,这种情况不会很多,大概几十首诗词,对于咱们几十万首诗词的数据集来说都是毛毛雨。

好了,上面就是咱们数据预处理的全部过程,最终你会得到一个如下结构的train.txttest.txt分别代表咱们前面提到过的训练集测试集
预处理后的数据集
最后,我把全部代码整理出来,方便大家可以复制到本地直接运行

import os, json
import openccbase_dir = 'chinese-poetry-master/'
classes = ['五代诗词', '元曲', '全唐诗', '四书五经', '宋词', '幽梦影', '御定全唐詩', '曹操诗集', '楚辞', '水墨唐诗','纳兰性德', '蒙学', '论语', '诗经']dst_train_file = open('./train.txt', 'w')
dst_test_file = open('./test.txt', 'w')converter = opencc.OpenCC('t2s')
error_count = 0def write_file(item, dst_file):global error_counttitle = item['title']paragraphs = item['paragraphs']content = f'\n{title}'for p in paragraphs:content = f'{content}\n{p}'content = converter.convert(content)if '𫗋' in content:print(f'{content}----')error_count += 1returncontent = content + '<|endoftext|>'dst_file.write(content)def process_json(file):if not file.endswith('.json'):returnwith open(file, 'r') as f:json_content = f.read()array = json.loads(json_content)if type(array) != list:returnif len(array) > 100:train_array = array[:-1]test_array = array[-1:]else:train_array = arraytest_array = Nonefor item in train_array:if 'title' not in item.keys() or 'paragraphs' not in item.keys():continuewrite_file(item, dst_train_file)if test_array is not None:for item in test_array:if 'title' not in item.keys() or 'paragraphs' not in item.keys():continuewrite_file(item, dst_test_file)for cls in classes:dir = base_dir + clsfiles = os.listdir(dir)for f in files:f = f'{dir}/{f}'if os.path.isdir(f):if 'error' in f:continuefor ff in os.listdir(f):process_json(f'{f}/{ff}')else:process_json(f)dst_train_file.close()
dst_test_file.close()dst_train_file = open('./train.txt', 'r')
dst_test_file = open('./test.txt', 'r')train_count = 0
test_count = 0for line in dst_train_file:if '<|endoftext|>' in line:train_count += 1for line in dst_test_file:if '<|endoftext|>' in line:test_count += 1print(f'train_count: {train_count}, test_count: {test_count}, error_count: {error_count}')

下一篇,我们将对pytorch框架做一个简单的入门介绍

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

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

相关文章

[svelte]属性和逻辑块

属性 / Default values • Svelte 教程 | Svelte 中文网 属性 Declaring props 到目前为止&#xff0c;我们只处理了内部状态——也就是说&#xff0c;这些值只能在给定的组件中访问。 在任何实际应用程序中&#xff0c;都需要将数据从一个组件向下传递到其子组件。为此&…

IO基础合集

IO基础合集 1. File类1.1 概述1.2 构造方法1.3 常用方法获取功能的方法绝对路径和相对路径判断功能的方法创建删除功能的方法 1.4 目录的遍历 2. IO概述2.1 什么是IO2.2 IO的分类2.3 IO的流向说明图解2.4 顶级父类们 3. 字节流3.1 一切皆为字节3.2 字节输出流【OutputStream】3…

Buck变换电路

Buck变换电路 Buck变换电路是最基本的DC/DC拓扑电路&#xff0c;属于非隔离型直流变换器&#xff0c;其输出电压小于输入电压。Buck变换电路具有效率高、输出稳定、控制简单和成本低的优点&#xff0c;广泛应用于稳压电源、光伏发电、LED驱动和能量回收系统。 电路原理 Buck变…

SV-29810T-蓝牙无线IP网络多功能多媒体防水音柱

SV-29810T-蓝牙无线IP网络多功能多媒体防水音柱 ◆室外室内豪华型防水音柱式一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用 ◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车场及露天市场等&#xff1b;室外使用效果均佳。 产品特点&#…

每日两题2

不同路径 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m1, vector<int>(n1,0));//创建dp表dp[0][1] 1;//初始化//填表for(int i 1; i < m; i){for(int j 1; j < n; j){dp[i][j] dp[i-1][j] dp[i][j-1];}}ret…

一分钟举例了解AI智能客服机器人的具体应用

AI智能客服机器人广泛应用于多个领域&#xff0c;充斥着我们生活的方方面面。在电商领域、银行业、电信行业、政府机构、教育机构、医疗机构等也借助AI智能客服机器人提供咨询、答疑等服务。但是具体是怎么应用到这些场景的呢&#xff1f;今天就用HelpLook的AI智能机器人的具体…

算法与数据结构(基于Go语言)学习笔记01

算法初识&#xff1a;汉诺塔问题(Towers of Hanoi) 规则简介 ​ 给定三根柱子&#xff0c;记为 A A A、 B B B、 C C C&#xff0c;其中 A A A 柱子上有 n − 1 n-1 n−1 个盘子&#xff0c;从上至下盘子越来越大。问&#xff1a;将 A A A柱上的盘子经由 B B B柱&#xff…

Leetcode 15. 三数之和(暴力->双指针)

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1…

解决EasyPoi导入Excel获取不到第一列的问题

文章目录 1. 复现错误2. 分析错误2.1 导入的代码2.2 DictExcel实体类2.2 表头和标题3. 解决问题1. 复现错误 使用EasyPoi导入数据时,Excel表格如下图: 但在导入时,出现如下错误: name为英文名称,在第一列,Excel表格有值,但导入的代码中为null,就很奇怪? 2. 分析错误 …

机器学习中的激活函数

激活函数存在的意义&#xff1a; 激活函数决定了某个神经元是否被激活&#xff0c;当这个神经元接收到的信息是有用或无用的时候&#xff0c;激活函数决定了对这个神经元接收到的信息是留下还是抛弃。如果不加激活函数&#xff0c;神经元仅仅做线性变换&#xff0c;那么该神经网…

基于Ultrascale+系列GTY收发器8b/10b编码方式的数据传输(三)——利用In System IBERT优化信号质量

基于Ultrascale系列GTY收发器8b/10b编码方式的数据传输&#xff08;二&#xff09;——数据收发及上板测试 一文介绍了利用GTY高速收发器进行8B/10B编码数据收发的使用方式&#xff0c;本文继续介绍使用In System IBERT IP核构建ibert眼图测试&#xff0c;以及通过设置参数以优…

ArcGIS三维景观分层显示

今天将向大家介绍的事在ArcGIS中如何创建多层三维显示。 地表为影像的 地表为地形晕渲的 在土壤分层、油气分层等都有着十分重要的应用。下面我们具体来看看实现过程 一、 准备数据及提取栅格范围 我们这次准备的数据是之前GIS100例-30讲的案例数据。《ArcGIS三维影像图剖面图…