尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

TF-IDF算法详解

TF-IDF算法详解 1. 引言TF-IDFTerm Frequency-Inverse Document Frequency是一种用于信息检索与文本挖掘的常用加权技术用于评估一个词语对于一个文件集或一个语料库中的其中一份文件的重要程度。它的核心思想是如果一个词语在一篇文档中出现的频率高TF高并且在其他文档中很少出现IDF高则认为这个词语具有很好的类别区分能力适合用来分类或检索。2. TF-IDF算法详解2.1 词频TF词频Term FrequencyTF表示某个词语在文档中出现的频率。它的计算方式通常是TF (词语在文档中出现的次数) / (文档总词数)例如一篇文档有 100 个词其中“算法”出现了 5 次那么“算法”的 TF 值就是 0.05。为了防止偏向长文档通常会进行归一化处理使得不同长度的文档可以横向比较。也有其他变体比如对数缩放、布尔频率等但最常用的还是归一化后的原始频率。2.2 逆文档频率IDF逆文档频率Inverse Document FrequencyIDF用于衡量一个词语的普遍重要程度。如果某个词语在很多文档中都出现那么它的 IDF 值会较低说明它不具备很好的区分能力反之如果词语只在少数文档中出现则 IDF 值较高说明它更“特别”。IDF log(总文档数 / (包含该词语的文档数 1))这里分母加 1 是为了避免当某个词语从未出现过时导致分母为 0。取对数是为了平滑数值使得 IDF 不会因为文档数量巨大而变得极端。常见的底数可以是自然对数或以 10 为底实际应用中差别不大。2.3 TF-IDF计算将 TF 和 IDF 相乘就得到了 TF-IDF 值TF-IDF(词语, 文档) TF(词语, 文档) × IDF(词语)这个值越高表示该词语在当前文档中越重要同时在整个语料库中越稀有。因此TF-IDF 常用于提取文档的关键词、构建文本特征向量以及信息检索中的排序等场景。2.4 示例假设有一个包含 1000 篇文档的语料库“机器学习”一词在 100 篇文档中出现过而在某篇文档 D 中出现了 10 次文档 D 的总词数为 200。那么TF 10 / 200 0.05IDF log(1000 / (100 1)) ≈ log(9.9) ≈ 0.996TF-IDF 0.05 × 0.996 ≈ 0.0498如果另一个词“卷积”只在 5 篇文档中出现在文档 D 中出现了 3 次则 TF 3/200 0.015IDF log(1000/(51)) ≈ log(166.7) ≈ 2.22TF-IDF 0.015 × 2.22 ≈ 0.0333。虽然“卷积”的 TF 较低但由于 IDF 很高其 TF-IDF 值仍然突出反映它在文档中的重要性。3. Python 中的 TF-IDF 使用简介在 Python 中最常用的 TF-IDF 实现来自scikit-learn库的TfidfVectorizer类。它能够将原始文本集合转换为 TF-IDF 特征矩阵方便后续的文本分类、聚类或相似度计算。3.1 基本使用步骤导入TfidfVectorizer准备一个文档列表每条文档是一个字符串创建TfidfVectorizer实例并调用fit_transform()获取特征矩阵和特征名称from sklearn.feature_extraction.text import TfidfVectorizer 文档集合 docs [ 机器学习是人工智能的重要分支, 深度学习是机器学习的一个子集, 自然语言处理是人工智能的核心方向 ] 创建 TfidfVectorizer 对象 vectorizer TfidfVectorizer() 计算 TF-IDF 矩阵 tfidf_matrix vectorizer.fit_transform(docs) 查看特征词 print(vectorizer.get_feature_names_out()) 输出特征矩阵的形状 print(tfidf_matrix.shape) 查看第一个文档的 TF-IDF 向量 print(tfidf_matrix[0].toarray())3.2 常用参数说明TfidfVectorizer提供了丰富的参数来控制分词、过滤和 IDF 计算方式max_df忽略在超过指定比例的文档中出现的词。例如max_df0.8会过滤掉在 80% 以上文档都出现的词有助于去除常见停用词。min_df忽略在少于指定比例或次数的文档中出现的词。例如min_df2表示至少出现在 2 篇文档中的词才保留。ngram_range控制是否提取 n-gram 特征。例如ngram_range(1, 2)会同时提取单个词和双词组合。stop_words指定停用词列表或使用内置停用词如english或chinese。sublinear_tf布尔值若为True则对 TF 取对数缩放1 log(tf)避免高频词过度主导。norm归一化方式默认l2对每个文档向量进行 L2 归一化使得文档长度不影响相似度比较。use_idf是否启用 IDF 加权默认为True。若设为False则只使用 TF。smooth_idf是否对 IDF 进行平滑处理默认为True即分母加 1避免零概率。通过调整这些参数可以灵活控制特征提取的效果以适应不同的文本分析任务。3.3 实际应用示例文本预处理与分词下面是一个完整的文本预处理示例演示如何使用pandas读取文件、借助jieba进行中文分词并结合停用词表过滤无意义词汇。该示例以《红楼梦》分卷文本为数据源展示了从文件读取到分词输出的完整流程。下面将代码拆分为几个逻辑部分逐一讲解第一部分导入库与初始化import pandas as pd import os filePaths [] fileContents []首先导入pandas用于数据处理和构建 DataFrame和os用于文件路径操作。接着初始化两个空列表filePaths用于存储每个文件的完整路径fileContents用于存储每个文件读取到的文本内容两者一一对应后续会一起放入 DataFrame。第二部分遍历文件夹读取所有分卷文件# 遍历分卷文件夹读取所有文件 for root, dirs, files in os.walk(r.\分卷): for name in files: filePath os.path.join(root, name) filePaths.append(filePath) f open(filePath, r, encodingutf-8) lines f.readlines() # 跳过第一行通常是标题取后续内容 fileContent .join(lines[1:]) f.close() fileContents.append(fileContent)这里使用os.walk()递归遍历.\分卷目录下的所有文件。os.walk每次返回三元组(root, dirs, files)其中root是当前目录路径files是当前目录下的文件列表。对每个文件用os.path.join拼接出完整路径并存入filePaths。读取文件时指定encodingutf-8确保中文正常解码。readlines()按行读取全部内容由于第一行通常是书名或卷标题用lines[1:]切片跳过首行再用.join()将剩余行拼接成完整文本。最后记得调用close()关闭文件句柄释放系统资源。第三部分构建 DataFrame# 构建 DataFrame corpos pd.DataFrame({ filePath: filePaths, fileContent: fileContents }) print(corpos)将filePaths和fileContents两个列表以字典形式传入pd.DataFrame键名成为列名。这样得到一个两列的表格每条记录对应一个分卷文件及其完整文本内容。打印corpos可以快速预览数据概览确认文件数量和内容是否正确加载。第四部分加载 jieba 分词器与停用词表import jieba 加载自定义词典红楼梦专有词汇 jieba.load_userdict(r.\红楼梦词库.txt) 加载停用词表 stopwords pd.read_csv( r./StopwordsCN.txt, encodingutf-8, enginepython, index_colFalse )导入jieba分词库后首先调用jieba.load_userdict()加载自定义词典。对于《红楼梦》这类古典文学存在大量人名如贾宝玉林黛玉、别称和专有词汇默认词典可能无法正确切分自定义词典能告诉 jieba 这些词应该作为一个整体避免被错误切碎。接着用pd.read_csv读取停用词表。StopwordsCN.txt是一行一个停用词的文件enginepython使用 Python 解析引擎对中文编码更友好index_colFalse表示不把第一列当作行索引。常用的停用词包括的了是在等高频但无实际语义的词汇过滤掉它们可以减少特征噪音提升 TF-IDF 质量。第五部分分词、去停用词并写入结果# 分词并过滤停用词写入输出文件 file_to_jieba open(r./分词后总结.txt, w, encodingutf-8) for index, row in corpos.iterrows(): fileContent row[fileContent] segs jieba.cut(fileContent) seg_text for seg in segs: # 过滤停用词和空白词 if seg not in stopwords.stopword.values and len(seg.strip()) 0: seg_text seg file_to_jieba.write(seg_text \n) file_to_jieba.close() print(分词完成结果已保存至 分词后总结.txt)这是核心处理环节。先用写模式打开输出文件分词后总结.txt。然后通过corpos.iterrows()逐行遍历 DataFrame每次迭代得到index行号和row该行数据。jieba.cut(fileContent)对文本进行分词返回一个可迭代的生成器每次 yield 一个词语。内层循环遍历每个词语首先判断它是否在停用词表中stopwords.stopword.values取出停用词列的 NumPy 数组再检查去除空白后是否为空——len(seg.strip()) 0可以过滤掉纯空格、换行符等无意义内容。满足条件的词语用空格拼接起来形成该文档的分词结果。每个文档处理完后用write()写入一行并追加换行符这样输出文件中每行对应一个文档的分词结果。遍历结束后关闭文件打印完成提示。整体回顾上述代码展示了中文 NLP 任务中常见的预处理流程文件遍历 → 内容读取 → 分词 → 去停用词 → 结果输出。在实际项目中这些预处理步骤往往是 TF-IDF 特征提取的前置环节经过分词和停用词过滤后的文本再输入TfidfVectorizer进行特征提取效果会更好。4. 总结TF-IDF 作为文本挖掘领域最经典的特征加权算法之一凭借其简洁直观的数学原理和出色的实际效果至今仍在关键词提取、文本相似度计算、搜索引擎排序等场景中广泛应用。本文从三个层面进行了系统梳理原理层面TF-IDF 由词频TF和逆文档频率IDF两部分组成前者衡量词语在单篇文档中的重要程度后者衡量词语在整个语料库中的区分能力两者相乘得到最终的加权分数。工具层面Python 的TfidfVectorizer提供了开箱即用的实现通过max_df、min_df、ngram_range、sublinear_tf等参数可以灵活控制特征提取策略适配不同语料和任务需求。实践层面以《红楼梦》分卷文本为例完整演示了从文件遍历、pandas 数据管理、jieba 中文分词、停用词过滤到分词结果输出的预处理流水线这正是 TF-IDF 特征提取前不可或缺的准备工作。掌握 TF-IDF 不仅有助于理解传统信息检索的核心机制也为进一步学习 Word2Vec、BERT 等现代文本表示方法打下了扎实的基础。在实际项目中建议先通过 TF-IDF 快速建立基线模型再根据业务需求逐步引入更复杂的语义表示技术。
返回列表