TF-IDF 算法详解及 Python 实现


前言

  本内容主要介绍 TF-IDF 算法,以及 Python 实现。

1.1 TF-IDF 算法的概念

  TF-IDF(Term Frequency - Inverse Document Frequency,词频-逆文档频率),是一种用于信息检索与数据挖掘的常用加权技术,常用于挖掘文章中的关键词。TF-IDF 是一种统计分析方法,用于评估一个词对一个文件集或者一个语料库的重要程度。

  TF-IDF 有两部分,TF 和 IDF,下面将进行说明。

1.1.1 TF

  TF(Term Frequency,词频),某个词在文档中出现的次数或频率。如果某篇文档中的某个词出现多次,那这个词可能是比较重要的词。当然,需要排除停用词。计算公式如下:

词 频 ( T F ) = 某 个 词 在 文 档 中 的 出 现 次 数 (1) 词频(TF)=某个词在文档中的出现次数 \tag{1} TF=(1)

  考虑到文档有长短之分,为了便于不同文档的比较,对“词频”进行标准化。计算公式如下:

词 频 ( T F ) = 某 个 词 在 文 档 中 出 现 的 次 数 / 文 档 的 总 词 数 (2) 词频(TF)= 某个词在文档中出现的次数 / 文档的总词数 \tag{2} TF=/(2)

1.1.2 IDF

  IDF(Inverse Document Frequency,逆文档频率),这是一个词语“权重”的度量,如果一个词在多篇文档中词频较低,也就表示这是一个比较少见的词,则这个词 IDF 值越大。计算公式如下:

逆 文 档 频 率 ( I D F ) = log ⁡ ( 语 料 库 的 文 档 总 数 / ( 包 含 该 词 的 文 档 数 + 1 ) ) (3) 逆文档频率(IDF)= \log(语料库的文档总数/(包含该词的文档数+1)) \tag{3} IDF=log(/(+1))(3)

  如果一个词越常见那么分母就越大,逆文档频率就越小越接近 0。分母之所以要加 1,是为了避免分母为 0(即所有文档都不包含该词),这属于一种平滑方法。

  注意:在不同的库中,实现 IDF 时,使用的平滑方法不完全相同。

1.1.3 TF-IDF

  将 TF 和 IDF 相乘就得到 TF-IDF,计算公式如下:

T F − I D F = 词 频 ( T F ) × 逆 文 档 频 率 ( I D F ) (4) TF-IDF=词频(TF)\times 逆文档频率(IDF) \tag{4} TFIDF=TF×IDF(4)

  一个词的重要程度跟它在文档中出现的次数成正比,跟它在语料库出现的次数成反比。这种计算方式能有效避免常用词对关键词的影响,提高了关键词与文章之间的相关性。

1.2 代码实现 TF-IDF 算法

1.2.1 用 Python 实现 TF-IDF 算法

使用 Python 手动实现 TF-IDF 算法,具体代码如下:

import math

class TfIdf:
    def __init__(self):
        self.num_docs = 0
        self.vocab = {}

    def add_corpus(self, corpus):
        self._merge_corpus(corpus)

        tfidf_list = []
        for sentence in corpus:
            tfidf_list.append(self.get_tfidf(sentence))
        return tfidf_list

    def _merge_corpus(self, corpus):
        """
        统计语料库,输出词表,并统计包含每个词的文档数。
        """
        self.num_docs = len(corpus)
        for sentence in corpus:
            words = sentence.strip().split()
            words = set(words)
            for word in words:
                self.vocab[word] = self.vocab.get(word, 0.0) + 1.0

    def _get_idf(self, term):
        """
        计算 IDF 值
        """
        return math.log(self.num_docs / (self.vocab.get(term, 0.0) + 1.0))

    def get_tfidf(self, sentence):
        tfidf = {}
        terms = sentence.strip().split()
        terms_set = set(terms)
        num_terms = len(terms)
        for term in terms_set:
            # 计算 TF 值
            tf = float(terms.count(term)) / num_terms
            # 计算 IDF 值,在实际实现时,可以提前将所有词的 IDF 提前计算好,然后直接使用。
            idf = self._get_idf(term)
            # 计算 TF-IDF 值
            tfidf[term] = tf * idf
        return tfidf

