TensorFlow练习1: 对评论进行分类

TensorFlow是谷歌2015年开源的一个深度学习库,到现在正好一年。和TensorFlow类似的库还有Caffe、Theano、MXNet、Torch。但是论火爆程度,TensorFlow当之无愧,短短一年就在Github就收获了4万+颗星,把前面几个库获得的star加起来也不敌TensorFlow。

TensorFlow使用C++开发,并提供了Python等语言的封装。如命名一样,TensorFlow为张量从图一端流动到另一端的计算过程,可以把张量看作矩阵(矩阵rank为2,Tensor的rank更高)。TensorFlow并不是一个抽象程度特别高的库,但是它实现了所有深度学习所需的函数。貌似有几个高度抽象的库使用TensorFlow做为后端。

TensorFlow可被用于语音识别或图像识别等多项机器深度学习领域,它可在小到手机、大到数千台服务器上运行。

本帖展示怎么使用TensorFlow实现文本的简单分类,判断评论是正面的还是负面的。

使用的数据集

我本想使用Python爬一些淘宝评论,但是脚本做到一半卡壳了,搞得火起。然后我上网找现成的数据,只找到了英文的电影评论数据(其实不管是英文还是中文,处理逻辑都一样)。

TensorFlow练习1: 对评论进行分类

如果你有一些好数据愿意分享,感激不尽。

由于处理的是字符串,我们首先要想方法把字符串转换为向量/数字表示。一种解决方法是可以把单词映射为数字ID。

第二个问题是每行评论字数不同,而神经网络需要一致的输入(其实有些神经网络不需要,至少本帖需要),这可以使用词汇表解决。

代码部分

