idf算法
‘壹’ Elasticsearch——评分机制详解
一个搜索引擎使用的时候必定需要排序这个模块,如果在不选择按照某一字段排序的情况下,都是按照打分的高低进行一个默认排序的,所以如果正式使用的话,必须对默认排序的打分策略有一个详细的了解才可以,否则被问起来为什么这个在前面,那个在后面?
将查询作为输入,将每一个因素最后通过公式综合起来,返回该文档的最终得分。这个综合考量的过程,就是将相关的文档被优先返回的考量过程。
Elasticsearch是基于Lucene的,所以它的评分机制也是基于Lucene的。在Lucene中把这种相关性称为得分(score),确定文档和查询有多大相关性的过程被称为打分(scoring)。
ES最常用的评分模型是 TF/IDF和BM25,TF-IDF属于向量空间模型,而BM25属于概率模型,但是他们的评分公式差别并不大,都使用IDF方法和TF方法的某种乘积来定义单个词项的权重,然后把和查询匹配的词项的权重相加作为整篇文档的分数。
在ES 5.0版本之前使用了TF/IDF算法实现,而在5.0之后默认使用BM25方法实现。
relevance score相关性算分:简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度。
通过倒排索引可以获取与查询语句相匹配的文档列表,那么如何将最符合用户查询需求的文档放到前列呢?
本质是一个排序问题,排序的依据是相关性算分。
Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法。TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)
相关性算分的几个重要概念如下:
ES目前主要有两个相关性算分模型,如下:
BM25中的IDF公式为:
原版BM25的log中是没有加1的,Lucene为了防止产生负值,做了一点小优化。虽然对公式进行了更改,但其实和原来的公式没有实质性的差异,下面是新旧函数曲线对比:
BM25中TF的公式为:
其中tf是传统的词频值。先来看下改良前后的函数曲线对比(下图中k=1.2):
可以看到,传统的tf计算公式中,词频越高,tf值就越大,没有上限。但BM中的tf,随着词频的增长,tf值会无限逼近(k+1),相当于是有上限的。这就是二者的区别。一般 k取 1.2,Lucene中也使用1.2作为 k 的默认值。
在传统的计算公式中,还有一个norm。BM25将这个因素加到了TF的计算公式中,结合了norm因素的BM25中的TF计算公式为:
和之前相比,就是给分母上面的 k 加了一个乘数 (1.0−b+b∗L)(1.0−b+b∗L)。 其中的 L 的计算公式为:
其中,|d|是当前文档的长度,avgDl 是语料库中所有文档的平均长度。
b 是一个常数,用来控制 L 对最总评分影响的大小,一般取0~1之间的数(取0则代表完全忽略 L )。Lucene中 b 的默认值为 0.75。
通过这些细节上的改良,BM25在很多实际场景中的表现都优于传统的TF-IDF,所以从Lucene 6.0.0版本开始,上位成为默认的相似度评分算法。
上例是通过similarity属性来指定打分模型,用到了以下三个参数:
如果我们要使用某种特定的打分模型,并且希望应用到全局,那么就在elasticsearch.yml配置文件中加入:
通过boosting可以人为控制某个字段的在评分过程中的比重,有两种类型:
通过在mapping中设置boost参数,可以在索引期间改变字段的评分权重:
需要注意的是:在索引期间修改的文档boosting是存储在索引中的,要想修改boosting必须重新索引该篇文档。
一旦映射建立完成,那么所有name字段都会自动拥有一个boost值,并且是以降低精度的数值存储在Lucene内部的索引结构中。只有一个字节用于存储浮点型数值(存不下就损失精度了),计算文档的最终得分时可能会损失精度。
另外,boost是应用与词条的。因此,再被boost的字段中如果匹配上了多个词条,就意味着计算多次的boost,这将会进一步增加字段的权重,可能会影响最终的文档得分。
查询期间的boosting可以避免上述问题。
几乎所有的查询类型都支持boost,例如:
就对于最终得分而言,加了boost的name查询更有影响力。也只有在bool查询中,boost更有意义。
boost也可以用于multi_match查询。
除此之外,我们还可以使用特殊的语法,只为特定的字段指定一个boost。通过在字段名称后添加一个^符号和boost的值。告诉ES只需对那个字段进行boost:
上例中,title字段被boost了3倍。
需要注意的是:在使用boost的时候,无论是字段或者词条,都是按照相对值来boost的,而不是乘以乘数。如果对于所有的待搜索词条boost了同样的值,那么就好像没有boost一样。因为Lucene会标准化boost的值。如果boost一个字段4倍,不是意味着该字段的得分就是乘以4的结果。
ES背后的评分过程比我们想象的要复杂,有时候某个查询结果可能跟我们的预期不太一样,这时候可以通过explain让ES解释一下评分细节。
由于结果太长,我们这里对结果进行了过滤("size": 1返回一篇文档),只查看指定的字段("_source": "name"只返回name字段)。
在新增的_explanation字段中,可以看到value值是0.9331132,那么是怎么算出来的呢?
分词spring在描述字段(name)出现了1次,所以TF的综合得分经过"description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:"计算,得分是0.43243244。
那么逆文档词频呢?根据"description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:"计算得分是0.98082924。
需要注意的是,explain的特性会给ES带来额外的性能开销,一般只在调试时使用。
搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values。
在建立索引的时候,一方面会建立倒排索引,以供搜索用;一方面会建立正排索引,也就是doc values,以供排序,聚合,过滤等操作使用。
doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上。
DocValues默认是启用的,可以在创建索引的时候关闭,如果后面要开启DocValues,需要做reindex操作。
参考:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/scoring-theory.html
https://blog.csdn.net/qq_29860591/article/details/109574595
https://www.jianshu.com/p/2624f61f1d02
http://www.dtmao.cc/news_show_378736.shtml
https://blog.csdn.net/molong1208/article/details/50623948
https://www.cnblogs.com/Neeo/articles/10721071.html
https://www.cnblogs.com/jpfss/p/10775376.html
https://zhuanlan.hu.com/p/27951938
‘贰’ TF-IDF 算法
有一篇很长的文章,用计算机提取它的关键词(Automatic Keyphrase extraction),完全不加以人工干预,请问怎样才能正确做到?
"智能问答"、"企业"、"问答库"这三个词的出现次数一样多。这是不是意味着,作为关键词,它们的重要性是一样的?
“企业”是很常见的词,相对而言“智能问答”和“问答库”不那么常见。如果这三个词在一篇文章的出现次数一样多,我们有理由可以认为,“智能问答”和“问答库”的重要程度要大于“企业”,也就是说,在关键词排序方面,“智能问答“和”问答库“应该排在”企业“前面。
需要一个重要性调整系数,衡量一个词是不是常见词。如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。
用统计学语言表达,就是在词频的基础上,要对每个词分配一个"重要性"权重。
这个权重叫做"逆文档频率"(Inverse Document Frequency,缩写为IDF),它的大小与一个词的常见程度成反比。
知道了"词频"(TF)和"逆文档频率"(IDF)以后,将这两个值相乘,就得到了一个词的TF-IDF值。某个词对文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的几个词,就是这篇文章的关键词。
需要一个语料库(corpus),用来模拟语言的使用环境。
逆文档频率(IDF)= log(语料库的文档总数/包含该词的文档数+1)
如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。
TF-IDF=词频(TF)*逆文档频率(IDF)
TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。
自动提取关键词,TF-IDF算法还可以用于许多别的地方。比如,信息检索时,对于每个文档,都可以分别计算一组搜索词("中国"、"蜜蜂"、"养殖")的TF-IDF,将它们相加,就可以得到整个文档的TF-IDF。这个值最高的文档就是与搜索词最相关的文档。
希望找到与原文章相似的其他文章,为了找出相似的文章,需要用到"余弦相似性"(cosine similiarity)。下面,我举一个例子来说明,什么是"余弦相似性"。
句子A:我喜欢吃苹果,不喜欢吃香蕉
句子B:我不喜欢吃苹果,也不喜欢吃香蕉
请问怎样才能计算上面两句话的相似程度?
基本思路是:如果这两句话的用词越相似,它们的内容就应该越相似。因此,可以从词频入手,计算它们的相似程度。
问题就变成了如何计算这两个向量的相似程度。
我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。
以二维空间为例,上图的a和b是两个向量,我们要计算它们的夹角θ。余弦定理告诉我们,可以用下面的公式求得:
coso=a_2+b_2-c_2/2ab
假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:
coso=x_1x_2+y_1+y_2/sqrt()
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。所以,上面的句子A和句子B是很相似的,事实上它们的夹角大约为20.3度。
由此,我们就得到了"找出相似文章"的一种算法:
如果能从3000字的文章,提炼出150字的摘要,就可以为读者节省大量阅读时间。由人完成的摘要叫"人工摘要",由机器完成的就叫"自动摘要"。
文章的信息都包含在句子中,有些句子包含的信息多,有些句子包含的信息少。"自动摘要"就是要找出那些包含信息最多的句子。
句子的信息量用"关键词"来衡量。如果包含的关键词越多,就说明这个句子越重要。Luhn提出用"簇"(cluster)表示关键词的聚集。所谓"簇"就是包含多个关键词的句子片段。
‘叁’ 情感分析之TF-IDF算法
http://mini.eastday.com/bdmip/180414224336264.html
在这篇文章中,主要介绍的内容有:
1、将单词转换为特征向量
2、TF-IDF计算单词关联度
文本的预处理和分词。
如何将单词等分类数据转成为数值格式,以方便我们后面使用机器学习来训练模型。
一、将单词转换为特征向量
词袋模型(bag-of-words model):将文本以数值特征向量的形式来表示。主要通过两个步骤来实现词袋模型:
1、为整个文档集(包含了许多的文档)上的每个单词创建一个唯一的标记。
2、为每个文档构建一个特征向量,主要包含每个单词在文档上的出现次数。
注意:由于每个文档中出现的单词数量只是整个文档集中很少的一部分,因此会有很多的单词没有出现过,就会被标记为0。所以,特征向量中大多数的元素就会为0,就会产生稀疏矩阵。
下面通过sklearn的CountVectorizer来实现一个词袋模型,将文档转换成为特征向量
通过count.vocabulary_我们可以看出每个单词所对应的索引位置,每一个句子都是由一个6维的特征向量所组成。其中,第一列的索引为0,对应单词"and","and"在第一和二条句子中没有出现过,所以为0,在第三条句子中出现过一些,所以为1。特征向量中的值也被称为原始词频(raw term frequency)简写为tf(t,d),表示在文档d中词汇t的出现次数。
注意:在上面词袋模型中,我们是使用单个的单词来构建词向量,这样的序列被称为1元组(1-gram)或单元组(unigram)模型。除了一元组以外,我们还可以构建n元组(n-gram)。n元组模型中的n取值与特定的应用场景有关,如在反垃圾邮件中,n的值为3或4的n元组可以获得比较好的效果。下面举例说明一下n元组,如在"the weather is sweet"这句话中,
1元组:"the"、"weather"、"is"、"sweet"。
2元组:"the weather"、"weather is"、"is sweet"。
在sklearn中,可以设置CountVecorizer中的ngram_range参数来构建不同的n元组模型,默认ngram_range=(1,1)。
sklearn通过CountVecorizer构建2元组
二、TF-IDF计算单词关联度
在使用上面的方法来构建词向量的时候可能会遇到一个问题:一个单词在不同类型的文档中都出现,这种类型的单词其实是不具备文档类型的区分能力。我们通过TF-IDF算法来构建词向量,从而来克服这个问题。
词频-逆文档频率(TF-IDF,term frequency-inverse document frequency):tf-idf可以定义为词频×逆文档频率
其中tf(t,d)表示单词t在文档d中的出现次数,idf(t,d)为逆文档频率,计算公式如下
其中,nd表示文档的总数,df(t,d)表示包含单词t的文档d的数量。分母中加入常数1,是为了防止df(t,d)=0的情况,导致分母为0。取log的目的是保证当df(t,d)很小的时候,不会导致idf(t,d)过大。
通过sklearn的TfidfTransformer和CountVectorizer来计算tf-idf
可以发现"is"(第二列)和"the"(第六列),它们在三个句子中都出现过,它们对于文档的分类所提供的信息并不会很多,所以它们的tf-idf的值相对来说都是比较小的。
注意:sklearn中的TfidfTransformer的TF-IDF的计算与我们上面所定义TF-IDF的公式有所不同,sklearn的TF-IDF计算公式
通常在计算TF-IDF之前,会对原始词频tf(t,d)做归一化处理,TfidfTransformer是直接对tf-idf做归一化。TfidfTransformer默认使用L2归一化,它通过与一个未归一化特征向量L2范数的比值,使得返回向量的长度为1,计算公式如下:
下面通过一个例子来说明sklearn中的TfidfTransformer的tf-idf的计算过程,以上面的第一句话"The sun is shining"为例子
1、计算原始词频
a、单词所对应的下标
b、计算第三句话的原始词频tf(t,d)
c、计算逆文档频率idf(t,d)
注意:其他的词在计算tf-idf都是0,因为原始词频为0,所以就不需要计算idf了,log是以自然数e为底。
d、计算tf-idf
所以,第一个句子的tf-idf特征向量为[0,1,1.29,1.29,0,1,0]
e、tf-idf的L2归一化
‘肆’ 如何用python玩转TF-IDF之寻找相似文章并生成摘要
应用1:关键词自动生成
核心思想是对于某个文档中的某个词,计算其在这个文档中的标准化TF值,然后计算这个词在整个语料库中的标准化IDF值。在这里,标准化是说对原始的计算公式进行了一些变换以取得更好的衡量效果,并避免某些极端情况的出现。这个词的TF-IDF值便等于TF*IDF。对于这个文档中的所有词计算它们的TF-IDF值,并按照由高到低的顺序进行排序,由此我们便可以提取我们想要的数量的关键词。
TF-IDF的优点是快捷迅速,结果相对来说比较符合实际情况。缺点是当一篇文档中的两个词的IDF值相同的时候,出现次数少的那个词有可能更为重要。再者,TF-IDF算法无法体现我词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。存在的解决办法是对文章的第一段和每段的第一句话给予比较大的权重。
应用2:计算文本相似度
明白了对于每个词,如何计算它的TF-IDF值。那么计算文本相似度也轻而易举。我们已经计算了文章中每个词的TF-IDF值,那么我们便可以将文章表征为词的TF-IDF数值向量。要计算两个文本的相似度,只需要计算余弦即可,余弦值越大,两个文本便越相似。
应用3:自动摘要
2007年,美国学者的论文<A Survey on Automatic Text Summarization>总结了目前的自动摘要算法,其中很重要的一种就是词频统计。这种方法最早出自1958年IBM公司一位科学家的论文<The Automatic Creation of Literature Abstracts>。这位科学家认为,文章的信息都包含在句子中,有的句子包含的信息多,有的句子包含的信息少。自动摘要就是找出那些包含信息最多的句子。那么句子的信息量怎么衡量呢?论文中采用了关键词来衡量。如果包含的关键词越多,就说明这个句子越重要,这位科学家提出用Cluster的来表示关键词的聚集。所谓簇,就是包含多个关键词的句子片段。
以第一个图为例,其中的cluster一共有7个词,其中4个是关键词。因此它的重要性分值就等于(4*4)/7=2.3。然后,找出包含cluster重要性分值最高的句子(比如5句),把它们合在一起,就构成了这篇文章的自动摘要。具体实现可以参见<Mining the Social Web: Analyzing Data from Facebook, Twitter, LinkedIn, and Other Social Media Sites>(O'Reilly, 2011)一书的第8章,Python代码见github。这种算法后来被简化,不再区分cluster,只考虑句子包含的关键词。伪代码如下。
Summarizer(originalText,maxSummarySize):
//计算文本的词频,生成一个列表,比如[(10,'the'),(3,'language'),(8,'code')...]
wordFrequences=getWordCounts(originalText)
//过滤掉停用词,列表变成[(3,'language'),(8,'code')...]
contentWordFrequences=filtStopWords(wordFrequences)
//按照词频的大小进行排序,形成的列表为['code','language'...]
contentWordsSortbyFreq=sortByFreqThenDropFreq(contentWordFrequences)
//将文章分成句子
sentences=getSentences(originalText)
//选择关键词首先出现的句子
setSummarySentences={}
:
firstMatchingSentence=search(sentences,word)
setSummarySentences.add(firstMatchingSentence)
ifsetSummarySentences.size()=maxSummarySize:
break
//将选中的句子按照出现顺序,组成摘要
summary=""
foreachsentenceinsentences:
:
summary=summary+""+sentence
returnsummary
类似的算法已经被写成了工具,比如基于Java的Classifier4J库的SimpleSummariser模块、基于C语言的OTS库、以及基于classifier4J的C#实现和python实现。
‘伍’ TFIDF算法实现关键词抽取
其实这是一个很简单的算法。
先来学习一下概念:
在实际的使用过程中,实际上先使用历史存量数据计算出每个词的IDF值,作为一个原始信息,在对新内容进行处理时,只需要计算出TF值就可以了,然后对这篇内容的所有词计算出TFIDF值,然后进行排序就ok了。
TFIDF是一种十分简单的关键词提取方案,在实际的应用中,还可以进行多种算法的融合,之后我再慢慢介绍。
当然了,该算法还有一些变种,基本上基于下面几种方法,有兴趣的可以了解一下。
‘陆’ 通俗理解TF-IDF
在信息检索中,tf-idf(词频-逆文档频率)是一种统计方法,用以评估一个单词在一个文档集合或语料库中的重要程度。经常被用作信息检索、文本挖掘以及用户模型的权重因素。tf-idf的值会随着单词在文档中出现的次数的增加而增大,也会随着单词在语料库中出现的次数的增多而减小。tf-idf是如今最流行的词频加权方案之一。
tf-idf的各种改进版本经常被搜索引擎用作在给定用户查询时对文档的相关性进行评分和排序的主要工具。tf-idf可以成功地用于各种主题字段的停用词过滤,包括文本摘要和分类。
TF-IDF实际上是:TF * IDF。主要思想是:如果某个词或短语在一篇文章中出现的频率高(即TF高),并且在其他文章中很少出现(即IDF高),则认为此词或者短语具有很好的类别区分能力,适合用来分类。
通俗理解TF-IDF就是:TF刻画了词语t对某篇文档的重要性,IDF刻画了词语t对整个文档集的重要性。
TF(Term Frequency,词频)表示一个给定词语t在一篇给定文档d中出现的频率。TF越高,则词语t对文档d来说越重要,TF越低,则词语t对文档d来说越不重要。那是否可以以TF作为文本相似度评价标准呢?答案是不行的,举个例子,常用的中文词语如“我”,“了”,“是”等,在给定的一篇中文文档中出现的频率是很高的,但这些中文词几乎在每篇文档中都具有非常高的词频,如果以TF作为文本相似度评价标准,那么几乎每篇文档都能被命中。
对于在某一文档 d j 里的词语 t i 来说,t i 的词频可表示为:
IDF(Inverse Document Frequency,逆向文件频率)的主要思想是:如果包含词语t的文档越少,则IDF越大,说明词语t在整个文档集层面上具有很好的类别区分能力。IDF说明了什么问题呢?还是举个例子,常用的中文词语如“我”,“了”,“是”等在每篇文档中几乎具有非常高的词频,那么对于整个文档集而言,这些词都是不重要的。对于整个文档集而言,评价词语重要性的标准就是IDF。
某一特定词语的IDF,可以由总文件数除以包含该词语的文件数,再将得到的商取对数得到:
TFIDF算法是建立在这样一个假设之上的:对区别文档最有意义的词语应该是那些在文档中出现频率高,而在整个文档集合的其他文档中出现频率少的词语,所以如果特征空间坐标系取TF词频作为测度,就可以体现同类文本的特点。另外考虑到单词区别不同类别的能力,TF-IDF法认为一个单词出现的文本频数(即包含某个单词的文本数)越小,它区别不同类别文本的能力就越大。因此引入了逆文本频度IDF的概念,以TF和IDF的乘积作为特征空间坐标系的取值测度,并用它完成对权值TF的调整,调整权值的目的在于突出重要单词,抑制次要单词。但是在本质上IDF是一种试图抑制噪声的加权,并且单纯地认为文本频率小的单词就越重要,文本频率大的单词就越无用,显然这并不是完全正确的。IDF的简单结构并不能有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能,所以TF-IDF法的精度并不是很高。
此外,在TFIDF算法中并没有体现出单词的位置信息,对于Web文档而言,权重的计算方法应该体现出HTML的结构特征。特征词在不同的标记符中对文章内容的反映程度不同,其权重的计算方法也应不同。因此应该对于处于网页不同位置的特征词分别赋予不同的系数,然后乘以特征词的词频,以提高文本表示的效果。
‘柒’ 文本特征提取
在对文本数据进行处理时,很大一部分精力都用在数据集的特征提取上,因此记录一下常用的文本特征提取方法。
文本特征提取一般分为两部分
(1)文本本身属性:元音字数数、辅音字母数、···
(2)基于文本的特征提取:TF-IDF等
比如提取以上文档的特征,基于文本本身可以提取特征:
(1)字数:统计每一行text文本的词汇数量(有多少个单词)
(2)非重复单词数量:统计每一行text文本中只出现一次的单词个数
(3)长度:每一行text的长度,占了多少存储空间(包含空格、符号、字母等的长度)
(4)停止词数量统计:between、but、about、very等词汇的数量统计
(5)标点符号数量:每一行text中包含的标点符号数量
(6)大写单词数量:统计大写单词数量
(7)标题式单词数量:统计单词拼写首字母是否为大写,且其他字母为小写的单词数量
(8)单词的平均长度:每一行text中每个单词长度的平均值
这些特征的提取不涉及复杂的函数计算,基于文本本身属性提取直观信息作为模型训练的特征。
·
TF-IDF算法 :计算单词权重最为有效的实现方法就是TF-IDF, 它是由Salton在1988 年提出的,以特征词在文档d中出现的次数与包含该特征词的文档数之比作为该词的权重。
python中使用TfidfVectorizer函数实现TF-IDF特征的提取,生成每个text的TF-IDF特征。
·
经过TF-IDF特征提取后,数据集的特征变量超级多(TF-IDF计算了整个数据集出现的所有单词对每个test的权重),面对这样庞大的特征数据,可以通过SVD实现对数据集的压缩。
SVD的原理是将庞大的TF-IDF生成的数据集A进行拆分,设置K值(想要压缩得到的维度,例如K=20,压缩后得到20列的特征数据集)X就是只有K个特征转换后的数据集。
经过压缩后的TF-IDF只有K列,与01中 基于文本本身特征 合并,即为文本数据集的特征向量。
‘捌’ CV(8):TD-IDF算法
参考: TF-IDF原理及使用
1. 原理
TF-IDF(Term Frequency-Inverse Document Frequency, 词频-逆文件频率),是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。 字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
词频 (term frequency, TF)指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(一般是词频除以文章总词数), 以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)
但是, 需要注意, 一些通用的词语对于主题并没有太大的作用, 反倒是一些出现频率较少的词才能够表达文章的主题, 所以单纯使用是TF不合适的。权重的设计必须满足:一个词预测主题的能力越强,权重越大,反之,权重越小。所有统计的文章中,一些词只是在其中很少几篇文章中出现,那么这样的词对文章的主题的作用很大,这些词的权重应该设计的较大。IDF就是在完成这样的工作.
逆向文件频率 (inverse document frequency, IDF): IDF的主要思想是如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
2. 实例:
‘玖’ 大数据算法:分类算法
KNN算法,即K近邻(K Nearest Neighbour)算法,是一种基本的分类算法。其主要原理是:对于一个需要分类的数据,将其和一组已经分类标注好的样本集合进行比较,得到距离最近的K个样本,K个样本最多归属的类别,就是这个需要分类数据的类别。下面我给你画了一个KNN算法的原理图。
图中,红蓝绿三种颜色的点为样本数据,分属三种类别 、 、 。对于待分类点 ,计算和它距离最近的5个点(即K为5),这5个点最多归属的类别为 (4个点归属 ,1个点归属 ),那么 的类别被分类为 。
KNN的算法流程也非常简单,请看下面的流程图。
KNN算法是一种非常简单实用的分类算法,可用于各种分类的场景,比如新闻分类、商品分类等,甚至可用于简单的文字识别。对于新闻分类,可以提前对若干新闻进行人工标注,标好新闻类别,计算好特征向量。对于一篇未分类的新闻,计算其特征向量后,跟所有已标注新闻进行距离计算,然后进一步利用KNN算法进行自动分类。
读到这你肯定会问,如何计算数据的距离呢?如何获得新闻的特征向量呢?
KNN算法的关键是要比较需要分类的数据与样本数据之间的距离,这在机器学习中通常的做法是:提取数据的特征值,根据特征值组成一个n维实数向量空间(这个空间也被称作特征空间),然后计算向量之间的空间距离。空间之间的距离计算方法有很多种,常用的有欧氏距离、余弦距离等。
对于数据 和 ,若其特征空间为n维实数向量空间 ,即 , ,则其欧氏距离计算公式为
这个欧式距离公式其实我们在初中的时候就学过,平面几何和立体几何里两个点之间的距离,也是用这个公式计算出来的,只是平面几何(二维几何)里的n=2,立体几何(三维几何)里的n=3,而机器学习需要面对的每个数据都可能有n维的维度,即每个数据有n个特征值。但是不管特征值n是多少,两个数据之间的空间距离的计算公式还是这个欧氏计算公式。大多数机器学习算法都需要计算数据之间的距离,因此掌握数据的距离计算公式是掌握机器学习算法的基础。
欧氏距离是最常用的数据计算公式,但是在文本数据以及用户评价数据的机器学习中,更常用的距离计算方法是余弦相似度。
余弦相似度的值越接近1表示其越相似,越接近0表示其差异越大,使用余弦相似度可以消除数据的某些冗余信息,某些情况下更贴近数据的本质。我举个简单的例子,比如两篇文章的特征值都是:“大数据”“机器学习”和“极客时间”,A文章的特征向量为(3, 3, 3),即这三个词出现次数都是3;B文章的特征向量为(6, 6, 6),即这三个词出现次数都是6。如果光看特征向量,这两个向量差别很大,如果用欧氏距离计算确实也很大,但是这两篇文章其实非常相似,只是篇幅不同而已,它们的余弦相似度为1,表示非常相似。
余弦相似度其实是计算向量的夹角,而欧氏距离公式是计算空间距离。余弦相似度更关注数据的相似性,比如两个用户给两件商品的打分分别是(3, 3)和(4, 4),那么两个用户对两件商品的喜好是相似的,这种情况下,余弦相似度比欧氏距离更合理。
我们知道了机器学习的算法需要计算距离,而计算距离需要还知道数据的特征向量,因此提取数据的特征向量是机器学习工程师们的重要工作,有时候甚至是最重要的工作。不同的数据以及不同的应用场景需要提取不同的特征值,我们以比较常见的文本数据为例,看看如何提取文本特征向量。
文本数据的特征值就是提取文本关键词,TF-IDF算法是比较常用且直观的一种文本关键词提取算法。这种算法是由TF和IDF两部分构成。
TF是词频(Term Frequency),表示某个单词在文档中出现的频率,一个单词在一个文档中出现的越频繁,TF值越高。
词频:
IDF是逆文档频率(Inverse Document Frequency),表示这个单词在所有文档中的稀缺程度,越少文档出现这个词,IDF值越高。
逆文档频率:
TF与IDF的乘积就是TF-IDF。
所以如果一个词在某一个文档中频繁出现,但在所有文档中却很少出现,那么这个词很可能就是这个文档的关键词。比如一篇关于原子能的技术文章,“核裂变”“放射性”“半衰期”等词汇会在这篇文档中频繁出现,即TF很高;但是在所有文档中出现的频率却比较低,即IDF也比较高。因此这几个词的TF-IDF值就会很高,就可能是这篇文档的关键词。如果这是一篇关于中国原子能的文章,也许“中国”这个词也会频繁出现,即TF也很高,但是“中国”也在很多文档中出现,那么IDF就会比较低,最后“中国”这个词的TF-IDF就很低,不会成为这个文档的关键词。
提取出关键词以后,就可以利用关键词的词频构造特征向量,比如上面例子关于原子能的文章,“核裂变”“放射性”“半衰期”这三个词是特征值,分别出现次数为12、9、4。那么这篇文章的特征向量就是(12, 9, 4),再利用前面提到的空间距离计算公式计算与其他文档的距离,结合KNN算法就可以实现文档的自动分类。
贝叶斯公式是一种基于条件概率的分类算法,如果我们已经知道A和B的发生概率,并且知道了B发生情况下A发生的概率,可以用贝叶斯公式计算A发生的情况下B发生的概率。事实上,我们可以根据A的情况,即输入数据,判断B的概率,即B的可能性,进而进行分类。
举个例子:假设一所学校里男生占60%,女生占40%。男生总是穿长裤,女生则一半穿长裤一半穿裙子。假设你走在校园中,迎面走来一个穿长裤的学生,你能够推断出这个穿长裤学生是男生的概率是多少吗?
答案是75%,具体算法是:
这个算法就利用了贝叶斯公式,贝叶斯公式的写法是:
意思是A发生的条件下B发生的概率,等于B发生的条件下A发生的概率,乘以B发生的概率,除以A发生的概率。还是上面这个例子,如果我问你迎面走来穿裙子的学生是女生的概率是多少。同样带入贝叶斯公式,可以计算出是女生的概率为100%。其实这个结果我们根据常识也能推断出来,但是很多时候,常识受各种因素的干扰,会出现偏差。比如有人看到一篇博士生给初中学历老板打工的新闻,就感叹读书无用。事实上,只是少见多怪,样本量太少而已。而大量数据的统计规律则能准确反映事物的分类概率。
贝叶斯分类的一个典型的应用场合是垃圾邮件分类,通过对样本邮件的统计,我们知道每个词在邮件中出现的概率 ,我们也知道正常邮件概率 和垃圾邮件的概率 ,还可以统计出垃圾邮件中各个词的出现概率 ,那么现在一封新邮件到来,我们就可以根据邮件中出现的词,计算 ,即得到这些词出现情况下,邮件为垃圾邮件的概率,进而判断邮件是否为垃圾邮件。
现实中,贝叶斯公式等号右边的概率,我们可以通过对大数据的统计获得,当有新的数据到来的时候,我们就可以带入上面的贝叶斯公式计算其概率。而如果我们设定概率超过某个值就认为其会发生,那么我们就对这个数据进行了分类和预测,具体过程如下图所示。
训练样本就是我们的原始数据,有时候原始数据并不包含我们想要计算的维度数据,比如我们想用贝叶斯公式自动分类垃圾邮件,那么首先要对原始邮件进行标注,需要标注哪些邮件是正常邮件、哪些邮件是垃圾邮件。这一类需要对数据进行标注才能进行的机器学习训练也叫作有监督的机器学习。
‘拾’ 搜索引擎的排序算法都有哪些是怎么实现的
2.1基于词频统计——词位置加权的搜索引擎
利用关键词在文档中出现的频率和位置排序是搜索引擎最早期排序的主要思想,其技术发展也最为成熟,是第一阶段搜索引擎的主要排序技术,应用非常广泛,至今仍是许多搜索引擎的核心排序技术。其基本原理是:关键词在文档中词频越高,出现的位置越重要,则被认为和检索词的相关性越好。
1)词频统计
文档的词频是指查询关键词在文档中出现的频率。查询关键词词频在文档中出现的频率越高,其相关度越大。但当关键词为常用词时,使其对相关性判断的意义非常小。TF/IDF很好的解决了这个问题。TF/IDF算法被认为是信息检索中最重要的发明。TF(Term Frequency):单文本词汇频率,用关键词的次数除以网页的总字数,其商称为“关键词的频率”。IDF(Inverse Document Frequency):逆文本频率指数,其原理是,一个关键词在N个网页中出现过,那么N越大,此关键词的权重越小,反之亦然。当关键词为常用词时,其权重极小,从而解决词频统计的缺陷。
2)词位置加权
在搜索引擎中,主要针对网页进行词位置加权。所以,页面版式信息的分析至关重要。通过对检索关键词在Web页面中不同位置和版式,给予不同的权值,从而根据权值来确定所搜索结果与检索关键词相关程度。可以考虑的版式信息有:是否是标题,是否为关键词,是否是正文,字体大小,是否加粗等等。同时,锚文本的信息也是非常重要的,它一般能精确的描述所指向的页面的内容。
2.2基于链接分析排序的第二代搜索引擎
链接分析排序的思想起源于文献引文索引机制,即论文被引用的次数越多或被越权威的论文引用,其论文就越有价值。链接分析排序的思路与其相似,网页被别的网页引用的次数越多或被越权威的网页引用,其价值就越大。被别的网页引用的次数越多,说明该网页越受欢迎,被越权威的网页引用,说明该网页质量越高。链接分析排序算法大体可以分为以下几类:基于随机漫游模型的,比如PageRank和Repution算法;基于概率模型的,如SALSA、PHITS;基于Hub和Authority相互加强模型的,如HITS及其变种;基于贝叶斯模型的,如贝叶斯算法及其简化版本。所有的算法在实际应用中都结合传统的内容分析技术进行了优化。本文主要介绍以下几种经典排序算法:
1)PageRank算法
PageRank算法由斯坦福大学博士研究生Sergey Brin和Lwraence Page等提出的。PageRank算法是Google搜索引擎的核心排序算法,是Google成为全球最成功的搜索引擎的重要因素之一,同时开启了链接分析研究的热潮。
PageRank算法的基本思想是:页面的重要程度用PageRank值来衡量,PageRank值主要体现在两个方面:引用该页面的页面个数和引用该页面的页面重要程度。一个页面P(A)被另一个页面P(B)引用,可看成P(B)推荐P(A),P(B)将其重要程度(PageRank值)平均的分配P(B)所引用的所有页面,所以越多页面引用P(A),则越多的页面分配PageRank值给P(A),PageRank值也就越高,P(A)越重要。另外,P(B)越重要,它所引用的页面能分配到的PageRank值就越多,P(A)的PageRank值也就越高,也就越重要。
其计算公式为:
PR(A):页面A的PageRank值;
d:阻尼系数,由于某些页面没有入链接或者出链接,无法计算PageRank值,为避免这个问题(即LinkSink问题),而提出的。阻尼系数常指定为0.85。
R(Pi):页面Pi的PageRank值;
C(Pi):页面链出的链接数量;
PageRank值的计算初始值相同,为了不忽视被重要网页链接的网页也是重要的这一重要因素,需要反复迭代运算,据张映海撰文的计算结果,需要进行10次以上的迭代后链接评价值趋于稳定,如此经过多次迭代,系统的PR值达到收敛。
PageRank是一个与查询无关的静态算法,因此所有网页的PageRank值均可以通过离线计算获得。这样,减少了用户检索时需要的排序时间,极大地降低了查询响应时间。但是PageRank存在两个缺陷:首先PageRank算法严重歧视新加入的网页,因为新的网页的出链接和入链接通常都很少,PageRank值非常低。另外PageRank算法仅仅依靠外部链接数量和重要度来进行排名,而忽略了页面的主题相关性,以至于一些主题不相关的网页(如广告页面)获得较大的PageRank值,从而影响了搜索结果的准确性。为此,各种主题相关算法纷纷涌现,其中以以下几种算法最为典型。
2)Topic-Sensitive PageRank算法
由于最初PageRank算法中是没有考虑主题相关因素的,斯坦福大学计算机科学系Taher Haveli-wala提出了一种主题敏感(Topic-Sensitive)的PageRank算法解决了“主题漂流”问题。该算法考虑到有些页面在某些领域被认为是重要的,但并不表示它在其它领域也是重要的。
网页A链接网页B,可以看作网页A对网页B的评分,如果网页A与网页B属于相同主题,则可认为A对B的评分更可靠。因为A与B可形象的看作是同行,同行对同行的了解往往比不是同行的要多,所以同行的评分往往比不是同行的评分可靠。遗憾的是TSPR并没有利用主题的相关性来提高链接得分的准确性。
3)HillTop算法
HillTop是Google的一个工程师Bharat在2001年获得的专利。HillTop是一种查询相关性链接分析算法,克服了的PageRank的查询无关性的缺点。HillTop算法认为具有相同主题的相关文档链接对于搜索者会有更大的价值。在Hilltop中仅考虑那些用于引导人们浏览资源的专家页面(Export Sources)。Hilltop在收到一个查询请求时,首先根据查询的主题计算出一列相关性最强的专家页面,然后根据指向目标页面的非从属专家页面的数量和相关性来对目标页面进行排序。
HillTop算法确定网页与搜索关键词的匹配程度的基本排序过程取代了过分依靠PageRank的值去寻找那些权威页面的方法,避免了许多想通过增加许多无效链接来提高网页PageRank值的作弊方法。HillTop算法通过不同等级的评分确保了评价结果对关键词的相关性,通过不同位置的评分确保了主题(行业)的相关性,通过可区分短语数防止了关键词的堆砌。
但是,专家页面的搜索和确定对算法起关键作用,专家页面的质量对算法的准确性起着决定性作用,也就忽略了大多数非专家页面的影响。专家页面在互联网中占的比例非常低(1.79%),无法代表互联网全部网页,所以HillTop存在一定的局限性。同时,不同于PageRank算法,HillTop算法的运算是在线运行的,对系统的响应时间产生极大的压力。
4)HITS
HITS(Hyperlink Inced Topic Search)算法是Kleinberg在1998年提出的,是基于超链接分析排序算法中另一个最着名的算法之一。该算法按照超链接的方向,将网页分成两种类型的页面:Authority页面和Hub页面。Authority页面又称权威页面,是指与某个查询关键词和组合最相近的页面,Hub页面又称目录页,该页面的内容主要是大量指向Authority页面的链接,它的主要功能就是把这些Authority页面联合在一起。对于Authority页面P,当指向P的Hub页面越多,质量越高,P的Authority值就越大;而对于Hub页面H,当H指向的Authority的页面越多,Authority页面质量越高,H的Hub值就越大。对整个Web集合而言,Authority和Hub是相互依赖、相互促进,相互加强的关系。Authority和Hub之间相互优化的关系,即为HITS算法的基础。
HITS基本思想是:算法根据一个网页的入度(指向此网页的超链接)和出度(从此网页指向别的网页)来衡量网页的重要性。在限定范围之后根据网页的出度和入度建立一个矩阵,通过矩阵的迭代运算和定义收敛的阈值不断对两个向量Authority和Hub值进行更新直至收敛。
实验数据表明,HITS的排名准确性要比PageRank高,HITS算法的设计符合网络用户评价网络资源质量的普遍标准,因此能够为用户更好的利用网络信息检索工具访问互联网资源带来便利。
但却存在以下缺陷:首先,HITS算法只计算主特征向量,处理不好主题漂移问题;其次,进行窄主题查询时,可能产生主题泛化问题;第三,HITS算法可以说一种实验性质的尝试。它必须在网络信息检索系统进行面向内容的检索操作之后,基于内容检索的结果页面及其直接相连的页面之间的链接关系进行计算。尽管有人尝试通过算法改进和专门设立链接结构计算服务器(Connectivity Server)等操作,可以实现一定程度的在线实时计算,但其计算代价仍然是不可接受的。
2.3基于智能化排序的第三代搜索引擎
排序算法在搜索引擎中具有特别重要的地位,目前许多搜索引擎都在进一步研究新的排序方法,来提升用户的满意度。但目前第二代搜索引擎有着两个不足之处,在此背景下,基于智能化排序的第三代搜索引擎也就应运而生。
1)相关性问题
相关性是指检索词和页面的相关程度。由于语言复杂,仅仅通过链接分析及网页的表面特征来判断检索词与页面的相关性是片面的。例如:检索“稻瘟病”,有网页是介绍水稻病虫害信息的,但文中没有“稻瘟病”这个词,搜索引擎根本无法检索到。正是以上原因,造成大量的搜索引擎作弊现象无法解决。解决相关性的的方法应该是增加语意理解,分析检索关键词与网页的相关程度,相关性分析越精准,用户的搜索效果就会越好。同时,相关性低的网页可以剔除,有效地防止搜索引擎作弊现象。检索关键词和网页的相关性是在线运行的,会给系统相应时间很大的压力,可以采用分布式体系结构可以提高系统规模和性能。
2)搜索结果的单一化问题
在搜索引擎上,任何人搜索同一个词的结果都是一样。这并不能满足用户的需求。不同的用户对检索的结果要求是不一样的。例如:普通的农民检索“稻瘟病”,只是想得到稻瘟病的相关信息以及防治方法,但农业专家或科技工作者可能会想得到稻瘟病相关的论文。
解决搜索结果单一的方法是提供个性化服务,实现智能搜索。通过Web数据挖掘,建立用户模型(如用户背景、兴趣、行为、风格),提供个性化服务。