当前位置:   article > 正文

情感分析中文本数据预处理_notebook情感分析的数据预处理

notebook情感分析的数据预处理

读数据

  • 直接获取文件内容

    1. # 获取文件内容 一个文件中有很多行信息,每一行是一个序列
    2. def getData(file):
    3. f = open(file,'r')
    4. raw_data = f.readlines()
    5. return raw_data
    6. # Read the file and split into lines 以换行符来分开和readlines 相似
    7. lines = open('data/%s-%s.txt' % (lang1, lang2), encoding='utf-8').\
    8. read().strip().split('\n')

                     

    1. #一个文件夹中有很多个文件,每一个文件是一个序列
    2. files = os.listdir(os.path.join(path,seg,label))
    3. for file in files:
    4. with open(os.path.join(path,seg,label,file),'r',encoding = 'utf-8') as rf:
    5. review = rf.read().replace('\n','')

     

  • 获取标签 对标签进行数字化

  • 每一个文件中的每一行前面是文本,后面是标签
    1. # Split every line into pairs and normalize
    2. pairs = [[normalizeString(s) for s in l.split('\t')] for l in lines]
    3. #normalize函数是一个正则化的函数,也就是使数据更加标准化的
    4. def normalizeString(s):
    5. s = unicodeToAscii(s.lower().strip())
    6. s = re.sub(r"([.!?])", r" \1", s)
    7. s = re.sub(r"[^a-zA-Z.!?]+", r" ", s)
    8. return s
    9. #如果只需要将text 和 label 分开 则可以
    10. pairs = [[l for l in l.split('\t')] for l in lines]

     

  • 构建label map直接后面添加 变成二分类问题
    1. if label == 'pos':
    2. data.append([review,1])
    3. else :
    4. data.append([review,0])

     

  • 构建labelmap

    1. label_map = {'pos':0,'neg':1}
    2. #转换
    3. y = label_map[d['type']] #根据label_map将label转换为数字表示

     

  • 观察数据分布,找到合适的长度作为截断长度。

    1. train_text = []
    2. for line in train_data:
    3. d = eval(line)
    4. t = jieba.cut(d['text'])
    5. train_text.append(t)
    6. sentence_length = [len(x) for x in train_text] #train_text是train.csv中每一行分词之后的数据 %matplotlib notebook
    7. import matplotlib.pyplot as plt
    8. plt.hist(sentence_length,1000,normed=1,cumulative=True)
    9. plt.xlim(0,1000)
    10. plt.show()

     

  • 由文本得到训练用的mini-batch数据

  • 分词
    1. #英文分词 只分空格即可
    2. vocab = [v.lower() for v in l.strip().split(' ')]
    3. #Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
    4. #注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
    5. #中文分词
    6. def tokenizer(x):
    7. res = [w for w in jieba.cut(x)]
    8. return res
    9. #注意去掉标点符号,一般使用正则表达式re

     

  •  
  • 去除停用词
    1. def stopwords_filter(filename,list_words_lemmatizer):
    2. list_filter_stopwords=[] #声明一个停用词过滤后的词列表
    3. with open(filename,'r') as fr:
    4. stop_words=list(fr.read().split('\n')) #将停用词读取到列表里
    5. for i in range(len(list_words_lemmatizer)):
    6. word_list = []
    7. for j in list_words_lemmatizer[i]:
    8. if j not in stop_words:
    9. word_list.append(j.lower()) #将词变为小写加入词列表
    10. list_filter_stopwords.append(word_list)
    11. return list_filter_stopwords
    12. #建立一个停用词表
    13. def stopwords(filepath):
    14. stopword=[]
    15. with open(filepath,'r') as f:
    16. for l in f.readllines():
    17. stopword.append(l.strip())
    18. return stopword

     

  • 建立词汇表
    1. vocab = set(chain(*train_tokenized))
    2. word_to_idx = {word:idx for idx,word in enumerate(vocab)}
    3. word_to_idx['<unk>'] = 0
    4. idx_to_word = {idx:word for idx,word in enumerate(vocab)}
    5. idx_to_word[0] = '<unk>'

     

  • 将分词去除停用词后的数据转换成下标数据,也就是转换成index。
    1. def indexesFromSentence( sentence):
    2. return [word2index[word] for word in sentence.split(' ')]
    3. def tensorFromSentence(lang, sentence):
    4. indexes = indexesFromSentence(lang, sentence)
    5. indexes.append(EOS_token)
    6. result = torch.LongTensor(indexes)
    7. return result

     

  • 将数据分成mini-batch
    1. 第一种是重写Dataset类,然后利用dataloader分batch
    2. from torch.utils.data import Dataset
    3. class TextDataset(Dataset):
    4. def __init__(self, dataload=prepareData, lang=['eng', 'fra']):
    5. self.input_lang, self.output_lang, self.pairs = dataload(
    6. lang[0], lang[1], reverse=True)
    7. self.input_lang_words = self.input_lang.n_words
    8. self.output_lang_words = self.output_lang.n_words
    9. def __getitem__(self, index):
    10. return tensorFromPair(self.input_lang, self.output_lang,
    11. self.pairs[index])
    12. def __len__(self):
    13. return len(self.pairs)
    14. #class torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=<function default_collate>, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None)
    15. #第二种,如果text和label都是Tensor的话,可以直接调用TensorDataset函数,然后再用dataloader读数据
    16. train_set = torch.utils.data.TensorDataset(train_features, train_labels)
    17. test_set = torch.utils.data.TensorDataset(test_features, test_labels)
    18. train_iter = torch.utils.data.DataLoader(train_set, batch_size=batch_size,
    19. shuffle=True)
    20. test_iter = torch.utils.data.DataLoader(test_set, batch_size=batch_size,
    21. shuffle=False)

     

  • 根据mini-batch中内个index对应的向量得到最终输入(一般在网络里,也就是embedding)

 

