当前位置: 首页 > news >正文

NLP冻手之路(2)——文本数据集的下载与各种操作(Datasets)


✅ NLP 研 0 选手的学习笔记


文章目录

  • 一、需要的环境
  • 二、数据集的了解
  • 三、数据集的获取
    • 3.1 方法一:直接调用函数获取
    • 3.2 方法二:官网下载获取
  • 四、数据集的操作
    • 4.1 排序与打乱
    • 4.2 选择和过滤
    • 4.3 切分和分桶
    • 4.4 列的新增、删除和重命名
    • 4.5 map 函数
    • 4.6 保存与加载
  • 五、小结
  • 六、补充说明


上一篇文章链接: NLP冻手之路(1)——中文/英文字典与分词操作(Tokenizer)


一、需要的环境

python 需要 3.6+,pytorch 需要 1.10+

● 本文使用的库基于 Hugging Face Transformer,官网链接:https://huggingface.co/docs/transformers/index 【一个很不错的开源网站,针对于 transformer 框架做了很多大集成,目前 github 72.3k ⭐️】

● 安装 Hugging Face Transformer 的库只需要在终端输入 pip install transformers【这是 pip 安装方法】;如果你用的是 conda,则输入 conda install -c huggingface transformers

● 本文除了要安装上述配置,还要安装名为 datasets 的数据集处理包,只需要在终端输入 pip install datasets【这是 pip 安装方法】;如果你用的是 conda,则输入 conda install -c huggingface -c conda-forge datasets



二、数据集的了解

● 这里我用了 pprint 函数来打印,它比 print 打印出来的内容更整洁。

import datasets
from pprint import pprint

my_datasets_list = datasets.list_datasets()
print("Number of datasets in the Datasets library: ", len(my_datasets_list))
pprint(my_datasets_list[:20], compact=True)  # 打印数据集列表中的前 20 个来看看

输出结果:
Number of datasets in the Datasets library:  12173 
['acronym_identification', 'ade_corpus_v2', 'adversarial_qa', 'aeslc',
 'afrikaans_ner_corpus', 'ag_news', 'ai2_arc', 'air_dialogue',
 'ajgt_twitter_ar', 'allegro_reviews', 'allocine', 'alt', 'amazon_polarity',
 'amazon_reviews_multi', 'amazon_us_reviews', 'ambig_qa', 'americas_nli', 'ami',
 'amttl', 'anli']

● 从结果可以看到,截止目前 2022年10月20日,目前数据库已有 12172 个数据集。

● 接着,我们来了解一下一个 中文情感分析的数据集,即 seamew/ChnSentiCorp注意,后面所有的实验都将基于这个数据集。一般这里面的数据集都有 description,但是这个没有,我大致说一下,就是这个数据集全是一段一段的文本,每一段文本都是用户针对于某件事、某个东西等的评价。

index = my_datasets_list.index('seamew/ChnSentiCorp')  # 获取该数据集在 my_datasets(其 type 为list) 的位置
info = datasets.list_datasets(with_details=True)[index]  # 通过设置 with_details 为 True 来获得数据集的详细信息
pprint(info)

输出:
DatasetInfo: {
	id: seamew/ChnSentiCorp
	sha: 5fad0d07523f9c5fc76b8babaca9ab6fdeb6af2d
	lastModified: 2021-06-22T08:58:53.000Z
	tags: []
	private: False
	author: seamew
	description: None
	citation: None
	cardData: None
	siblings: None
	gated: False
	downloads: 1512
	likes: 8
}


三、数据集的获取

● 数据集的获取有两种方法,第一种是直接调用 load_dataset 函数获取,第二种是从官网下载下来。

● 第一种方法可能需要一下 F墙 的 VPN,需注意的是,这个 VPN 要打开到 “网卡模式”,而不只是 “网页模式”。因为 “网页模式” 只能去看看 Youtube 等外网网页,并不能使得 Python编辑器 访问到外网。

3.1 方法一:直接调用函数获取

● 我们通过设置 cache_dir 来将数据集下载到 ./my_data 中。

import datasets

my_dataset_all = datasets.load_dataset(path='seamew/ChnSentiCorp', cache_dir='./my_data')  # 获取整个数据集
my_dataset_train = my_dataset_all['train']
my_dataset_validation = my_dataset_all['validation']
my_dataset_test = my_dataset_all['test']

print("my_dataset_all:", my_dataset_all)
print("my_dataset_train:", my_dataset_train)
print("my_dataset_validation[0]:", my_dataset_validation[0])  # 打印第一个
print("my_dataset_test[:3]:", my_dataset_test[:3])  # 打印前三个

● 运行结果如下,其中 label1 代表对应的那段评论是 积极 的,反之,若 label0 则代表对应的那段评论是 消极 的。其中训练集有 9600 个样例,验证集和测试集分别有 1200 个样例。
在这里插入图片描述

● 如果通过这种方法下载的数据集,即可通过 save_to_disk 函数来保存到本地,下一次加载数据集时,就不需要再重复到网上下载,直接加载本地的即可。加载函数详见 “2.2 方法二:官网下载获取” 的 load_from_disk