安装nltk(自然语言工具库 Natural Language Toolkit

下载nltk数据:

ntlk有详细安装文档。

测试nltk安装:

Python代码:

执行结果:

TensorFlow练习1: 对评论进行分类

准确率真tm喜人,才60%多,比瞎猜强点有限。

那么问题出在哪呢?

准确率低主要是因为数据量太小,同样的模型,如果使用超大数据训练,准确率会有显著的提升。

下文我会使用同样的模型,但是数据量要比本文使用的多得多,看看准确率能提高多少。由于本文使用的神经网络模型(feed-forward)过于简单,使用大数据也不一定有质的提升,尤其是涉及到自然语言处理。

相关文章

《TensorFlow练习1: 对评论进行分类》有21个想法

  1. tokenize 後有 230193 字
    lemmatize 後 word_count 裡有 18642 字
    用 20 < word_count[word] < 2000 篩選後剩下 1065 字
    篩掉太多了

  2. 这异常该怎么改呢?
    Traceback (most recent call last):
    File “06021.py”, line 92, in
    dataset = normalize_dataset(lex)
    File “06021.py”, line 86, in normalize_dataset
    one_sample = string_to_vector(lex, line, [0,1]) # [array([ 0., 0., 0., …, 0., 0., 0.]), [0,1]]]
    File “06021.py”, line 70, in string_to_vector
    words = [lemmatizer.lemmatize(word) for word in words]
    File “/usr/local/lib/python2.7/dist-packages/nltk/stem/wordnet.py”, line 40, in lemmatize
    lemmas = wordnet._morphy(word, pos)
    File “/usr/local/lib/python2.7/dist-packages/nltk/corpus/reader/wordnet.py”, line 1794, in _morphy
    forms = apply_rules([form])
    File “/usr/local/lib/python2.7/dist-packages/nltk/corpus/reader/wordnet.py”, line 1775, in apply_rules
    if form.endswith(old)]
    UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xc2 in position 4: unexpected end of data

  3. 感觉都是大神呀,终于跑通了一个程序,准备研究当中。。。。很显然我还没有非常懂里面的内容。。。

  4. 新手偷懒去掉了词形还原的步骤,直接把r’\w+’匹配的结果作为words,只保留出现次数<10次的单词,epochs和batch_size都设为为10,结果跑出来88%的正确率。。。

  5. 0 : 60996.565155
    1 : 60996.565155
    2 : 60996.565155
    3 : 60996.565155
    4 : 60996.565155
    5 : 60996.565155
    6 : 60996.565155
    7 : 60996.565155
    8 : 60996.565155
    9 : 60996.565155
    10 : 60996.565155
    11 : 60996.565155
    12 : 60996.565155
    准确率: 0.681989

    贴下我的系统版本,方便后来的同学,调试
    Python 3.6.1 (default, Mar 27 2017, 00:27:06)
    [GCC 6.3.1 20170306] on linux
    python-tensorflow 1.1.0-4
    改了两个,一处是Geoffrey说的
    def string_to_vector(lex, review, clf):
    words = word_tokenize(line.lower())
    Should be this instead?:
    def string_to_vector(lex, review, clf):
    words = word_tokenize(review.lower())
    要改成这个样子
    words = word_tokenize(review.lower())

    第二处是cost_func这里,可能是Tensorflow版本升级代来的改变
    cost_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(predict, Y))
    这句我是改成了下面这样的
    cost_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predict, labels=Y))

    然后通过的
    对了 我用的Archlinux,都是新的软件,从库里安装的,没有手动安装

    机器里存在python2和python3搞半天没搞好,最后没办法只好安装了个pycharm去自动修改python的环境

  6. “named arguments (labels=…, logits=…, …)” % name)
    ValueError: Only call softmax_cross_entropy_with_logits with named arguments (labels=…, logits=…, …)
    一直出现这个问题,后来改了下参数可以了
    tf.nn.softmax_cross_entropy_with_logits(None,Y, predict)

    但是在win10系统上出现这个问题,一直没解决:
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “BestSplits” device_type: “CPU”‘) for unknown op: BestSplits
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “CountExtremelyRandomStats” device_type: “CPU”‘) for unknown op: CountExtremelyRandomStats
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “FinishedNodes” device_type: “CPU”‘) for unknown op: FinishedNodes
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “GrowTree” device_type: “CPU”‘) for unknown op: GrowTree
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “ReinterpretStringToFloat” device_type: “CPU”‘) for unknown op: ReinterpretStringToFloat
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “SampleInputs” device_type: “CPU”‘) for unknown op: SampleInputs
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “ScatterAddNdim” device_type: “CPU”‘) for unknown op: ScatterAddNdim
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “TopNInsert” device_type: “CPU”‘) for unknown op: TopNInsert
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “TopNRemove” device_type: “CPU”‘) for unknown op: TopNRemove
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “TreePredictions” device_type: “CPU”‘) for unknown op: TreePredictions
    E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel (‘op: “UpdateFertileSlots” device_type: “CPU”‘) for unknown op: UpdateFertileSlots

    1. 你把 def train_neural_network(X, Y)里面的train_x = dataset[:, 0]改成了train_x = train_dataset[:, 0] 吗? 改了后准确率才六十多

  7. i和epoch_loss应该在每epoch开始的时候初始化为0吧,按照你现在的代码只会进行一epoch,后面的epoch由于i没再初始化,所以根本不做任何事啊。

  8. 多挑兩個小bug:
    line 28-29:
    def process_file(f):
    with open(pos_file, ‘r’) as f:
    Should be this instead?:
    def process_file(txtfile):
    with open(txtfile, ‘r’) as f:

    line 63-64:
    def string_to_vector(lex, review, clf):
    words = word_tokenize(line.lower())
    Should be this instead?:
    def string_to_vector(lex, review, clf):
    words = word_tokenize(review.lower())

    算出來才50中間, 比你的更喜感/-\ 從代碼學到處理文字數據和tensorflow挺多, 感謝!

  9. 请问def train_neural_network(X, Y)里面的train_x = dataset[:, 0]是否应该是train_x = train_dataset[:, 0],这里不应该拿全部数据去训练哇。

发表评论

电子邮件地址不会被公开。 必填项已用*标注