直接用torchtext来进行上述步骤

  1. TEXT = data.Field(sequential=True, tokenize=tokenizer,fix_length=1000,stop_words=stop_words)
  2. LABEL = data.Field(sequential=False,use_vocab=False)

torchtext 的组件 

Field :主要包含以下数据预处理的配置信息,比如指定分词方法,是否转成小写,起始字符,结束字符,补全字符以及词典等等

Dataset :继承自pytorch的Dataset,用于加载数据,提供了TabularDataset可以指点路径,格式,Field信息就可以方便的完成数据加载。同时torchtext还提供预先构建的常用数据集的Dataset对象,可以直接加载使用,splits方法可以同时加载训练集,验证集和测试集。

Iterator : 主要是数据输出的模型的迭代器,可以支持batch定制。

 

  • Field

  • Field 包含一写文本处理的通用参数的设置,同时还包含一个词典对象,可以把文本数据表示成数字类型,(即转换成index形式)进而可以把文本表示成需要的tensor类型完成了分词,固定长度,去掉停用词等
  • 以下是Field对象包含的参数:

    sequential: 是否把数据表示成序列,如果是False, 不能使用分词 默认值: True.

    use_vocab: 是否使用词典对象. 如果是False 数据的类型必须已经是数值类型. 默认值: True.

    init_token: 每一条数据的起始字符 默认值: None.

    eos_token: 每条数据的结尾字符 默认值: None.

    fix_length: 修改每条数据的长度为该值,不够的用pad_token补全. 默认值: None.为None则按每个Batch内的最大长度进行动态padding。

    tensor_type: 把数据转换成的tensor类型 默认值: torch.LongTensor.

    preprocessing:在分词之后和数值化之前使用的管道 默认值: None.

    postprocessing: 数值化之后和转化成tensor之前使用的管道默认值: None.

    lower: 是否把数据转化为小写 默认值: False.

    tokenize: 分词函数. 默认值: str.split.

    include_lengths: 是否返回一个已经补全的最小batch的元组和和一个包含每条数据长度的列表 . 默认值: False.

    batch_first: Whether to produce tensors with the batch dimension first. 默认值: False.

    pad_token: 用于补全的字符. 默认值: "<pad>".

    unk_token: 不存在词典里的字符. 默认值: "<unk>".

    pad_first: 是否补全第一个字符. 默认值: False.

  1. TEXT = data.Field(tokenize=data.get_tokenizer('spacy'), init_token='<SOS>', eos_token='<EOS>',lower=True)
  2. Lable = data.Field(squential = False,use_vocab = False)

2.Dataset

torchtext的Dataset是继承自pytorch的Dataset,提供了一个可以下载压缩数据并解压的方法(支持.zip, .gz, .tgz)完成了读取数据问题

splits方法可以同时读取训练集,验证集,测试集

TabularDataset可以很方便的读取CSV, TSV, or JSON格式的文件,例子如下:

  1. train, val, test = data.TabularDataset.splits( path='./data/',
  2. train='train.tsv', validation='val.tsv', test='test.tsv',
  3. format='tsv', fields=[('Text', TEXT), ('Label', LABEL)])

加载数据后可以建立词典,建立词典的时候可以使用与训练的word vector

TEXT.build_vocab(train, vectors="glove.6B.100d")

3. Iterator           完成了分batch的问题

Iterator是torchtext到模型的输出,它提供了我们对数据的一般处理方式,比如打乱,排序,等等,可以动态修改batch大小,这里也有splits方法 可以同时输出训练集,验证集,测试集,类似dataloader

参数如下:

dataset: 加载的数据集

batch_size: Batch 大小.

batch_size_fn: 产生动态的batch大小 的函数

sort_key: 排序的key

train: 是否是一个训练集

repeat: 是否在不同epoch中重复迭代

shuffle: 是否打乱数据

sort: 是否对数据进行排序

sort_within_batch: batch内部是否排序

device: 建立batch的设备 -1:CPU ;0,1 ...:对应的GPU

 

  1. train_iter, val_iter, test_iter = data.Iterator.splits( (train, val, test),
  2. sort_key=lambda x: len(x.Text), batch_sizes=(32, 256, 256), device=-1)

4.其他

torchtext提供常用文本数据集,并可以直接加载使用:

train,val,test = datasets.WikiText2.splits(text_field=TEXT)

现在包含的数据集包括:

 

  • Sentiment analysis: SST and IMDb
  • Question classification: TREC
  • Entailment: SNLI
  • Language modeling: WikiText-2
  • Machine translation: Multi30k, IWSLT, WMT14
    1. import spacy
    2. import torch
    3. from torchtext import data, datasets
    4. spacy_en = spacy.load('en')
    5. def tokenizer(text): # create a tokenizer function
    6. return [tok.text for tok in spacy_en.tokenizer(text)]
    7. TEXT = data.Field(sequential=True, tokenize=tokenizer, lower=True, fix_length=150)
    8. LABEL = data.Field(sequential=False, use_vocab=False)
    9. train, val, test = data.TabularDataset.splits( path='./data/', train='train.tsv', validation='val.tsv', test='test.tsv', format='tsv', fields=[('Text', TEXT), ('Label', LABEL)])
    10. TEXT.build_vocab(train, vectors="glove.6B.100d")
    11. train_iter, val_iter, test_iter = data.Iterator.splits( (train, val, test), sort_key=lambda x: len(x.Text), batch_sizes=(32, 256, 256), device=-1)
    12. vocab = TEXT.vocab

     

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/725401
推荐阅读
相关标签
  

闽ICP备14008679号