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

news2024/11/26 18:38:49

专栏规划: 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 + cls
    files = os.listdir(dir)

    for f in files:
        f = f'{dir}/{f}'
        if os.path.isdir(f):
            if 'error' in f:
                continue

            for 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'):
        return

    with open(file, 'r') as f:
        json_content = f.read()
        array = json.loads(json_content)
        if type(array) != list:
            return

        if len(array) > 100:
            train_array = array[:-1]
            test_array = array[-1:]
        else:
            train_array = array
            test_array = None

        for item in train_array:
            if 'title' not in item.keys() or 'paragraphs' not in item.keys():
                continue

            write_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():
                    continue

                write_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_count

    title = 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 += 1
        return
    content = 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 opencc

base_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 = 0


def write_file(item, dst_file):
    global error_count

    title = 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 += 1
        return
    content = content + '<|endoftext|>'
    dst_file.write(content)


def process_json(file):
    if not file.endswith('.json'):
        return

    with open(file, 'r') as f:
        json_content = f.read()
        array = json.loads(json_content)
        if type(array) != list:
            return

        if len(array) > 100:
            train_array = array[:-1]
            test_array = array[-1:]
        else:
            train_array = array
            test_array = None

        for item in train_array:
            if 'title' not in item.keys() or 'paragraphs' not in item.keys():
                continue

            write_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():
                    continue

                write_file(item, dst_test_file)


for cls in classes:
    dir = base_dir + cls
    files = os.listdir(dir)

    for f in files:
        f = f'{dir}/{f}'
        if os.path.isdir(f):
            if 'error' in f:
                continue

            for 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 = 0

for line in dst_train_file:
    if '<|endoftext|>' in line:
        train_count += 1

for line in dst_test_file:
    if '<|endoftext|>' in line:
        test_count += 1

print(f'train_count: {train_count}, test_count: {test_count}, error_count: {error_count}')

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

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

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

相关文章

雨润万物生,酒伴谷雨行

谷雨&#xff0c;是中国传统二十四节气之一 标志着中国农历的春季即将结束&#xff0c;夏季即将来临。在古代中国, 谷雨时节是农民开始播种、收获的时节,也是酿酒的好季节。谷雨时节,气温适宜、湿度较高&#xff0c;是酵母繁殖和发酵的好时候。 谷雨时节酿酒不仅仅是普通人们…

37-2 Python 的 requests 库发送 POST 请求

准备 sqlilabs 靶场: 构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、发送 POST 请求 首先使用bp对 sqlilabs 靶场的第12关抓个包,了解这个关卡是如何发包的 打开靶场:本地ip+ /sqli-labs-master/Less-12/ 先随便输入个账号登录如…

Postman之页面简介 V9.31.0

Postman之页面简介 V9.31.0 一、顶部栏二、左部栏三、中部栏四、下部栏 一、顶部栏 &#xff08;1&#xff09;new选项框&#xff0c;生成新建请求、集合、环境等 &#xff08;2&#xff09;import选项框&#xff0c;可以导入文件、文件夹、链接、文本信息等 &#xff08;3&…

(2022级)成都工业学院数据库原理及应用实验四: SQL简单查询

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、成品仅提供参考 3、如果成品不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 Navicat Premium 16 Mysql 8.0.36 实验要求 在实验三的基础上完成下列查询&#xff1a; 1、查询所有…

穿越物联网的迷雾:深入理解MQTT协议

目录标题 1、MQTT简介核心特性 2、MQTT的工作原理通信过程 3、MQTT的消息质量&#xff08;QoS&#xff09;4、安全机制5、实践应用环境准备示例项目发布者客户端订阅者客户端 6、最佳实践7、结论8、参考资料 在物联网&#xff08;IoT&#xff09;的海洋中&#xff0c;数据像水流…

【ACM列表推荐会议 | EI稳定检索】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

二叉树的最大深度 - LeetCode 热题 37

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 37 天 二叉树第 2 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最…

麒麟服务器操作系统自动化安装应答文件制作

原文链接&#xff1a;麒麟服务器操作系统自动化安装应答文件制作 Hello&#xff0c;大家好啊&#xff01;今天我们将探讨如何为麒麟服务器操作系统制作自动化安装应答文件。在部署大量服务器时&#xff0c;自动化安装是提高效率和确保安装一致性的关键技术。通过使用应答文件&a…

【计算机网络】ip子网划分--超详细例题解析

