TF-IDF算法的代码实践应用——关键词提取、文本分类、信息检索

回顾:TF-IDF算法详解与实践总结

上一篇文章我们深入剖析了TF-IDF的原理与细节,但实践才是检验真理的唯一标准!今天,我们将从“纸上谈兵”转向“实战演练”:通过纯Python手写实现与调用sklearn工具包两种方式,带你一步步完成TF-IDF在真实场景中的应用

  • 关键词提取:如何从一篇长文中精准抓取核心词汇?
  • 文本分类:如何让机器自动识别“AI”、“ML”、“DL”类别的文本?
  • 信息检索:如何根据查询语句,从文档库中找到最相关的内容?

TF-IDF 基类实现

手搓版本

import mathclass TFIDFBase:def __init__(self, corpus):self.corpus = corpusself.tokenized_corpus = [preprocess(doc) for doc in corpus]self.N = len(corpus)  # 文档总数self.df = self._compute_df()self.idf = self._compute_idf()def _compute_df(self):"""计算文档频率 (Document Frequency)"""df = defaultdict(int)for tokens in self.tokenized_corpus:unique_tokens = set(tokens)for token in unique_tokens:df[token] += 1return dfdef _compute_idf(self):"""计算逆文档频率 (IDF)"""idf = defaultdict(float)for token, count in self.df.items():idf[token] = math.log(self.N / (count + 1)) + 1  # 平滑处理return idfdef compute_tf(self, tokens):"""计算词频 (TF)"""tf = defaultdict(int)total = len(tokens)for token in tokens:tf[token] += 1 / total  # 归一化return tfdef compute_tfidf(self, tf):"""计算 TF-IDF 向量"""return {token: tf[token] * self.idf[token] for token in tf}def get_tfidf_vector(self):"""生成整个语料库的 TF-IDF 向量"""tfidf_vectors = []for tokens in self.tokenized_corpus:tf = self.compute_tf(tokens)tfidf = self.compute_tfidf(tf)tfidf_vectors.append(tfidf)return tfidf_vectors

依赖版本

from sklearn.feature_extraction.text import TfidfVectorizervectorizer = TfidfVectorizer(tokenizer=preprocess,  # 指定自定义分词函数token_pattern=r"(?u)\b\w+\b",  # 匹配中文分词结果max_features=1000  # 控制词汇表大小
)

文本预处理

import jieba
import nltk
from nltk.corpus import stopwordstry:nltk.download('stopwords')stopwords_cn = stopwords.words('chinese')print("已下载 NLTK 中文停用词")
except:# 若 nltk 中文停用词缺失,手动补充常用中文停用词stopwords_cn = ['的', '了', '和', '是', '在', '中', '也', '都', '而', '就','那', '这', '之', '为', '对', '与', '于', '上', '下', '前']# 中文文本预处理(分词 + 去停用词)
def preprocess(text):tokens = jieba.cut(text)return [token for token in tokens if token not in stopwords_cn and token.strip()]

TD-IDF 关键词提取

手搓版本

提取关键词

class KeywordExtractor(TFIDFBase):def extract_keywords(self, top_k=5):"""提取每个文档的 top-k 关键词"""tfidf_vectors = self.get_tfidf_vector()results = []for idx, tfidf in enumerate(tfidf_vectors):sorted_keywords = sorted(tfidf.items(), key=lambda x: -x[1])[:top_k]results.append([kw[0] for kw in sorted_keywords])return results

执行

corpus = ["自然语言处理是人工智能领域的一个重要分支","信息检索技术帮助我们从大量文档中找到相关内容","BM25算法是信息检索中常用的经典算法","中文分词是中文自然语言处理的基础步骤","搜索引擎使用各种算法来提高搜索结果的相关性","TF-IDF和BM25都是基于统计的检索模型","深度学习在自然语言处理中取得了显著进展","倒排索引是信息检索系统的核心技术之一","查询扩展可以提高信息检索的召回率","准确率和召回率是评价信息检索系统的重要指标"
]extractor = KeywordExtractor(corpus)
keywords = extractor.extract_keywords(top_k=3)
for i, kws in enumerate(keywords):print(f"Document {i + 1} Keywords: {kws}")

结果