my_dataset_all.save_to_disk(dataset_dict_path='./save_data')  

3.2 方法二:官网下载获取

● 如果方法一行不通,就用这个方法。首先进入该数据集的网页:https://huggingface.co/datasets/seamew/ChnSentiCorp。

在这里插入图片描述
● 然后,依照上图打开对话框,接着使用 git clone https://huggingface.co/datasets/seamew/ChnSentiCorp 来将数据集下载到本地,如下图所示。
在这里插入图片描述
● 我们然后还有做一系列文件夹划分操作,以便代码调用:1. 首先,我们在 ChnSentiCorp 文件夹里新建一个 dataset.json 文件,其中写入 { "splits": ["train", "validation", "test"] } 即可。2. 然后,我们需要编辑三个文件夹,分别命名为 trainvalidationtest。然后需要将 dataset_info.json 复制三份,分别放到这三个文件夹中,同时,对应的 *.arrow 数据文件也放入其中。3. 最后,在这三个文件夹内新建一个 state.json 文件,其内容如下(以 train 为例,注意,对于不同的文件夹(train、validation和test),其 filename_split 要做相应的改写):

{
    "_data_files": [
      {
        "filename": "chn_senti_corp-train.arrow"
      }
    ],
    "_fingerprint": "24c4fd9824d8b978",
    "_format_columns": null,
    "_format_kwargs": {},
    "_format_type": null,
    "_indexes": {},
    "_output_all_columns": false,
    "_split": "train"
}

● 最后,ChnSentiCorp 文件夹里面的结构如下:
在这里插入图片描述
● 我们通过 load_from_disk 函数来将本地保存的数据集加载到内存:

my_dataset_all_git = datasets.load_from_disk('./git_example/ChnSentiCorp')
print(my_dataset_all_git)

输出:
DatasetDict({
    train: Dataset({
        features: ['text', 'label'],
        num_rows: 9600
    })
    validation: Dataset({
        features: ['text', 'label'],
        num_rows: 1200
    })
    test: Dataset({
        features: ['text', 'label'],
        num_rows: 1200
    })
})


四、数据集的操作

4.1 排序与打乱

● 在实际训练的时候,我们常用到 排序(sort) 与 打乱(shuffle),具体操作如下:

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
print(my_dataset)  # 简单打印 train集 的信息
pprint(my_dataset[:10])  # 未排序的 label 是乱序的

my_dataset_sort = my_dataset.sort('label')  # 排序之后 label 便有序了
print(my_dataset_sort['label'][:10])  # 前十个 label 的值
print(my_dataset_sort['label'][-10:])  # 最后十个 label 的值

shuffled_dataset = my_dataset.shuffle(seed=42)  # 打乱顺序 seed 的值可调
print(shuffled_dataset['label'][:10])

● 运行结果:
在这里插入图片描述


4.2 选择和过滤

● 再介绍一下常用的选择函数 select 和 过滤函数 filter

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
x = my_dataset.select([1, 0, 10, 20, 30, 40, 50])  # 选择下标为 1、0、10、...、50 的数据
pprint(x)

def f(data):
    return data['text'].startswith('很差')  # 返回一个 true 或者 false

# 这里的 filter 函数需要用一个 lambda 函数
start_with_ar = my_dataset.filter(f)
print(len(start_with_ar), start_with_ar['text'])  # 打印以 '很差' 开头的句子的数量和内容

输出:
Dataset({
    features: ['label', 'text'],
    num_rows: 7
})
2 ['很差,相当差,搞得我们的外国客人都发大火了!!!服务不符合四星级的酒店标准!', '很差劲的地方。是人都不要住。设施什么都不好还贵。真是晦气']

4.3 切分和分桶

● 如果我们还想对 train集 进行划分,可以用 train_test_split 函数,另外还有一个好用的均分函数 shard

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
x = my_dataset.train_test_split(test_size=0.1)  # 按照 9:1 的比例对 train集 再划分为新的 'train集' 和 'test集'
print("原始 train集: ", my_dataset)
print("切分过后的 train集: ", x)

t = my_dataset.shard(num_shards=4, index=0)  # 把数据均匀分配到 4 个桶中. 然后取下标为 0 的桶里的数据
print("均匀(4)分桶过后且取下标为 0 的桶里的数据: ", t)

● 运行结果:
在这里插入图片描述


4.4 列的新增、删除和重命名

● 如果我们想对数据集里面的每一个样例都多加一个标签,即列的新增,那就要用到 add_column,具体方法如下。另外还有常用的,列的删除 remove_columns 和列的重命名 rename_column

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
new_column = ["null"] * len(my_dataset)
my_dataset_add = my_dataset.add_column("info", new_column)
print("原始 train集: ", my_dataset)
print("新增了一列的 train集: ", my_dataset_add)
print("原始 train集 的一个例子: ", my_dataset[1])
print("新增了一列的 train集 的一个例子: ", my_dataset_add[1])

