
如果你的 NLP 项目还停留在“打开一个 Python 文件从头写到尾”的阶段那这篇内容应该能帮你把实验环境规范起来。这篇文章是系列 P2目标是搭好一套能直接用于 NLP 与关键词提取的 Jupyter Notebook Python 虚拟环境并用 jieba、TF-IDF、TextRank 跑通完整流程。核心解决四个问题依赖隔离怎么做、Jupyter Notebook 怎么装、虚拟环境怎么注册成 Notebook 内核、中文关键词提取怎么在不同算法之间做对比。先给结论这套方案不需要 GPU不需要高内存服务器一台普通办公电脑就能跑。Windows、macOS、Linux 都支持核心工具就是 Python 自带的 venv Jupyter Notebook jieba scikit-learn。关键词提取任务数据量不大时CPU 推理完全够用。如果你已经在做文本分类、新闻处理、舆情分析这类场景直接按本文步骤复现即可。本文会带你把环境全部跑通再给出可复制的分词、TF-IDF、TextRank 示例代码最后用一个批量关键词提取案例演示如何把方法封装成函数方便后续接到 API 服务或自动化脚本里。全程没有复杂算法推导每个命令都能直接执行。1. 核心能力速览能力项说明项目类型Python 开发环境搭建 NLP 关键词提取实战核心工具Jupyter Notebook、Python venv、jieba、scikit-learn主要功能虚拟环境隔离、Jupyter 内核管理、中文分词、TF-IDF 关键词提取、TextRank 关键词提取硬件需求无 GPU 要求普通 CPU 4GB 内存即可支持平台Windows、macOS、LinuxPython 版本建议 Python 3.8 及以上启动方式命令行启动 Jupyter Notebook浏览器访问是否支持 API示例函数可封装为接口本文不复现 FastAPI 服务是否支持批量任务支持提供批量文本目录处理示例适合场景NLP 实验、文本预处理、关键词提取、数据分析、教学演示从表格能看出来这套方案是典型的数据分析型工作流核心收益是环境不互相污染算法对比方便实验结果可复现。下面从环境准备开始一步一步来。2. 适用场景与使用边界这套方案适合三类人。第一类是刚入门 NLP 的开发者需要一个干净的实验环境来跑分词和关键词提取不想因为反复安装包把系统 Python 搞乱。第二类是做新闻处理、舆情分析、文本挖掘的数据分析人员需要批量提取一批文本的核心词并对比不同算法的效果。第三类是教学场景Jupyter Notebook 天然适合边写说明边跑代码把分词结果、权重分数可视化地展示给学生。它不适合什么场景呢如果是几十 GB 级别的语料训练或者需要分布式计算那就不是 Jupyter Notebook 关键词提取能覆盖的范围了。关键词提取本身是文本预处理的上游环节不是完整的 NLP 生产系统。你可以在 Notebook 里完成算法验证但生产环境的定时任务、接口高并发、模型持久化还是需要单独写服务。还有一个边界必须强调如果你处理的文本来自新闻稿件、社交平台、用户评论请注意数据合规。拿用户数据做关键词提取前要确认你拥有合法处理权限。包含个人信息、未公开内容、受版权保护的文本都要先脱敏或获得授权不要直接把敏感语料放到 Notebook 里长期保存。3. 环境准备与前置条件开始之前建议先检查本机环境。这里给出一份通用检查清单具体版本以你本机实际情况为准。3.1 确认 Python 版本打开终端执行python --versionWindows 系统下如果提示python不是内部或外部命令可以尝试py --version只要 Python 版本在 3.8 以上后续基本不会遇到兼容性问题。如果你还没有安装 Python请先到 Python 官网下载安装包安装时勾选“Add Python to PATH”。这一步很重要否则后面执行python -m venv会找不到解释器。3.2 选择虚拟环境工具Python 虚拟环境工具有很多常见的是venv、virtualenv、conda。本文以 Python 自带的venv为主因为不需要额外安装创建和激活都简单适合大多数 NLP 项目。如果你已经在用 Anaconda也可以用 conda 创建环境思路一样先建独立环境再装 Jupyter再把环境注册为内核。两种方式选一种即可不要混用否则会出现“在 conda 环境里激活了 venv包装到了奇怪位置”的混乱。3.3 磁盘空间与端口Jupyter Notebook 本体加 jieba、scikit-learn 等依赖大概需要 1GB 左右空间语料和输出另算。Jupyter 默认使用 8888 端口如果你本机 8888 已经被其他服务占用后面启动时要用--port参数换端口。4. 安装部署与虚拟环境配置4.1 创建项目目录与虚拟环境先建一个项目目录目录名建议与项目语义一致例如nlp-keyword-extraction。mkdir nlp-keyword-extraction cd nlp-keyword-extraction创建虚拟环境环境名用venv这是 Python 社区约定俗成的名字后面写.gitignore也方便。python -m venv venvWindows 系统激活虚拟环境venv\Scripts\activatemacOS 或 Linux 系统激活虚拟环境source venv/bin/activate激活成功后终端提示符前面会出现(venv)说明当前已经进入独立环境。后面安装的所有 Python 包都只会装到这个环境里不会影响系统全局 Python。4.2 安装 Jupyter Notebook 与 NLP 依赖激活虚拟环境后执行安装命令pip install --upgrade pip pip install jupyter pip install jieba scikit-learn pandas numpy matplotlib如果国内网络下载较慢可以使用镜像源pip install jieba scikit-learn pandas numpy matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后可以验证一下关键包是否正常导入python -c import jieba, sklearn, jupyter; print(ok)这一步通过说明依赖安装成功。4.3 将虚拟环境注册为 Jupyter 内核这里是最容易踩坑的地方。很多人在虚拟环境里装了 Jupyter启动后发现 Notebook 里的 Python 内核还是系统的全局环境import jieba直接报 ModuleNotFoundError。原因就是没有把当前虚拟环境注册成 Jupyter 内核。安装 ipykernel并把环境注册为内核pip install ipykernel python -m ipykernel install --user --namevenv --display-namePython (NLP)参数说明--namevenv内核内部名称随便起但建议与虚拟环境名一致。--display-namePython (NLP)Jupyter 页面上显示的名字方便识别。--user注册到当前用户目录不需要管理员权限。注册完成后启动 Jupyter Notebookjupyter notebook浏览器会自动打开http://localhost:8888/tree。新建 Notebook 时在右上角 Kernel 下拉框里选择Python (NLP)这样 Notebook 用的才是当前虚拟环境。4.4 验证内核是否生效新建一个 Notebook输入以下代码并运行import sys import jieba print(sys.executable) print(jieba.__version__)如果sys.executable输出的是你项目目录下venv里的python.exe或python说明内核绑定正确。如果输出的路径是系统全局 Python说明内核没有切换成功回到 4.3 节重新注册。5. NLP 文本预处理与关键词提取功能测试环境跑通后进入正题用 jieba、TF-IDF、TextRank 提取中文关键词。这里我会用一个新闻类文本作为测试语料。5.1 准备测试语料在 Notebook 里创建一段测试文本news_text 人工智能技术正在深刻改变内容生产行业。从新闻采集、稿件撰写到信息分发大语言模型都能提供辅助。 然而在垂直领域的专业报道中模型生成内容的准确性和事实核查仍然是关键挑战。 关键词提取是文本信息处理的重要环节它能够从非结构化文本中自动识别出最能代表文档主题的词语 广泛应用于检索系统、推荐系统、舆情监测和文本分类等场景。 这段文本不算长但包含“人工智能”“关键词提取”“大语言模型”等典型词汇足够验证分词和关键词提取效果。5.2 jieba 分词与词性过滤jieba 默认是全模式分词但关键词提取一般用精确模式。import jieba seg_list jieba.cut(news_text, cut_allFalse) print( / .join(seg_list))预期输出是一串切分后的词序列。可以看到“人工智能”“关键词提取”“大语言模型”等词被正确切分。jieba 内置的词典对通用领域覆盖不错但如果你处理的是法律、医疗、金融等垂直领域需要加载自定义词典。词性过滤可以让结果更干净。例如只保留名词、动词、形容词import jieba.posseg as pseg for word, flag in pseg.cut(news_text): if flag.startswith((n, v, a)): print(f{word}: {flag})这一步的作用是过滤掉标点、助词、介词等对关键词提取没有帮助的成分。在关键词提取前做词性过滤可以减少噪音。5.3 TF-IDF 关键词提取jieba 自带 TF-IDF 关键词提取接口底层基于 TF-IDF 算法使用默认 IDF 语料库。import jieba.analyse keywords jieba.analyse.extract_tags( news_text, topK10, withWeightTrue ) for word, weight in keywords: print(f{word}: {weight})参数说明topK10返回权重最高的 10 个词。withWeightTrue同时返回每个词的 TF-IDF 权重值。注意jieba 的 TF-IDF 实现使用的是自带 IDF 语料这套默认词频来自多个领域的通用文本。如果你处理的文本领域很垂直比如全是你公司的产品评论最好基于自己的语料重新计算 IDF否则结果可能偏向通用词。针对垂直语料可以调用jieba.analyse.set_idf_path()加载自定义 IDF 文件。文件格式是“词语 频率”一行一个需要自己提前统计好。5.4 TextRank 关键词提取TextRank 与 TF-IDF 的思路不同。TF-IDF 看的是词在文档中的统计重要性TextRank 通过词之间的共现关系构建图网络然后迭代算出每个词的权重。jieba 也提供了现成接口keywords_tr jieba.analyse.textrank( news_text, topK10, withWeightTrue ) for word, weight in keywords_tr: print(f{word}: {weight})对比 TF-IDF 结果你会发现TextRank 提取出的候选词更倾向于在文本中反复共现的实词比如“关键词”“文本”“模型”。这不是谁好谁坏的问题而是两种算法的侧重点不同。实际项目中比较稳妥的做法是两种算法各跑一遍再取交集或加权融合最后人工复核。5.5 基于 scikit-learn 的 TF-IDF 对比jieba 的 TF-IDF 输出的是单个文本的词语权重。如果有一批文本想统一做向量化用 scikit-learn 的TfidfVectorizer更合适。from sklearn.feature_extraction.text import TfidfVectorizer corpus [ 人工智能技术正在改变内容生产行业, 关键词提取是文本信息处理的重要环节, 大语言模型在垂直领域报道中面临事实核查挑战, ] vectorizer TfidfVectorizer(tokenizerjieba.cut, token_patternNone) tfidf_matrix vectorizer.fit_transform(corpus) feature_names vectorizer.get_feature_names_out() for i in range(len(corpus)): row tfidf_matrix.getrow(i).toarray()[0] word_weight sorted( zip(feature_names, row), keylambda x: x[1], reverseTrue )[:5] print(f第{i1}篇文本的关键词{word_weight})这里传入tokenizerjieba.cut让 sklearn 使用 jieba 做分词然后计算整个语料库的 TF-IDF 向量。与 jieba 自带 TF-IDF 相比sklearn 版本的优势是IDF 基于当前语料统计多文档对比时更公平。不过要注意TfidfVectorizer的默认token_pattern是英文单词匹配必须设置token_patternNone否则中文文本会被错误切分成单个字符。这是新手最常遇到的问题。5.6 自定义停用词与词表每个 NLP 项目都应该维护一份自己的停用词表。jieba 默认不会自动过滤“关于”“基于”“对于”这类常见功能词虽然它们权重往往不高但会干扰阅读。准备一个stopwords.txt文件每行一个停用词的 了 是 在 关于 一个 我们然后在代码里加载stopwords set() with open(stopwords.txt, encodingutf-8) as f: for line in f: word line.strip() if word: stopwords.add(word) keywords jieba.analyse.extract_tags( news_text, topK10, withWeightTrue ) filtered [(word, weight) for word, weight in keywords if word not in stopwords] print(filtered)这个过滤逻辑对 TF-IDF 和 TextRank 都适用。如果你使用 scikit-learn 版本可以直接把停用词传给TfidfVectorizer(stop_wordsstopwords)。6. 接口 API 与批量任务调用示例Jupyter Notebook 适合做实验但关键词提取真正落地通常要支持“给一段文本返回关键词列表”的批量处理能力。这一节把方法封装成函数并提供批量处理示例。6.1 封装关键词提取函数创建一个keyword_extractor.py文件或者直接在 Notebook 里定义函数import jieba import jieba.analyse from sklearn.feature_extraction.text import TfidfVectorizer class KeywordExtractor: 统一封装的关键词提取器支持 tfidf 和 textrank 两种算法 def __init__(self, topk10, stopwords_fileNone): self.topk topk self.stopwords set() if stopwords_file: with open(stopwords_file, encodingutf-8) as f: for line in f: word line.strip() if word: self.stopwords.add(word) def _filter_stopwords(self, pairs): return [(word, weight) for word, weight in pairs if word not in self.stopwords] def extract(self, text, methodtfidf): if method tfidf: pairs jieba.analyse.extract_tags(text, topKself.topk, withWeightTrue) elif method textrank: pairs jieba.analyse.textrank(text, topKself.topk, withWeightTrue) else: raise ValueError(method 只支持 tfidf 或 textrank) return self._filter_stopwords(pairs)调用示例extractor KeywordExtractor(topk10, stopwords_filestopwords.txt) result extractor.extract(news_text, methodtfidf) print(result)封装的好处是后续接 FastAPI、Flask、命令行脚本时不需要重复写提取逻辑只需要调用extractor.extract()。6.2 批量处理目录下的文本文件批量场景常见做法是把待处理文本放到input/目录脚本遍历目录逐文件提取关键词结果写入 CSV。import os import csv input_dir input output_file keyword_result.csv extractor KeywordExtractor(topk10, stopwords_filestopwords.txt) results [] for filename in os.listdir(input_dir): if not filename.endswith(.txt): continue filepath os.path.join(input_dir, filename) with open(filepath, encodingutf-8) as f: text f.read() keywords extractor.extract(text, methodtfidf) keyword_str 、.join([word for word, _ in keywords]) results.append([filename, keyword_str]) print(f{filename} 处理完成关键词{keyword_str}) with open(output_file, w, encodingutf-8-sig, newline) as f: writer csv.writer(f) writer.writerow([文件名, 关键词]) writer.writerows(results)这里使用encodingutf-8-sig是因为 Excel 直接打开 UTF-8 编码的 CSV 时会出现中文乱码utf-8-sig会带上 BOM 头兼容性更好。批量任务的注意点是异常捕获。单个文件编码异常或内容为空会导致整个脚本中断建议在循环里加 try/except 并记录失败文件列表。for filename in os.listdir(input_dir): try: # 处理逻辑 pass except Exception as e: print(f{filename} 处理失败{e})6.3 导出结果为 JSON除了 CSV关键词结果也经常要输出为 JSON方便其他系统读取。import json output [] for item in results: output.append({ file: item[0], keywords: item[1].split(、) }) with open(keyword_result.json, w, encodingutf-8) as f: json.dump(output, f, ensure_asciiFalse, indent2)这样后续系统可以直接拿到结构化数据不用再解析 CSV。6.4 后续接入服务的思路如果你要把关键词提取能力给公司内部系统用可以考虑用 FastAPI 包一层 HTTP 接口。# 伪代码示例需要先安装 fastapi 和 uvicorn from fastapi import FastAPI from pydantic import BaseModel app FastAPI() extractor KeywordExtractor() class Item(BaseModel): text: str method: str tfidf topk: int 10 app.post(/extract) def extract(item: Item): return {keywords: extractor.extract(item.text, methoditem.method, topkitem.topk)}注意上面是伪代码extractor.extract()没有topk参数实际需要调整类方法定义。这里只是想说明接口封装方向。如果你要真正部署还要加请求频率限制、文本长度限制、鉴权等。7. 资源占用与性能观察Jupyter Notebook 关键词提取的资源占用主要看语料规模。文本量不大时CPU 和内存都很轻松。但如果批量处理上百个文件每个文件几千字就需要关注几个性能指标。7.1 如何观察资源占用Windows 下打开任务管理器macOS 下打开活动监视器Linux 下使用top或htop。重点看两个进程python.exeJupyter 内核进程实际跑分词和关键词提取逻辑的进程。浏览器页面Notebook 前端只是展示层资源占用集中在内核侧。如果你使用 Jupyter Notebook 的新版本注意它默认会在用户目录下启动一个jupyter-server进程这个进程是后端服务内存占用一般在 100MB 到 300MB 之间属于正常范围。7.2 CPU 推理与耗时观察jieba 分词是 CPU 密集型操作。对于一篇几千字的新闻文本TF-IDF 关键词提取的耗时通常在几百毫秒到几秒之间。如果发现单篇文本处理时间超过 10 秒重点检查两个原因一是文本长度是不是很大二是是否加载了超大的自定义词典。scikit-learn 的TfidfVectorizer在多文本场景下计算时间会随文档数量线性增长。批量处理时建议先观察一篇文本的处理耗时再估算总耗时避免中途卡死。7.3 文本长度、topK 与性能关系关键词提取性能受三个参数影响文本长度分词耗时随文本长度增长。topK返回关键词数量只影响排序和输出对计算耗时影响很小。停用词表大小停用词过滤是集合查找操作O(1) 复杂度影响可忽略。长文本场景下可以考虑先做段落分割每个段落独立提取关键词再合并结果。7.4 降低资源占用的建议如果内存吃紧可以用 generator 方式逐篇处理不要一次性把所有文本读入列表。上面批量处理示例里是一个文件一个文件读取的已经比较省内存。如果数据量很大建议参考这个思路不要用readlines()一次性加载所有文件。8. 常见问题与排查方法问题现象可能原因排查方式解决方案执行jupyter notebook提示命令不存在虚拟环境未激活或 Jupyter 未安装检查终端是否有(venv)前缀执行pip list查看 jupyter 是否存在激活虚拟环境后重新安装 jupyterNotebook 里import jieba报 ModuleNotFoundError内核未切换到虚拟环境或 jieba 装在别的环境里打印sys.executable看路径重新注册 ipykernel并在 Notebook 里选择正确内核Windows 激活虚拟环境失败执行策略限制在 PowerShell 中执行Get-ExecutionPolicy查看策略使用Set-ExecutionPolicy Unrestricted -Scope CurrentUser或用 cmd 执行venv\Scripts\activate.batJupyter 页面打不开 8888 端口端口被占用或防火墙拦截执行netstat -ano查看端口占用使用jupyter notebook --port8889换端口中文关键词提取结果全是单字TfidfVectorizer的token_pattern未设置查看特征词列表设置token_patternNone并传入tokenizerjieba.cut关键词结果里都是连接词、助词没有加载停用词表检查输出结果中是否包含“的”“了”“是”维护自己的停用词表并在提取后过滤批量处理时脚本中途中断某个文件编码或内容异常打印正在处理的文件名用 try/except 包裹处理逻辑记录失败文件内核连接失败Notebook 卡在 Connectingkernel 与服务版本不匹配查看终端内核日志重启 kernel重装 ipykernel自定义 IDF 文件不生效路径错误或文件格式不对检查路径和文件内容确认每行是“词语 空格 频率”格式9. 最佳实践与使用建议9.1 每个项目一个虚拟环境NLP 项目依赖变化快有的项目要 jieba 0.42有的项目要 scikit-learn 最新版。共用一个全局环境迟早出问题。建议一个项目建一个虚拟环境环境名用venv这样团队协作时大家路径一致。9.2 维护 requirements.txt环境配置好后立刻导出依赖列表pip freeze requirements.txt下次换机器或给别人复现时一条命令装完所有依赖pip install -r requirements.txt这比口述“你装一下 jieba、sklearn、pandas”可靠得多。9.3 目录结构推荐建议用以下结构管理项目nlp-keyword-extraction/ ├── venv/ ├── data/ │ ├── raw/ │ └── processed/ ├── input/ ├── output/ ├── stopwords.txt ├── requirements.txt └── notebooks/原始语料放data/raw处理后的结构化数据放data/processedNotebook 统一放notebooks关键词提取结果放output。这样项目越大越不会乱。9.4 Jupyter Notebook 保存格式与 Git 协作Notebook 文件是 JSON 格式直接用 Git 管理会出现大量 diff因为输出结果和内核信息都包含在文件里。建议使用 Jupyter 的nbdime工具处理 Notebook 的 Git 冲突。另外把.ipynb_checkpoints目录加入.gitignore。9.5 数据合规与隐私保护关键词提取经常处理用户评论、新闻内容、内部文档。上生产环境前确认以下几点数据来源是否合规。是否包含个人可识别信息。文本是否涉及未公开的敏感内容。处理后结果是否需要脱敏存储。Notebook 中如果出现密码、Token、密钥要立即清除使用环境变量或.env文件管理敏感配置。9.6 结果复核机制TF-IDF 和 TextRank 都是无监督方法提取结果不一定完美。建议加人工抽检环节每批结果抽 5% 到 10% 复核关键词质量。如果发现大量结果跑偏优先检查分词词典和停用词表。10. 总结与下一步这套环境最值得尝试的点在于venv 解决了依赖隔离问题Jupyter Notebook 提供了交互式验证体验jieba、TF-IDF、TextRank 覆盖了主流中文关键词提取方法。三个工具组合起来适用于大多数文本处理实验场景。建议第一次跑通时按这个顺序验证先确认虚拟环境激活再确认 Jupyter 内核选择正确然后跑一遍 5.3 小节的 TF-IDF 示例最后跑 6.2 小节的批量处理脚本。三个环节全通这套环境就算真正可用了。最容易踩的坑只有一个虚拟环境建好了但 Notebook 内核没有切换导致 import 报错。遇到 ModuleNotFoundError先打印sys.executable不要急着重装包。后续可以继续扩展几个方向接入 FastAPI 做关键词提取服务基于 TF-IDF 向量做文本相似度计算或者用 sklearn 把关键词特征喂给分类模型做舆情分析。如果你想继续看这部分内容可以在评论区留言我把对应的环境配置和代码整理出来。建议先把本篇的环境搭好收藏备用。