zoukankan      html  css  js  c++  java
  • NLP.TM | GloVe模型及其Python实现

    在进行自然语言处理中,需要对文章的中的语义进行分析,于是迫切需要一些模型去描述词汇的含义,很多人可能都知道word2vector算法,诚然,word2vector是一个非常优秀的算法,并且被广泛运用,为人们熟知,然而,从结果的优劣性来看,其实word2vector并非唯一的优秀方案,斯坦福大学提出的GloVe就是其中之一。今天我来为大家介绍一下GloVe模型,但是重点,还是放在实现上。

    原论文:http://www.eecs.wsu.edu/~sji/classes/DL16/CNN-text/glove.pdf

    简单地说一下原理

    这里的原理我主要参考了两篇博客,感谢两位优秀的博主。

    前者会比较通俗,后者则比较深刻。

    共现关系

    和word2vector不同,GloVe更倾向于进行分析前后语境之间的共现关系,通过共现关系抽象出词向量。

    所谓的共现,共同出现,其实就是看一个词有没有在另一个词的附近出现,所谓的附近,其实就是一个移动窗口的概念,定义窗口的半径(从中心词到边缘的距离)后,看看方圆多少范围内出现词的个数,就是共现,现在看看例子。

    假设语料库就只有下面一行:

    i love you but you love him i am sad

    设半径为2,于是移动窗口的滑动就有下面的形式:

    以窗口5为例,此处就可以认为,love分别和but, you, him, i共同出现了一次,通过这种方式去计数,就能知道任意两个词之间的共现关系(一般是可逆的),构成共现矩阵X,一般地,X是一个对称矩阵。

    词向量的产生

    首先,模型的损失函数长这样的:

     
    image

    vi和vj是词汇i和j的词向量,bi和bj是常数项,f是特定的权重函数,N是词汇表大小。

    这个损失函数怎么来的,我觉得上面的第一个链接讲的非常清楚,看的时候注意一个核心,就是考虑两个词汇的共现关系与词向量之间的关系(映射)尽可能接近,于是就构造了上面的损失函数。

    GloVe的Python实现

    在pypi里面看到了很多GloVe的包,但是很多都有坑,我直接说一个我自己已经走通的包mittens。

    下载方式还是比较简单的, pip install mittens基本没什么问题,想要去看看源码的话,在这里:

    https://github.com/roamanalytics/mittens

    一般而言GloVe按照计算共现矩阵和GloVe训练两大模块,而mittens里面其实只提供了后者,前者还是需要自己写,这是我写的部分内容,给大家详细讲讲(复杂度啥的基本没做什么优化,欢迎提出一些意见)。

    共现矩阵的计算

    将之前事先说明一下,现在读进来的数据,即代码中的“data”变量,每行不是对应的单词或者短语,而是已经对应在词典中的该短语的index(自己构建词典,一般设置为0-(N-1),N为词典中词语的个数),尤其在后面的cooccurrence的统计,即如果句子数组中的第i个词语是词典中的第j个词,则句子向量中第i个位置就是数字j,这种方式对cooccurrence的统计非常方便。

    # 构建空的词表
    coWindow = 3 # 共现窗口大小(半径)
    tableSize = 1000 # 共现矩阵维度
    cooccurrence = np.zeros((tableSize, tableSize), "int64" )
    

    首先是数据初始化,这里不详细说数据载入了,但是共现矩阵当然是需要初始化的(np是numpy别忘了)。

    # 开始统计
    flag = 0
    for item in data:
       itemInt = [int(x) for x in item]
       for core in range(1, len(item)):
           if core <= coWindow + 1:
               # 左窗口不足
               window = itemInt[1:core + coWindow + 1]
               coreIndex = core - 1
               cooccurrence = countCOOC(cooccurrence, window, coreIndex)
           elif core >= len(item) - 1 - coWindow:
               # 右窗口不足
               window = itemInt[core - coWindow:(len(item))]
               coreIndex = coWindow
               cooccurrence = countCOOC(cooccurrence, window, coreIndex)
           else:
               # 左右均没有问题
               window = itemInt[core - coWindow:core + coWindow + 1]
               coreIndex = coWindow
               cooccurrence = countCOOC(cooccurrence, window, coreIndex)
       flag = flag + 1
       if flag % 1000 == 0:
           endTime = datetime.datetime.now()
           print("已经计算了%s条数据,用时%s" % (flag, endTime - startTime))
    

    这一块里面主要是为了设置移动窗口来进行挪动识别,具体统计移动窗口内部的共现,是在countCOOC函数里面做的。

    def countCOOC(cooccurrence, window, coreIndex):
       # cooccurrence:当前共现矩阵
       # window:当前移动窗口数组
       # coreIndex:当前移动窗口数组中的窗口中心位置
       for index in range(len(window)):
           if index == coreIndex:
               continue
           else:
               cooccurrence[window[coreIndex]][window[index]] = cooccurrence[window[coreIndex]][window[index]] + 1
       return cooccurrence
    

    countCOOC用来当前移动窗口的共现,一个一个计数即可。

    GloVe的训练

    # 包的引入
    from mittens import GloVe
    # 初始化模型
    vecLength=100           # 矩阵长度
    max_iter=100000         # 最大迭代次数
    display_progress=1000   # 每次展示
    glove_model = GloVe(n=vecLength, max_iter=max_iter, display_progress=display_progress)
    # 模型训练与结果输出
    embeddings = glove_model.fit(coocMatric)
    

    引入包之后,配置相应的参数,然后可以开始训练,训练完的返回值embeddings就是得到的词向量词典,通过词向量词典,就能够将每篇文本的每一个单词转化为词向量,从而进行进一步分析。

    小结

    GloVe终于写完了,不知道大家觉得怎么样,关于原理写的人相对比较多,也理解的比我好我就不再解释了,而代码这块,网上写的不多,所以我写得详细一些,这也是我把结果写出来的核心代码,有什么问题我来回答,欢迎通过下面的联系方式联系我。



    作者:机智的叉烧
    链接:https://www.jianshu.com/p/d0cb367752e8
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    五.Flink实时项目电商用户行为分析之订单支付实时监控
    四.Flink实时项目电商用户行为分析之恶意登录监控
    三.Flink实时项目电商用户行为分析之市场营销商业指标统计分析
    二.Flink实时项目电商用户行为之实时流量统计
    一.Flink实时项目电商用户行为分析之实时热门商品统计
    Flink 流处理API之实现UDF函数——更细粒度的控制流
    二.Flink 流处理API之Transform
    5组-Alpha冲刺-1/6
    5组 需求分析报告
    5组 团队展示
  • 原文地址:https://www.cnblogs.com/jfdwd/p/11086914.html
Copyright © 2011-2022 走看看