一般而言,我們若想處理文本數據,一種是將文本數據轉爲one-hot向量處理,另一種是轉爲下標組成的向量然後通過一層詞嵌入轉爲待處理的向量。
keras內置的函數可以快速幫助我們達到目的:
首先我們需要引入Tokenizer
from keras.preprocessing.text import Tokenizer
實例化這個類,初始時我們可以傳入參數num_words指定詞典最大索引
tokenizer = Tokenizer(num_words=10000)
使用tokenizer對象去對文本數據生成字典
tokenizer.fit_on_texts(samples)
生成字典後,按照之前所說,一種是轉化爲單詞下標組成的向量:
sequences = tokenizer.texts_to_sequences(samples)
另一種是直接轉化爲one-hot:
one_hot_seq = tokenizer.texts_to_matrix(samples,mode='binary')
其中mode也可以改爲其他形式,比如也可以數出出現了多少次。
除此之外,當唯一標記的token過多時,可以使用one-hot散列技巧,這種技巧使用hash函數將每個單詞映射到某一值,通常我們將這個值對設定的最大下標值取餘即可獲得單詞的標記值,這樣就不用顯式的維護一個字典了。當然,這種方法存在散列衝突的可能。
下面,我們可以查看生成的字典
word_index = tokenizer.word_index
由單詞下標組成的向量無法直接被神經網絡利用,而是需要先經過Embedding層進行詞嵌入,此外,由於句子長短不一,想進入Embedding層的向量要確保長度一致,然後才能進行詞嵌入。
from keras.preprocessing import sequence
train_data = sequence.pad_sequences(train_data,maxlen=20)
test_data = sequence.pad_sequences(test_data,maxlen=20)
然後我們使用keras中的Embedding層
from keras import layers,models
model = models.Sequencial()
model.add(layers.Embedding(10000,8,input_length=20)) # 10000是最大下標值,8是轉成向量的維度,20是每句話的詞個數
model.add(layers.Flatten()) # 單個輸入攤平爲8*20長度的向量
model.add(layers.Dense(1,activation='sigmoid'))
這裏的Embedding層相當於做了單個數字和對應8個數字組成向量的映射,所以Embedding層這裏需要估計10000*8=80000個權重參數。