6.GitHub pytorch sentiment analysis(使用自己的数据集)

Using TorchText with Your Own Datasets

之前都是用的IMDB数据集,他是TorchText自带的。TorchText还有其他的数据集,包括分类,语言模型,是否是连续句子等等
然而大部分时间使用自己的数据,TorchText会帮你

一般步骤:
定义Fields
加载数据集
created the splits

TorchText可以读取3种格式的数据,json,tsv(用tab隔开的数据),csv(用逗号隔开)
作者的观点,最好的TorchText最好的格式是json,稍后解释

1.读取JSON

json格式长这样,每一行代表一个json对象

{"name": "John", "location": "United Kingdom", "age": 42, "quote": ["i", "love", "the", "united kingdom"]}
{"name": "Mary", "location": "United States", "age": 36, "quote": ["i", "want", "more", "telescopes"]}

定义fields

from torchtext import data
from torchtext import datasets

NAME = data.Field()
SAYING = data.Field()
PLACE = data.Field()

接下来要告诉TorchText,哪个field应用到json中的哪个元素
对于json数据,我们要创建一个字典,其中:
字典的键key,对应json对象中的key
字典的值value,是一个元组:其中元组的第一个元素是batch对象的属性名,第二个元素是Field的名称

fields = {'name': ('n', NAME), 'location': ('p', PLACE), 'quote': ('s', SAYING)}

注意点:
1.fields字典中的key的顺序无所谓,只要字典中的key对应上json数据中的key就行
2.Field名称不需要与json对象中的key的名称对应,例如我们用PLACE来对应location
3.处理json数据,并不是所有的keys都会被使用,例如,我们没有用age filed
4.如果json filed的值是字符串,那么Fields的tokenization 就会被应用(默认是根据空格分词),然而如果值是list列表,就不会tokenization。通常最好是先自己进行分词,分词成列表后在传入field,这样就不用等TorchText来处理
5.json fields 的值不一定要同一种格式,有些样本可以用“quote” 作为字符串,有些则是列表。tokenization只会应用于“quote’”作为字符串的
6.如果使用json field,样本必须有field的实例,在这个例子中,所有的元素都必须有name,location,和quote。 然而我们不使用age field,就无所谓是否有一个样本没有age field了

现在,在训练循环中,我们可以在data iterator上进行迭代,来通过batch.n来获取name,通过batch.p获取location,通过batch.s来获取quote

2.创建数据集

接着我们使用 TabularDataset.splits函数来创建数据集(text_data和train_data)
path 属性是明确数据文件夹所在的位置,train,和text指定其文件名,下面的例子中,训练集存储在 data/train.json这个位置

train_data, test_data = data.TabularDataset.splits(
                            path = 'data',
                            train = 'train.json',
                            test = 'test.json',
                            format = 'json',
                            fields = fields
)

如果已经有验证集

train_data, valid_data, test_data = data.TabularDataset.splits(
                                        path = 'data',
                                        train = 'train.json',
                                        validation = 'valid.json', #验证集
                                        test = 'test.json',
                                        format = 'json',
                                        fields = fields
)

查看一个样本

print(vars(train_data[0]))

{‘n’: [‘John’], ‘p’: [‘United’, ‘Kingdom’], ‘s’: [‘i’, ‘love’, ‘the’, ‘united kingdom’]}

注意到p中的"United Kingdom"是被分词了的,而s中的"United Kingdom"还保持原样,因为就像上面所说的,TorchText会对所有的json fields进行分词,除非它原本就是list格式

接下来就可以用train_data, test_data 和 valid_data 构建词汇表和迭代器了,就像之前的notebook一样。

3.读取TSV 文件

tsv和 csv格式很像,有如下样本

name    location    age quote
John    United Kingdom  42  i love the united kingdom
Mary    United States   36  i want more telescopes

第一行是header,也就是每一列的名称,在tsv和csv文件中,不能有list
创建fileds的方法跟json的不一样。我们现在使用的是由元组组成的列表,每个元组又是一个元组,
内部元组的第一个元素是batch对象的属性名,第二个元素是Field 名

fields = [('n', NAME), ('p', PLACE), (None, None), ('s', SAYING)]

并不像json数据,这个元组的数据顺序必须和原始文件里的列的顺序一致。当不用某列数据时,我们要用None,None来跳过那一列,

如果只用name,和locaton这两个属性,你只要设置前两个field元组就好,后面的不用设置为None,忽略即可

我们使用TabularDataset来读取tsv文件

train_data, valid_data, test_data = data.TabularDataset.splits(
                                        path = 'data',
                                        train = 'train.tsv',
                                        validation = 'valid.tsv',
                                        test = 'test.tsv',
                                        format = 'tsv',  #这里设置csv还是tsv
                                        fields = fields,  # 上面设置好了的
                                        skip_header = True  # 如果传入的数据有表头(属性名),必须设置为True,要不然会把第一行当样本
)

展示第一个样本

print(vars(train_data[0]))

4.读取CSV文件


fields = [('n', NAME), ('p', PLACE), (None, None), ('s', SAYING)]

train_data, valid_data, test_data = data.TabularDataset.splits(
                                        path = 'data',
                                        train = 'train.csv',
                                        validation = 'valid.csv',
                                        test = 'test.csv',
                                        format = 'csv',
                                        fields = fields,
                                        skip_header = True
)
print(vars(train_data[0]))

5.为什么JSON比CSV、TSV更好

csv和tsv不能存储lists,这意味着数据之前没被tokenized, 因此每一次运行脚本,通过TorchText读取数据,就要进行一次分词操作。
会花很多时间,因此,最好是先对数据集进行分词,然后将其储存在json格式中

TorchText会误认为tsv数据中的tab和csv中的都好是分列符号,会导致不必要的问题。

6. 构建迭代器

构建词汇表

NAME.build_vocab(train_data)
SAYING.build_vocab(train_data)
PLACE.build_vocab(train_data)

构建迭代器

默认的,train data会在每轮epoch进行洗牌,但训练集和验证集是按顺序排列的。然而TorchText不知道如何进行排列,如果不设置的话会报错。

有两种方法来处理,
第一种:告诉迭代器不对验证集和测试集进行排序,传入sort = False即可

import torch

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

BATCH_SIZE = 1

train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
    (train_data, valid_data, test_data),
    sort = False, #don't sort test/validation data
    batch_size=BATCH_SIZE,
    device=device)

第二种,传入sort_key告诉迭代器如何排序,例如 sort_key = lambda x: x.s, 就是告诉迭代器,按照s,也就是quote进行排序

import torch

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

BATCH_SIZE = 1

train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
    (train_data, valid_data, test_data),
    sort_key = lambda x: x.s, #sort by s attribute (quote)
    batch_size=BATCH_SIZE,
    device=device
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值