corpus = [
    "What is the weather like today",
    "what is for dinner tonight",
    "this is question worth pondering",
    "it is a beautiful day today"
]

tfidf = TfIdf()
tfidf_values = tfidf.add_corpus(corpus)
for tfidf_value in tfidf_values:
    print(tfidf_value)

1.2.2 用 sklearn 实现 TF-IDF 算法

  使用 sklearn 实现 TF-IDF 时,需要用到 TfidfVectorizer,具体代码如下:

from sklearn.feature_extraction.text import TfidfVectorizer


corpus = [
    "What is the weather like today",
    "what is for dinner tonight",
    "this is question worth pondering",
    "it is a beautiful day today"
]

tfidf_vec = TfidfVectorizer()

# 使用 fit_transform() 得到 TF-IDF 矩阵
tfidf_matrix = tfidf_vec.fit_transform(corpus)
print(tfidf_matrix)

# 使用 get_feature_names() 得到不重复的单词
print(tfidf_vec.get_feature_names())

# 得到每个单词对应的 ID
print(tfidf_vec.vocabulary_)

将输出如下信息:

  (0, 11)	0.3710221459250386
  (0, 6)	0.47059454669821993
  (0, 13)	0.47059454669821993
  (0, 9)	0.47059454669821993
  (0, 4)	0.24557575678403082
  (0, 14)	0.3710221459250386
  (1, 12)	0.506765426545092
  (1, 2)	0.506765426545092
  (1, 3)	0.506765426545092
  (1, 4)	0.2644512224141842
  (1, 14)	0.3995396830595886
  (2, 7)	0.4838025881780501
  (2, 15)	0.4838025881780501
  (2, 8)	0.4838025881780501
  (2, 10)	0.4838025881780501
  (2, 4)	0.25246826075544676
  (3, 1)	0.506765426545092
  (3, 0)	0.506765426545092
  (3, 5)	0.506765426545092
  (3, 11)	0.3995396830595886
  (3, 4)	0.2644512224141842
['beautiful', 'day', 'dinner', 'for', 'is', 'it', 'like', 'pondering', 'question', 'the', 'this', 'today', 'tonight', 'weather', 'what', 'worth']
{'what': 14, 'is': 4, 'the': 9, 'weather': 13, 'like': 6, 'today': 11, 'for': 3, 'dinner': 2, 'tonight': 12, 'this': 10, 'question': 8, 'worth': 15, 'pondering': 7, 'it': 5, 'beautiful': 0, 'day': 1}

1.3 总结

  TF-IDF 的优点是简单快速,而且容易理解。

  TF-IDF 的缺点是有时候用词频来衡量文章中的一个词的重要性不够全面,有时候重要的词出现的可能不够多,而且这种计算无法体现位置信息,无法体现词在上下文的重要性。

参考

[1] 机器学习:生动理解TF-IDF算法

[2] TF-IDF算法原理及其使用详解

