微信登录

文本表示 - TF IDF - 计算词频 逆文档频率

文本表示 - TF - IDF - 计算词频 逆文档频率

一、引言

在自然语言处理(NLP)中,文本表示是一个基础且关键的任务,它旨在将文本数据转化为计算机能够理解和处理的数值形式。TF - IDF(Term Frequency - Inverse Document Frequency)是一种常用的文本特征提取方法,用于评估一个词在文档集合中的重要性。通过计算词频(TF)和逆文档频率(IDF),TF - IDF 能够突出那些在特定文档中频繁出现,但在整个文档集合中相对较少出现的词,这些词通常更能代表文档的主题。

二、TF - IDF 原理

2.1 词频(Term Frequency, TF)

词频指的是一个词在文档中出现的频率。计算公式为:
[ TF{t,d} = \frac{n{t,d}}{\sum{i} n{i,d}} ]
其中,(n{t,d}) 是词 (t) 在文档 (d) 中出现的次数,(\sum{i} n_{i,d}) 是文档 (d) 中所有词的出现次数之和。

2.2 逆文档频率(Inverse Document Frequency, IDF)

逆文档频率衡量的是一个词的普遍重要性。如果一个词在很多文档中都出现,那么它的 IDF 值就会较低;反之,如果一个词只在少数文档中出现,它的 IDF 值就会较高。计算公式为:
[ IDF{t} = \log \frac{N}{df{t}} ]
其中,(N) 是文档集合中的文档总数,(df_{t}) 是包含词 (t) 的文档数。

2.3 TF - IDF 值

将词频和逆文档频率相乘,就得到了 TF - IDF 值:
[ TF - IDF{t,d} = TF{t,d} \times IDF_{t} ]

三、TF - IDF 计算示例

假设我们有以下三个文档的文档集合:

  • 文档 1:“The cat sat on the mat.”
  • 文档 2:“The dog chased the cat.”
  • 文档 3:“The bird flew in the sky.”

下面我们手动计算 “cat” 这个词在文档 1 中的 TF - IDF 值。

3.1 计算词频(TF)

在文档 1 中,“cat” 出现了 1 次,文档 1 总共有 6 个词。所以 “cat” 在文档 1 中的词频为:
[ TF_{cat,doc1} = \frac{1}{6} \approx 0.167 ]

3.2 计算逆文档频率(IDF)

文档总数 (N = 3),包含 “cat” 的文档数 (df{cat} = 2)。所以 “cat” 的逆文档频率为:
[ IDF
{cat} = \log \frac{3}{2} \approx 0.405 ]

3.3 计算 TF - IDF 值

“cat” 在文档 1 中的 TF - IDF 值为:
[ TF - IDF{cat,doc1} = TF{cat,doc1} \times IDF_{cat} \approx 0.167 \times 0.405 \approx 0.068 ]

四、Python 代码演示

  1. import math
  2. from collections import Counter
  3. # 文档集合
  4. documents = [
  5. "The cat sat on the mat.",
  6. "The dog chased the cat.",
  7. "The bird flew in the sky."
  8. ]
  9. # 计算词频(TF)
  10. def compute_tf(document):
  11. word_counts = Counter(document.lower().split())
  12. total_words = len(document.lower().split())
  13. tf = {word: count / total_words for word, count in word_counts.items()}
  14. return tf
  15. # 计算逆文档频率(IDF)
  16. def compute_idf(documents):
  17. num_docs = len(documents)
  18. word_doc_count = {}
  19. for doc in documents:
  20. unique_words = set(doc.lower().split())
  21. for word in unique_words:
  22. word_doc_count[word] = word_doc_count.get(word, 0) + 1
  23. idf = {word: math.log(num_docs / count) for word, count in word_doc_count.items()}
  24. return idf
  25. # 计算 TF - IDF
  26. def compute_tf_idf(documents):
  27. tf_list = [compute_tf(doc) for doc in documents]
  28. idf = compute_idf(documents)
  29. tf_idf_list = []
  30. for tf in tf_list:
  31. tf_idf = {word: tf[word] * idf[word] for word in tf}
  32. tf_idf_list.append(tf_idf)
  33. return tf_idf_list
  34. # 计算 TF - IDF 值
  35. tf_idf_result = compute_tf_idf(documents)
  36. # 输出结果
  37. for i, doc_tf_idf in enumerate(tf_idf_result):
  38. print(f"文档 {i + 1} 的 TF - IDF 值:")
  39. for word, score in doc_tf_idf.items():
  40. print(f" {word}: {score:.4f}")

五、总结

TF - IDF 是一种简单而有效的文本表示方法,它通过结合词频和逆文档频率,能够突出文档中的重要词汇。以下是 TF - IDF 的优缺点总结:

优点 缺点
简单易懂,计算效率高 没有考虑词的语义信息
能够有效过滤常见词,突出关键词 对于短文本效果可能不佳
不需要额外的训练数据 对于新出现的词,IDF 值可能不准确

TF - IDF 在信息检索、文本分类、关键词提取等任务中都有广泛的应用。通过合理使用 TF - IDF,我们可以更好地处理和分析文本数据。