3

torchtext能够读取包含一些列的文件,每列对应一个字段。如果我想创建一个新列(我将用作功能)怎么办?例如,假设文件有两列,文本和目标,我想从文本中提取一些信息并生成一个新特征(例如,如果它包含某些单词),我可以直接torchtext这样做还是需要这样做它在文件之前?

谢谢!

4

1 回答 1

0

可以办到。

def postprocessing(arr,vocab,pad_token):
    # required to pad the sequence
    max_len = max([len(a) for a in arr])
    l = []
    for a in arr:
        res = max_len - len(a)
        if res > 0:
            a.extend([[pad_token]*len(a[0])]*res)
        l.append(a)
    return l

def featurization(text_list):
    # creates character level features
    # text_list is a list of characters.
    features = []
    for ch in text_list:
        l = []
        l.append(1 if ch.isupper() else 0)
        l.append(1 if ch in string.digits else 0)
        l.append(1 if ch in string.punctuation else 0)
        features.append(l)
    return features

temp_data = pd.read_csv("../data/processed/data.csv")

下面的步骤是必要的,只需要我们想要处理的那些列并且列顺序很重要

temp_data.loc[:,["text","label"]].to_csv("temp.csv",index=False)

创建文本、特征和目标字段。在这里,我将一个句子标记为字符。

TEXT = torchtext.data.Field(sequential=True, use_vocab=True,
                               tokenize=lambda x: list(x), include_lengths=True,
                               batch_first=True)
    

LABEL_PAD_TOKEN=-1
FEAT = torchtext.data.LabelField(use_vocab=False,batch_first=True,preprocessing=featurization,
                                    pad_token=None,postprocessing=lambda x, _:postprocessing(x,_,LABEL_PAD_TOKEN))

LABELS = torchtext.data.Field(use_vocab=False,pad_token=LABEL_PAD_TOKEN,unk_token=None,
                                  batch_first=True,dtype=torch.int64,tokenize=lambda x: list(x),
                                 preprocessing=lambda x:[eval(i) for i in x])
    

在 TabularDataset 中,正确的字段顺序应与 temp.csv 列顺序相匹配。

train_data = torchtext.data.TabularDataset(path="temp.csv",format="csv",skip_header=True,
                                               fields=[(("text","feat"),(TEXT,FEAT)),
                                                       ("labels",LABELS)])
TEXT.build_vocab(train_data)
    
train_data,valid_data = train_data.split() # create train val 

构建迭代器

   train_iter,valid_iter=torchtext.data.BucketIterator.splits((train_data,valid_data,),batch_size=2,device=device                                                                  ,sort_within_batch=True,sort_key=lambda x:len(x.text))
            
a = next(iter(train_iter))
a.feat.shape, a.text[0].shape   # printing the shape 

(torch.Size([2, 36, 3]), torch.Size([2, 36]))

接下来,您可以将文本传递给嵌入input[batch_size, seq_len]output [batch_size, seq_len, emb_dim]

这些特征的形状是[batch_size, seq_len,3]因为我们有 3 个特征

在最后一个维度上连接这两个[batch_size, seq_len, emb_dim+3]并将其传递给 LSTM 或 CNN

于 2020-07-14T16:13:09.800 回答