Hello!这一篇主要是计算机网络中的ip地址子网划分的例题&#xff0c;这里例举了四个题型。保证即便从0也可以掌握&#xff01;(前面是一些预备知识&#xff0c;不熟悉的小伙伴一定要看下学习下哦&#xff5e;) 这也是博主的学习过程&#xff0c;做题中仅仅我的理解哦。若文章中…

【k8s】:kubectl 命令设置简写启用自动补全功能

【k8s】&#xff1a;kubectl 命令设置简写&启用自动补全功能 1、设置kubectl命令简写2、启用kubectl自动补全功能 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Kubernetes&#xff08;K8s&#xff09;是一个强大的容器编排平台&#…

Grid Controller

完整、易于使用的基于网格的第一人称控制器,具有《格里姆洛克传奇》、《地下城大师》和《巫师》的风格。 网格控制器是一种基于网格的第一人称控制器,设置简单,但具有鲁棒性和通用性。不需要脚本。 特征: 实时或基于回合的移动 平滑移动或即时捕捉到网格位置 倾斜、下降和蹲…

DevOps(七)Jenkins发布第一个流水线任务

Jenkins的流水线&#xff08;Pipeline&#xff09;是一种强大的工具&#xff0c;用于定义和管理持续集成和持续交付&#xff08;CI/CD&#xff09;过程。它允许你以代码的形式&#xff08;即"Pipeline as Code"&#xff09;定义整个构建、测试和部署流程&#xff0c;…

Linux中用户通过系统调用实现硬件驱动全流程

驱动全流程&#xff1a; 以基于设备树、Pinctrl、gpio子系统&#xff0c;打开一个字符设备为例&#xff1a; 1、通过系统调用open进入内核 当我们在用户空间调用open之后&#xff0c;应用程序会使用系统调用指令&#xff08;在上图中可看到&#xff0c;ARM架构中软中断汇编指…

浏览器工作原理与实践--浏览上下文组:如何计算Chrome中渲染进程的个数

经常有朋友问到如何计算Chrome中渲染进程个数的问题&#xff0c;那么今天就来完整地解答这个问题。 在前面“04 | 导航流程”这一讲中我们介绍过了&#xff0c;在默认情况下&#xff0c;如果打开一个标签页&#xff0c;那么浏览器会默认为其创建一个渲染进程。不过我们在“04 |…

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容&#xff1a; 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故&#xff0c;展现井下常见机械伤害事故&#xff0c;表现伤害事故的隐患点&#xff0c;能够模拟事故发生和发展过程&#xff1b;营造井下灾害发…

C#基于SSE传递消息给Vue前端实现即时单向通讯

一、简述 通常前端调用后端的API&#xff0c;调用到了&#xff0c;等待执行完&#xff0c;拿到返回的数据&#xff0c;进行渲染&#xff0c;流程就完事了。如果想要即时怎么办&#xff1f;如果你想问什么场景非要即时通讯&#xff0c;那可就很多了&#xff0c;比如在线聊天、实…

HQL,SQL刷题,尚硅谷(中级)

目录 相关表结构&#xff1a; 1、order_info表 2、order_detail表 题目及思路解析&#xff1a; 第一题&#xff0c;查询各品类销售商品的种类数及销量最高的商品 第二题 查询用户的累计消费金额及VIP等级 第三题 查询首次下单后第二天连续下单的用户比率 总结归纳&#xff1a…

C#版Facefusion:让你的脸与世界融为一体!-02 获取人脸关键点

C#版Facefusion&#xff1a;让你的脸与世界融为一体&#xff01;-02 获取人脸关键点 目录 说明 效果 模型信息 项目 代码 下载 说明 C#版Facefusion一共有如下5个步骤&#xff1a; 1、使用yoloface_8n.onnx进行人脸检测 2、使用2dfan4.onnx获取人脸关键点 3、使用arcfa…

【MATLAB源码-第36期】matlab基于BD,SVD,ZF,MMSE,MF,SLNR预编码的MIMO系统误码率分析。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. MIMO (多输入多输出)&#xff1a;这是一个无线通信系统中使用的技术&#xff0c;其中有多个发送和接收天线。通过同时发送和接收多个数据流&#xff0c;MIMO可以增加数据速率和系统容量&#xff0c;同时提高信号的可靠性。…

算法1: 素数个数统计

统计n以内的素数个数 素数&#xff1a;只能被1和自身整除的自然数&#xff0c;0和1除外&#xff1b; 举例&#xff1a; 输入&#xff1a;100 输出&#xff1a;25 import java.util.*; class Test1{public static void main(String[] args){int a 100; //输入数字//…