Document 1 Keywords: ['人工智能', '领域', '一个']
Document 2 Keywords: ['技术', '文档', '找到']
Document 3 Keywords: ['算法', '常用', '经典']
Document 4 Keywords: ['中文', '分词', '基础']
Document 5 Keywords: ['搜索引擎', '搜索', '相关性']
Document 6 Keywords: ['TF', '-', 'IDF']
Document 7 Keywords: ['深度', '学习', '进展']
Document 8 Keywords: ['倒排', '索引', '核心技术']
Document 9 Keywords: ['查询', '扩展', '提高']
Document 10 Keywords: ['准确率', '评价', '指标']

依赖版本

执行

# 拟合语料库并生成TF-IDF矩阵
tfidf_matrix = vectorizer.fit_transform(corpus)# 提取关键词(每个文档的Top N关键词)
for i, text in enumerate(corpus):feature_index = tfidf_matrix[i, :].nonzero()[1]  # 非零元素的索引tfidf_scores = zip(feature_index, [tfidf_matrix[i, x] for x in feature_index])  # (词索引, 权重)sorted_tfidf = sorted(tfidf_scores, key=lambda x: x[1], reverse=True)  # 按权重排序top_n = 3  # 提取每个文档的前3个关键词keywords = [vectorizer.get_feature_names_out()[idx] for idx, score in sorted_tfidf[:top_n]]print(f"文档 {i + 1} 的关键词: {keywords}")

结果

文档 1 的关键词: ['人工智能', '领域', '一个']
文档 2 的关键词: ['技术', '文档', '找到']
文档 3 的关键词: ['算法', '常用', '经典']
文档 4 的关键词: ['中文', '分词', '基础']
文档 5 的关键词: ['搜索引擎', '搜索', '相关性']
文档 6 的关键词: ['tf', '-', 'idf']
文档 7 的关键词: ['深度', '学习', '进展']
文档 8 的关键词: ['倒排', '索引', '核心技术']
文档 9 的关键词: ['查询', '扩展', '提高']
文档 10 的关键词: ['准确率', '评价', '指标']

TF-IDF 文本分类

设置的分类语料以及标签

corpus = [# AI类"人工智能正在改变医疗、金融和教育等多个行业","自然语言处理技术使计算机能够理解和生成人类语言","计算机视觉是人工智能领域的重要研究方向之一","智能语音助手通过人工智能实现了语音识别和对话功能","人工智能伦理问题成为学术界和工业界讨论的焦点","自动驾驶技术依赖人工智能实现环境感知和决策","人工智能在游戏开发中用于创建智能NPC和动态剧情","工业机器人通过人工智能优化生产流程和质量检测","人工智能与物联网结合推动了智能家居的发展","人工智能辅助诊断系统能快速分析医学影像并提供建议",# ML类"机器学习算法通过数据训练模型来预测未来趋势","监督学习需要标注数据来训练分类和回归模型","随机森林是一种集成学习方法,常用于分类任务","特征工程是机器学习中提升模型性能的关键步骤","支持向量机(SVM)适用于高维数据的分类问题","交叉验证技术用于评估机器学习模型的泛化能力","梯度下降法是优化机器学习模型参数的常用方法","K近邻算法基于数据点的距离进行分类或回归","贝叶斯分类器利用概率统计实现高效的文本分类","机器学习中的过拟合问题可通过正则化技术缓解",# DL类"深度学习通过多层神经网络模拟人脑的信息处理方式","卷积神经网络(CNN)在图像识别任务中表现出色","循环神经网络(RNN)擅长处理时序数据和自然语言","生成对抗网络(GAN)可用于生成逼真的图像和文本","Transformer模型推动了自然语言处理领域的突破","深度学习需要大量数据和计算资源进行模型训练","注意力机制提升了深度学习模型对关键信息的捕捉能力","迁移学习在深度学习中广泛应用于小样本场景","深度强化学习被用于训练机器人完成复杂任务","神经网络的参数调优对深度学习模型性能至关重要"
]labels = ['AI'] * 10 + ['ML'] * 10 + ['DL'] * 10  # 生成对应标签

手搓版本

