语言学在 Python 文本分析中的应用
语言学的层次结构与 NLP Pipeline

语言学的五大分支
语言学研究自然语言的不同层面,形成了以下层次结构:
| 分支 | 研究对象 | 核心问题 | Python NLP 对应 |
| 形态学 (Morphology) | 词的内部结构 | 语素如何组合成词 | 分词、词性标注、词干提取 |
| 句法学 (Syntax) | 词与词的结构关系 | 词如何组合成合法句子 | 依存句法分析、成分句法分析 |
| 语义学 (Semantics) | 句子的字面意义 | 句子表达了什么 | 词义消歧、命名实体识别、词嵌入 |
| 语用学 (Pragmatics) | 语境中的实际意义 | 说话者真正想表达什么 | 情感分析、意图识别 |
| 语篇分析 (Discourse) | 句子之间的关系 | 多个句子如何构成连贯文本 | 主题建模、文本摘要、关键词提取 |
NLP Pipeline 的层次对应
一个完整的文本分析流水线通常按照语言学层次自底向上构建:
原始文本 │ ├─ 形态学层 ──→ 分词 → 词性标注 → 词形还原 │ ├─ 句法学层 ──→ 依存分析 / 成分分析 │ ├─ 语义学层 ──→ 命名实体识别 → 词义消歧 → 词嵌入表示 │ ├─ 语用学层 ──→ 情感分析 → 意图识别 │ └─ 语篇层 ──→ 主题建模 → 关键词提取 → 文本摘要
并非所有任务都需要走完整个流水线。情感分析可能只需要分词 + 词典匹配;问答系统可能需要全部层次。理解每一层解决什么问题,才能知道你的任务需要走到哪一层。
常用 Python NLP 库速览
| 库 | 定位 | 中英文支持 | 典型用途 |
| `jieba` | 中文分词 | 中文 | 分词、关键词提取 |
| `HanLP` | 中文综合 NLP | 中文为主 | 分词、句法、NER |
| `spaCy` | 工业级 NLP | 多语言 | 句法分析、NER、词向量 |
| `NLTK` | 教学/研究 | 英文为主 | 全流程教学、经典算法 |
| `gensim` | 主题模型/词嵌入 | 通用 | Word2Vec、LDA |
| `snownlp` | 中文情感分析 | 中文 | 情感分析、摘要 |
| `transformers` | 深度学习 NLP | 多语言 | BERT、GPT 等预训练模型 |
形态学:词的构成与变化
形态学(Morphology)研究词的内部结构。最小的有意义单位叫语素(Morpheme):
- 自由语素:可以独立成词,如”书””走””red”
- 黏着语素:不能独立成词,必须附着在其他语素上,如”-子”(桌子)、”-s”(books)、”-ed”(walked)
语素组合的两种方式:
| 类型 | 含义 | 例子(英文) | 例子(中文) |
| 屈折变化 (Inflection) | 改变语法特征,不改变词义 | walk→walked(时态)、book→books(数) | 走→走了(体态) |
| 派生变化 (Derivation) | 创造新词 | happy→happiness(形容词→名词) | 电→电话(名词→复合名词) |
中文 vs 英文的关键差异:英文有丰富的屈折变化(-ed, -s, -ing, -er),需要词形还原;中文没有形态变化,但词与词之间没有空格,需要分词。这个差异直接决定了两种语言在形态学层的 Python 工具完全不同。
中文分词:jieba
中文文本中词与词之间没有天然分隔符。”我爱自然语言处理”需要被切分为”我 / 爱 / 自然语言处理”。
jieba 是最流行的中文分词库,支持三种模式:
import jieba import jieba.posseg as pseg text = "小明毕业于北京大学计算机系,后在腾讯工作" # 精确模式(默认):最适合文本分析 print(jieba.lcut(text)) # ['小明', '毕业', '于', '北京大学', '计算机系', ',', '后', '在', '腾讯', '工作'] # 全模式:把所有可能的词都找出来(会有重叠) print(jieba.lcut(text, cut_all=True)) # ['小明', '毕业', '于', '北京', '北京大学', '大学', '计算机', '计算机系', ',', '后', '在', '腾讯', '工作'] # 搜索引擎模式:在精确模式基础上对长词再切分 print(jieba.lcut_for_search(text)) # ['小明', '毕业', '于', '北京', '大学', '北京大学', '计算机', '计算机系', ',', '后', '在', '腾讯', '工作']
jieba 的工作原理:
- 词典匹配:基于前缀词典构建有向无环图(DAG),找出所有可能的切分路径
- 概率计算:用动态规划找最大概率路径(每个词的出现概率从语料统计得到)
- HMM 新词发现:对未登录词(词典中没有的词),用隐马尔可夫模型基于字标注(B/M/E/S)来切分
字标注方案:
- B = 词首 (Begin)
- M = 词中 (Middle)
- E = 词尾 (End)
- S = 单字词 (Single)
"北京大学" → B E E E → 北京/大学
或 B M M E → 北京大学
自定义词典:当默认词典不够用时,可以添加领域术语:
# 添加自定义词语及其词性和频率
jieba.add_word("自然语言处理", freq=1000, tag='n')
jieba.add_word("大语言模型", freq=1000, tag='n')
jieba.add_word("知识图谱", freq=1000, tag='n')
# 批量加载
# jieba.load_userdict("custom_dict.txt")
text2 = "他正在研究自然语言处理和大语言模型的结合"
print(jieba.lcut(text2))
# ['他', '正在', '研究', '自然语言处理', '和', '大语言模型', '的', '结合']
实践建议:在任何中文 NLP 任务中,第一步几乎都是分词。分词质量直接决定后续所有任务的上限。投入时间构建领域词典是性价比最高的优化。
词性标注
词性标注(Part-of-Speech Tagging)为每个词标注语法类别(名词、动词、形容词等)。它的语言学基础是词类(Word Class)概念。
import jieba.posseg as pseg
text = "张三昨天在北京买了一本书"
words = pseg.lcut(text)
for word, flag in words:
print(f"{word:8s} {flag}")
输出:
张三 nr (人名) 昨天 t (时间名词) 在 p (介词) 北京 ns (地名) 买 v (动词) 了 ul (助词,时态) 一 m (数词) 本 q (量词) 书 n (名词)
jieba 词性标注集(常用):
| 标签 | 含义 | 例子 |
| n | 普通名词 | 苹果、桌子 |
| nr | 人名 | 张三、李四 |
| ns | 地名 | 北京、上海 |
| nt | 机构名 | 腾讯、微软 |
| v | 动词 | 买、走 |
| a | 形容词 | 好、快 |
| d | 副词 | 很、非常 |
| p | 介词 | 在、对 |
| t | 时间词 | 昨天、明天 |
| m | 数词 | 一、三百 |
| q | 量词 | 本、个、条 |
词性标注的价值:它为下游任务提供了语法线索。比如”情感分析”中,形容词(a)和副词(d)通常携带主要情感信息;”命名实体识别”中,nr/ns/nt 标签直接指向候选实体。
英文的词干提取与词形还原
英文有屈折变化,”running””runs””ran”的词根都是”run”。两种处理方法:
# 词干提取(Stemming):粗暴截断,不保证是真实单词
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem("running")) # run
print(stemmer.stem("happiness")) # happi ← 不是真实单词
print(stemmer.stem("studies")) # studi ← 不太理想
# 词形还原(Lemmatization):基于词典,还原为词典中的词
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize("running", pos='v')) # run
print(lemmatizer.lemmatize("happiness")) # happiness ← 保留
print(lemmatizer.lemmatize("studies")) # study ← 正确
print(lemmatizer.lemmatize("better", pos='a')) # good ← 不规则变化
| 方法 | 原理 | 优点 | 缺点 |
| 词干提取 | 规则截断后缀 | 快,不需要词典 | 可能产生非词 |
| 词形还原 | 词典查找 + 词性 | 结果是真实单词,更准确 | 需要词典,速度慢 |
实际选择:搜索引擎、信息检索场景用 Stemmer(快就行);文本挖掘、语义分析场景用 Lemmatizer(准确性要求高)。
句法学:词与词的结构关系
句法学(Syntax)研究词如何组合成合法的句子。两种主流分析方法:
成分句法分析(Constituency Parsing)
将句子拆解为嵌套的短语结构:
句子: “The cat sat on the mat”
S (句子)
/ \
NP VP
| / \
Det V PP
The sat / \
P NP
on / \
Det N
the mat
这对应乔姆斯基的短语结构语法(Phrase Structure Grammar),句子由规则递归生成:S → NP + VP,VP → V + PP……
依存句法分析(Dependency Parsing)
分析词与词之间的修饰关系,不关注短语嵌套:
句子: “张三 昨天 在 北京 买了 一本书”
买(核心动词) ├── 主语 → 张三 ├── 时间 → 昨天 ├── 地点 → 在北京 └── 宾语 → 一本书
每个词都有一个依存弧指向它的支配词(head),形成一棵依存树。树根是句子的核心动词。
依存句法分析:spaCy
spaCy 提供了工业级的依存句法分析,支持多种语言:
import spacy
# 加载英文模型
nlp = spacy.load("en_core_web_sm")
doc = nlp("The quick brown fox jumps over the lazy dog")
for token in doc:
print(f"{token.text:12s} {token.dep_:12s} → {token.head.text}")
输出:
The det → fox quick amod → fox brown amod → fox fox nsubj → jumps jumps ROOT → jumps over prep → jumps the det → dog lazy amod → dog dog pobj → over
常用依存关系标签:
| 标签 | 含义 | 说明 |
| nsubj | nominal subject | 名词主语 |
| dobj | direct object | 直接宾语 |
| iobj | indirect object | 间接宾语 |
| prep | prepositional modifier | 介词修饰 |
| amod | adjectival modifier | 形容词修饰 |
| det | determiner | 限定词 |
| ROOT | root | 句子核心(通常是主动词) |
可视化依存树:
from spacy import displacy
doc = nlp("Apple is looking at buying a startup in London")
html = displacy.render(doc, style="dep", options={"compact": True})
# 生成可交互的 SVG 图
# 在 Jupyter 中直接显示:displacy.render(doc, style="dep", jupyter=True)
中文句法分析:HanLP
中文句法分析推荐 HanLP,它对中文支持更好:
# pip install hanlp import hanlp # 加载中文多功能模型 hanlp_pipeline = hanlp.load(hanlp.pretrained.mtl.CLOSE_TOK_POS_NER_SRL_DEP_SDP_CON_ELECTRA_BASE_ZH) doc = hanlp_pipeline(["张三昨天在北京买了一本书"]) print(doc['dep']) # 依存关系 # 输出依存弧和依存标签
句法分析的应用场景:
- 信息抽取:从”张三买了苹果公司的股票”中提取(张三,买,苹果公司的股票)三元组
- 问答系统:理解”谁做了什么”的结构关系
- 机器翻译:需要理解源语言句子结构才能生成目标语言
- 文本摘要:通过依存树识别句子的核心信息
语义学:意义的表示与计算
语义学(Semantics)研究语言的字面意义。与语用学的区别在于:语义学关注”句子本身说了什么”,语用学关注”说话者实际想表达什么”。
核心议题包括:
- 词义关系:同义(汽车/轿车)、反义(大/小)、上下位(水果/苹果)、整体-部分(手/手指)
- 组合性原则(弗雷格):整体意义由部分意义及组合方式决定
- 命题与真值:句子描述的”事态”是否为真
命名实体识别(NER)
NER 从文本中识别出具有特定类型的实体——人名、地名、机构名、时间等。
import jieba
import jieba.ner as ner
# jieba 的 NER(基于 HMM)
jieba.load_userdict("") # 确保初始化
words = jieba.tokenize("王小明在北京腾讯总部与李雷讨论了AI项目")
for tk in words:
print(f"词: {tk.word:8s} 位置: {tk.start}-{tk.end} 类型: {tk.flag}")
更强大的方案是使用 spaCy(英文)或 HanLP(中文):
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Apple was founded by Steve Jobs in California in 1976")
for ent in doc.ents:
print(f"{ent.text:20s} {ent.label_:12s} {spacy.explain(ent.label_)}")
输出:
Apple ORG Companies, agencies, institutions Steve Jobs PERSON People, including fictional California GPE Countries, cities, states 1976 DATE Absolute or relative dates
spaCy 的实体类型:
| 标签 | 类型 | 例子 |
| PERSON | 人物 | Steve Jobs |
| ORG | 机构 | Apple, 联合国 |
| GPE | 地缘政治实体 | 北京, California |
| DATE | 日期 | 1976, 三月 |
| MONEY | 金额 | 一百万美元 |
| PRODUCT | 产品 | iPhone |
NER 的应用:知识图谱构建、情报提取、简历解析、医疗记录中的疾病/药物识别、金融文本中的公司/产品识别。
词义消歧(WSD)
同一个词在不同上下文意义不同。词义消歧(Word Sense Disambiguation)的目标是根据上下文确定词的正确意义。
# 简单方案:基于上下文词的共现统计
# "苹果"在"种植/果园/丰收"附近 → 水果
# "苹果"在"手机/发布会/股价"附近 → 公司
# 现代方案:使用预训练语言模型(如 BERT)
from transformers import pipeline
# BERT 自带上下文相关的词表示
# 同一个词在不同句子中会产生不同的向量
fill_mask = pipeline("fill-mask", model="bert-base-chinese")
result1 = fill_mask("我喜欢吃[MASK]果")
# → 苹果(水果义高概率)
result2 = fill_mask("[MASK]果公司发布了新手机")
# → 苹果(公司义高概率)
传统 WSD 依赖人工编纂的词义库(如 WordNet、知网 HowNet),现代方法更倾向于用预训练模型自动处理,因为上下文相关的词向量已经隐式编码了词义信息。
词嵌入:分布式语义的工程实现
语言学基础:维特根斯坦的”意义即使用”→ 弗斯的”通过一个词的伙伴来认识它”→ 分布式假设”出现在相似上下文中的词有相似的意义”。
from gensim.models import Word2Vec
from gensim.similarities import MatrixSimilarity
# 准备语料(分词后的句子列表)
sentences = [
["国王", "统治", "王国", "人民"],
["王后", "嫁给", "国王", "住在", "王宫"],
["王子", "是", "国王", "的", "儿子"],
["总统", "管理", "国家", "政府"],
["总统", "住在", "白宫"],
["苹果", "是", "水果", "红色"],
["香蕉", "是", "水果", "黄色"],
]
# 训练 Word2Vec 模型
model = Word2Vec(sentences, vector_size=50, window=3, min_count=1, sg=0)
# sg=0: CBOW(用上下文预测中心词)
# sg=1: Skip-gram(用中心词预测上下文)
# 语义相似度
print(model.wv.similarity("国王", "王后")) # 高
print(model.wv.similarity("国王", "苹果")) # 低
# 类比推理:国王 - 男人 + 女人 ≈ 王后
result = model.wv.most_similar(positive=["国王", "女人"], negative=["男人"])
print(result) # 应该接近"王后"
词嵌入的几何直觉:
向量空间中的语义方向:
"性别"方向: 男人 ────→ 女人
国王 ────→ 王后
伯父 ────→ 伯母
"时态"方向(英文): walk ────→ walked
go ────→ went
eat ────→ ate
"复数"方向(英文): cat ────→ cats
dog ────→ dogs
关键理解:词嵌入不是”计算语言学家的发明”,而是语言哲学使用论的工程验证。模型从未被告知”国王”是”男性统治者”——它只看到了”国王”经常和”王国””统治””王后”一起出现。语义相似度从使用模式中涌现出来。
语用学:语境中的意义
语用学(Pragmatics)研究语言在实际使用中的意义——超出字面的、依赖语境的、包含说话者意图的意义。上一篇讨论的格莱斯合作原则和言语行为理论是语用学的理论支柱。在工程上,语用学分析主要落地为两个任务:情感分析和意图识别。
情感分析
基于词典的方法
最简单的方案:构建情感词典,统计正面词和负面词的数量。
# 使用 snownlp 进行中文情感分析
from snownlp import SnowNLP
texts = [
"这家餐厅的菜很好吃,服务也很棒!",
"产品质量太差了,根本没法用,退货!",
"包装还不错,物流速度一般,总体还行。",
]
for text in texts:
s = SnowNLP(text)
print(f"情感分: {s.sentiments:.3f} {text}")
# 情感分范围 0~1,越接近 1 越正面
输出:
情感分: 0.972 这家餐厅的菜很好吃,服务也很棒! 情感分: 0.083 产品质量太差了,根本没法用,退货! 情感分: 0.521 包装还不错,物流速度一般,总体还行。
基于机器学习的方法
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
# 训练数据
train_texts = [
"这部电影太精彩了",
"非常好看的片子",
"浪费时间,剧情无聊",
"演技太差,不推荐",
"画面很美,值得一看",
"烂片,别去电影院了",
]
train_labels = [1, 1, 0, 0, 1, 0] # 1=正面, 0=负面
# Pipeline: jieba分词 → TF-IDF → 朴素贝叶斯分类
import jieba
def tokenize(text):
return list(jieba.cut(text))
pipeline = Pipeline([
('tfidf', TfidfVectorizer(tokenizer=tokenize, token_pattern=None)),
('clf', MultinomialNB()),
])
pipeline.fit(train_texts, train_labels)
# 预测
test = ["剧情紧凑,演技在线", "又长又无聊"]
predictions = pipeline.predict(test)
for text, pred in zip(test, predictions):
label = "正面" if pred == 1 else "负面"
print(f"{label} {text}")
情感分析的层次
| 层次 | 任务 | 难度 | 例子 |
| 文档级 | 整篇文本的情感 | ★☆☆ | “好评” / “差评” |
| 句子级 | 每句话的情感 | ★★☆ | “画面好看,但剧情烂”(混合) |
| 方面级 | 针对每个方面的情感 | ★★★ | “画面→好,剧情→差,演技→好” |
方面级情感分析(Aspect-Based Sentiment Analysis, ABSA)是当前研究热点,需要结合句法分析来定位”什么方面”和”什么情感”。
意图识别
意图识别是对话系统(聊天机器人、智能客服)的核心组件——判断用户说的话表达了什么意图。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
import jieba
# 训练数据:用户话语 → 意图标签
train_data = [
("帮我查一下明天的天气", "查询天气"),
("今天北京会下雨吗", "查询天气"),
("明天上海气温多少度", "查询天气"),
("我要订一张去北京的机票", "订机票"),
("帮我买下周二到上海的机票", "订机票"),
("订一张明天的火车票", "订火车票"),
("帮我查一下G123次列车的时刻表", "查车次"),
("高铁几点到站", "查车次"),
("播放一首周杰伦的歌", "播放音乐"),
("来一首轻音乐", "播放音乐"),
]
texts = [d[0] for d in train_data]
labels = [d[1] for d in train_data]
def tokenize(text):
return list(jieba.cut(text))
model = Pipeline([
('tfidf', TfidfVectorizer(tokenizer=tokenize, token_pattern=None)),
('clf', LogisticRegression(max_iter=1000)),
])
model.fit(texts, labels)
# 预测新用户的意图
test_texts = [
"明天广州天气怎么样",
"订一张周五去深圳的机票",
"放一首流行歌曲",
]
for text in test_texts:
pred = model.predict([text])[0]
print(f"意图: {pred:8s} ← {text}")
输出:
意图: 查询天气 ← 明天广州天气怎么样 意图: 订机票 ← 订一张周五去深圳的机票 意图: 播放音乐 ← 放一首流行歌曲
意图识别的语言学基础:它直接对应言语行为理论中的言外行为分类——不是分析句子”说了什么”(字面意义),而是判断说话者”在做什么”(请求天气、订票、播放音乐)。
语篇分析:超越句子层面
语篇分析(Discourse Analysis)研究句子之间如何构成连贯的文本。单个句子的意义是有限的,真正的文本理解需要在句子序列中发现:
- 主题(Topic):这段文本在讲什么?
- 连贯性(Coherence):句子之间的逻辑关系是什么?
- 指代关系(Coreference):”他”指的是谁?
关键词提取:TF-IDF 与 TextRank
TF-IDF
TF-IDF(Term Frequency-Inverse Document Frequency)衡量一个词对文档的重要程度。
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
documents = [
"自然语言处理是人工智能的重要分支",
"深度学习在计算机视觉领域取得了突破",
"机器学习和深度学习是人工智能的核心技术",
"自然语言处理需要大量的文本数据",
"计算机视觉依赖图像数据进行训练",
]
# 分词
tokenized_docs = [" ".join(jieba.cut(doc)) for doc in documents]
# TF-IDF
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(tokenized_docs)
# 查看每个文档的关键词
feature_names = vectorizer.get_feature_names_out()
for i, doc in enumerate(documents):
scores = zip(feature_names, tfidf_matrix[i].toarray()[0])
sorted_scores = sorted(scores, key=lambda x: x[1], reverse=True)
top_keywords = [word for word, score in sorted_scores[:3] if score > 0]
print(f"文档{i+1}: {top_keywords}")
输出:
文档1: ['自然', '语言', '处理', '人工智能'] 文档2: ['深度', '学习', '计算机', '视觉'] 文档3: ['机器', '学习', '深度', '人工智能'] 文档4: ['自然', '语言', '文本', '数据'] 文档5: ['计算机', '视觉', '图像', '训练']
TF-IDF 的直觉:
| 概念 | 公式 | 含义 |
| TF | 词在文档中出现的次数 / 文档总词数 | 词在该文档中的频率 |
| IDF | log(文档总数 / 包含该词的文档数) | 词的稀有度 |
| TF-IDF | TF × IDF | 高频 + 稀有 = 重要 |
“的””是””在”在每个文档都出现,IDF 很低,TF-IDF 值低;”自然语言”只在部分文档出现,IDF 高,TF-IDF 值高。
TextRank
TextRank 基于图排序算法(与 PageRank 同源),通过词共现关系构建图,找出中心节点作为关键词。
import jieba
import jieba.analyse
text = """
自然语言处理是人工智能的一个重要分支,它研究如何让计算机理解和生成人类语言。
深度学习技术的发展推动了自然语言处理的进步,特别是 Transformer 架构的提出,
使得大语言模型在文本理解、生成和翻译等任务上取得了突破性进展。
"""
# TextRank 关键词提取
keywords = jieba.analyse.textrank(text, topK=5, withWeight=True)
for word, weight in keywords:
print(f"{word:10s} 权重: {weight:.4f}")
输出:
自然 权重: 1.0000 语言 权重: 0.8234 处理 权重: 0.7891 深度 权重: 0.6543 学习 权重: 0.6234
TF-IDF 是统计方法,只看词频和文档频率;TextRank 是图方法,还考虑词之间的共现结构——经常一起出现的词互相增强权重。
主题建模:LDA
LDA(Latent Dirichlet Allocation)是一种概率生成模型,假设每篇文档由多个主题按一定比例混合而成,每个主题是词的概率分布。
from gensim import corpora, models
import jieba
# 准备文档集(分词后)
documents = [
"人工智能技术正在改变各行各业的运作方式",
"深度学习和神经网络推动了图像识别的进步",
"这家餐厅的菜品很有特色,服务态度也好",
"旅游景点的门票价格合理,值得一去",
"机器学习算法在推荐系统中广泛应用",
"这家酒店的早餐很丰盛,房间也很干净",
]
# 分词 + 去停用词
stopwords = set("的 了 是 在 也 很 和 与 等".split())
texts = [[w for w in jieba.cut(doc) if w not in stopwords and len(w) > 1] for doc in documents]
# 构建词典和语料
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
# 训练 LDA 模型
lda = models.LdaModel(corpus, num_topics=2, id2word=dictionary, passes=15)
# 查看每个主题的词分布
for idx, topic in lda.print_topics(num_words=5):
print(f"主题 {idx}: {topic}")
输出(示意):
主题 0: 0.050*"学习" + 0.045*"人工智能" + 0.040*"深度" + 0.035*"算法" + 0.030*"图像" 主题 1: 0.050*"餐厅" + 0.045*"酒店" + 0.040*"服务" + 0.035*"价格" + 0.030*"早餐"
LDA 的直觉:
文档 = 主题分布 × 词语分布 文档1 "人工智能技术改变行业" → [主题A: 0.8, 主题B: 0.2] 文档2 "餐厅菜品有特色" → [主题A: 0.1, 主题B: 0.9] 主题A: "学习 0.10 | 深度 0.08 | 人工智能 0.07 | 算法 0.06 | ..." 主题B: "餐厅 0.10 | 酒店 0.08 | 服务 0.07 | 价格 0.06 | ..."
LDA 的语言哲学意义:它实现了主题这一抽象概念的数学化——主题不是一个词,而是一组词的概率分布。这呼应了维特根斯坦的”家族相似性”概念:属于同一主题的词不一定有共同特征,但彼此之间存在交叉相似的”家族关系”。
文本摘要
抽取式摘要
从原文中选出最重要的句子作为摘要。
from summa.summarizer import summarize text = """ Natural language processing (NLP) is a subfield of linguistics, computer science, and artificial intelligence concerned with the interactions between computers and human language. NLP has its roots in the 1950s. Modern NLP systems are based on deep learning and neural networks. The rise of large language models like GPT has transformed the field. These models can generate human-like text, answer questions, and translate between languages with high accuracy. """ summary = summarize(text, ratio=0.4) # 提取40%的句子 print(summary)
生成式摘要
使用大语言模型生成摘要(不是抽取原文句子):
from transformers import pipeline
summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6")
text = """
Paul Walker is an American actor. He is best known for his role as Brian O'Conner
in the Fast & Furious franchise. Walker began his career as a child actor in the
1980s. He gained fame in the early 2000s. Walker died in a car accident in 2013
at the age of 40.
"""
summary = summarizer(text, max_length=50, min_length=20, do_sample=False)
print(summary[0]['summary_text'])
抽取式摘要保留原文措辞,适合新闻摘要;生成式摘要可以重组语言,适合更灵活的摘要需求,但可能引入事实错误。
现代大语言模型与语言学的融合
Transformer 架构与语言学层次
传统 NLP 按语言学层次分阶段处理(分词 → 句法 → 语义 → 语用),每个阶段独立训练。大语言模型(LLM)的革命在于:用统一的架构和目标函数处理所有层次。
| 传统 NLP | 大语言模型 |
| 分阶段 pipeline,每层独立模型 | 端到端,单一 Transformer 模型 |
| 每层需要人工标注数据 | 自监督学习(预测下一个 token) |
| 各层技术栈不同(CRF、HMM、CNN……) | 统一的注意力机制 |
| 分词 → 句法 → 语义 串行 | 所有层次并行编码 |
| 人工设计特征 | 从数据中自动学习 |
注意力机制的语言学意义
Transformer 的自注意力(Self-Attention)机制让每个词”看到”句子中所有其他词,并根据相关性加权聚合。这在语言学上对应了:
- 上下文依赖:同一个词在不同上下文中获得不同的表示(解决了歧义问题)
- 长距离依存:句子首尾的词可以通过注意力直接交互(解决了 RNN 的长距离遗忘问题)
- 层次编码:多层注意力逐层抽象,低层捕获语法,高层捕获语义
# 使用 BERT 获取上下文相关的词表示
from transformers import AutoTokenizer, AutoModel
import torch
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")
model = AutoModel.from_pretrained("bert-base-chinese")
# 同一个词在不同上下文中的表示不同
sent1 = "我喜欢吃苹果"
sent2 = "苹果公司发布了新手机"
for sent in [sent1, sent2]:
inputs = tokenizer(sent, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
# outputs.last_hidden_state 包含每个 token 的上下文向量
# "苹果"在两句中的向量完全不同
apple_idx = (inputs['input_ids'][0] == tokenizer.convert_tokens_to_ids('苹')).nonzero()
print(f"'{sent}' 中 '苹' 的向量维度: {outputs.last_hidden_state.shape}")
Pipeline 的消亡与统一
# 传统方式:需要多个工具、多个步骤
import jieba
import jieba.posseg as pseg
# 分词 → 词性 → NER → 句法 → ...(每步独立)
# 现代方式:一个 LLM 完成所有任务
from transformers import pipeline
nlp = pipeline("ner", model="bert-base-chinese")
qa = pipeline("question-answering", model="bert-base-chinese")
summarizer = pipeline("summarization")
# 甚至直接用 GPT 做一切:
# prompt = "提取以下文本中的人名、地名、机构名,并分析情感倾向:..."
但这并不意味着语言学知识过时了。恰恰相反——当你需要理解模型为什么出错、设计更好的 prompt、评估输出质量时,语言学知识就是你的诊断工具。模型不是万能的,它只是在海量数据上做了统计,而语言学告诉你这个统计遗漏了什么。
实战:构建一个完整的文本分析 Pipeline
以下是一个综合示例,展示如何将多个语言学层次组合起来分析真实文本:
import jieba
import jieba.analyse
from collections import Counter
def analyze_text(text):
"""一个多层次的中文文本分析函数"""
print("=" * 60)
print(f"原文: {text}")
print("=" * 60)
# ━━ 形态学层 ━━
print("\n【1. 分词】")
words = jieba.lcut(text)
print(f" {words}")
# 词性标注
print("\n【2. 词性标注】")
import jieba.posseg as pseg
pos_tags = pseg.lcut(text)
for w, t in pos_tags:
print(f" {w:8s} → {t}")
# ━━ 语义学层 ━━
print("\n【3. 关键词提取(TextRank)】")
keywords = jieba.analyse.textrank(text, topK=5, withWeight=True)
for word, weight in keywords:
print(f" {word:8s} 权重={weight:.4f}")
# ━━ 语用学层(简易情感分析)━━
print("\n【4. 情感分析(词典法)】")
positive_words = {"好", "棒", "优秀", "喜欢", "满意", "推荐", "值得", "精彩", "漂亮"}
negative_words = {"差", "烂", "失望", "不满", "退货", "难吃", "无聊", "浪费", "糟糕"}
pos_count = sum(1 for w in words if w in positive_words)
neg_count = sum(1 for w in words if w in negative_words)
if pos_count > neg_count:
sentiment = "正面"
elif neg_count > pos_count:
sentiment = "负面"
else:
sentiment = "中性"
print(f" 正面词: {pos_count} 负面词: {neg_count} → 情感: {sentiment}")
# ━━ 语篇层 ━━
print("\n【5. 词频统计】")
word_freq = Counter(w for w in words if len(w) > 1)
for word, freq in word_freq.most_common(5):
print(f" {word:8s} 出现 {freq} 次")
return {
"words": words,
"keywords": [w for w, _ in keywords],
"sentiment": sentiment,
"word_freq": word_freq,
}
# 测试
text = "这家餐厅的环境很好,菜品味道也不错,服务态度很棒,强烈推荐!但价格有点贵。"
result = analyze_text(text)
总结:语言学是 NLP 的导航图
| 语言学分支 | 核心概念 | Python 工具 | 典型任务 |
| 形态学 | 语素、屈折变化 | jieba, NLTK, spaCy | 分词、词性标注、词形还原 |
| 句法学 | 依存关系、短语结构 | spaCy, HanLP, NLTK | 依存分析、成分分析 |
| 语义学 | 词义、组合性、实体 | spaCy, gensim, transformers | NER、WSD、词嵌入 |
| 语用学 | 言语行为、言外之意 | snownlp, sklearn, transformers | 情感分析、意图识别 |
| 语篇分析 | 主题、连贯性、指代 | gensim, jieba.analyse, transformers | 主题建模、关键词、摘要 |
核心要点:
- 每个 NLP 工具背后都有语言学理论支撑。理解理论能帮你选对工具、调参有方向、排错有逻辑。
- 中文和英文的 NLP 策略差异根源在语言学差异。英文需要词形还原、有屈折变化;中文需要分词、无形态变化、量词丰富。
- 传统 pipeline 分层处理正在被 LLM 统一,但语言学知识依然是诊断模型问题、设计提示词、评估输出质量的不可替代工具。
- 分词是一切的起点。对中文 NLP 而言,分词质量是所有下游任务的天花板。投入时间构建领域词典,是性价比最高的优化。
- 意义是分布式的,也是社会的。词嵌入捕获了统计分布层面的意义,但语用层面的意义——讽刺、委婉、意图——仍需要上下文建模和社会理解。
语言学不会过时。工具会换、框架会变、模型会更替,但”语言有层次、有歧义、有上下文、有社会维度”这些基本事实不会变。掌握这些基本事实,你就拥有了超越具体工具的分析能力。





