我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:港彩神鹰 > 读入文本 >

手把手教你用 TensorFlow 实现文本分类(上)

归档日期:04-23       文本归类:读入文本      文章编辑:爱尚语录

  由于需要学习语音识别,期间接触了深度学习的算法。利用空闲时间,想用神经网络做一个文本分类的应用, 目的是从头到尾完成一次机器学习的应用,学习模型的优化方法,同时学会使用主流的深度学习框架(这里选择tensorflow)。

  文章分为两部分,本文仅实现流程,用简单的softmax回归对文本进行分类,后面一篇文章再从流程的各个方面对模型进行优化,达到比较好的效果。

  该部分不是这里的重点,数据从各大新闻网站爬取新闻文本,分十类保存到本地,包括科技、生活、体育、娱乐等。文本分别保存到training_set和testing_set目录下,如:

  文本以text_id.txt的格式保存在不同类的目录下(如text_1234.txt)。本例保存了共113673个训练文本和等数量的测试文本(暂时按1:1的比例)。

  通俗来讲,文本分类的主要思想,是构建各类文本的汉语词典,通过对文本进行分析,观察文本中哪类词汇比较多,由此判断文本所属类别。因此,文本分类需要对文本进行分词操作,可以选择的分词工具很多,这里选择Python编写的jieba开源库对文本进行分词,并以行为单位,将文本保存到输出文件,该部分实现比较简单:

  函数传入参数为数据集目录路径,以及数据集类型(train or test)。结果文件保存形如train.txt,后续的操作在该输出文件基础之上。输出文件格式为: words

  这部分主要删去文本中的停用词,停用词包括一些对于文本分类无用,而且出经常出现的词汇或符号,如“因此”、“关于”、“嘿嘿”、标点符号等。去除停用词需根据停用词典,去除上面经过分词操作的文本中的停用词。停用词典可以根据自己需要生成或在网络上获得,这里后面源码链接中会给出使用的停用词词典。

  代码中经过简单的按行读文本,然后搜索停用词典,如果文本中的词汇在词典中,则跳过,否则保存。这里每行对应数据集中的一个文本。

  上面提到文本分类需要得到能表征各类文本的汉语词典,这部分的主要思路是实现tf_idf算法自动提取关键词,根据词频(TF)和逆文档频率(IDF)来衡量词汇在文章中的重要程度。这里词频的计算采用公式:

  由于是衡量某类文本的关键词,公式中的“文章”为某类所有文本的总和。逆文档频率计算采用公式:

  上面的文档总数为train数据集所有文本的数目。tf-idf为两个指标的乘积,计算各类文本中所有词汇的tf-idf,由小到大排序,默认取前500个词汇作为该类的关键词保存到词典。最终生成大小为5000的词典。简洁考虑,该部分的关键代码(gen_dict方法中):

  class_dict是类id到该类文本信息(text_info)的字典,text_info.wordmap保存了该类文本的所有不重复的词汇,text_info.tf_idf方法计算该类文本某词的tf-idf,输入参数为词汇,词汇在整个语料库出现的文本数和语料库的文本数。text_info.get_mainwords方法得到该类本前500个关键词。完整的定义与实现参考源码。

  该部分实现向量化文本,利用生成的词典,以行为单位将去停用词后的文本转换为向量,这里向量为5000维。如果文本出现词典中的某词汇,则文本向量对应词典中该词汇的位置的计数累加。最终生成文件,行数为文本数,列为5000。此外生成对应的label文件,行数为文本数,对应于文本向量文件行,列为1,对应某文本的类别(1-10)。该部分代码比较简单,实现在gen_wordbag方法中。

  到此完成了文本的预处理,接下来针对不同分类算法,将有不同的处理,这里参考tensotflow处理MNIST数据集,读取预处理后的文本到系统,进行线性回归。

  该部分主要包括两部分,一是从磁盘读取向量化后的文本保存到numpy数组,将数据和类别分别存储,数据保存为二维(text_line_num, 5000)的数组,text_line_num为数据集的文本数,5000为词典的维度,也是后面模型输入参数的个数。类别保存为标签向量(label_line_num, 1),label_line_num,同样为数据集的大小。

  为方便处理,将类别10的标签保存为0,并对label进行“one_hot”处理,这部分解释可参考上个tensotflow链接。该部分在datasets类中实现。需要注意的是这里train部分数据最为cv(cross validation)数据,这里暂时不会用到。此外,由于数据较多,为节省内存,提高整体运算速度,分别读取train数据集和test数据集。dataset类中保存不同类型的数据集,并实现next_batch方法,获取指定数目的数据。

  该部分利用softmax回归对数据进行训练,对于tensorflow的使用这里不作介绍。完整代码如下:

  ● x : 对于输入数据,None占位符标示输入样本的数量,5000为单个样本的输入维度,对应字典维度。

  ● y_ : 真实样本的类别,从数据集读入,None占位符标示输入样本的数量,10为输出的维度。

  ● cross_entropy: 交叉熵,衡量真实值与预测值的偏差程度,训练过程中目的是最小化该值。

  训练对cross_entropy进行梯度下降算法更新参数,学习率为0.01。迭代1000次,每次使用100个训练集。最后保存训练的模型到指定目录。

  直接通过上面过程训练模型,得到的准确率大概为65%,虽然比10%高出许多,仍然属于比较低的准确率。在后面一篇文章重点对上面的过程进行改进,提高预测的准确性。

  此外,值得一提的是,一开始,直接参考tensorflow官网给的例子进行训练会出现准确率为0的现象,观察TensorBord,发现权重和偏重一直不更新,打印W和b发现值为Nan,最后找到问题所在:

  使用交叉熵作为cost function,由于文本矩阵为严重稀疏矩阵,导致出现y_ tf.log(y)结果为0log0的现象。导致训练参数为Nan,给预测值加一个极小的值,防止与测试为0。

本文链接:http://chuyenchame.com/duruwenben/101.html