class TextClassifier(TFIDFBase):def __init__(self, corpus, labels):super().__init__(corpus)self.labels = labelsself.class_vectors = self._build_class_vectors()def _build_class_vectors(self):"""按类别聚合 TF-IDF 向量(简单平均)"""class_vectors = defaultdict(list)tfidf_vectors = self.get_tfidf_vector()for label, tfidf in zip(self.labels, tfidf_vectors):class_vectors[label].append(tfidf)# 计算类别向量(平均)avg_class_vectors = {}for label, vectors in class_vectors.items():avg_vector = defaultdict(float)count = len(vectors)for vec in vectors:for token, val in vec.items():avg_vector[token] += val / countavg_class_vectors[label] = avg_vectorreturn avg_class_vectorsdef classify(self, text):"""对新文本分类(余弦相似度)"""tokens = preprocess(text)tf = self.compute_tf(tokens)tfidf = self.compute_tfidf(tf)# 计算余弦相似度def cosine_sim(vec1, vec2):common_tokens = set(vec1.keys()) & set(vec2.keys())dot = sum(vec1[t] * vec2[t] for t in common_tokens)norm1 = math.sqrt(sum(v ** 2 for v in vec1.values()))norm2 = math.sqrt(sum(v ** 2 for v in vec2.values()))return dot / (norm1 * norm2 + 1e-8)max_sim = -1predicted_label = Nonefor label, class_vec in self.class_vectors.items():sim = cosine_sim(tfidf, class_vec)if sim > max_sim:max_sim = simpredicted_label = labelreturn predicted_label

执行

new_text = "强化学习是人工智能的前沿领域"classifier = TextClassifier(corpus, labels)
print(f"Classified Label: {classifier.classify(new_text)}")

结果

Classified Label: AI

依赖版本

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report# 使用TF - IDF向量化器
vectorizer = TfidfVectorizer(tokenizer=preprocess,  # 指定自定义分词函数token_pattern=r"(?u)\b\w+\b",  # 匹配中文分词结果(可忽略)max_features=1000  # 控制词汇表大小
)

执行

# 将文本转换为TF-IDF特征向量
X = vectorizer.fit_transform(corpus)
y = np.array(labels)# 划分训练集和测试集(由于样本太少,此处仅演示流程)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 训练分类模型(以逻辑回归为例)
model = LogisticRegression()
model.fit(X_train, y_train)# 预测与评估
# 使用训练好的TF-IDF向量化器转换新文本
X_new = vectorizer.transform([new_text])
y_pred = model.predict(X_new)
print("分类标签:", y_pred)

结果

分类标签: ['AI']

TF-IDF 信息检索

手搓版本

class InformationRetriever(TFIDFBase):def __init__(self, corpus):super().__init__(corpus)self.tfidf_matrix = self._build_tfidf_matrix()def _build_tfidf_matrix(self):"""构建 TF-IDF 矩阵(文档向量化)"""tfidf_vectors = self.get_tfidf_vector()# 构建全局词表self.vocab = {token: idx for idx, token in enumerate(set(token for vec in tfidf_vectors for token in vec))}# 转换为 NumPy 矩阵matrix = np.zeros((self.N, len(self.vocab)))for i, vec in enumerate(tfidf_vectors):for token, val in vec.items():matrix[i, self.vocab[token]] = valreturn matrixdef search(self, query, top_k=2):"""根据查询语句检索最相关文档"""# 预处理查询tokens = preprocess(query)tf = self.compute_tf(tokens)tfidf = self.compute_tfidf(tf)# 构建查询向量query_vec = np.zeros(len(self.vocab))for token, val in tfidf.items():if token in self.vocab:query_vec[self.vocab[token]] = val# 计算余弦相似度sims = []for i in range(self.N):doc_vec = self.tfidf_matrix[i]sim = np.dot(query_vec, doc_vec) / (np.linalg.norm(query_vec) * np.linalg.norm(doc_vec) + 1e-8)sims.append((i, sim))# 返回 top-k 相关文档return [self.corpus[i] for i, _ in sorted(sims, key=lambda x: -x[1])[:top_k]]

执行

corpus = ["自然语言处理是人工智能的一个重要分支","机器学习方法在自然语言处理中起着关键作用","深度学习技术推动了自然语言处理的发展","计算机视觉是人工智能领域的重要研究方向之一","强化学习是人工智能的前沿领域"
]
# "信息检索"
query = "人工智能和机器学习的关系"
retriever = InformationRetriever(corpus)
results = retriever.search(query, top_k=3)
for idx, r in enumerate(results):print(f"Matched Document {idx}: {r}")

结果

