TF-IDF(词频-逆文档频率)介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TF-IDF(词频-逆文档频率)介绍相关的知识,希望对你有一定的参考价值。

参考技术A

词频-逆文档频度(Term Frequency - Inverse Document Frequency,TF-IDF) 技术,是一种用于资讯检索与文本挖掘的常用加权技术,可以用来评估一个词对于一个文档集或语料库中某个文档的重要程度。字词的重要性随着它在文件中出现的次数成正比增加 ,但同时会 随着它在语料库中出现的频率成反比下降 。如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。

以统计一篇文档的关键词为例,最简单的方法就是计算每个词的词频。
词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。

出现频率最高的词就是这篇文档的关键词。但是一篇文章中出现频率最高的词肯定是“的”、‘是’、‘也’……这样的词,这些词显然不能反应文章的意思,此时就需要对每个词加一个权重,最常见的词("的"、"是"、"在")给予最小的权重,较少见的但能反应这篇文章意思的词给予较大的权重,这个权重叫做逆文档频率。
**逆文档频率(nverse Document Frequency,IDF) **是一个词语普遍重要性的度量,它的大小与一个词的常见程度成反比,计算方法是语料库的文档总数除以语料库中包含该词语的文档数量,再将得到的商取对数。

知道了TF和IDF以后,将这两个值相乘,就得到了一个词的TF-IDF值。某个词对文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的几个词,就是这篇文章的关键词。

可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

翻译: 词频逆文档频率TF-IDF算法介绍及实现 手把手用python从零开始实现

从头开始创建 TF-IDF 模型
在本文中,我将解释如何在 python 中从头开始实现 tf-idf 技术,该技术用于查找由单词组成的句子的含义,并消除了词袋不能实现技术,该技术有利于文本分类或帮助机器读取数字中的单词。

TF-IDF应用(1)搜索引擎;(2)关键词提取;(3)文本相似性;(4)文本摘要

1 - 术语:

  • t - term(单词)
  • d — document文档(单词集)
  • N — count of corpus语料库计数
  • corpus — 总文档集

2 term单词频率Term Frequency (TF):

假设我们有一组英文文本文档,并希望对与查询最相关的文档进行排名,“Data Science is awesome!” 一个简单的开始方法是删除不包含所有三个单词“Data”、“is”、“Science”和“awesome”的文档,但这仍然会留下很多文档。为了进一步区分它们,我们可能会计算每个术语在每个文档中出现的次数;一个词在文档中出现的次数称为词频。

文档中出现的词的权重与词频成正比。

公式 :

# tf(t,d) = d 中 t 的计数 / d 中的单词数
tf(t,d) = count of t in d / number of words in d

3 文件频率-Document Frequency :

这 衡量了文档在整个语料集中的重要性,这与 TF 非常相似。唯一的区别是 TF 是文档 d 中术语 t 的频率计数器,其中 DF 是文档集 N 中术语 t 的出现次数。换句话说,DF 是存在该词的文档数. 如果该词在文档中至少包含一次,我们认为出现一次,我们不需要知道该词出现的次数。

# df(t) = t 在文档中的出现
df(t) = occurrence of t in documents

4 逆文档频率-Inverse Document Frequency(IDF):

在计算 TF 时,所有项都被认为同样重要。然而,众所周知,某些术语,例如“is”、“of”和“that”,可能会出现很多次但并不重要。因此,我们需要权衡频繁项,同时扩大稀有项,通过计算 IDF,加入一个逆文档频率因子,减少文档集中出现频率很高的词项的权重,增加很少出现的词项的权重.

IDF 是文档频率的倒数,它衡量术语 t 的信息量。当我们计算 IDF 时,对于出现次数最多的词,例如停用词,它会非常低(因为“is”等停用词几乎存在于所有文档中,而 N/df 会给该词一个非常低的值)。这最终给出了我们想要的,一个相对的权重。

idf(t) = N/df

现在 IDF 的其他问题很少,如果语料库很大,比如 100,000,000,IDF 值会爆炸,以避免我们取 idf 的 log 的影响。

