TensorFlow2实战-系列教程10:RNN文本分类2

TensorFlow2实战-系列教程 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Jupyter Notebook中进行
本篇文章配套的代码资源已经上传

4、构建语料表

构建语料表,基于词频来进行统计。
比如我现在有一组数据有一万篇文章,这些文章中所有的词出现的次数进行统计,将所有不重复的词统计出来

counter = Counter()
with open('./data/train.txt',encoding='utf-8') as f:
    for line in f:
        line = line.rstrip()
        label, words = line.split('\t')
        words = words.split(' ')
        counter.update(words)
words = [''] + [w for w, freq in counter.most_common() if freq >= 10]
print('Vocab Size:', len(words))
Path('./vocab').mkdir(exist_ok=True)
with open('./vocab/word.txt', 'w',encoding='utf-8') as f:
    for w in words:
        f.write(w+'\n')
  1. 构建一个计数器
  2. 打开训练数据txt文件
  3. 遍历每一条数据
  4. 移除每行末尾的空白字符(如换行符)
  5. 通过 ‘\t’ 制表符分离出标签和数据
  6. 通过空格将数据的每一个单词分类出来成一个数组
  7. 更新 Counter 对象,计数每个单词的出现次数
  8. 将 counter 对象中出现频率大于或等于 10 的单词加入词汇表。词汇表以特殊标记 ‘’ 开始,这通常用于填充较短的文本序列,以便所有文本序列长度一致。如果在所有数据中出现次数小于10的就不要了
  9. 打印词汇表的大小(即不同单词的数量)
  10. 创建一个目录来存储词汇表文件
  11. 打开文件 word.txt 并以写入模式写入所有词汇。每个词汇写入一行。

打印结果:

Vocab Size: 20598

这个结果就是表示,最后一共有20598在我们的语料表中,这相当于我们这个任务的词典
打开保存的语料表文件看看:

TensorFlow2实战-系列教程10:RNN文本分类2_第1张图片 TensorFlow2实战-系列教程10:RNN文本分类2_第2张图片
word2idx = {}
with open('./vocab/word.txt',encoding='utf-8') as f:
    for i, line in enumerate(f):
        line = line.rstrip()
        word2idx[line] = i

得到新的word2id映射表

  1. word2idx 是一个词典数据结构,这里表示这20000多个词对应的索引,key就是词,value就是索引值
  2. 打开文件
  3. 遍历每一行
  4. 直接把行索引作为词的索引

5、embedding

  • 可以基于网络来训练,也可以直接加载预训练的,一般都是加载预训练模型
  • 这里有一些常用的

TensorFlow2实战-系列教程10:RNN文本分类2_第3张图片
文本数据,分解为一个一个单词,再根据语料表做成索引,再将索引做成向量,这个过程称为embedding即词嵌入:
TensorFlow2实战-系列教程10:RNN文本分类2_第4张图片
在data文件夹中,有3个文件,分别是glove.6B.50d.txt、train.txt、test.txt,其中glove.6B.50d.txt就是上图展示的界面,一共有40万行即40万个词,每个单词都被转换成了向量,这里是一个50维的向量。

所以词嵌入应该就是有一个大表,每个词都有一个对应的向量。

embedding = np.zeros((len(word2idx)+1, 50))
with open('./data/glove.6B.50d.txt',encoding='utf-8') as f:
    count = 0
    for i, line in enumerate(f):
        if i % 100000 == 0:
            print('- At line {}'.format(i))
        line = line.rstrip()
        sp = line.split(' ')
        word, vec = sp[0], sp[1:]
        if word in word2idx:
            count += 1
            embedding[word2idx[word]] = np.asarray(vec, dtype='float32')
  1. 这里的embedding是一个初始化,做成一个len(word2idx)+1)*50的矩阵,全部为0,这里的+1表示未知的一个词
  2. 打开glove.6B.50d.txt这个词嵌入文件
  3. 计数器
  4. 遍历这个文件的所有行,即所有单词
  5. 每一万次
  6. 打印一条信息
  7. 按照行进行分隔
  8. 将行按照空格进行分割
  9. 第一个为当前的词,第二个为这个词对应的向量
  10. 如果这个词在语料表中
  11. 计数器+1
  12. word2idx[word]是词对应的索引,按照索引在embedding中定位,更新embedding对应的向量

打印结果:

At line 0
At line 100000
At line 200000
At line 300000

所以这里的embedding 是一个ndarray,需要和word2idx字典配合使用

print("[%d / %d] words have found pre-trained values"%(count, len(word2idx)))
np.save('./vocab/word.npy', embedding)
print('Saved ./vocab/word.npy')

将前面的embedding 保存下来
打印结果:

[19676 / 20598] words have found pre-trained values
Saved ./vocab/word.npy

你可能感兴趣的:(TensorFlow,tensorflow,rnn,nlp,文本分类,深度学习)