目录
1.安装
2.分词
2.1tokenizer.encode()
2.2tokenizer.encode_plus ()
2.3tokenizer.batch_encode_plus()
3.添加新词或特殊字符
3.1tokenizer.add_tokens()
3.2 tokenizer.add_special_tokens()
4.datasets的使用
4.1加载datasets
4.2从dataset中取数据
4.3对datasets中的label排序
4.4打乱数据
4.5select 选择指定位置的数据
4.6过滤
4.7切分训练集和测试集
4.8分桶
4.9列的重命名
4.10删除列
4.11map()函数, 统一在相同位置添加相同信息
4.12设置格式
4.13导出与加载csv这种常见格式
4.14导出与加载json这种常见格式
1.安装
#安装python语句
pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install datasets -i https://pypi.tuna.tsinghua.edu.cn/simple
#在jupyter notebook中 安装语句
!pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple
!pip install datasets -i https://pypi.tuna.tsinghua.edu.cn/simple
2.分词
2.1tokenizer.encode()
from transformers import BertTokenizer
#本地磁盘加载bert-base-chinese预训练词向量模型
tokenizer = BertTokenizer.from_pretrained(
pretrained_model_name_or_path=r'E:\ALOT\10_deep_learning\data\bert-base-chinese',
cache_dir=None, #有无缓存目录
fore_download=False #需不需要下载
)
sents = [
'选择珠江花园的原因就是方便。',
'笔记本的键盘确实爽。',
'房间太小。其他的都一般。',
'今天才知道这书还有第6卷,真有点郁闷.',
'机器背面似乎被撕了张什么标签,残胶还在。',
]
out = tokenizer.encode(
text=sents[0],
text_pair=sents[1],
#句子长度>max_length时, 进行截断操作
truncation=True,
#句子长度不够就统一拼接
padding='max_length',
add_special_tokens=True, #添加特殊字符,如<pad>、<unk>.....
max_length=30,
#默认None返回一个列表, 或者选择 tf(tensflow),pt(pytorch), np(numpy)
return_tensors=None
)
print(out)
[101, 6848, 2885, 4403, 3736, 5709, 1736, 4638, 1333, 1728, 2218, 3221, 3175, 912, 511, 102, 5011, 6381, 3315, 4638, 7241, 4669, 4802, 2141, 4272, 511, 102, 0, 0, 0]
tokenizer.decode(out)
'[CLS] 选 择 珠 江 花 园 的 原 因 就 是 方 便 。 [SEP] 笔 记 本 的 键 盘 确 实 爽 。 [SEP] [PAD] [PAD] [PAD]'
2.2tokenizer.encode_plus ()
#增强版编码endoce函数
out = tokenizer.encode_plus(
text=sents[0],
text_pair=sents[1],
truncation=True,
padding='max_length',
add_special_tokens=True,
max_length=15,
return_tensors=None,
#增强版的增加的参数
return_token_type_ids=True, #标记0是第一句话;标记1是第二句话
return_attention_mask=True,
return_special_tokens_mask=True, #返回特殊符号的标识
return_length=True #返回length标识长度
)
for k, v in out.items():
print(k,':', v)
input_ids : [101, 6848, 2885, 4403, 3736, 5709, 1736, 4638, 1333, 1728, 2218, 3221, 3175, 912, 511, 102, 5011, 6381, 3315, 4638, 7241, 4669, 4802, 2141, 4272, 511, 102, 0, 0, 0] token_type_ids : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0] special_tokens_mask : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1] attention_mask : [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0] length : 30
print(out) #多输出会变成字典
{'input_ids': [101, 6848, 2885, 4403, 3736, 5709, 1736, 4638, 1333, 1728, 2218, 3221, 3175, 912, 511, 102, 5011, 6381, 3315, 4638, 7241, 4669, 4802, 2141, 4272, 511, 102, 0, 0, 0], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], 'special_tokens_mask': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], 'length': 30}
2.3tokenizer.batch_encode_plus()
#批量编码句子
out_batch_encode = tokenizer.batch_encode_plus(
batch_text_or_text_pairs=[sents[0], sents[1], sents[2]],
truncation=True,
padding='max_length',
add_special_tokens=True,
max_length=50,
return_tensors=None,
#增强版的增加的参数
return_token_type_ids=True, #标记0是第一句话;标记1是第二句话, 1后面的0表示第二句话补充的pad
return_attention_mask=True,
return_special_tokens_mask=True, #返回特殊符号的标识
return_length=True #返回length标识长度
)
for k, v in out_batch_encode.items():
print(k, ':', v)
input_ids : [[101, 6848, 2885, 4403, 3736, 5709, 1736, 4638, 1333, 1728, 2218, 3221, 3175, 912, 102], [101, 5011, 6381, 3315, 4638, 7241, 4669, 4802, 2141, 4272, 511, 102, 0, 0, 0], [101, 2791, 7313, 1922, 2207, 511, 1071, 800, 4638, 6963, 671, 5663, 511, 102, 0]] token_type_ids : [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] special_tokens_mask : [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]] length : [15, 12, 14] attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]
tokenizer.decode(out_batch_encode['input_ids'][0]), tokenizer.decode(out_batch_encode['input_ids'][1])
('[CLS] 选 择 珠 江 花 园 的 原 因 就 是 方 便 [SEP]', '[CLS] 笔 记 本 的 键 盘 确 实 爽 。 [SEP] [PAD] [PAD] [PAD]')
#编码批量成对的句子
out_batch_encode_2 = tokenizer.batch_encode_plus(
batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
truncation=True,
padding='max_length',
add_special_tokens=True,
max_length=30,
return_tensors=None,
#增强版的增加的参数
return_token_type_ids=True, #标记0是第一句话;标记1是第二句话, 1后面的0表示第二句话补充的pad
return_attention_mask=True,
return_special_tokens_mask=True, #返回特殊符号的标识
return_length=True #返回length标识长度
)
for k, v in out_batch_encode_2.items():
print(k, ':', v)
input_ids : [[101, 6848, 2885, 4403, 3736, 5709, 1736, 4638, 1333, 1728, 2218, 3221, 3175, 912, 511, 102, 5011, 6381, 3315, 4638, 7241, 4669, 4802, 2141, 4272, 511, 102, 0, 0, 0], [101, 2791, 7313, 1922, 2207, 511, 1071, 800, 4638, 6963, 671, 5663, 511, 102, 791, 1921, 2798, 4761, 6887, 6821, 741, 6820, 3300, 5018, 127, 1318, 117, 4696, 3300, 102]] token_type_ids : [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] special_tokens_mask : [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]] length : [27, 30] attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
len(vocab)
21128
'手机' in vocab
False
3.添加新词或特殊字符
3.1tokenizer.add_tokens()
#添加新词
tokenizer.add_tokens(new_tokens=['你好', '手机'])
2
3.2 tokenizer.add_special_tokens()
#添加新字符
tokenizer.add_special_tokens({'eos_token':'[EOS]'})
vocab = tokenizer.get_vocab() #获取词汇表
len(vocab)
21131
'你好' in vocab
True
#用get查询不存在的词,不会报错
vocab.get('你好') #获取查询词的索引
#查询不存在的词,会报错
vocab['你好'] vocab['你好']
21128
#编码新添加的词
out_new_add_word_encode = tokenizer.encode(text='你好的手机[EOS]',
text_pair=None,
truncation=True,
#句子长度不够就统一拼接
padding='max_length',
add_special_tokens=True, #添加特殊字符,如<pad>、<unk>.....
max_length=10,
#默认None返回一个列表, 或者选择 tf(tensflow),pt(pytorch), np(numpy)
return_tensors=None
)
print(out_new_add_word_encode)
[101, 21128, 4638, 21129, 21130, 102, 0, 0, 0, 0]
tokenizer.decode(out_new_add_word_encode)
'[CLS] 你好 的 手机 [EOS] [SEP] [PAD] [PAD] [PAD] [PAD]'
4.datasets的使用
#从镜像网站下载的datasets 本地磁盘加载方式一
#网址:seamew/ChnSentiCorp at mainseamew/ChnSentiCorp at mainseamew/ChnSentiCorp at main
4.1加载datasets
from datasets import load_dataset
datasets = load_dataset(path=r'E:\ALOT\10_deep_learning\data\Chn')
datasets
DatasetDict({ train: Dataset({ features: ['label', 'text'], num_rows: 9600 }) validation: Dataset({ features: ['label', 'text'], num_rows: 1200 }) test: Dataset({ features: ['label', 'text'], num_rows: 1200 }) })
#从学习课件资料的datasets 本地磁盘加载方式二
# from datasets import load_dataset
# #直接从官网下载datasets
# dataset = load_dataset(path='seamew/ChnSentiCorp')
# #保存数据集到磁盘
# #注意:上面的加载数据要成功运行才可以执行保存
# dataset.save_to_disk(dataset_dict_path='../data/ChnSentiCorp')
from datasets import load_from_disk
dataset = load_from_disk(r'E:\ALOT\10_deep_learning\data\ChnSentiCorp')
dataset
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.2从dataset中取数据
#按照字典的方法取数据
dataset_train = dataset['train']
dataset_train #可迭代的Dataset对象,像列表一样用索引获取数据
Dataset({ features: ['text', 'label'], num_rows: 9600 })
dataset_train[0]
{'text': '选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般', 'label': 1}
type(dataset_train)
datasets.arrow_dataset.Dataset
4.3对datasets中的label排序
#排序
print(dataset_train['label']) #标签是乱码的
输出太多,展示部分
[1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,]
#对标签排序
dataset_sorted = dataset_train.sort('label')
dataset_sorted
Dataset({ features: ['text', 'label'], num_rows: 9600 })
print(dataset_sorted[:5])
{'text': ['房间太小。其他的都一般。。。。。。。。。', '1.接电源没有几分钟,电源适配器热的不行. 2.摄像头用不起来. 3.机盖的钢琴漆,手不能摸,一摸一个印. 4.硬盘分区不好办.', '机器背面似乎被撕了张什么标签,残胶还在。但是又看不出是什么标签不见了,该有的都在,怪', '呵呵,虽然表皮看上去不错很精致,但是我还是能看得出来是盗的。但是里面的内容真的不错,我妈爱看,我自己也学着找一些穴位。', '这本书实在是太烂了,以前听浙大的老师说这本书怎么怎么不对,哪些地方都是误导的还不相信,终于买了一本看一下,发现真是~~~无语,这种书都写得出来'], 'label': [0, 0, 0, 0, 0]}
print(dataset_sorted['label'][:5]) #前5条数据的标签
[0, 0, 0, 0, 0]
print(dataset_sorted['text'][:5]) #前5条数据的文本
['房间太小。其他的都一般。。。。。。。。。', '1.接电源没有几分钟,电源适配器热的不行. 2.摄像头用不起来. 3.机盖的钢琴漆,手不能摸,一摸一个印. 4.硬盘分区不好办.', '机器背面似乎被撕了张什么标签,残胶还在。但是又看不出是什么标签不见了,该有的都在,怪', '呵呵,虽然表皮看上去不错很精致,但是我还是能看得出来是盗的。但是里面的内容真的不错,我妈爱看,我自己也学着找一些穴位。', '这本书实在是太烂了,以前听浙大的老师说这本书怎么怎么不对,哪些地方都是误导的还不相信,终于买了一本看一下,发现真是~~~无语,这种书都写得出来']
print(dataset_sorted['label'][-5:]) #最后5条数据的标签
[1, 1, 1, 1, 1]
4.4打乱数据
#打乱数据
#shuffle
dataset_shuffle=dataset_sorted.shuffle(seed=10) #seed=10随机种子,将打乱之后的顺序固定
print(dataset_shuffle['label'][:5])
[0, 1, 0, 0, 0]
4.5select 选择指定位置的数据
#select 选择指定位置的数据
dataset_select = dataset_train.select([0, 10, 20, 30, 40, 50])
dataset_select
Dataset({ features: ['text', 'label'], num_rows: 6 })
dataset_select[0]
{'text': '选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般', 'label': 1}
4.6过滤
#过滤
#filter () 里面需要放一个函数来过滤
def f(data):
return data['text'].startswith('选择')
start_with_ar = dataset_train.filter(f)
len(start_with_ar), start_with_ar['text']
(2, ['选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般', '选择的事例太离奇了,夸大了心理咨询的现实意义,让人失去了信任感!如果说这样写的效果能在一开始抓住读者的眼球,但是看到案例主人公心理问题的原因解释时就逐渐失去了兴趣,反正有点拣了芝麻丢了西瓜的感觉。'])
4.7切分训练集和测试集
dataset_train.train_test_split(test_size=0.2)
DatasetDict({ train: Dataset({ features: ['text', 'label'], num_rows: 7680 }) test: Dataset({ features: ['text', 'label'], num_rows: 1920 }) })
4.8分桶
#分桶
#把数据均匀分配到N个桶中
dataset_train.shard(num_shards=4, index=1) #num_shards=4分的桶数, index=1获取索引为1的桶里的数据
Dataset({ features: ['text', 'label'], num_rows: 2400 })
4.9列的重命名
#列的重命名
dataset_train.rename_column('text', 'context')
Dataset({ features: ['context', 'label'], num_rows: 9600 })
4.10删除列
#删除列
dataset_train.remove_columns(['text'])
Dataset({ features: ['label'], num_rows: 9600 })
4.11map()函数, 统一在相同位置添加相同信息
#map()函数, 统一在相同位置添加相同信息
def m_f(data):
data['text'] = 'My sentence:' + data['text']
return data
dataset_map = dataset_train.map(m_f)
dataset_map['text'][:5]
['My sentence:选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般', 'My sentence:15.4寸笔记本的键盘确实爽,基本跟台式机差不多了,蛮喜欢数字小键盘,输数字特方便,样子也很美观,做工也相当不错', 'My sentence:房间太小。其他的都一般。。。。。。。。。', 'My sentence:1.接电源没有几分钟,电源适配器热的不行. 2.摄像头用不起来. 3.机盖的钢琴漆,手不能摸,一摸一个印. 4.硬盘分区不好办.', 'My sentence:今天才知道这书还有第6卷,真有点郁闷:为什么同一套书有两种版本呢?当当网是不是该跟出版社商量商量,单独出个第6卷,让我们的孩子不会有所遗憾。']
4.12设置格式
#设置格式
dataset_train.set_format(type='torch', columns=['label'])
dataset_train[0]
{'label': tensor(1)}
4.13导出与加载csv这种常见格式
#导出为csv这种常见格式
dataset_train.to_csv(path_or_buf='../data/ChnSentiCorp/ChnSC.csv')
3032906 字节
#加载本地磁盘csv格式文件
#split='train'指定加载TensorFlow Datasets中的数据集的哪一部分,即训练集。
csv_dataset = load_dataset(path='csv', data_files='../data/ChnSentiCorp/ChnSC.csv', split='train')
csv_dataset[20]
{'text': '非常不错,服务很好,位于市中心区,交通方便,不过价格也高!', 'label': 1}
4.14导出与加载json这种常见格式
#导出成json格式文件
dataset_train.to_json(path_or_buf='../data/ChnSentiCorp/ChnSC.json')
6125321 字节
#加载json格式的数据
json_dataset = load_dataset(path='json', data_files='../data/ChnSentiCorp/ChnSC.json', split='train')
json_dataset[20]
{'text': '非常不错,服务很好,位于市中心区,交通方便,不过价格也高!', 'label': 1}