📜  网页排名的tf-idf模型

📅  最后修改于: 2021-04-17 01:45:57             🧑  作者: Mango

tf-idf代表术语频率-文档频率。 tf-idf权重是信息检索和文本挖掘中经常使用的权重。搜索引擎经常使用tf-idf加权方案的变体来对给定查询的文档相关性进行评分和排名。此权重是一种统计量度,用于评估单词对集合或语料库中文档的重要性。重要性与单词在文档中出现的次数成正比,但与语料库(数据集)中单词的出现频率相抵消。

如何计算:
tf-idf是一种加权方案,它根据文档中的每个术语的术语频率(tf)和反向文档频率(idf)为其分配权重。体重得分较高的术语被认为更为重要。

通常,tf-idf权重由两个项组成-

  1. 归一化词频(tf)
  2. 反文档频率(idf)

让我们拿3个文档来说明它是如何工作的。

Doc 1: Ben在计算机实验室研究计算机。
Doc 2:史蒂夫在布朗大学任教。
Doc 3:数据科学家致力于大型数据集。

假设我们正在使用以下查询对这些文档进行搜索:数据科学家

该查询是自由文本查询。这意味着查询中的查询字词在搜索界面中以自由格式键入,而没有任何连接的搜索运算符。

步骤1:计算字词频率(tf)

频率表示文档d中特定术语t的出现次数。所以,

tf(t, d) = N(t, d), wherein tf(t, d) = term frequency for a term t in document d.

N(t, d)  = number of times a term t occurs in document d

我们可以看到,术语在文档中出现的次数越多,它就越重要,这是合乎逻辑的。由于术语的顺序并不重要,因此我们可以使用向量以单词袋模型表示文档。文档中每个唯一术语都有一个条目,其值是其术语频率。

下面给出的是每个文档中的术语及其使用频率。 [N(t,d)]

tf for document 1:

Doc 1 Ben Studies Computer Lab
tf 1 1 2 1

Doc 1的向量空间表示形式: [ 1,1,2,1 ]

tf for document 2:

Doc 2 Steve teaches Brown University
tf 1 1 1 1

Doc 2的向量空间表示形式: [ 1、1、1、1 ]

tf for document 3:

Doc 3 Data Scientists work large datasets
tf 1 1 1 1 1

Doc 3的向量空间表示形式: [ 1,1,1,1,1 ]

因此,在公共向量空间中将文档表示为向量被称为向量空间模型,这对于信息检索非常重要。

由于我们处理的是“频率”一词,它取决于出现次数,因此,较长的文档将受到更多青睐。为避免这种情况,请标准化术语“频率”

tf(t, d) = N(t, d) / ||D||
wherein, ||D|| = Total number of term in the document

||D|| for each document:

Documents ||D||
1 7
2 5
3 6

以下是所有文档的标准化术语频率,即[N(t,d)/ || D ||]

Normalized TF for Document 1:

Doc1 Ben studies Computer Lab
Normalized Tf 0.143 0.143 0.286 0.143

文档1的向量空间表示形式: [0.143,0.143,0.286,0.143]

Normalized tf for document 2:

Doc 2 Steve teaches Brown University
NormalizedTf 0.2 0.2 0.2 0.2

文档2的向量空间表示形式: [0.2,0.2,0.2,0.2]

Normalized tf for document 3:

Doc 3 Data Scientists work large datasets
NormalizedTf 0.167 0.167 0.167 0.167 0.167

文档3的向量空间表示形式: [0.167,0.167,0.167,0.167,0.167]

Python的以下函数将执行标准化的TF计算:

def termFrequency(term, doc): 
      
    """
    Input: term: Term in the Document, doc: Document
    Return: Normalized tf: Number of times term occurs
      in document/Total number of terms in the document
    """
    # Splitting the document into individual terms
    normalizeTermFreq = doc.lower().split() 
  
    # Number of times the term occurs in the document
    term_in_document = normalizeTermFreq.count(term.lower()) 
  
    # Total number of terms in the document
    len_of_document = float(len(normalizeTermFreq )) 
  
    # Normalized Term Frequency
    normalized_tf = term_in_document / len_of_document 
  
    return normalized_tf

第2步:计算反向文档频率– idf

