使用
datasets
库,对数据集进行处理可以更方便与高效;
常用的csv、excel 和 json 等数据格式,可以很方便的转换为datasets的样式;
左侧有很多文章列表,右侧是Process
文章的目录,该目录有很多的不错的内容。
有很多内容本博客没有提及,推荐读者阅读原始文档。
安装
pip install datasets
导入 huggingface 数据集
from datasets import load_dataset
ds = load_dataset("fancyzhx/ag_news")
由于huggingface的服务器在海外,一般都连接不上。如果连接不上,使用代理进行连接。先运行下述代理设置,再运行上述的数据集导入:
import os
os.environ['HTTP_PROXY'] = 'http://127.0.0.1:7890'
os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'
ds的features:
ds["train"].features
输出结果:
{'text': Value(dtype='string', id=None),
'label': ClassLabel(names=['World', 'Sports', 'Business', 'Sci/Tech'], id=None)}
fancyzhx/ag_news
是一个文本分类数据集,有['World', 'Sports', 'Business', 'Sci/Tech']
四个类别。
ds
输出结果:
DatasetDict({
train: Dataset({
features: ['text', 'label'],
num_rows: 120000
})
test: Dataset({
features: ['text', 'label'],
num_rows: 7600
})
})
ds["test"][0]
输出结果:
{'text': "Fears for T N pension after talks Unions representing workers at Turner Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul.",
'label': 2}
导入本地数据集
from datasets import load_dataset, Dataset
导入json文件为数据集:
query_dataset = load_dataset(
"json",
data_files="xxx.json",
split="train"
)
导出为json:
dataset.to_json(
"xxx.jsonl",
force_ascii=False,
)
从字典/列表导入为数据集:
corpus = Dataset.from_dict({"text": corpus_list})
filter
datasets的数据集对象有filter方法,实现对数据集元素进行筛选。
比如,想筛选出在训练集中,label 全为2的数据。
tmp = ds["train"].filter(lambda x: x["label"] == 2)
print(tmp)
print(tmp[0])
输出结果:
Filter: 100%|██████████| 120000/120000 [00:00<00:00, 453257.78 examples/s]
Dataset({
features: ['text', 'label'],
num_rows: 30000
})
{'text': "Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again.", 'label': 2}
如上述的输出结果所示,在训练集中label为2的数据有30000条。最后一行是筛选出的一个示例。
map
数据集转换,原始的数据集通常可能不满足需求,要对其进行一些转化。
要让大模型对文本进行分类,需要给样例数据中添加一些提示词。
下述是大模型给文本分类的提示词:
prompt_cls = """你是文本分类领域的专家,请你给下述文本分类,把它分到下述类别中:
* World
* Sports
* Business
* Science / Technology'
text是待分类的文本,label是文本的类别:
text: {text}
label:
"""
想把原始的数据集中的text,自动放入到{text}
中,实现代码如下:
def trans2llm(item):
item["text"] = prompt_cls.format(text=item["text"])
return item
tmp = ds["test"].map(trans2llm)
print(tmp[0])
输出结果:
Map: 100%|██████████| 7600/7600 [00:00<00:00, 57726.64 examples/s]
{'text': "你是文本分类领域的专家,请你给下述文本分类,把它分到下述类别中:\n* World\n* Sports\n* Business\n* Science / Technology'\n\ntext是待分类的文本,label是文本的类别:\ntext: Fears for T N pension after talks Unions representing workers at Turner Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul.\nlabel: \n", 'label': 2}
如上述结果所示,使用map
完成了数据集的转换。
map
需要传入一个数据处理的函数,本例子中的函数是:trans2llm
。
trans2llm
接收的参数是原始数据集的item,返回的结果是一个新的item。
select
数据集采样,随机采样、下标采样等;
有时候,可能只想要数据集的随机一部分样本、某些下标的样本。
filter 函数筛选
select 筛选下标
ds["train"].select([0, 10, 20, 30, 40, 50])
输出结果:
Dataset({
features: ['text', 'label'],
num_rows: 6
})
如果我们要在数据集中,随机采样,只需要传入随机的下标就可以:
import random
numbers = list(range(1000))
# 从这个列表中随机选择100个不重复的数
random_numbers = random.sample(numbers, 100)
# 打印生成的随机数列表
print(random_numbers)
# 通过长度验证是否有重复元素
print(len(set(random_numbers)) == len(random_numbers))
获取随机采样的样本数据:
ds["train"].select(random_numbers)
输出结果:
Dataset({
features: ['text', 'label'],
num_rows: 100
})
数据集拼接
使用拼接函数,把一些数据集拼接到一起。
若想区分训练集和测试集,使用train_test_split
切分开。
from datasets import concatenate_datasets
dataset = concatenate_datasets([true_dataset, false_dataset])
# dataset.train_test_split(train_size=0.8)
add_column
添加属性列:
dataset["train"] = dataset["train"].add_column("index", list(range(786701)))
rename_column
属性列重命名:
dataset["train"] = dataset["train"].rename_column("idx", "file_sent_index")