my_dataset_newName = my_dataset_add.rename_column('info', 'likes')
print("重命名后的 train集: ", my_dataset_newName)

my_dataset_remove = my_dataset_newName.remove_columns(['likes'])
print("删除了一列的 train集: ", my_dataset_remove)

● 运行结果:
在这里插入图片描述


4.5 map 函数

● 这个 map 函数是比较重要的,说白了,可以用这个函数对数据集里面的内容进行了人为的修改。

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
def m(data):
    data['text'] = 'My sentence: ' + data['text']
    return data

my_datatset_map = my_dataset.map(m)  # 也是通过一个 lambda 函数来处理
pprint(my_datatset_map['text'][:5], width=300)  # 打印前五个
print("原始 train集: ", my_dataset)
print("经过 map 后的 train集: ", my_datatset_map)

● 运行结果:

在这里插入图片描述


4.6 保存与加载

● 其实在 “3.1 方法一:直接调用函数获取” 中已经讲了一个保存的函数 save_to_disk,下面运行结果图中,文件夹里的 save_data 即为函数 my_dataset.save_to_disk(dataset_dict_path='./save_data') 运行后的结果。另外,如果保存为 .csv.json 格式的文件,就要用到 to_csvto_json 函数,加载的话,除了本地加载的 load_from_disk 函数,还有一个就是 load_dataset

my_dataset = datasets.load_from_disk('./git_example/ChnSentiCorp')['train']  # 获取 train 集
print("原始的数据:", my_dataset[1:3], end='\n')  # 打印 2 个例子看看
my_dataset.to_csv(path_or_buf='./save_csv_data.csv')  # 导出为 csv 格式
csv_dataset = datasets.load_dataset(path='csv', data_files='./save_csv_data.csv', split='train')  # 加载 csv 格式数据
print("csv 格式的数据:", csv_dataset[1:3], end='\n')  # 打印 2 个例子看看

csv_dataset.to_json(path_or_buf='./save_json_data.json')  # 导出为 json 格式
json_dataset = datasets.load_dataset(path='json', data_files='./save_json_data.json', split='train')  # 加载 json 格式数据
print("json 格式的数据:", json_dataset[1:3], end='\n')  # 打印 2 个例子看看

● 运行结果:

在这里插入图片描述



五、小结

● 关于数据集的操作不难,但是很重要,大致看一遍,过一遍即可。


六、补充说明

上一篇文章链接: NLP冻手之路(1)——中文/英文字典与分词操作(Tokenizer)

● 若有写得不对的地方,或有疑问,欢迎评论交流。

● 参考视频:HuggingFace简明教程,BERT中文模型实战示例.NLP预训练模型,Transformers类库,datasets类库快速入门.

● 参考资料:使用Hugging Face的数据集库


⭐️ ⭐️

相关文章:

  • 【Java】异常
  • 第22章 软件安装 RPM/ YUM
  • 手把手教你如何使用YOLOV5训练自己的数据集
  • 公众号网课搜题接口
  • 八、创建JWT工具类
  • 这家公司只有1个人,年赚一个亿
  • 【前端攻城师之JS基础】02JS对象基础
  • 【C/C++】程序环境,探索程序的执行过程(习得无上内功《易筋经》的第一步)
  • 计算机网络——基于UDP与TCP网络编程
  • 中兴设备18种命令模式总结大全,全网第一篇,强烈建议收藏!
  • 【学生管理系统】权限管理
  • NLP学习之:Bert 模型复现(1)任务分析 + 训练数据集构造
  • 【PTA】《数据结构与算法》线性结构复习题
  • Java利用工具类提升写报表效率
  • RFSoC应用笔记 - RF数据转换器 -14- RFSoC自动增益控制与NCO跳频功能
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • cookie和session
  • create-react-app做的留言板
  • Cumulo 的 ClojureScript 模块已经成型
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • ES2017异步函数现已正式可用
  • git 常用命令
  • Java-详解HashMap
  • JS实现简单的MVC模式开发小游戏
  • MD5加密原理解析及OC版原理实现
  • React-flux杂记
  • Theano - 导数
  • Vue2.0 实现互斥
  • vue的全局变量和全局拦截请求器
  • 测试如何在敏捷团队中工作?
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 软件开发学习的5大技巧,你知道吗?
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 通信类
  • 一天一个设计模式之JS实现——适配器模式
  • 【云吞铺子】性能抖动剖析(二)
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​学习一下,什么是预包装食品?​
  • # 安徽锐锋科技IDMS系统简介
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #define、const、typedef的差别
  • (10)STL算法之搜索(二) 二分查找
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (办公)springboot配置aop处理请求.
  • (论文阅读11/100)Fast R-CNN
  • (七)Knockout 创建自定义绑定
  • (十) 初识 Docker file
  • (转)德国人的记事本
  • ******之网络***——物理***
  • .NET Project Open Day(2011.11.13)
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET是什么
  • .net项目IIS、VS 附加进程调试