它通常测量术语的重要性。进行搜索的主要目的是找出与查询匹配的相关文档。由于tf认为所有术语同等重要,因此,我们不能仅使用术语频率来计算文档中术语的权重。但是,众所周知,某些术语(例如“是”,“属于”和“那个”)可能会出现很多次,但意义不大。因此,我们需要权衡常用条款,同时扩大稀有条款。对数可以帮助我们解决这个问题。

首先,通过计算包含术语t的文档数来找到术语t的文档频率:

df(t) = N(t)

where-
df(t) = Document frequency of a term t
N(t) = Number of documents containing the term t

术语频率仅是一个特定文档中一个术语的出现次数;而文档频率是该术语出现在不同文档中的数量,因此它取决于整个语料库。现在让我们看一下逆文档频率的定义。术语的idf是语料库中文档的数量除以术语的文档频率。

idf(t) = N/ df(t) = N/N(t)

可以预期,较频繁的术语被认为不太重要,但是该因子(最有可能是整数)似乎太苛刻了。因此,我们采用逆文档频率的对数(以2为底)。因此,项t的idf变为:

idf(t) = log(N/ df(t))

这样做更好,并且由于log是单调递增的函数我们可以安全地使用它。让我们为“计算机”一词计算IDF:

idf(computer) = log(Total Number Of Documents / Number Of Documents with term Computer in it)

共有3个文档= Document1,Document2,Document3

The term Computer appears in Document1

idf(computer) = log(3 / 1)
          = 1.5849

以下给出的是所有文档中出现的术语的IDF

Given No. of documents in which term appears(Nt) idf = Log(N/Nt)
Ben 1 Log(3/1)=1.5849
Studies 1 Log(3/1)=1.5849
Computer 1 Log(3/1)=1.5849
Lab 1 Log(3/1)=1.5849
Steve 1 Log(3/1)=1.5849
Teaches 1 Log(3/1)=1.5849
Brown 1 Log(3/1)=1.5849
University 1 Log(3/1)=1.5849
Data 1 Log(3/1)=1.5849
Scientists 1 Log(3/1)=1.5849
Work 1 Log(3/1)=1.5849
Large 1 Log(3/1)=1.5849
Dataset 1 Log(3/1)=1.5849

下面给出的是Python用于计算idf的函数:

def inverseDocumentFrequency(term, allDocs):
    num_docs_with_given_term = 0
  
    """
    Input: term: Term in the Document,
           allDocs: List of all documents
    Return: Inverse Document Frequency (idf) for term
            = Logarithm ((Total Number of Documents) / 
            (Number of documents containing the term))
    """
    # Iterate through all the documents
    for doc in allDocs:
          
        """
        Putting a check if a term appears in a document.
        If term is present in the document, then 
        increment "num_docs_with_given_term" variable
        """
        if term.lower() in allDocs[doc].lower().split():
            num_docs_with_given_term += 1
  
    if num_docs_with_given_term > 0:
        # Total number of documents
        total_num_docs = len(allDocs) 
  
        # Calculating the IDF 
        idf_val = log(float(total_num_docs) / num_docs_with_given_term)
        return idf_val
    else:
        return 0

步骤3:TF-IDF计分

现在我们已经定义了tf和idf,现在我们可以将它们结合起来以产生文档d中项t的最终分数。所以,

tf-idf(t, d) = tf(t, d)* idf(t, d)

对于查询中的每个术语,将其归一化的术语频率与每个文档上的IDF相乘。在文档3中,针对术语数据,归一化的术语频率为0.167,其IDF为1.5849。将它们相乘得到0.2646。下面给出的是所有文档中数据和科学家的TF * IDF计算。

Doc 1 Doc 2 Doc 3
Data 0 0 0.2646
Scientists 0 0 0.2646

我们将使用任何相似度度量(例如,余弦相似度方法)来查找查询和每个文档之间的相似度。例如,如果我们使用余弦相似度方法来查找相似度,则角度越小,相似度就越大。

使用下面给出的公式,我们可以找出任何两个文档之间的相似性,比如说d1,d2。

Cosine Similarity (d1, d2) =  Dot product(d1, d2) / ||d1|| * ||d2||

Dot product (d1, d2) = d1[0] * d2[0] + d1[1] * d2[1] * … * d1[n] * d2[n]
||d1|| = square root(d1[0]^2 + d1[1]^2 + ... + d1[n]^2)
||d2|| = square root(d2[0]^2 + d2[1]^2 + ... + d2[n]^2)

参考:

  • 维基百科
  • Arden Dertat |搜索引擎实施