在查询期间,当出现不在 vocab 中的单词时,df 将为 0。由于我们不能除以 0,因此我们通过在分母上加 1 来平滑值。

这是最终的公式:

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

tf-idf 现在是评估单词对集合或语料库中的文档的重要性的正确方法。这里有许多不同的 TF-IDF 变体,但现在让我们专注于这个基本版本。

公式 :

tf-idf(t, d) = tf(t, d) * log(N/(df + 1))

5 TF-IDF用Python从零开始实现 -Implementing TF-IDF in Python From Scratch :

为了在 python 中从头开始制作 TF-IDF,让我们想象一下来自不同文档的这两句话:

first_sentence:“Data Science is the sexiest job of the 21st century”。
second_sentence :“machine learning is the key for data science”。

第一步,我们必须创建 TF 函数来计算所有文档的总词频。以下是以下代码:

首先像往常一样,我们应该导入必要的库:

import pandas as pd
import sklearn as sk
import math

所以让我们加载我们的句子并将它们组合成一个集合:

first_sentence = "Data Science is the sexiest job of the 21st century"
second_sentence = "machine learning is the key for data science"

# split so each word have their own string

first_sentence = first_sentence.split(" ")
second_sentence = second_sentence.split(" ") 
# join them to remove duplicate words
total = set(first_sentence).union(set(second_sentence))

print(total)

输出 :

'21st', 'machine', 'Science', 'Data', 'of', 'learning', 'for', 'job', 'key', 'century', 'sexiest', 'data', 'the', 'is', 'science'

现在让我们添加一种使用字典键值对对两个句子进行计数的方法:

wordDictA= dict.fromkeys(total, 0)
wordDictB = dict.fromkeys(total, 0)

for word in first_sentence:
    wordDictA[word] += 1

for word in second_sentence:
    wordDictB[word] += 1

现在我们将它们放入数据框中,然后查看结果:

pd.DataFrame([wordDictA, wordDictB])


让我们编写 TF 函数:

def computeTF(wordDict, doc):
    tfDict = 
    corpusCount = len(doc)
    for word, count in wordDict.items():
        tfDict[word] = count/float(corpusCount)
    return(tfDict)
#running our sentences through the tf function:
tfFirst = computeTF(wordDictA, first_sentence)
tfSecond = computeTF(wordDictB, second_sentence)
#Converting to dataframe for visualization
tf = pd.DataFrame([tfFirst, tfSecond])
print(tf)

这是预期的输出:

这就是 TF 公式的全部内容,我只想谈谈我们应该消除它们的停用词,因为它们是最常见的词,不会给文档向量带来任何额外的价值。事实上,删除这些会增加计算和空间效率.

nltk 库有一种下载停用词的方法,因此我们可以使用 nltk 库并遍历所有单词并删除停用词,而不是自己明确提及所有停用词。有很多有效的方法可以做到这一点,但我只给出一个简单的方法。

这些是英语停用词的样本:

这是一个下载停用词并删除它们的简单代码。

import nltk
nltk.download('stopwords') # this need vpn
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
filtered_sentence = [w for w in wordDictA if not w in stop_words]
print(filtered_sentence)

输出 :

['21st', 'machine', 'Science', 'Data', 'learning', 'job', 'key', 'century', 'sexiest', 'data', 'science']

现在我们完成了 TF 部分,我们进入 IDF 部分:

def computeIDF(docList):
    idfDict = 
    N = len(docList)
    
    idfDict = dict.fromkeys(docList[0].keys(), 0)
    for word, val in idfDict.items():
        idfDict[word] = math.log10(N / (float(val) + 1))
        
    return (idfDict)

# imputing our sentences in the log file
idfs = computeIDF([wordDictA, wordDictB])
print(idfs)

输出

