tf-idf代表术语频率-文档频率。 tf-idf权重是信息检索和文本挖掘中经常使用的权重。搜索引擎经常使用tf-idf加权方案的变体来对给定查询的文档相关性进行评分和排名。此权重是一种统计量度,用于评估单词对集合或语料库中文档的重要性。重要性与单词在文档中出现的次数成正比,但与语料库(数据集)中单词的出现频率相抵消。
如何计算:
tf-idf是一种加权方案,它根据文档中的每个术语的术语频率(tf)和反向文档频率(idf)为其分配权重。体重得分较高的术语被认为更为重要。
通常,tf-idf权重由两个项组成-
- 归一化词频(tf)
- 反文档频率(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 |搜索引擎实施