zoukankan      html  css  js  c++  java
  • 如何科学地使用keras的Tokenizer进行文本预处理

    如何科学地使用keras的Tokenizer进行文本预处理

    缘起

    之前提到用keras的Tokenizer进行文本预处理,序列化,向量化等,然后进入一个simple的LSTM模型中跑。但是发现用Tokenizer对象自带的 texts_to_matrix 得到的向量用LSTM训练不出理想的结果,反倒是换成Dense以后效果更好。后来实验了一下发现是对这个向量化函数的理解出现了偏差。鉴于网上没找到相关的讲解,就自己实验了一下,并在这里做一个总结。

    关于Tokenizer

    原本以为直接用 texts_to_matrix 方法就可以直接把texts中的每个text,也就是每个string都转成LSTM输入所需要的向量,于是直接输入进去LSTM了。其实稍微一想就可以发现,LSTM要求的是每个string都是一个(num of word , length of word vector) 的矩阵,而这个函数出来的则是一个一维的向量,显然是有问题的。当时误判是因为没有仔细看,看到to matrix 并且得到了0-1的binary的matrix就想当然地当做输入了。那么下面就来看一下这个matrix究竟是什么:

    somestr = ['ha ha gua angry','howa ha gua excited']
    tok = tt.Tokenizer()
    tok.fit_on_texts(somestr)
    tok.word_index
    Out[74]: {'angry': 3, 'excited': 5, 'gua': 2, 'ha': 1, 'howa': 4}
    tok.word_counts
    Out[75]: OrderedDict([('ha', 3), ('gua', 2), ('angry', 1), ('howa', 1), ('excited', 1)])
    tok.texts_to_matrix(somestr)
    Out[76]: 
    array([[ 0.,  1.,  1.,  1.,  0.,  0.],
           [ 0.,  1.,  1.,  0.,  1.,  1.]])

    可以看出,实际上这是一个binary的向量,如果dictionary的下标为i 的那个词在这个string中出现了,那么就给一个1,否则给0。当然,可以通过mode参数,进行设置,比如改成counts或者freq:

    tok.texts_to_matrix(somestr,mode='count')
    Out[83]: 
    array([[ 0.,  2.,  1.,  1.,  0.,  0.],
           [ 0.,  1.,  1.,  0.,  1.,  1.]])
    tok.texts_to_matrix(somestr,mode='freq')
    Out[84]: 
    array([[ 0.  ,  0.5 ,  0.25,  0.25,  0.  ,  0.  ],
           [ 0.  ,  0.25,  0.25,  0.  ,  0.25,  0.25]])

    Tokenizer实际上只是生成了一个字典,并且统计了词频等信息,并没有把文本转成需要的向量表示。
    如果Tokenizer加上num_words这个参数,那么生成的就是列数为这个参数的matrix,其中包含单词表中most frequent的单词的binary或者count或者词频。

    科学地使用Tokenizer

    所以科学使用Tokenizer的方法是,首先用Tokenizer的 fit_on_texts 方法学习出文本的字典,然后word_index 就是对应的单词和数字的映射关系dict,通过这个dict可以将每个string的每个词转成数字,可以用texts_to_sequences,这是我们需要的,然后通过padding的方法补成同样长度,在用keras中自带的embedding层进行一个向量化,并输入到LSTM中。

    somestr = ['ha ha gua angry','howa ha gua excited naive']
    tok = tt.Tokenizer()
    tok.fit_on_texts(somestr)
    tok.word_index
    Out[90]: {'angry': 3, 'excited': 5, 'gua': 2, 'ha': 1, 'howa': 4, 'naive': 6}
    tok.texts_to_sequences(somestr)
    Out[91]: [[1, 1, 2, 3], [4, 1, 2, 5, 6]]

    2018年03月05日16:11:27
    大地春又回,长空裂惊雷。万物生欲动,无为自有为。 —— 诗人,余世存

  • 相关阅读:
    一周之内了解一个行业的方法
    du命令 实现Linux 某个文件夹下的文件按大小排序
    蝴蝶效应、青蛙现象、鳄鱼法则、鲇鱼效应.......
    MYSQ提高L查询效率的策略总结
    12个高矮不同的人,排成两排(catalan数)
    四人过桥、三盏灯 三个开关 的答案
    给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。
    一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
    二分检索(查找)的各种变种
    排序算法稳定性
  • 原文地址:https://www.cnblogs.com/morikokyuro/p/13256789.html
Copyright © 2011-2022 走看看