文章目录
- 一、 什么是TF-IDF?
-
- 1.公式详解
- 2.实例详解
- 二、 为什么使用TF-IDF?
- 三、 Python API 实践:`scikit-learn`
-
- 1.`TfidfVectorizer` 主要参数
- 2.核心方法
- 四、 实战例子:从文件读取并分析关键词
-
- 1.文件数据
- 2..完整代码
- 3.代码详解
- 4.输出示例
- 5.改进建议
- 五、 总结与展望
在自然语言处理(NLP)和信息检索领域,如何将人类语言(文本)转化为计算机可以理解和处理的数值形式,是至关重要的第一步。
TF-IDF(Term Frequency-Inverse Document Frequency)就是这样一个经典且强大的技术,它能够衡量一个词在文档集合(语料库)中某个文档里的
重要程度。本文将带你深入理解TF-IDF的原理,介绍常用的Python API,并通过一个基于真实文件读取的完整实战例子进行演示。
一、 什么是TF-IDF?
TF-IDF是一种统计方法,用于评估一个词在文档集合(语料库)中某个文档里的重要程度。其核心思想是:
简单来说,TF-IDF值高的词,是那些在当前文档中频繁出现,但在整个语料库的其他文档中很少出现的词。这些词往往最能代表该文档的独特主题。
1.公式详解
- TF (词频):
- 最简单的形式:TF(t, d) = 词t在文档d中出现的次数 / 文档d的总词数
- 还有其他变体,如对数缩放:TF(t, d) = 1 + log(词t在文档d中出现的次数),以避免长文档中词频过高。
- IDF (逆文档频率):
- IDF(t) = log(语料库中文档总数 / 包含词t的文档数)
- 这里的 log 通常以自然对数(e)或以10为底,具体实现可能不同。分母加1(或分子加1)是常见的平滑处理,防止分母为0。
- TF-IDF:
- TF-IDF(t, d) = TF(t, d) * IDF(t)
2.实例详解
假定有一篇文章《中国的蜜蜂养殖》,该文长度为1000个词,“中国”、“蜜蜂”、“养殖”各出现20次,则这三个词的“词频”(TF)都为0.02。然后,搜索Google发现,包含“的”字的网页共有250亿张,假定这就是中文网页总数。包含“中国”的网页共有62.3亿张,包含“蜜蜂”的网页为0.484亿张,包含“养殖”的网页为0.973亿张。则它们的逆文档频率(IDF)和TF-IDF如下:
中国 | 62.3 | 0.603 | 0.0121 |
蜜蜂 | 0.484 | 2.713 | 0.0543 |
养殖 | 0.973 | 2.410 | 0.0482 |
从上表可见,“蜜蜂”的TF-IDF值最高,“养殖”其次,“中国”最低。所以,如果只选择一个词,“蜜蜂”就是这篇文章的关键词。
结果解释:
- 高TF-IDF值:该词在当前文档中很常见,但在语料库的其他文档中不常见。这通常是一个关键词。
- 低TF-IDF值:该词要么在当前文档中不常见(低TF),要么在很多文档中都很常见(低IDF,如“的”、“是”、“在”等停用词)。这类词通常不重要。
二、 为什么使用TF-IDF?
- 降维与特征提取:将文本转换为数值向量,便于机器学习模型处理。
- 关键词提取:找出最能代表文档主题的词汇。
- 文档相似度计算:通过比较文档的TF-IDF向量(如计算余弦相似度)来判断它们的相似性。
- 信息检索:搜索引擎用来评估文档与查询的相关性。
- 文本分类:作为分类模型的输入特征。
三、 Python API 实践:scikit-learn
Python中最常用且最方便实现TF-IDF的库是 scikit-learn。其核心类是 TfidfVectorizer。
1.TfidfVectorizer 主要参数
- max_features:保留TF-IDF值最高的前N个词作为特征。
- stop_words:指定停用词列表(如英文的'english'),这些词会被忽略。
- ngram_range:考虑词组(n-grams),例如 (1, 2) 表示同时考虑单个词和二元词组。
- min_df / max_df:过滤掉在少于min_df个文档或超过max_df比例文档中出现的词。
- sublinear_tf:如果为True,则使用1 + log(TF)作为词频,有助于抑制高频词的影响。
- norm:向量的归一化方式,通常是'l2'。
2.核心方法
- fit(documents):学习词汇表和IDF值。
- transform(documents):将文档转换为TF-IDF矩阵。
- fit_transform(documents):一步完成学习和转换。
- get_feature_names_out():获取特征(词)的名称列表。
- get_idf():获取每个词的IDF值(需要先调用fit)。
四、 实战例子:从文件读取并分析关键词
现在,我们来看一个更贴近实际应用场景的例子。我们将从一个名为 task2_1.txt 的文本文件中读取多行文本(每行视为一个独立的文档),然后使用TF-IDF分析并提取最重要的关键词。
1.文件数据
This is the first document
This document is the second document
And this is the third one
Is this the first document
This line has several words
This is the final document
2…完整代码
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
# 1. 读取文本文件内容
# 假设 task2_1.txt 每行是一个文档
inFile = open(r'task2_1.txt', 'r', encoding='utf-8') # 建议指定编码
corpus = inFile.readlines()
inFile.close() # 关闭文件释放资源
# 或者使用更安全的 with 语句:
# with open(r'task2_1.txt', 'r', encoding='utf-8') as f:
# corpus = f.readlines()
# 2. 初始化TF-IDF向量器并计算矩阵
# 使用默认参数,可根据需要添加 stop_words, max_features 等
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(corpus)
# 3. 获取词汇列表(兼容新版本sklearn)
wordlist = vectorizer.get_feature_names_out()
# 4. 转换为DataFrame(行:词汇,列:文档)
# .T 表示转置,使得词汇成为行索引,文档成为列
df = pd.DataFrame(tfidf_matrix.T.todense(), index=wordlist)
# 5. 计算每个词汇的平均TF-IDF值(作为重要性指标)
# axis=1 表示对每一行(即每个词在所有文档中的TF-IDF值)求平均
df['mean_tfidf'] = df.mean(axis=1)
# 6. 按平均TF-IDF值降序排序
# ascending=False 表示降序排列,高分在前
sorted_words = df.sort_values(by='mean_tfidf', ascending=False)
# 7. 打印完整排序结果(所有词汇及其平均TF-IDF值)
print("所有关键词按平均TF-IDF值排序(降序):")
print(sorted_words[['mean_tfidf']]) # 只显示平均TF-IDF值列
# 8. 打印前五名关键词
print("\\n排名前五的关键词:")
top5_words = sorted_words.head(5)
print(top5_words.index.tolist()) # 只显示词汇名称
3.代码详解
- tfidf_matrix 的原始形状是 (文档数, 词汇数)。
- .T 将其转置为 (词汇数, 文档数),这样每个词汇就对应一行。
- .todense() 将稀疏矩阵转换为普通的NumPy数组,便于Pandas处理(对于非常大的矩阵,此步骤可能消耗较多内存,可考虑直接使用稀疏矩阵计算均值)。
4.输出示例
所有关键词按平均TF-IDF值排序(降序):
mean_tfidf
document 0.330080
is 0.281045
the 0.281045
this 0.279621
first 0.206838
final 0.115731
second 0.094208
and 0.086389
one 0.086389
third 0.086389
has 0.081354
line 0.081354
several 0.081354
words 0.081354
排名前五的关键词:
['document', 'is', 'the', 'this', 'first']
这意味着 document 是整个文件集合中最重要的关键词。
5.改进建议
- 文件编码:读取文件时最好指定 encoding='utf-8',避免编码错误。
- 资源管理:使用 with open(…) as f: 语句可以自动管理文件关闭。
- 停用词:对于英文文本,强烈建议添加 stop_words='english' 来过滤掉 the, is, and 等无意义的词。
- 内存优化:对于大文件,避免使用 .todense(),可以直接用 tfidf_matrix.mean(axis=0) 计算每列(词汇)的均值,然后与 wordlist 结合排序。
- 预处理:可以自定义 token_pattern 或使用更复杂的分词器(如jieba用于中文)。
五、 总结与展望
TF-IDF是一个简单但极其有效的文本表示方法,至今仍在许多应用中发挥着重要作用。通过 scikit-learn 的 TfidfVectorizer,我们可以非常方便地将其应用于实际项目,如本文展示的从文件读取并分析关键词。
优点:
- 概念清晰,易于理解和实现。
- 有效抑制常见词(停用词)的影响,突出关键词。
- 计算相对高效。
局限性:
-
忽略词序和语义:将文本视为“词袋”(Bag of Words),丢失了词序和上下文信息。
-
无法处理同义词/多义词:不同的词可能有相同含义(同义词),同一个词在不同上下文可能有不同含义(多义词)。
-
对短文本效果可能不佳。
-
概念清晰,易于理解和实现。
-
有效抑制常见词(停用词)的影响,突出关键词。
-
计算相对高效。
局限性:
- 忽略词序和语义:将文本视为“词袋”(Bag of Words),丢失了词序和上下文信息。
- 无法处理同义词/多义词:不同的词可能有相同含义(同义词),同一个词在不同上下文可能有不同含义(多义词)。
- 对短文本效果可能不佳。
随着深度学习的发展,像 Word2Vec, GloVe, 以及基于Transformer的模型(如 BERT)能够捕捉更丰富的语义和上下文信息,性能往往优于TF-IDF。然而,TF-IDF因其简单、高效和可解释性强,仍然是一个不可或缺的基线工具和特征工程手段。
评论前必须登录!
注册