'21st': 0.3010299956639812,
 'machine': 0.3010299956639812,
 'Science': 0.3010299956639812,
 'Data': 0.3010299956639812,
 'of': 0.3010299956639812,
 'learning': 0.3010299956639812,
 'for': 0.3010299956639812,
 'job': 0.3010299956639812,
 'key': 0.3010299956639812,
 'century': 0.3010299956639812,
 'sexiest': 0.3010299956639812,
 'data': 0.3010299956639812,
 'the': 0.3010299956639812,
 'is': 0.3010299956639812,
 'science': 0.3010299956639812

现在我们实现了 idf 公式,让我们完成计算 TFIDF

def computeTFIDF(tfBow, idfs):
    tfidf = 
    for word, val in tfBow.items():
        tfidf[word] = val * idfs[word]
    return (tfidf)

# running our two sentencese through the IDF:
idfFirst = computeTFIDF(tfFirst, idfs)
idfSecond = computeTFIDF(tfSecond, idfs)
# putting it in a dataframe
idf = pd.DataFrame([idfFirst, idfSecond])
print(idf)

输出 :

那是很多工作。但是,如果您将来被要求从头开始编写 TF-IDF 代码,知道这一点很方便。但是,由于 sklearn 库,这可以更简单地完成。让我们看看下面的例子:

# first step is to import the library
from sklearn.feature_extraction.text import TfidfVectorizer
# for the sentence, make sure all words are lowercase or you will run into error.
# for simplicity, I just make the same sentence all lowercase

firstV= "Data Science is the sexiest job of the 21st century"
secondV= "machine learning is the key for data science"

# calling the TfidfVectorizer
vectorize = TfidfVectorizer()
# fitting the model and passing our sentences right away:
response = vectorize.fit_transform([firstV, secondV])
print(response)

这就是预期的输出:

6. 总结

在这篇文章中,我们将解释如何使用 python 和一种称为词频——逆文档频率 ( tf-idf ) 的自然语言处理 (NLP) 技术来总结文档。

6.1 tf-idf的理论依据及不足

tf-idf算法是建立在这样一个假设之上的:对区别文档最有意义的词语应该是那些在文档中出现频率高,而在整个文档集合的其他文档中出现频率少的词语,所以如果特征空间坐标系取tf词频作为测度,就可以体现同类文本的特点。另外考虑到单词区别不同类别的能力,tf-idf法认为一个单词出现的文本频数越小,它区别不同类别文本的能力就越大。因此引入了逆文本频度idf的概念,以tf和idf的乘积作为特征空间坐标系的取值测度,并用它完成对权值tf的调整,调整权值的目的在于突出重要单词,抑制次要单词。但是在本质上idf是一种试图抑制雜訊的加权,并且单纯地认为文本頻率小的单词就越重要,文本頻率大的单词就越无用,显然这并不是完全正确的。idf的简单结构并不能有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能,所以tf-idf法的精度并不是很高。

此外,在tf-idf算法中并没有体现出单词的位置信息,对于Web文档而言,权重的计算方法应该体现出HTML的结构特征。特征词在不同的标记符中对文章内容的反映程度不同,其权重的计算方法也应不同。因此应该对于处于网页不同位置的特征词分别赋予不同的系数,然后乘以特征词的词频,以提高文本表示的效果。

参考

https://towardsdatascience.com/tf-term-frequency-idf-inverse-document-frequency-from-scratch-in-python-6c2b61b78558

https://zh.m.wikipedia.org/zh/Tf-idf

以上是关于TF-IDF(词频-逆文档频率)介绍的主要内容,如果未能解决你的问题,请参考以下文章

翻译: 词频逆文档频率TF-IDF算法介绍及实现 手把手用python从零开始实现

翻译: 词频逆文档频率TF-IDF算法介绍及实现 手把手用python从零开始实现

TF-IDF(词频-逆文件频率)

机器学习入门-文本数据-构造Tf-idf词袋模型(词频和逆文档频率) 1.TfidfVectorizer(构造tf-idf词袋模型)

机器学习入门-文本数据-构造Tf-idf词袋模型(词频和逆文档频率) 1.TfidfVectorizer(构造tf-idf词袋模型)

逆文档频率的例子