tensorflow之路-如何处理原始文本数据
来源:互联网 发布:华为紧急数据怎么处理 编辑:程序博客网 时间:2024/06/03 19:43
写这个系列的初衷在于,现在关于tensorflow的教程还是太少了,有也都是歪果仁写的。比如以下几个:
TensorFlow-Examples
tensorflow_tutorials
TensorFlow-Tutorials
Tensorflow-101
个人感觉这些教程对于新手来说讲解的并不细致,几乎都是作者写好了代码放到ipython notebook上,大家下载到本地run一run,很开心地得到结果,实际并不明白为什么要这么搭建,每一步得到什么样的结果。或者自己很想弄懂这些牛人的代码,但是官方的api文档对于入门来说还不够友好,看了文档也不太清楚,这时候十分渴望有人来指导一把。
因此我就萌生了写一个”手把手&零门槛的tensorflow中文教程”的想法。希望更多的人能了解deep learning和tensorflow,大家多多提意见,多多交流!
今天来解读的代码还是基于CNN来实现文本分类,这个问题很重要的一步是原始数据的读取和预处理,详细代码参看
(1) load data and labels
实验用到的数据是烂番茄上的moview reviews,先看看提供的数据长什么样
sorry, 图片缺失
可以看到,每一行是一条review,数据进行过初步的处理,但是类似于”doesn’t/it’s”这种并没有进行分割。后面会讲到这个问题。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
这个函数的作用是从文件中加载positive和negative数据,将它们组合在一起,并对每个句子都进行分词,因此x_text是一个二维列表,存储了每个review的每个word;它们对应的labels也组合在一起,由于labels实际对应的是二分类输出层的两个神经元,因此用one-hot编码成0/1和1/0,然后返回y。
其中,f.readlines()的返回值就是一个list,每个元素都是一行文本(str类型,结尾带有”\n”),因此其实不需要在外层再转换成list()
用s.strip()函数去掉每个sentence结尾的换行符和空白符。
去除了换行符之后,由于刚才提到的问题,每个sentence还需要做一些操作(具体在clean_str()函数中),将标点符号和缩写等都分割开来。英文str最简洁的分词方式就是按空格split,因此我们只需要将各个需要分割的部位都加上空格,然后对整个str调用split(“ “)函数即可完成分词。
labels的生成也类似。
(2) padding sentence
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
为什么要对sentence进行padding?
因为TextCNN模型中的input_x对应的是tf.placeholder,是一个tensor,shape已经固定好了,比如[batch, sequence_len],就不可能对tensor的每一行都有不同的长度,因此需要找到整个dataset中最长的sentence的长度,然后在不足长度的句子的末尾加上padding words,以保证input sentence的长度一致。
由于在load_data函数中,得到的是一个二维列表来存储每个sentence数据,因此padding_sentences之后,仍以这样的形式返回。只不过每个句子列表的末尾可能添加了padding word。
(3) build vocabulary
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
我们知道,collections模块中的Counter可以实现词频的统计,例如:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
Counter接受的参数是iterable,但是现在有多个句子列表,如何将多个sentence word list中的所有word由一个高效的迭代器生成呢?
这就用到了itertools.chain(*iterables),具体用法参考这里
将多个迭代器作为参数, 但只返回单个迭代器, 它产生所有参数迭代器的内容, 就好像他们是来自于一个单一的序列.
由此可以得到整个数据集上的词频统计,word_counts。
但是要建立字典vocabulary,就需要从word_counts中提取出每个pair的第一个元素也就是word(相当于Counter在这里做了一个去重的工作),不需要根据词频建立vocabulary,而是根据word的字典序,所以对vocabulary进行一个sorted,就得到了字典顺序的word list。首字母小的排在前面。
再建立一个dict,存储每个word对应的index,也就是vocabulary变量。
(4) build input data
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
由上面两个函数我们得到了所有sentences分词后的二维列表,sentences对应的labels,还有查询每个word对应index的vocabulary字典。
但是!!想一想,当前的sentences中存储的是一个个word字符串,数据量大时很占内存,因此,最好存储word对应的index,index是int,占用空间就小了。
因此就利用到刚生成的vocabulary,对sentences的二维列表中每个word进行查询,生成一个word index构成的二维列表。最后将这个二维列表转化成numpy中的二维array。
对应的lables因为已经是0,1的二维列表了,直接可以转成array。
转成array后,就能直接作为cnn的input和labels使用了。
(5) load data
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
最后整合上面的各部分处理函数,
1.首先从文本文件中加载原始数据,一开始以sentence形式暂存在list中,然后对每个sentence进行clean_str,并且分词,得到word为基本单位的二维列表sentences,labels对应[0,1]和[1,0]
2.找到sentence的最大长度,对于长度不足的句子进行padding
3.根据数据建立词汇表,按照字典序返回,且得到每个word对应的index。
4.将str类型的二维列表sentences,转成以int为类型的sentences,并返回二维的numpy array作为模型的input和labels供后续使用。
(6) generate batch
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
这个函数的作用是在整个训练时,定义一个batches = batch_iter(…),整个训练过程中就只需要for循环这个batches即可对每一个batch数据进行操作了。
- tensorflow之路-如何处理原始文本数据
- tensorflow之路-如何处理原始文本数据
- 如何处理原始文本数据(CNN情感分析yoom例子二)
- Python自然语言处理--处理原始文本
- Python自然语言处理 3 处理原始文本
- NLP with python 3 处理原始文本
- tensorflow用CNN 处理文本
- 数据挖掘 NLP 之 文本挖掘 文本处理 通用流程
- NLTK04《Python自然语言处理》code03 处理原始文本
- 对文本和数据进行处理之awk编程
- matlab之原始处理图像几何变换
- matlab之原始处理图像几何变换
- matlab之原始处理图像几何变换
- tensorflow如何自由处理梯度
- Linux文本处理之如何比较很长的字符串
- Golang之文本处理
- Tensorflow中如何加载数据
- 文本挖掘--数据文本处理-java
- XDOJ 1181
- 怎样查看本机外网ip
- sqlite3数据库命令
- 怎么打开VisualSVN图形化管理界面
- 使用Jenkins进行Android自动打包
- tensorflow之路-如何处理原始文本数据
- 已知集合A和B的元素分别用不含头结点的单链表存储, 求解集合A与B的差集,并将结果保存在集合A的单链表中
- JAVA学习笔记
- 使用javaNIO实现C/S模式的通信
- 【Bmob】Bemob对后台数据的增删改
- Zlib压缩库压缩比率和压缩性能测试 (1)
- RHEL7.2和RHEL6.5配置网络yum源和本地yum源
- 浅谈引用<二> Java中引用的分类
- Android WebView调试利器之 Chrome DevTools