Matched Document 0: 机器学习方法在自然语言处理中起着关键作用
Matched Document 1: 强化学习是人工智能的前沿领域
Matched Document 2: 自然语言处理是人工智能的一个重要分支

依赖版本

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity# 使用TF-IDF向量化器
vectorizer = TfidfVectorizer(tokenizer=preprocess,  # 自定义分词函数token_pattern=r"(?u)\b\w+\b",  # 对中文无效,但不影响max_features=1000  # 控制词汇表大小
)

执行

# 将语料库转换为TF-IDF特征向量
X_corpus = vectorizer.fit_transform(corpus)# 示例查询
query = "人工智能和机器学习的关系"# 预处理并转换查询
X_query = vectorizer.transform([query])  # 注意:必须用列表包裹# 计算余弦相似度
similarities = cosine_similarity(X_query, X_corpus)# 输出最相关的文档
top_n = 3  # 返回前3个最相关文档
top_indices = np.argsort(similarities[0])[::-1][:top_n]  # 降序排序取索引print("查询:", query)
print("最相关的文档:")
for idx in top_indices:print(f"文档 {idx + 1}: {corpus[idx]} (相似度: {similarities[0][idx]:.4f})")

结果

查询: 人工智能和机器学习的关系
最相关的文档:
文档 2: 机器学习方法在自然语言处理中起着关键作用 (相似度: 0.4752)
文档 5: 强化学习是人工智能的前沿领域 (相似度: 0.3458)
文档 1: 自然语言处理是人工智能的一个重要分支 (相似度: 0.1913)

结语

通过本文的实践,我们不仅验证了TF-IDF算法的实用性,更展示了它在关键词提取、文本分类和信息检索中的多样化应用场景。

当然,TF-IDF并非万能钥匙:它无法捕捉词序、上下文语义,对动态语境和复杂任务的支持有限。但正如我们所见,它依然是许多现代算法(如BM25、深度学习模型)的重要基础。

关于我

在这里插入图片描述

TFIDF #关键词抽取 #文本分类 #信息检索 # 文本匹配

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/84503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端面试宝典---事件循环面试题

浏览器进程模型与 JavaScript 执行机制 现代浏览器采用多进程架构,包含浏览器进程、渲染进程、网络进程等多个核心进程。每个标签页会独立创建一个渲染进程,负责页面内容的解析、渲染和执行脚本代码。 JavaScript 的单线程特性 JavaScript 采用单线程…

postman调用接口报错401, Unauthorized, Invalid Token. null解决办法

1、先登录系统,F12找到token并复制 2、postman里选中Authorization,下拉选中选择Bearer Token,把复制好的token黏贴到右侧输入框,如下所示: 3、如果是json格式的参数拷贝到Body中,如下所示: 4、 接口调用成功

C++----剖析list

前面学习了vector和string,接下来剖析stl中的list,在数据库中学习过,list逻辑上是连续的,但是存储中是分散的,这是与vector这种数组类型不同的地方。所以list中的元素设置为一个结构体,将list设计成双向的&…

为什么已经有 Nginx 了,还需要服务网关?

在当前微服务架构中,虽然 Nginx 是一个高性能的反向代理和负载均衡服务器,但在实际使用中仍然存在诸多局限性。为了满足运维效率、功能统一治理以及与微服务生态集成的需求,通常会在 Nginx 和业务服务之间引入一层基于 Java 实现的服务网关&a…

Kendo UI 中,ViewModel、DataSource 和 Grid的关系。Kendo 框架发起 HTTP 请求

Kendo UI 中,ViewModel、DataSource 和 Grid的关系 在 Kendo UI 中,ViewModel、DataSource 和 Grid 是构建动态数据应用的核心组件,三者协同工作实现数据的绑定、管理和展示。 一、三者关系图解 #mermaid-svg-3lWxu2zWB23wDYEz {font-family…

宇树开源 Qmini 双足机器人,可通过 3D 打印动手制作,使用树莓派作为主控制器

Unitree Qmini 是一款由宇树科技设计并开源的低成本双足机器人,开发者可以完全通过 3D 打印进行复刻。Qmini 专为业余爱好者、教育工作者和研究人员设计,使用户能够快速上手,并以类似乐高的模块化方式组装自己的机器人。该项目为机器人技术提…

解决华为云服务器无法ping通github问题