[3] 基于TF-IDF算法抽取文章关键词

  • 25
    点赞
  • 171
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: TF-IDF算法是一种常用的文本处理算法,可以用于计算文本中每个单词的重要程度。在Python中,可以使用scikit-learn库来实现TF-IDF算法。为了改进TF-IDF算法的效果,可以考虑以下几点: 1. 去除停用词:停用词是指在文本中频繁出现但没有实际意义的词语,如“的”、“是”等。在TF-IDF算法中,去除停用词可以减少噪声,提高算法的准确性。 2. 调整权重:TF-IDF算法中,词频文档频率的权重默认是相等的,但实际上不同的文本可能需要不同的权重。可以通过调整权重来提高算法的效果。 3. 使用n-gram模型:n-gram模型是指将文本中的词语按照一定的顺序组合成n个词语的模型。使用n-gram模型可以更好地捕捉文本中的语义信息,提高算法的准确性。 4. 使用词根还原:词根还原是指将单词还原为其原始形式,如将“running”还原为“run”。使用词根还原可以减少单词形态的差异,提高算法的准确性。 以上是TF-IDF算法改进的一些方法,可以根据具体情况选择适合自己的方法来实现算法。 ### 回答2: TF-IDF算法是信息检索中常用的一种技术,它能够帮助我们对文本数据进行快速、准确的搜索。它的核心思想是通过计算每个单词在文档集合中出现的频率文档频率,来权衡单词的重要程度,从而得出每份文档关键词。这样,我们就能用这些关键词来快速地判断一份文档与搜索实例的相关性。 Python作为一种广泛使用的编程语言,在实现TF-IDF算法方面具有一定优势。下面就来介绍一下如何改进Python实现TF-IDF算法。 1. 加载数据 首先,需要将文本数据加载到Python中。常用的方法是使用pandas库中的read_csv函数。 2. 预处理 在计算TF-IDF之前,需要进行一些预处理。首先要将所有文本都转换成小写字母,以避免大小写带来的误差。同时,还需要去除一些停用词,例如“the”、“a”、“an”等等。这些词并不会对文本的相关性产生太大的影响,反而会干扰计算。 3. 分词 将文本进行分词,是TF-IDF算法的一个重要步骤。在Python中,可以使用NLTK(自然语言工具包)来进行分词操作。NLTK提供了许多分词方法,例如最简单的word_tokenize函数。此外,还可以使用正则表达式的方法进行分词,更加灵活。 4. 计算词频 计算每个单词在文档集合中的频率,是TF-IDF算法的第一部分。在Python中,可以使用collections库的Counter函数来计算单词出现的次数。 5. 计算文档频率 计算每个单词的文档频率,是TF-IDF算法的第二部分。在Python中,可以使用math库的log函数来计算自然对数。然后,将所有文档中的单词频率除以单词的文档频率,即可得到TF-IDF值。 6. 排序 对计算出的TF-IDF值进行排序,并筛选出一定数量的关键词。在Python中,可以使用pandas库的sort_values函数进行排序。此外,也可以使用Python自带的sorted函数,更加灵活。 总之,TF-IDF算法Python中的实现,需要依次进行数据加载、预处理、分词、计算词频、计算文档频率、排序等一系列步骤。通过适当的改进,可以使这些步骤更加高效、精确。这样,就能够为我们提供更加可靠、快速的检索服务。 ### 回答3: tf-idf算法是一种常用的文本挖掘算法,用于计算文档中每个词语的重要性,它基于两个统计量:词频(term frequency)和文档频率(inverse document frequency)。在实际应用中,tf-idf算法往往需要与其他算法一起使用,以提高算法的准确性和效率。 为了改进tf-idf算法python实现,我们可以从以下几个方面入手: 1. 数据预处理:在使用tf-idf算法之前,需要对文本数据进行预处理,包括分词、去停用词、词干提取等。可以使用已有的分词库,如jieba分词库,来对文本进行分词,并使用NLTK库来对文本进行预处理。 2. 选择合适的权重计算方法:如果使用普通的TF-IDF算法,容易忽略一些重要的词语。因此,我们可以使用改进的TF-IDF算法,如Okapi BM25、Full-tF、Bidirectional TF-IDF、Sensitive TF-IDF等,来计算每个词语的权重。 3. 使用稀疏矩阵压缩数据:当文本数据量非常大时,使用稀疏矩阵压缩数据可以减少内存占用,提高算法的运行效率。可以使用Python的SciPy库来实现稀疏矩阵。 4. 优化算法实现tf-idf算法实现可以使用多线程技术,以提高算法的运行速度。可以使用Python的线程库,如threading和multiprocessing,来实现多线程计算。 总之,改进tf-idf算法python实现可以通过优化数据预处理、选择合适的权重计算方法、使用稀疏矩阵压缩数据和优化算法实现这几个方面来实现。这些改进可以提高算法的准确性和效率,使得tf-idf算法更加适用于实际应用场景。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值