机器学习入门:TF-IDF
机器学习入门TF-IDF前言本文是“机器学习入门”系列的第十站。前几篇我们学习了各种分类和聚类算法但你会发现一个问题——这些算法处理的都是数值型数据。如果我们面对的是文本数据如新闻、评论、邮件该怎么办计算机不认识文字它只认识数字。本篇我们将学习如何把文本变成数字——这就是TF-IDF的作用。它是文本挖掘中最经典、最基础的特征提取方法能将一篇文章“翻译”成一个数值向量让后续的机器学习模型能够理解和处理文本数据。目录一、认识 TF-IDF二、TF-IDF 的核心原理三、TF-IDF 的优缺点四、典型应用场景五、核心 API 速查六、实战案例红楼梦各回关键词提取七、总结一、认识 TF-IDF1.1 什么是 TF-IDFTF-IDFTerm Frequency-Inverse Document Frequency词频-逆文档频率是一种文本特征提取技术。它的作用是将一段文本转换成一个数值向量同时评估每个词对这篇文档的重要性。通俗理解想象你在读一篇关于“机器学习”的文章。如果“算法”这个词出现了很多次它可能很重要——这是词频。但如果“的”、“是”这类词也出现很多次它们其实没什么用。TF-IDF 会惩罚这些太常见的词提升真正有区分度的词的权重——这是逆文档频率。TF-IDF 用于特征提取是连接“原始文本”和“机器学习模型”的桥梁。1.2 为什么需要 TF-IDF计算机不认识文字只认识数字。如果我们要用机器学习处理文本如垃圾邮件分类、新闻分类、情感分析第一步就是把文本变成数字向量。最简单的想法是直接统计每个词在文档中出现的次数——出现次数越多就认为这个词越重要。但这种方法有一个问题像“的”、“是”、“在”这类词几乎每篇文档都有频率很高但对区分文档主题毫无帮助。TF-IDF 的巧妙之处在于它会自动降低那些在很多文档中都出现的词的权重提升那些只在少数文档中出现的词的权重。这样真正能代表文档主题的关键词就被突显出来了。二、TF-IDF 的核心原理2.1 词频TFTerm Frequency词频指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化一般是词频除以文章总词数以防止它偏向长的文件。词频 ( T F ) 某个词在文章中的出现次数 文章的总词数 \text{词频}(TF) \frac{\text{某个词在文章中的出现次数}}{\text{文章的总词数}}词频(TF)文章的总词数某个词在文章中的出现次数​直观理解一个词在文档中出现次数越多它在这篇文档中就越“重要”。但仅靠 TF 是不够的——像 “this”、“is”、“the” 这类词虽然出现频繁但没有任何区分度。2.2 逆文档频率IDFInverse Document FrequencyIDF 的核心思想是如果包含词条 t 的文档越少IDF 越大则说明词条具有很好的类别区分能力。逆文档频率 ( I D F ) log ⁡ ( 语料库的文档总数 包含该词的文档数 1 ) \text{逆文档频率}(IDF) \log\left(\frac{\text{语料库的文档总数}}{\text{包含该词的文档数} 1}\right)逆文档频率(IDF)log(包含该词的文档数1语料库的文档总数​)IDF 值含义高 IDF该词出现在很少的文档中 → 稀有、有区分度 →重要低 IDF该词出现在很多文档中 → 常见、区分性弱 →不重要2.3 TF-IDF因此TF-IDF 倾向于过滤掉常见的词语保留重要的词语。T F − I D F 词频 ( T F ) × 逆文档频率 ( I D F ) TF-IDF \text{词频}(TF) \times \text{逆文档频率}(IDF)TF−IDF词频(TF)×逆文档频率(IDF)总结TF-IDF 值越高说明该词在当前文档中既频繁出现又具有区分度——它就是这篇文档的关键词。2.4 计算示例假设有以下 6 篇文档文档编号内容D1This is the first documentD2This document is the second documentD3And this is the third oneD4Is this the first documentD5This line has several wordsD6This is the final document计算单词 “first” 在 D1 中的 TF-IDFStep 1计算 TFD1 总词数为 5“first” 出现 1 次 → TF 1/5 0.2Step 2计算 IDF总文档数 N 6包含 “first” 的文档为 D1、D4共 2 篇→ IDF log(6/(21)) log(2) ≈ 0.301Step 3计算 TF-IDFTF-IDF 0.2 × 0.301 ≈ 0.060再对比单词 “document” 在 D1 中的 TF-IDFTF 1/5 0.2同样出现 1 次IDF log(6/(41)) log(1.2) ≈ 0.079在 D1、D2、D4、D6 中出现共 4 篇TF-IDF 0.2 × 0.079 ≈ 0.016再对比单词 “this” 在 D1 中的 TF-IDFTF 1/5 0.2同样出现 1 次IDF log(6/(61)) log(0.857) ≈ -0.067出现在所有 6 篇文档中无区分度IDF 接近 0TF-IDF 0.2 × (-0.067) ≈ -0.013结果对比单词TF出现文档数IDFTF-IDF说明“first”0.22 篇0.3010.060只在少数文档出现区分度强权重最高“document”0.24 篇0.0790.016在多篇文档出现区分度中等权重中等“this”0.26 篇-0.067-0.013在所有文档出现无区分度权重为负这个示例说明仅仅出现频率高并不代表重要只有在特定文档中频繁出现且在其他文档中少见的词TF-IDF 才会赋予高权重。TF-IDF 正是通过这种方式过滤掉常见的词语保留重要的词语。三、TF-IDF 的优缺点3.1 优点简单高效计算速度快易于理解实现。自动降权通用词能自动降低“的”、“是”等高频无意义词的权重突出关键词。无需训练不依赖任何模型直接基于统计计算。可解释性强每个特征的权重都有明确含义。3.2 缺点忽略词序和语义“我打你”和“你打我”的 TF-IDF 向量可能相同但意思完全相反。维度高词汇量通常很大导致特征向量非常稀疏。丢失上下文信息无法理解同义词和一词多义。四、典型应用场景文本分类将新闻、邮件、评论自动分类。信息检索搜索引擎判断文档与查询词的相关性。关键词提取自动提取一篇文章的核心关键词。文本聚类将相似主题的文档归为一组。垃圾邮件过滤判断邮件是否为垃圾邮件。五、核心 API 速查5.1 导包方式fromsklearn.feature_extraction.textimportTfidfVectorizer5.2 核心参数详解参数名类型默认值说明max_featuresint / NoneNone最大特征数保留最重要的 N 个词用于限制词汇量、降维stop_wordsstr / listNone停用词english使用内置停用词表或自定义列表ngram_rangetuple(1, 1)词组合范围(1, 2) 表示同时考虑单个词和相邻双词组合max_dffloat / int1.0忽略在超过此比例的文档中出现的词用于过滤通用词min_dffloat / int1忽略在少于此数量的文档中出现的词用于过滤太生僻的词use_idfboolTrue是否使用 IDF 加权smooth_idfboolTrue平滑 IDF 计算避免除零sublinear_tfboolFalse使用亚线性 TF 缩放 log(1TF)5.3 常用属性属性名说明get_feature_names_out()返回所有特征词词汇表vocabulary_词到索引的映射字典idf_每个特征的 IDF 值5.4 常用方法方法名说明fit_transform(X)训练并返回 TF-IDF 矩阵transform(X)将新文档转换为 TF-IDF 向量用已训练的参数六、实战案例红楼梦各回关键词提取6.1 案例背景《红楼梦》作为中国古典文学的巅峰之作全书共120回每一回都有其独特的情节重点和核心人物。本案例利用 TF-IDF 对《红楼梦》每一回的内容进行关键词提取帮助我们快速了解每一回的核心内容为文学分析提供量化视角。6.2 数据说明数据说明分卷目录每回一个文本文件共120个文件每回内容包含回目名称和正文内容红楼梦词库自定义词典确保人名、地名等专有名词被正确识别停用词表过滤“的”、“了”、“是”等无意义词6.3 完整代码importosimportjiebaimportpandasaspdfromsklearn.feature_extraction.textimportTfidfVectorizer# 读取红楼梦分卷数据filePaths[]# 存储文件路径fileContents[]# 存储文件内容forroot,dirs,filesinos.walk(r.\红楼梦\分卷):fornameinfiles:filePathos.path.join(root,name)filePaths.append(filePath)withopen(filePath,r,encodingutf-8)asf:linesf.read().splitlines()content.join(lines[2:])# 跳过前两行回目信息contentcontent.replace( ,).replace(\t,)fileContents.append(content)corpospd.DataFrame({filePath:filePaths,fileContent:fileContents})print(f共加载{len(corpos)}回内容)# 加载自定义词库与停用词jieba.load_userdict(r.\红楼梦\红楼梦词库.txt)# 加载红楼梦专属词库stopwordspd.read_csv(r.\红楼梦\StopwordsCN.txt,encodingutf-8,enginepython,index_colFalse)# 分词处理corpos[cut_words]withopen(r.\红楼梦\分词后汇总.txt,w,encodingutf-8)asfile_to_jieba:forindex,rowincorpos.iterrows():juan_cifileContentrow[fileContent]segsjieba.cut(fileContent)# jieba分词forseginsegs:ifsegnotinstopwords.stopword.valuesandlen(seg.strip())0:juan_ciseg file_to_jieba.write(juan_ci\n)corpos.loc[index,cut_words]juan_ci.strip()print(分词完成)# 读取分词结果withopen(r.\红楼梦\分词后汇总.txt,r,encodingutf-8)asf:corpusf.readlines()# TFIDF向量化vectorizerTfidfVectorizer()tfidfvectorizer.fit_transform(corpus)# 训练并转换为TFIDF矩阵wordlistvectorizer.get_feature_names_out()# 获取词汇表dfpd.DataFrame(tfidf.T.todense(),indexwordlist)# 转为DataFrameprint(f词汇表大小:{len(wordlist)})print(fTFIDF矩阵形状:{tfidf.shape})# 各回提取Top10关键词print(\n 各回 Top 10 关键词 )foriinrange(len(corpus)):featurelistdf.iloc[:,i].to_list()# 获取第i回所有词的TFIDF值resdict{}forjinrange(len(wordlist)):resdict[wordlist[j]]featurelist[j]# 构建词-权重字典resdictsorted(resdict.items(),keylambdax:x[1],reverseTrue)# 按权重降序排序print(f\n第{i1}回)forword,scoreinresdict[:10]:# 取前10个关键词print(f{word}:{score:.4f})输出示例 共加载 120 回内容 Building prefix dict from the default dictionary ... Loading model from cache C:\Users\Lenovo\AppData\Local\Temp\jieba.cache Loading model cost 0.983 seconds. Prefix dict has been built successfully. 分词完成 词汇表大小: 40260 TFIDF矩阵形状: (120, 40260) 各回 Top 10 关键词 第1回 士隐: 0.4481 雨村: 0.1591 弟子: 0.1399 道人: 0.1270 那僧: 0.1224 英莲: 0.1117 那僧道: 0.1049 一段: 0.0979 封肃: 0.0931 空空道人: 0.0931 ...... 第120回 贾母: 0.2430 宝玉: 0.2287 牛黄: 0.2101 贾政道: 0.1893 薛姨妈: 0.1632 巧姐儿: 0.1625 凤姐: 0.1574 老太太: 0.1331 破题: 0.1313 贾政: 0.12176.4 关键步骤说明步骤说明数据加载遍历分卷目录读取每回内容跳过回目信息行自定义词典加载红楼梦专属词库确保人名、地名被正确分词停用词过滤删除“的”、“了”、“是”等1000个无意义词分词处理使用 jieba 分词结果写入文件并存入 DataFrameTF-IDF 提取将分词后的文本转为 TF-IDF 向量提取每回 Top 10 关键词七、总结核心知识点速查知识点关键概念TF-IDF文本特征提取方法将文本转换为数值向量TF词频词在当前文档中的出现频率IDF逆文档频率惩罚高频通用词奖励稀有区分词TfidfVectorizersklearn 实现 TF-IDF 的工具类max_features限制最大特征数控制维度ngram_range考虑单词组合捕获短语信息核心 API 一览用途对应模块 / 方法模型sklearn.feature_extraction.text.TfidfVectorizer训练并转换fit_transform(X)转换新文档transform(X)特征词列表get_feature_names_out()词汇表vocabulary_注意事项要点说明中文需先分词中文没有空格分隔需使用 jieba 等分词工具停用词过滤必须去除“的”、“是”等无意义词否则干扰结果特征维度控制用max_features或max_df/min_df控制维度训练集/测试集分离fit_transform用于训练集transform用于测试集系列直达上篇机器学习入门DBSCAN 聚类本篇机器学习入门TF-IDF本文下篇敬请期待