在push代码到github上的时候,发现显示22端口无法连接,在已经开放了端口,防火墙关闭的情况下仍然无法连接到GitHub。 发现是服务器和github断连,选择 sudo vim /etc/hosts 添加一下代码 # GitHub Start140.82.121.4 gith…

关于electron-vite koffi 读取 dll 打包等问题得记录

koffi const koffi require(‘koffi’) import iconv from ‘iconv-lite’;const libPath path.resolve(__dirname, ‘…/…/resources/dll/sss.dll’) const yktLib koffi.load(libPath) const ret yktLib.func(‘string sss(string Url, string Data, string OutData)’…

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…

通过关键字批量抓取淘宝商品数据实现方法途径分享--API

item_search 按关键字搜索淘宝商品item_search_tmall 按关键字搜索天猫商品item_search_pro 高级关键字搜索淘宝商品item_search_img 按图搜索淘宝商品(拍立淘)item_search_shop 获得店铺的所有商品 一、引言 在电商领域,获取淘宝商品数据对…

用 Lazarus IDE 写一个邮件客户端软件,能收发邮件,编写邮件

下面是一个使用Lazarus IDE开发的基本邮件客户端实现方案,包含收发邮件和编写邮件的核心功能。我们将使用Synapse库(跨平台的网络通信库)来处理邮件协议。 步骤1:安装依赖 安装Synapse库: 下载地址:https:…

第二部分-IP及子网划分

目录 一、什么是IP? 1.1.IP地址的由来 1.2.IP地址的表示 1.3.IP地址的构成 1.4.IP地址的分类 1.5.IP地址类型 1.6.IP地址的计算 1.7.私网IP地址 1.8.特殊IP地址 二、子网划分 2.1.什么是子网划分及为什么要进行子网划分? 2.2.如何进行子网划分? 实例: …

【javascript】泡泡龙游戏中反弹和查找匹配算法

引言 泡泡龙游戏的核心玩法依赖于物理碰撞与颜色匹配的算法实现。反弹效果需要模拟泡泡与边界或障碍物的弹性碰撞,确保轨迹符合物理规律;匹配算法则需快速检测相邻同色泡泡,触发消除逻辑。高效的处理方式直接影响游戏流畅度和玩家体验。 以…

如何使用deepseek满血版

deepseek 访问方式 DeepSeek满血版可通过官方网站或官方应用商店下载安装。确保设备满足最低系统要求,如操作系统版本和硬件配置。 账号注册与登录 访问平台后完成账号注册流程,提供必要信息并验证邮箱或手机号。登录后进入用户中心,查看…

网络管理【Linux/Unix/Windows】命令大全

在跨平台网络运维中,管理员常需快速切换Windows与Linux环境下的命令操作。本文整合了核心网络管理命令的跨平台对照表,涵盖连通性测试、路由追踪、DNS解析、ARP管理、会话监控等高频场景。无论您负责服务器维护、网络排障还是安全审计,此表可…

Gremlin创建schema(包括实体和关系)

1、构建图谱schema,流程包括图创建、实体构建以及关系构建。 创建图时需要指定图库名称以及主键字段。 实体构建时需要指定主键字段,每个属性需要指定数据类型,是否非空以及默认值。关系构建时需要包括关系名称、指向头实体的标签&#xff0c…

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…

鸿蒙Next仓颉语言开发实战教程:店铺详情页

各位好,幽蓝君又来分享仓颉开发教程了,今天的内容是店铺详情页: 这个页面的内容看似简单,其实有很多小细节需要注意,主要还是让大家熟悉List容器的使用。 整个页面由导航栏和List容器两大部分组成,导航栏我…

FEMFAT许可使用数据分析工具介绍

在高度竞争和快速变化的工程仿真领域,数据驱动的决策变得越来越重要。为了更好地了解FEMFAT许可的使用情况、提高资源利用率、优化工作流程,FEMFAT许可使用数据分析工具应运而生。本文将为您介绍这款强大的工具,助您轻松驾驭FEMFAT许可数据&a…

大模型原理面试题及参考答案

目录 什么是大语言模型(LLM)?它与传统语言模型的本质差异在哪里? 自回归模型(autoregressive)与掩码语言模型(masked LM)的异同是什么?各适合于哪些任务? Transformer 的核心构件——多头自注意力机制如何捕捉长距离依赖? 位置编码(positional encoding)的作用…