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

Posted AI架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了翻译: 词频逆文档频率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算法介绍及实现 手把手用python从零开始实现的主要内容,如果未能解决你的问题,请参考以下文章

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

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

TF-IDF算法——原理及实现

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

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

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