资讯详情 Python中文自然语言处理入门:分词与情感分析实战
📅 2026/10/26 19:24:42
简介这份《Python中文自然语言处理基础与实战》配套资料面向希望系统入门并动手实践中文NLP的学生、开发者与算法爱好者内容覆盖分词、词性标注、命名实体识别、情感分析、主题建模及深度学习序列任务。压缩包共42个文件、约53.58MB含28个txt语料与词典文本、5个json结构化数据、3个csv评论数据以及ipynb实战笔记本、pkl模型和少量jpg示意图便于直接读取复现。材料中既有停用词、否定词、程度副词和情感词典也收录金庸小说、人民日报语料及新闻分类、垃圾短信识别等样本可支撑中文分词、情感判断、文本分类、HMM训练与聊天机器人练习。已有11492人学习适合借助notebook串联语料清洗、特征构建、模型训练与结果分析在真实文本中理解算法流程并积累可复用实验素材。1. 从一句「这句评论是夸我还是骂我」说起中文自然语言处理到底在做什么你大概在购物评价区见过这种场面同一句话有人读成真心夸有人读成阴阳怪气。人判断起来都费劲让程序去判断听着更像玄学。python 中文自然语言处理要做的事说到底就是教计算机读懂中文——把一段文字切开、读懂情绪、拎出重点最后变成一个能判断、能排序、能报警的结果。它适合谁适合会一点点 Python手上有一堆评论、工单、聊天记录、问卷答案却不知道从哪儿下手的人。学它不需要先把数学啃完第一步比想象中轻得多后面几章就从这里开始。2. 为什么值得学先看清它能解决什么问题刚接触这个方向的人最常见的误区是先去找一本厚书从数学公式第一页开始看看到第三章就放弃了。换个顺序会轻松很多先知道自己想让程序替你干什么活再去补对应的那一点知识缺什么补什么。这一章就干这件事把「中文处理难在哪」「学完能干什么」「入门要准备什么」三件事说清楚后面的代码才有地方落。2.1 中文和英文不一样分词这一步就绕不开英文句子天然带空格I love natural language processing一切就得到四个词程序不用动脑子。中文不一样我爱自然语言处理这一串字是连着的计算机看到的只是一排字符它不知道「自然」和「语言」该合在一起还是分开。所以做中文处理第一道工序永远是分词——把连续的汉字切成一个个有意义的单位。分词听起来简单真正做起来有一堆麻烦。第一是歧义比如「乒乓球拍卖完了」这句话可以切成「乒乓球 / 拍卖 / 完 / 了」也可以切成「乒乓球拍 / 卖 / 完 / 了」两种切法人读起来都通但意思完全不同程序得靠上下文 statistics 去猜。第二是未登录词新出现的网络词、人名、产品型号词典里根本没有规则切不出来。第三是颗粒度你到底要「自然语言处理」整块当一个词还是拆成「自然」「语言」「处理」取决于你后面要做什么任务。我第一次学的时候以为分词是个已经被解决的小问题随手调个库就完事。后来发现很多下游任务效果差追根溯源居然是分词把关键短语切碎了比如「不满意」被切成「不 / 满意」情绪直接反了。这种血泪经验说明一件事中文 NLP 的很多坑埋在最前面这一步。入门阶段不用急着优化分词但一定要知道它的存在知道后面所有环节都架在它上面。理解这一点你就明白为什么中文自然语言处理的入门路径和英文资料对不上。看英文教程直接跳到模型跟着做中文语料会发现处处别扭。正确的顺序是先接受「中文要多一道预处理」再往下走。2.2 这门技术能落到哪些地方从后端服务到人工智能应用很多人以为自然语言处理离自己很远其实它藏在你每天用的功能后面。做后端开发的同学最容易碰到这类需求运营跑来说「能不能把用户反馈自动分成投诉、咨询、建议三类」或者「能不能每天把提到某个功能的评论捞出来」。这类活儿用传统关键词匹配能凑合但词一多规则就爆炸最后还是得上文本分类。学一点 NLP你就能把这种需求从「做不了」变成「一周能出个能用的版本」。再往上一层是人工智能应用。智能客服要理解用户到底问的是退款还是物流搜索要判断两个句子是不是一个意思内容平台要给文章打标签、做推荐这些都建立在文本表示和相似度计算上。深度学习在这类任务上确实更强尤其是数据量大的时候模型能自动学到「退款」和「退货」是一回事不用你手写同义词表。但要注意深度学习不是入场券它是加速器。零基础直接冲模型很容易变成只会调参、出了问题完全不知道从哪查的黑匣子状态。还有一种容易被忽略的用法给自己省时间。比如把几百页的会议记录做成关键词索引把一堆问卷的开放题答案自动聚类把合同里所有涉及金额的句子抽出来。这些场景不需要多高的准确率能省掉一半人工就值了。入门阶段做这种小工具正反馈来得快比一上来追求论文级效果靠谱得多。把场景想清楚还有一个好处你会知道自己该学多深。做评论情感监控词典法加规则可能就够用做智能问答绕不开词向量和模型。目标不同路线完全不同这也是后面几章反复强调「先跑通再深入」的原因。2.3 零基础要补哪些前置知识Python 基础够用就行先说结论会写 Python 的变量、列表、字典、循环、函数就能开始学。这几样东西是后面所有代码的地基尤其是字典文本处理里到处都是「词 → 权重」「词 → 标签」的映射字典用不熟会处处卡壳。如果你连for循环都还写得磕磕绊绊建议先花两天把基础语法过一遍不用学类和装饰器够用就行。数学方面入门阶段只需要两样一是百分比和平均值二是向量和相似度的直觉。你不需要会推导梯度但要知道「两个向量越接近余弦相似度越接近 1」这种程度。真到要用模型的时候框架已经把反向传播封装好了你的工作是准备数据、看指标、调参数不是手算导数。很多人被「人工智能需要高数」这句话劝退其实是被吓退的不是被难退的。工具方面先装好 Python 3再学会用虚拟环境把每个项目的依赖隔开。这一步很多人跳过结果两个项目互相打架排查半天。编辑器用自己顺手的就行不必纠结。剩下要补的只有一点耐心文本处理的结果经常「看起来差不多但就是不对」需要你愿意把中间结果打印出来一行行看这个习惯比任何技巧都重要。3. 第一步怎么迈把第一个中文 NLP 例子跑通概念听再多不如亲手跑一行。这一章的目标很朴素让你的电脑上出现一行「切分正确的中文」和一行「判断正确的情感分」。为了不让你在第一分钟就卡在安装上例子只用 Python 自带的东西不依赖任何第三方包。等你跑通了再去换成工程里常用的成熟库心里有底换起来也不慌。3.1 装什么、不装什么新手最小准备清单必装三样Python 3 解释器、一个能运行脚本的编辑器、一个终端。够了。真的够了。我在新手群里见过太多人第一天就装了五六个深度学习框架环境冲突到连print都跑不起来最后放弃。入门阶段的正确做法是把依赖降到零先让逻辑跑通再按需加库。装好 Python 之后第一件事是建虚拟环境。虚拟环境说白了就是给每个项目建一个独立的小房间A 项目装的库不会影响 B 项目。命令就一行在项目文件夹里执行# 在项目目录下创建名为 venv 的虚拟环境 python -m venv venv # 激活它macOS / Linux source venv/bin/activate # 激活它Windows venv\Scripts\activate-m venv表示用标准库里的 venv 模块创建环境后面那个venv是你给这个环境起的文件夹名叫什么都行习惯上就叫 venv。激活成功后终端提示符前面会多一个(venv)看到它就说明后面的安装都装进这个小房间了。要退出就敲deactivate。提示如果你敲python提示找不到命令试试python3。Windows 上装 Python 时记得勾选「Add Python to PATH」否则命令行认不出它。进去之后写一个hello.py打印一句话确认环境是通的。这一步别嫌傻它验证的是「编辑器写的文件能被解释器执行」这条链路链路断了后面全是白费功夫。3.2 第一个例子手搓一个最简中文分词器现在开始写真正的代码。分词最直观的做法叫正向最大匹配从左往右扫每次尽量取最长的、词典里有的词。词典就是你自己定义的一个词表代码只用标准库# 最简中文分词器正向最大匹配 # 词典里放你认为「应该是一个词」的字符串 word_dict {我, 爱, 自然, 语言, 处理, 自然语言, 自然语言处理} max_len max(len(w) for w in word_dict) # 最长词长度决定每次最多看几个字 def cut(text): result [] i 0 while i len(text): # 从最长候选开始往短试第一个在词典里命中的就是这一刀 for size in range(min(max_len, len(text) - i), 0, -1): piece text[i:i size] if piece in word_dict: result.append(piece) i size break else: # 一个都没命中就把当前这个字单独切成一个词向后挪一格 result.append(text[i]) i 1 return result print(cut(我爱自然语言处理))跑完你会看到[我, 爱, 自然语言处理]。这就是分词去掉神秘感之后它其实就是一次带优先级的字符串匹配。几个参数值得说清楚。word_dict是词典它直接决定切分结果你把「自然语言处理」删掉再跑一次结果会变成[我, 爱, 自然语言, 处理]这就是颗粒度的影响。max_len取词典里最长词的长度它的作用是限制每次最多看几个字取太小会把长词切碎取太大只是多试几次、不影响正确性。range里那个从大到小的顺序就是「最长优先」这条规则的代码表达。自己手写一遍的意义在于你会明白分词器出错时该往哪看切碎了多半是词典缺词切错了多半是优先级或歧义规则的问题。等你换成成熟分词库这些问题一样存在只是库帮你处理了大部分。3.3 第二个例子用词典法判断一句话的情绪分词之后能做很多事最容易上手的是情感判断。思路土但有效准备一个正面词表和一个负面词表句子里命中正面词加一分命中负面词减一分最后看得分正负。难点在于否定词「不满意」如果只按「满意」算会被判成正面所以要多一步取反pos_words {好, 喜欢, 满意, 快, 划算, 推荐} neg_words {差, 慢, 失望, 退货, 贵} negation {不, 没, 别} # 否定词遇到它就把后面那个词的情感取反 def score(text): total 0 flip False # 标记「上一个字是不是否定词」 for ch in text: if ch in negation: flip True continue if ch in pos_words: total -1 if flip else 1 elif ch in neg_words: total 1 if flip else -1 flip False # 每处理一个字就重置避免影响太远 return total for s in [质量很好物流也快, 不推荐太贵了, 不满意退货]: print(s, score(s))三句话的得分依次是 2、-2、-2方向都对。这段代码里有三个可以动手改的地方。词表是最直接的你往pos_words里加几个自己领域的词效果立刻就变。flip的重置位置决定了否定的作用范围现在只影响紧挨着的一个词如果你想让它管一整句就把重置挪到标点处。第三个是权重现在每个词都是一分你可以改成字典存分值让「垃圾」比「贵」扣得更狠。写完这两段你已经摸到了中文自然语言处理的完整骨架先切词再把词变成可计算的信号最后汇总成一个结论。后面所有的模型不管多复杂本质上都在把这三步做得更准而已。4. 往后学的四个基本功词、句、向量、模型跑通例子之后很多人会急着上模型结果发现自己连数据长什么样都说不清。这一章按真实的学习顺序展开先把句子拆成零件再清洗脏数据然后把文字变成数字最后才轮到模型登场。每一步都给一个能跑的小片段让你看得见中间结果不至于全程黑箱。4.1 分词和词性标注把句子切成能用的零件分词解决「切开」词性标注解决「每块是什么」。名词、动词、形容词这些标签看着像语文课的内容实际上非常有用抽关键词时你只想要名词和动词做实体识别时你要找连续的专有名词做句法分析时词性决定了谁能修饰谁。没有词性很多规则根本写不出来。入门阶段可以用查表法理解这件事代码很短# 用一个字典模拟词性标注真实场景里由模型根据上下文判断 pos_dict {我: 代词, 吃: 动词, 苹果: 名词, 很: 副词, 甜: 形容词} def tag(words): # 查不到的词统一标成「未知」真实系统里这一步由模型补 return [(w, pos_dict.get(w, 未知)) for w in words] print(tag([我, 吃, 苹果])) print(tag([苹果, 很, 甜]))输出是[(我, 代词), (吃, 动词), (苹果, 名词)]这样的形式。注意「苹果」在两句话里都被标成名词但意思一个是水果一个是品牌这就是查表法的局限——真实的词性标注要看上下文同一个词在不同句子里标签可能不同。入门时知道这个局限就够了不必现在解决。和分词的关系也要理清词性标注通常建立在分词结果之上分词错了词性必然跟着错。所以如果你发现标注结果离谱先回头检查分词别急着怀疑标注模型。4.2 文本清洗与关键词抽取脏数据才是真问题真实语料没有教科书上那么干净。全角半角混用、表情符号、重复字符「好好好好好」、HTML 标签、无意义的「啊啊啊」这些东西不处理后面所有统计都会被污染。清洗的原则是「保留信息去掉噪声」不是一刀切全删。关键词抽取最经典的算法叫 TF-IDF思路很朴素一个词在这篇文章里出现得多TF 高但在其他文章里很少出现IDF 高它就越可能是关键词。「的」「是」这类词每篇都有IDF 低自然被压下去。手写一遍能看清它到底在算什么import math from collections import Counter docs [ [手机, 电池, 续航, 好], [手机, 屏幕, 坏, 退货], [电池, 续航, 差, 退货], ] def idf(word): n sum(1 for d in docs if word in d) # 出现在几篇文档里 return math.log((len(docs) 1) / (n 1)) 1 # 加一平滑防止除零 doc docs[2] count Counter(doc) for w, c in count.items(): tf c / len(doc) # 词频该词在本篇中的占比 print(w, round(tf * idf(w), 3))len(docs)是文档总数n是包含这个词的文档数1是平滑避免某个词在所有文档都出现时除出零来。跑完你会发现「电池」「续航」得分高「退货」因为两篇都有所以被压低——这正好说明 TF-IDF 会偏爱「有区分度」的词而不是「出现次数多」的词。清洗和抽取合起来构成一个完整的预处理流程去噪 → 分词 → 去停用词 → 统计 → 排序。每一步的中间结果都建议打印出来看一眼很多「效果不对」的锅其实在清洗环节。4.3 词向量让「银行」和「钱」在数学上靠近计算机不认识字只认识数字所以要把文本变成向量。最笨的办法是词袋给每个词编个号句子变成一个长长的计数向量。它的问题是丢了顺序也没法表达「意思相近」。进阶一点是词向量每个词变成一个几十到几百维的稠密向量语义相近的词在空间里距离近这才是「人工智能」能理解语言的起点。入门时不必训练词向量但要理解余弦相似度这个度量。下面这段用词袋向量算两句话的相似程度逻辑和词向量是完全一致的import math from collections import Counter s1 手机 电池 续航 不错.split() s2 手机 电池 续航 一般.split() s3 手机 屏幕 碎了.split() # 把所有句子里的词汇总成词表每个词占一个维度 vocab, vecs sorted({w for s in (s1, s2, s3) for w in s}), [Counter(s) for s in (s1, s2, s3)] def cosine(a, b): dot sum(a[w] * b[w] for w in vocab) # 分子对应维度相乘再相加 na math.sqrt(sum(a[w] ** 2 for w in vocab)) # 分母各自向量的长度 nb math.sqrt(sum(b[w] ** 2 for w in vocab)) return dot / (na * nb) if na and nb else 0.0 print(vocab) print(round(cosine(vecs[0], vecs[1]), 3)) # 0.75前两句高度相似 print(round(cosine(vecs[0], vecs[2]), 3)) # 0.25第三句只共用一个「手机」结果 0.75 和 0.25 的差距就是「相似度」这四个字的直观含义。余弦相似度只看方向不看长度所以长句子不会因为词多就天然得分高这一点在处理长短不一的文本时很重要。到这里你已经能把文本变成数字并比较了。深度学习模型做的其实是同一件事只是它不再靠词表编号而是学出更聪明的向量表示能处理没见过的词、能捕捉语序。什么时候该上模型我的建议是先用规则和统计跑到一个基线比如准确率 70%然后看业务能不能接受。接受了就别急着换模型不接受再上深度学习这时候你有一个明确的对比基准才知道换模型到底带来了多少收益。5. 新手避坑四个最容易翻车的现场入门阶段踩的坑高度集中来来回回就那么几个。这一章把最常见的四个列出来每个按「现象 → 原因 → 解决」写清楚遇到时对照着查比漫无目的地搜索快得多。5.1 环境和依赖上的坑第一个坑敲完安装命令终端报一堆红字或者装成功了但导入还是失败。现象很典型pip install看起来跑完了脚本里一导入就报找不到模块。原因基本是两个一是装到了另一个 Python 环境里二是在虚拟环境没激活的情况下安装的。你的电脑上可能同时有三四个 Pythonpip指向的未必是你运行脚本的那个。解决办法是养成固定动作先激活虚拟环境、看到提示符前面的(venv)再执行安装安装完用python -c import 模块名验证一下。如果还是找不到用python -c import sys; print(sys.executable)打印出当前解释器的路径和pip -V显示的路径对比两边不一致就是装错地方了。第二个坑跟着教程装了一堆包版本之间互相冲突代码跑出各种奇怪的报错。现象是「昨天还能跑今天突然报错」或者换个项目就崩。原因是全局装了太多互相不兼容的版本A 库要旧版本B 库要新版本谁都不让谁。这在深度学习相关的库里尤其常见因为它们的依赖树又深又长。解决办法只有一条一个项目一个虚拟环境把依赖写进requirements.txt换机器时按文件重装。真遇到版本锁死宁可给项目建个新的干净环境也不要硬在旧环境里来回升降级那样只会越修越乱。5.2 数据和效果上的坑第三个坑在自己造的例子上准确率九成换成真实数据直接崩盘。现象是演示时行云流水一上线就各种误判。原因是真实语料和你的测试样例分布完全不同你的样例是精挑细选的干净句子真实数据里全是错别字、网络缩写、反讽、中英混排。模型或规则没见过的模式一律判错。解决办法是尽早拿真实数据来看哪怕只有一两百条也要人工过一遍看看错在哪类样本上。把错误样本单独存成一份每次改完规则或模型都拿它回归测试一遍。这份错误样本集比任何教程都值钱。第四个坑只看总准确率忽略了类别不平衡。现象是模型报告准确率 95%你挺高兴结果发现它把所有样本都判成了同一个类别而那个类别刚好占 95%。原因是你用的指标在数据倾斜时完全失真多数类压倒一切。解决办法是换指标看每一类的精确率和召回率别只看总数。同时在切分训练集和测试集时保证各类比例合理样本太少的类别考虑先补数据或者合并。这个坑在文本分类里极其常见因为真实语料的类别分布本来就是倾斜的。6. 下一步学什么一条能自己走通的学习路线跑通上面那些例子之后最容易出现的状态是「会了但又好像什么都不会」。这不是你的问题是入门材料的通病——每个知识点都碰了一下但没串成线。接下来的路该怎么走我给一个按周推进的顺序你可以照着改。阶段时间重点做什么怎么算过关打基础第 12 周分词、词性、清洗、TF-IDF全部用真实语料跑能独立写出一条完整的预处理流水线上工具第 34 周换成成熟分词库和机器学习分类器做一次文本分类在一个自己找的数据集上跑出可解释的结果进模型第 58 周词向量、预训练模型微调理解每个参数在干什么能说清模型为什么错而不只是报告分数做项目第 9 周起选一个真实需求从头做到能给别人用有人真的在用哪怕只有你自己打基础那两周最枯燥但最不能跳。我的建议是找一个你真正关心的语料比如自己收藏的文章、某个产品的评论、社团的问卷答案用它跑完整流程。用自己的数据有个巨大好处结果对不对你一眼就能看出来不用别人告诉你。上工具阶段要注意一件事换库的时候把你手写的版本留着做对照。同一句话手写版切出五个词库切出六个差在哪这个对比过程比读十篇文档都有用。进模型阶段别贪多先把一个模型吃透搞清楚输入长什么样、输出是什么意思、损失函数在惩罚什么再横向看别的。最后说一个我自己的习惯。从那以后我每次开始一个新文本任务都强制走一遍「先看 100 条原始数据」这一步不管多急。因为我吃过太多次亏自以为数据很干净结果里面有大量重复、编码错乱、标注错误模型怎么调都上不去最后发现是数据本身的问题。这个动作花不了半小时却能省掉后面好几天的瞎折腾。希望帮到你从今天先把那个分词例子跑起来就行。本文还有配套的精品资源点击获取