#使用keras准备文本数据
深度学习模型不会在原始文件中做任何处理的,为了使用深度学习模型,文本数据必须编码为数字,这样才可以顺利的使用机器学习和深度学习模型,keras深度学习库提供了一些基本的工具来帮助预处理文本数据。本章中你将学习如何使用keras准备文本数据。在本教程中你将了解:
- 关于可用于快速准备文本数据的便捷方法
- Tokenizer API,适用于训练数据,用于编码训练,验证和测试文档
- Tokenizer API提供4中不同文档编码方案。
4.1 教程简述
本教程分为以下几个部分:
- 用text_to_word_sequence()分词
- 如何转换成one-hot编码
- 适用hash_trick进行哈希编码
- 使用分词API,Tokenizer API
4.2 使用text_to_word_sequence分词
使用文本的第一步是将其拆分为单词,单词称为标记(token),将文本拆分为标记的过程称为标记化(tokeniztion)。Keras提供了函数text_to_word_sequence(),使用该函数,将文本拆分为单词列表。默认情况下,该函数自动执行下面三个操作:
- 按空格拆分单词
- 过滤掉标点符号
- 将文本转换为小写
你可可以将参数传递给函数来改变这些默认值,下面是使用text_to_word_sequence()函数将文档拆分为单词列表的示例:
from tensorflow.python.keras.preprocessing import text
texts = 'The quick brown fox junped over the lazy dog.'
result = text.text_to_word_sequence(
text=texts,
lower=True
)
print(result)
运行该示例将创建一个包含文档中所有单词的数组:
['the', 'quick', 'brown', 'fox', 'junped', 'over', 'the', 'lazy', 'dog']
这是文本处理的第一步,在使用文本之前还需要进一步预处理。
4.3 使用one_hot 编码
将文档表示为整数值序列是很流行的,其中文档中的每一个单词都被表示为唯一的整数。keras提供one_hot函数,使用one_hot函数可以对文本文档进行标记化这整数编码。该名称表明它将文档转化为ont_hot形式的编码。one_hot函数是下一节hashing_trick函数的包装饰器,返回文档的整数编码版本,散列函数的式使用意味着可能存在冲突,而且并不是所有的单词将被分配唯一的整数值,以上一节的text_to_word_sequence函数一样,one_hot函数将长串字符,按空格划分单词,让单词小写,过滤掉标点符号。
除了文本外,还必须指定词汇量(总词数),这个数字应该是你编码文档的数,当然如果你希望未来能更好的处理其他文档,这个词汇量会非常大。词汇表的大小定义了散列单词的散列空间。默认情况下使用散列函数,尽管我将在下一节中看到,可以直接调用hashing_trick函数时指定备用散列函数。
与上一节介绍的text_to_word_sequence函数将文档拆分为单词,然后使用集合操作获取文档的所有独立词,从上一节中我我们也能看到,所有的单词汇聚在一个列表中。该列表的大小反映了该文档词汇量的大小。
from tensorflow.python.keras.preprocessing.text import text_to_word_sequence
texts = 'The quick brown fox junped over the lazy dog.'
words = set(text_to_word_sequence(texts))
vocab_size = len(words)
print(vocab_size)
其结果是:
8
我们可以将它和one_hot函数放在一起使用,并对文档中的单词进行编码,下面列出了完整的示例:
from tensorflow.python.keras.preprocessing.text import text_to_word_sequence
from tensorflow.python.keras.preprocessing.text import one_hot
texts = 'The quick brown fox junped over the lazy dog.'
words = set(text_to_word_sequence(texts))
vocab_size = len(words)
print(vocab_size)
result = one_hot(texts,round(vocab_size*1.3))
print(result)
其结果:
8
[7, 2, 2, 6, 7, 7, 7, 5, 8]
注:由于随机性,你的结果回和的的不一样。
4.4 使用hashing_trick进行哈希编码
下面我们来看看hashing_trick怎么编码:
from tensorflow.python.keras.preprocessing.text import text_to_word_sequence,hashing_trick
texts = 'The quick brown fox junped over the lazy dog.'
words = set(text_to_word_sequence(texts))
vocab_size = len(words)
print(vocab_size)
result = hashing_trick(texts,round(vocab_size*1.3),hash_function='md5')
print(result)
结果为:
8
[6, 4, 1, 2, 7, 5, 6, 2, 6]
这里大部分都和上一节一样,其中将one_hot变为hashing_trick。hashing_trick函数对分词后的文档进行编码,但是和one_hot不同的是hashing_trick更加灵活,它允许指定散列或者其他的散列函数,比如上面内置的md5函数,也可以是自己定义的函数。
4.5 Tokenizer API
到目前为止,我们已经了解了使用keras准备文本的快捷方法,但是这不是Keras文本预处理的全部,Keras提供了大量的效率更好的文本处理API,用于当个或多个文本文档的预处理,许多成功的商业项目就是大量使用Keras内置的API进行文本预处理。Keras提供了Tokenizer类,用于深度学习文本文档的预处理。首先引入并实例化Tokenizer,接着就可以使用这个Tekenizer对文本处理或者对文本进行编码。
from tensorflow.python.keras.preprocessing.text import Tokenizer
docs = [
'hellow,Jena',
'Well done',
'Good work',
'nice day',
'beauti girl',
'Excellent'
]
t = Tokenizer()
t.fit_on_texts(docs)
这里:
t = Tokenizer()
t.fit_on_texts(docs)
之后Tokenizer提供了4个属性:
- word_counts:字典,保存每个词在文档中出现的次数;
- word_docs:字典,保存每个词出现文档数量
- word_index :字典,保存所有Word对应的ID编号,从1开始
- document_count:处理的文档数
from tensorflow.python.keras.preprocessing.text import Tokenizer
docs = [
'Well done',
'Good work',
'Great effort',
'nice work',
'Excellent'
]
t = Tokenizer()
t.fit_on_texts(docs)
print(t.word_counts)
print(t.word_index)
print(t.document_count)
print(t.word_docs)
结果:
print(t.word_counts):
OrderedDict([('well', 1), ('done', 1), ('good', 1), ('work', 2), ('great', 1), ('effort', 1), ('nice', 1), ('excellent', 1)])
print(t.word_index):
{'work': 1, 'well': 2, 'done': 3, 'good': 4, 'great': 5, 'effort': 6, 'nice': 7, 'excellent': 8}
print(t.document_count):5
print(t.word_docs):
defaultdict(<class 'int'>, {'done': 1, 'well': 1, 'good': 1, 'work': 2, 'effort': 1, 'great': 1, 'nice': 1, 'excellent': 1})
Tokenizer中还提供了text_to_matrix函数,用于为每个输入文档向量化,文档向量的长度是词汇表的总大小。此函数提供了一套标准的词袋模型文本编码方案,可以通过函数的参数mode设定其编码方案。可用的模式包括:
- binary:文档中是否有该词,这是默认值
- count :文档中每个单词的计数
- tfidf:文档中每个单词的评分TF-IDF
- freq :每个单词的频率,作为每个文档中单词的比例
请看下面示例:
from tensorflow.python.keras.preprocessing.text import Tokenizer
docs = [
'Well done',
'Good work',
'Great effort',
'nice work',
'Excellent'
]
t = Tokenizer()
t.fit_on_texts(docs)
print(t.word_counts)
print(t.word_index)
print(t.document_count)
print(t.word_docs)
encoded_docs = t.texts_to_matrix(docs,mode='count')
print(encoded_docs)
结果为:
print(t.word_counts):
OrderedDict([('well', 1), ('done', 1), ('good', 1), ('work', 2), ('great', 1), ('effort', 1), ('nice', 1), ('excellent', 1)])
print(t.word_index):
{'work': 1, 'well': 2, 'done': 3, 'good': 4, 'great': 5, 'effort': 6, 'nice': 7, 'excellent': 8}
print(t.document_count):5
print(t.word_docs):
defaultdict(<class 'int'>, {'done': 1, 'well': 1, 'good': 1, 'work': 2, 'effort': 1, 'great': 1, 'nice': 1, 'excellent': 1})
encoded_docs = t.texts_to_matrix(docs,mode='count'):
[[0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 1. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 1. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1.]]
encoded_docs = t.texts_to_matrix(docs,mode='binary')
[[0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 1. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 1. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1.]]
encoded_docs = t.texts_to_matrix(docs,mode='tfidf')
[[0. 0. 1.25276297 1.25276297 0. 0.
0. 0. 0. ]
[0. 0.98082925 0. 0. 1.25276297 0.
0. 0. 0. ]
[0. 0. 0. 0. 0. 1.25276297
1.25276297 0. 0. ]
[0. 0.98082925 0. 0. 0. 0.
0. 1.25276297 0. ]
[0. 0. 0. 0. 0. 0.
0. 0. 1.25276297]]
encoded_docs = t.texts_to_matrix(docs,mode='freq')
[[0. 0. 0.5 0.5 0. 0. 0. 0. 0. ]
[0. 0.5 0. 0. 0.5 0. 0. 0. 0. ]
[0. 0. 0. 0. 0. 0.5 0.5 0. 0. ]
[0. 0.5 0. 0. 0. 0. 0. 0.5 0. ]
[0. 0. 0. 0. 0. 0. 0. 0. 1. ]]
以上结果是5个小文档的fit,打印适合token的详细信息,然后使用字数对5个文档进行编码,被编码成9元素向量,每个具有一个位置,并且每个位置具有所选择的编码方案值。