数据预处理:从语料库生成上下文和目标词。如下图所示,contexts 的各行成为神经网络的输入,target 的各行成为正确解标签(要预测出的单词)。
之前做过一个preprocess函数,将文本分割为单词,并将分割后的单词列表转化为单词ID列表。实现代码如下,其中corpus 是单词ID列表,word_to_id 是单词到单词ID的字典,id_to_word是单词ID到单词的字典。
def preprocess(text):text = text.lower()text = text.replace('.', ' .')words = text.split(' ')word_to_id = {}id_to_word = {}for word in words:if word not in word_to_id:new_id = len(word_to_id)word_to_id[word] = new_idid_to_word[new_id] = wordcorpus = np.array([word_to_id[w] for w in words])return corpus, word_to_id, id_to_word
然后生成上下文和目标词的create_contexts_target函数就可以将corpus(单词ID列表)作为参数。函数的输出contexts是一个二维数组,第 0 维保存的是各个上下文数据。函数的输出 target[N] 保存的是第 N 个目标词,如下图所示。
def create_contexts_target(corpus, window_size=1):'''生成上下文和目标词:param corpus: 语料库(单词ID列表):param window_size: 窗口大小(当窗口大小为1时,左右各1个单词为上下文):return:'''target = corpus[window_size:-window_size]contexts = []for idx in range(window_size, len(corpus)-window_size):cs = []for t in range(-window_size, window_size + 1):if t == 0:continuecs.append(corpus[idx + t])contexts.append(cs)return np.array(contexts), np.array(target)
用这个函数:
import sys
sys.path.append('..')
from common.util import preprocess #, create_co_matrix, most_similar
from common.util import create_contexts_targettext = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)
contexts, target = create_contexts_target(corpus, window_size=1)
print(contexts)
print(target)
输出:
[[0 2][1 3][2 4][3 1][4 5][1 6]]
[1 2 3 4 1 5]
因为这些上下文和目标词的元素还是单词 ID,所以 还需要将它们转化为 one-hot 表示。如下图所示。
实现代码如下:convert_one_hot函数的参数是单词 ID 列表和词汇个数。
def convert_one_hot(corpus, vocab_size):'''转换为one-hot表示:param corpus: 单词ID列表(一维或二维的NumPy数组):param vocab_size: 词汇个数:return: one-hot表示(二维或三维的NumPy数组)'''N = corpus.shape[0]if corpus.ndim == 1:one_hot = np.zeros((N, vocab_size), dtype=np.int32)for idx, word_id in enumerate(corpus):one_hot[idx, word_id] = 1elif corpus.ndim == 2:C = corpus.shape[1]one_hot = np.zeros((N, C, vocab_size), dtype=np.int32)for idx_0, word_ids in enumerate(corpus):for idx_1, word_id in enumerate(word_ids):one_hot[idx_0, idx_1, word_id] = 1return one_hot
运行上面几个预处理函数:
import sys
sys.path.append('..')
from common.util import preprocess #, create_co_matrix, most_similar
from common.util import create_contexts_target, convert_one_hottext = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)
contexts, target = create_contexts_target(corpus, window_size=1)
print(contexts)
print(target)
vocab_size = len(word_to_id)
target = convert_one_hot(target, vocab_size)
contexts = convert_one_hot(contexts, vocab_size)
print(vocab_size)
print(target)
print(contexts)
结果:
[[0 2][1 3][2 4][3 1][4 5][1 6]]
[1 2 3 4 1 5]
7
[[0 1 0 0 0 0 0][0 0 1 0 0 0 0][0 0 0 1 0 0 0][0 0 0 0 1 0 0][0 1 0 0 0 0 0][0 0 0 0 0 1 0]]
[[[1 0 0 0 0 0 0][0 0 1 0 0 0 0]][[0 1 0 0 0 0 0][0 0 0 1 0 0 0]][[0 0 1 0 0 0 0][0 0 0 0 1 0 0]][[0 0 0 1 0 0 0][0 1 0 0 0 0 0]][[0 0 0 0 1 0 0][0 0 0 0 0 1 0]][[0 1 0 0 0 0 0][0 0 0 0 0 0 1]]]