内容简介:更具体的说:该单词对应所在元素为1,向量中其他元素均为0,向量的维度就等于词库中的单词数目词袋模型(Bag of Words,简称BoW)。词袋模型假设我们不考虑文本中词与词之间的上下文关系,仅仅只考虑所有词的权重。而权重与词在文本中出现的频率有关。
更具体的说:
该单词对应所在元素为1,向量中其他元素均为0,向量的维度就等于词库中的单词数目
所有向量都是互相正交的,我们无法有效的表示两个向量间的相似度
向量维度过大。
词袋模型
词袋模型(Bag of Words,简称BoW)。词袋模型假设我们不考虑文本中词与词之间的上下文关系,仅仅只考虑所有词的权重。而权重与词在文本中出现的频率有关。
词袋模型首先会进行分词,在分词之后,通过统计每个词在文本中出现的次数,我们就可以得到该文本基于词的特征,如果将各个文本样本的这些词与对应的词频放在一起,就是我们常说的向量化。向量化完毕后一般也会使用TF-IDF进行特征的权重修正,再将特征进行标准化。 再进行一些其他的特征工程后,就可以将数据带入机器学习算法进行分类聚类了。
总结下词袋模型的三部曲:分词(tokenizing),统计修订词特征值(counting)与标准化(normalizing)。
与词袋模型非常类似的一个模型是词集模型(Set of Words,简称SoW),和词袋模型唯一的不同是它仅仅考虑词是否在文本中出现,而不考虑词频。也就是一个词在文本在文本中出现1次和多次特征处理是一样的。在大多数时候,我们使用词袋模型,后面的讨论也是以词袋模型为主。
当然,词袋模型有很大的局限性,因为它仅仅考虑了词频,没有考虑上下文的关系,因此会丢失一部分文本的语义。但是大多数时候,如果我们的目的是分类聚类,则词袋模型表现的很好。
下面使用sklearn的CountVectorizer分别实现词集模型和词袋模型。
词集模型代码
from sklearn.feature_extraction.text import CountVectorizer import seaborn as sns import matplotlib.pyplot as plt corpus = ['Time flies flies like an arrow.', 'Fruit flies like a banana.'] vocab = set([word for sen in corpus for word in sen.split(" ")]) one_hot_vectorizer = CountVectorizer(binary=True) one_hot = one_hot_vectorizer.fit_transform(corpus).toarray() print(one_hot_vectorizer.vocabulary_) print(one_hot) sns.heatmap(one_hot, annot=True,cbar=False, xticklabels=vocab, yticklabels=['Sentence 2']) plt.show()
输出结果:
{'time': 6, 'flies': 3, 'like': 5, 'an': 0, 'arrow': 1, 'fruit': 4, 'banana': 2} [[1 1 0 1 0 1 1] [0 0 1 1 1 1 0]]
词袋模型代码
如果设置为False,那幺还会包含进词频信息,这就是词袋模型。输出如下:
{'time': 6, 'flies': 3, 'like': 5, 'an': 0, 'arrow': 1, 'fruit': 4, 'banana': 2} [[1 1 0 2 0 1 1] [0 0 1 1 1 1 0]]
Hash Trick
在大规模的文本处理中,由于特征的维度对应分词词汇表的大小,所以维度可能非常恐怖,此时需要进行降维,不能直接用我们上一节的向量化方法。而最常用的文本降维方法是Hash Trick。
Hash Trick降维后的特征我们已经不知道它代表的特征名字和意义。此时我们不能像上一节向量化时候可以知道每一列的意义,所以Hash Trick的解释性不强。
TF-IDF
TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF是词频(Term Frequency)词频(TF)表示词条(关键字)在文本中出现的频率。这个数字通常会被归一化(一般是词频除以文章总词数), 以防止它偏向长的文件。
IDF是逆向文件频率(Inverse Document Frequency)逆向文件频率 (IDF) :总文件数目除以包含该词语的文件的数目,再将得到的商取对数得到。罕见词的IDF很高,高频词的IDF很低。
TF-IDF实际上是:TF * IDF
应用
关键字:计算出文章中每个词的TF-IDF值之后,进行排序,选取其中值最高的几个作为关键字。
文章的相似性: 计算出每篇文章的关键词,从中各选取相同个数的关键词,合并成一个集合,计算每篇文章对于这个集合中的词的词频,生成两篇文章各自的词频向量,进而通过欧氏距离或余弦距离求出两个向量的余弦相似度,值越大就表示越相似。
使用sklearn计算tfidf
from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer,TfidfVectorizer from pprint import pprint import seaborn as sns from matplotlib.pylab import plt corpus = ['Time flies flies like an arrow.', 'Fruit flies like a banana.'] one_hot_vectorizer = CountVectorizer() one_hot = one_hot_vectorizer.fit_transform(corpus).toarray() pprint(one_hot) #输出词频 transformer = TfidfTransformer() tfidf = transformer.fit_transform(one_hot) vocab = one_hot_vectorizer.get_feature_names() print(vocab) #打印词典 pprint(transformer.idf_ ) #输出逆文档频率 pprint(tfidf.toarray()) #输出TFIDF sns.heatmap(tfidf.toarray(), annot=True, cbar=False, xticklabels=vocab, yticklabels= ['Sentence 1', 'Sentence 2']) plt.show()
输出如下:
array([[1, 1, 0, 2, 0, 1, 1], [0, 0, 1, 1, 1, 1, 0]], dtype=int64) ['an', 'arrow', 'banana', 'flies', 'fruit', 'like', 'time'] array([1.40546511, 1.40546511, 1.40546511, 1. , 1.40546511, 1. , 1.40546511]) array([[0.42519636, 0.42519636, 0. , 0.60506143, 0. , 0.30253071, 0.42519636], [0. , 0. , 0.57615236, 0.40993715, 0.57615236, 0.40993715, 0. ]])
简单验证
取文档1的词频表示为TF,计算IDF的公式是
其中 为总的文档数,
是包含词 t 的文档数。 首先根据词表,计算出来含词 t 的文档数。然后计算TFIDF并归一化。
import numpy as np tf = np.array([1, 1, 0, 2, 0, 1, 1]) x = np.array([1, 1, 1, 2, 1, 2, 1]) idf = np.log(3/(1+x))+1 print(idf) tfidf = tf * idf print(tfidf / np.linalg.norm(tfidf))
输出如下:
[1.40546511 1.40546511 1.40546511 1. 1.40546511 1. 1.40546511] [0.42519636 0.42519636 0. 0.60506143 0. 0.30253071 0.42519636]
实际使用的时候也可以一步到位:
from sklearn.feature_extraction.text import TfidfVectorizer tfidf2 = TfidfVectorizer() result = tfidf2.fit_transform(corpus) print(result)
几个问题
为什幺idf的大小总是有限的?
出现在所有文档中的词项的idf值是多少?
词项的tfidf权重能否超过1?
idf的对数底数会对tfidf有什幺影响?
假设idf以2为底,给出idf的一个简单近似。
向量空间模型(VSM)
使用TF-IDF可以把文档表示成向量,其中每个分量表示一个词项,但是这种表示忽略了词语的相对顺序。把不同的文档用向量表示称为向量空间模型。 然后文档相似度可以用余弦相似度表示出来:
其他的距离函数还有:
欧式距离
曼哈顿距离
Topk相似度计算和优化
主题模型
在传统信息检索领域里,实际上已经有了很多衡量文档相似性的方法,比如经典的VSM模型。然而这些方法往往基于一个基本假设:文档之间重复的词语越多越可能相似。这一点在实际中并不尽然。很多时候相关程度取决于背后的语义联系,而非表面的词语重复。 举个例子: 设有两个句子,我们想知道它们之间是否相关联:
第一个是:“乔布斯离我们而去了。”
第二个是:“苹果价格会不会降?”
这两个句子之间虽然没有任何公共词语,但仍然是很相关的。
主题模型,顾名思义,就是对文字中隐含主题的一种建模方法。 主题 就是词汇表上词语的条件概率分布 。与主题关系越密切的词语,它的条件概率越大,反之则越小。
主题模型就是用大量已知的“词语-文档”矩阵 ,通过一系列的训练,推理出右边的“词语-主题”矩阵Φ 和“主题-文档”矩阵Θ 。
主题模型的 优点 :
1)它可以衡量文档之间的语义相似性。对于一篇文档,我们求出来的主题分布可以看作是对它的一个抽象表示。对于概率分布,我们可以通过一些距离公式(比如KL距离)来计算出两篇文档的语义距离,从而得到它们之间的相似度。
2)它可以解决多义词的问题。回想最开始的例子,“苹果”可能是水果,也可能指苹果公司。通过我们求出来的“词语-主题”概率分布,我们就可以知道“苹果”都属于哪些主题,就可以通过主题的匹配来计算它与其他文字之间的相似度。
3)它可以排除文档中噪音的影响。一般来说,文档中的噪音往往处于次要主题中,我们可以把它们忽略掉,只保持文档中最主要的主题。
4)它是无监督的,完全自动化的。我们只需要提供训练文档,它就可以自动训练出各种概率,无需任何人工标注过程
5)它是跟语言无关的。任何语言只要能够对它进行分词,就可以进行训练,得到它的主题分布。
主题模型训练推理的方法主要有两种,一个是pLSA(Probabilistic Latent Semantic Analysis),另一个是LDA(Latent Dirichlet Allocation)。pLSA主要使用的是EM(期望最大化)算法;LDA采用的是Gibbs sampling方法。
pLSA
pLSA采用的方法叫做EM(期望最大化)算法,它包含两个不断迭代的过程:E(期望)过程和M(最大化)过程。
LDA
LDA 采用词袋模型。所谓词袋模型,是将一篇文档,我们仅考虑一个词汇是否出现,而不考虑其出现的顺序。在词袋模型中,“我喜欢你”和“你喜欢我”是等价的。与词袋模型相反的一个模型是n-gram,n-gram考虑了词汇出现的先后顺序。 LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,也称为一个三层贝叶斯概率模型,包含词、主题和文档三层结构。所谓生成模型,即认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词”这样一个过程得到。文档到主题服从多项式分布,主题到词服从多项式分布。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java语言程序设计(基础篇 原书第10版)
[美]粱勇(Y.Daniel Liang) / 戴开宇 / 机械工业出版社 / 2015-7 / 85.00元
《Java语言程序设计(基础篇 原书第10版)》是Java语言的经典教材,中文版分为基础篇和进阶篇,主要介绍程序设计基础、面向对象编程、GUI程序设计、数据结构和算法、高级Java程序设计等内容。本书以示例讲解解决问题的技巧,提供大量的程序清单,每章配有大量复习题和编程练习题,帮助读者掌握编程技术,并应用所学技术解决实际应用开发中遇到的问题。您手中的这本是其中的基础篇,主要介绍了基本程序设计、语法......一起来看看 《Java语言程序设计(基础篇 原书第10版)》 这本书的介绍吧!