情感分析(1)—— Word2vec词向量

情感分析(1)—— Word2vec词向量

一、Word2vec需要做什么?

1、NLP模型

  • 对于任何模型,都可以视为一种映射 f(x) -> y
  • 其中,如果在 NLP 中,x 可以为词语,y 可以为词语 x 的上下文词语,而映射 f 是一种判别语言的模型 language model,用于判断 (x,y) 是否能构成可行的自然语言

2、Word2vec 核心

  • Word2vec 需要获得 f 模型映射的训练产物——模型参数,或者说NLP神经网络的权重。将模型参数作为输入 x 的某种向量化的表示,即词向量
  • 寻找相似词:f(x) = f(y),即上下文相同,因此可以认定 x = y

二、Word2vec的两种模型

1、Skip-gram 和 CBOW 模型

情感分析(1)—— Word2vec词向量_第1张图片

  • CBOW 模型:输入层模型,即用上下文词语输入,预测核心词语
  • Skip-gram 模型:输出层模型,即用核心词输入,预测核心词的上下文词语

2、One-hot encoder 模式

  • x 的一个原始输入形式 —— one-hot encoder
  • 思想类似于特征工程里处理类别变量的 one-hot ,本质上是用向量(1,0,…,0)唯一标识词语。
  • 词库共 n 个词,已有固定顺序,只含一个 1、其他 n-1 个都为 0 的向量,便可以唯一标识词库中的词。

3、简述Skip-gram 的网络结构模型

【1 vs 1】
  • x 表示为 one-hot encoder 输入,y 表示为归属于词库中 n 个词的概率,其中隐层是线性激活函数,训练时用反向传播算法(本质为链式求导)。
  • 模型训练后,得到了神经网络的权重。
    • 输入:x 的 one-hot encoder 群,唯一标识一个词语
    • 输入-隐含层:只有向量中为 1 位置的权重被激活。有多少权重,就有多少隐含层。将权重组成一个向量 Vx,可以唯一表示 x
    • 隐藏层-输出:为了输出 V 个词语,即 V 个结点,即 V 个 one-hot encoder ,也可以组成向量 Vy
  • 输入与输出的词向量维度与隐含层节点数一致,一般情况下要远小于词库词语总数。即产生了词库的降维操作,即从 one-hot encoder 到 Word2vec 。
  • N为词库词数,V为word2vec词数,N>V
Input layer Hidden layer Output layer
x1…xN h1…hV y1…yN
【1 vs N】

有多个y,即可以看成 单个x->单个y 模型的并联,cost function 是单个 cost function 的累加

4、简述 CBOW 的网络结构模型

  • 这次,跟 Skip-gram 相似。
  • 当并联时,输入变成了多个单词,需要处理输入(均值?),输出的 cost function 不变。

三、实战

我不需要价值观,我要方法论

1、Gensim 库

  • 用途:从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达
  • 支持:包括TF-IDF,LSA,LDA,和word2vec 等多种主题模型算法,支持流式训练,提供诸如相似度计算,信息检索等常用API接口
基本概念
  • 语料(Corpus):一组原始文本的集合,不需要人工标注的附加信息,用于无监督地训练文本主题的隐层结构。在Gensim中通常是一个可迭代的对象,比如列表。每一次迭代,返回一个可用于表达文本对象的稀疏向量。
  • 向量(Vector):由一组文本特征构成的列表,是一段文本在语料的内部表达。
  • 稀疏向量(SparseVector):将向量中 0 元素略去,表达为 (key, value) 的元组
  • 模型(Model):定义了两个向量空间的变换,即 f 映射,从文本的一种向量表达变换为另一种向量表达。
步骤一:训练语料的预处理
# 安装
pip install gensim
  • 训练语料的预处理:将文档中原始的字符文本,转换成Gensim模型所能理解的稀疏向量的过程。

    • 原生语料:一堆文档的集合,每篇文档为原生字符的集合。
    • 格式解析:将原生字符解析成 Gensim 能处理的稀疏向量的格式。
  • 操作:

    • 1、先对原始的文本进行分词,去除停用词,得到每一篇文档的特征列表。例如,在词袋模型(Bag-of-words model)中,文档特征为其包含的word:texts = [[’’, ‘’, ‘’], [’’, ‘’, ‘’, ‘’, ‘’, ‘’], … , ]。其中,corpus的每一个元素对应一篇文档。
    • 2、调用 Gensim 提供的API建立语料特征的索引字典,并将文本特征的原始表达转化成稀疏向量的表达,向量的每一个元素代表了每个词在文档中出现次数。
    # 以词袋模型为例,doc2bow函数
    from gensim import corpora
    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    print corpus[0] # [(0, 1), (1, 1), (2, 1)]
    
  • 出于内存优化,Gensim 支持文档的流式处理。

  • 因此,将列表封装成Python迭代器,每次迭代都返回一个稀疏向量。

    class MyCorpus(object):
    def __iter__(self):
        for line in open('mycorpus.txt'):
            # assume there's one document per line, tokens                   separated by whitespace
            yield dictionary.doc2bow(line.lower().split())
    
