word2vec中Skip-Gram和CBOW

Word2Vec是从大量文本语料中以无监督的方式学习语义知识的一种模型,它被大量地用在自然语言处理(NLP)中。Word2Vec模型中,主要有Skip-Gram和CBOW两种模型,本文将详细介绍这两种模型。

CBOW

CBOW全称是Continuous Bag of Words Model,即连续词袋模型,模型如下图(图为七月在线NLP课程截图)
在这里插入图片描述
由图可看出,CBOW的输入是上下文,输出是中间词,即是通过上下文内容来预测中间词。

接下来我们来看看如何训练我们的神经网络。假如我们有一个句子“The dog barked at the mailman”。
定义两个参数batch_size和bag_window,batch_size定义了batch个数,bag_window定义了上下文长度,假设我们设置batch_size为4,bag_window为1,那么我们得到的batch为:[['The', 'barked'], ['dog', 'at'], ['barked', 'the'], ['at,'mailman']],对应的labels为['dog', 'barked', 'at', 'the']将batch作为x,label作为y喂入构造的网络中就可以生成一个概率分布

定义batch的代码可参考以下代码:

data_index = 0

def cbow_batch(batch_size, bag_window):
    global data_index
    batch = np.ndarray(shape=(batch_size,bag_window*2), dtype=np.int32)
    labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
    span = 2 * bag_window + 1 # [ bag_window target bag_window ]
    buffer = collections.deque(maxlen=span)
    for _ in range(span):
        buffer.append(data[data_index])
        data_index = (data_index + 1) % len(data)
    for i in range(batch_size):
        batch[i] = list(buffer)[:bag_window] + list(buffer)[bag_window+1:]
        labels[i] = buffer[bag_window]
        buffer.append(data[data_index])
        data_index = (data_index + 1) % len(data)
    return batch, labels

对于CBOW还有以下一些改进模型:
在这里插入图片描述
在这里插入图片描述

Skip-Gram

Skip-Gram与CBOW的输入输出正好相反,Skip-Gram是以中心词作为输入,上下文作为输出,具体模型如下:
在这里插入图片描述
接下来我们来看看如何训练我们的神经网络。假如我们有一个句子“The dog barked at the mailman”。

定义两个参数,一个叫做skip_window的参数,它代表着我们从当前input word的一侧(左边或右边)选取词的数量,另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word。假设当batch_size=4,skip_window=2,num_skips=2时,得到batch为['barked', 'barked', 'at', 'at'],labels为['dog', 'at', 'barked', 'the'] 其中label和batch不是一一对应的,假设以中心词’barked’为例,因为num_skips=2,所以label是从’The’, ‘dog’, ‘at’, 'the’四个词中随机调出的两个。
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。

定义batch的代码可参考以下代码:

def generate_batch(batch_size, num_skips, skip_window):
    global data_index
    assert batch_size % num_skips == 0
    assert num_skips <= 2 * skip_window
    # x y
    batch = np.ndarray(shape=(batch_size), dtype=np.int32)
    labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
    span = 2 * skip_window + 1 # context word context
    # deque是一个左右都可以增加元素的结构
    buffer = collections.deque(maxlen=span)
    
    # 滑动窗口大小,取上下文
    for _ in range(span):
        buffer.append(data[data_index])
#         print(buffer)
#         print(data_index)
        # 循环使用
        data_index = (data_index + 1) % len(data)
        
    # i表示batch中中心词的个数
    for i in range(batch_size // num_skips):
        target = skip_window  # 
        targets_to_avoid = [ skip_window ]
        # j表示一个中心词取多少个上下文
        for j in range(num_skips):
#             print(target)
#             print(targets_to_avoid)
            # 随机从span个词中出num_skips个
            while target in targets_to_avoid:
                target = random.randint(0, span - 1)       
            targets_to_avoid.append(target)
            batch[i * num_skips + j] = buffer[skip_window]
            labels[i * num_skips + j, 0] = buffer[target]
        buffer.append(data[data_index])
        data_index = (data_index + 1) % len(data)
    return batch, labels

参考:https://blog.csdn.net/qq_24003917/article/details/80389976

发布了69 篇原创文章 · 获赞 28 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_24852439/article/details/91443576