步骤二:主题向量的变换
  • 在Gensim中,每一个向量变换的操作都对应着一个主题模型,每一个模型又都是一个标准的Python对象。我们希望变换文本向量,挖掘语料中隐藏的语义结构特征,得到一个简洁高效的文本向量。
  • 下面以TF-IDF模型为例,介绍Gensim模型的一般使用方法。
    • 1、模型对象的初始化。Gensim模型接受一段训练语料,即一个稀疏向量的迭代器,作为初始化的参数。显然,越复杂的模型需要配置的参数越多。
    • 2、接下来,我们可以将语料转化成TFIDF向量迭代器,语料必须与训练语料的向量共享同一个特征字典(向量空间)。
	# 完成对corpus中出现的每一个特征的IDF值的统计工作
 	from gensim import models
 	tfidf = models.TfidfModel(corpus)
 	# 调用模型,将任意一段语料转化成TFIDF向量(的迭代器)
 	doc_bow = [(0, 1), (1, 1)]
 	print tfidf[doc_bow] # [(0, 0.70710678), (1, 0.70710678)]
 	# 如果要多次访问model[corpus]的返回结果,可以先将结果向量序列化到磁盘上。我们也可以将训练好的模型持久化到磁盘上,以便下一次使用:
 	tfidf.save("./model.tfidf")
 	tfidf = models.TfidfModel.load("./model.tfidf")
  • Gensim内置了多种主题模型的向量变换,包括LDA,LSI,RP,HDP等。
  • 模型通常以bow向量或tfidf向量的语料为输入,生成相应的主题向量。所有的模型都支持流式计算。
步骤三:文档相似度的计算

计算文档间相似度,进而完成其他任务,如文本聚类、信息检索等。

以信息检索为例,对于一篇待检索的query,我们的目标是从文本集合中检索出主题相似度最高的文档。

  1. 首先,我们需要将待检索的query和文本放在同一个向量空间里进行表达(以LSI向量空间为例):
# 构造LSI模型并将待检索的query和文本转化为LSI主题向量
# 转换之前的corpus和query均是BOW向量
lsi_model = models.LsiModel(corpus, id2word=dictionary,          num_topics=2)
documents = lsi_model[corpus]
query_vec = lsi_model[query]
  1. 接下来,我们用待检索的文档向量初始化一个相似度计算的对象:
index = similarities.MatrixSimilarity(documents)
  1. 我们也可以通过save()和load()方法持久化这个相似度矩阵:
index.save('/tmp/test.index')
index = similarities.MatrixSimilarity.load('/tmp/test.index')
# 注意,如果待检索的目标文档过多,使用similarities.MatrixSimilarity类往往会带来内存不够用的问题。
# 此时,可以改用similarities.Similarity类,二者的接口基本保持一致。
  1. 最后,我们借助index对象计算任意一段query和所有文档的(余弦)相似度:
sims = index[query_vec] 
#返回一个元组类型的迭代器:(idx, sim)

2、NLTK 库

(略略略)

3、常见主题模型总结

[TF-IDF]
  • 用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
  • 字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
  • TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。
  1. 一个词预测主题能力越强,权重就越大,反之,权重就越小。我们在网页中看到“原子能”这个词,或多或少地能了解网页的主题。我们看到“应用”一次,对主题基本上还是一无所知。因此,“原子能“的权重就应该比应用大。
  2. 应删除词的权重应该是零。
[LDA文档主题生成模型]

LDA是一种文档主题生成模型,包含词、主题和文档三层结构。所谓生成模型,就是说,我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。文档到主题服从多项式分布,主题到词服从多项式分布。

LDA是一种非监督机器学习技术,可以用来识别大规模文档集或语料库中潜藏的主题信息。它采用了词袋的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。

但是词袋方法没有考虑词与词之间的顺序,这简化了问题的复杂性,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。

参考资料
1、[NLP] 从语言模型看Bert的善变与GPT的坚守 - 穆文的文章 - 知乎
https://zhuanlan.zhihu.com/p/66409688
2、15分钟入门Gensim - 李东坡的文章 - 知乎 https://zhuanlan.zhihu.com/p/37175253
只是个人笔记,侵权马上删

你可能感兴趣的:(Data,Science,python,nlp)