当前位置: 首页 > ds >正文

【NLP第二期中文分词技术:规则、统计与混合方法全解】

🚀 作者 :“码上有前”
🚀 文章简介 :NLP
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬
请添加图片描述

在这里插入图片描述

中文分词技术:规则、统计与混合方法全解

摘要:本文围绕中文分词技术展开深入剖析,详细讲解基于规则(正向/逆向/双向最大匹配法)、基于统计(n - gram模型、隐马尔可夫模型)以及混合分词(以jieba库为例)的三类方法。通过原理阐释、实例演示与代码实践,对比不同分词技术的优缺点与适用场景,帮助读者全面掌握中文分词核心技能,为自然语言处理后续任务筑牢基础。

一、引言

中文分词作为自然语言处理(NLP)基石,需将连续文本切分为词汇单元,为文本分析、信息检索等上层应用奠基。因中文无天然分词标记,需借助规则、统计及混合技术实现,以下逐层解析。

二、基于规则(词典)的分词方法

(一)核心逻辑

依赖预构建词典,按匹配规则从文本识别词汇,以“南京市长江大桥”演示三种方法。

(二)具体方法

1. 正向最大匹配法(MM)

步骤
① 设定最大词长(如5),从文本开头截取等长片段;
② 查词典,匹配则分割,失败则缩短片段长度(减1),重复匹配;
③ 遍历文本,直至全部分割。

Python示例代码

def forward_max_match(text, word_dict, max_len=5):result = []while text:start = 0end = min(max_len, len(text))while end > start:segment = text[start:end]if segment in word_dict:result.append(segment)text = text[end:]breakend -= 1else:# 未匹配到,单字分割(可选策略)result.append(text[0])text = text[1:]return resultword_dict = {"南京市", "长江", "大桥"}
text = "南京市长江大桥"
print(forward_max_match(text, word_dict))  
# 输出: ['南京市', '长江', '大桥']

优缺点

  • 优点:逻辑直观,词典匹配成功时分词高效;
  • 缺点:依赖词典完备性,遇未登录词易出错;最大词长难适配所有文本,长文本易因片段截取策略产生歧义。
2. 逆向最大匹配法(RMM)

步骤
① 设定最大词长,从文本末尾截取等长片段;
② 查词典,匹配则分割,失败缩短片段长度(减1),重复匹配;
③ 遍历文本,完成分割。

Python示例代码

def reverse_max_match(text, word_dict, max_len=5):result = []while text:end = len(text)start = max(0, end - max_len)while start < end:segment = text[start:end]if segment in word_dict:result.insert(0, segment)text = text[:start]breakstart += 1else:result.insert(0, text[-1])text = text[:-1]return resultword_dict = {"南京市", "长江", "大桥"}
text = "南京市长江大桥"
print(reverse_max_match(text, word_dict))  
# 输出: ['南京市', '长江', '大桥']

优缺点

  • 优点:对部分歧义文本(如“研究生命起源”),逆向匹配结果更优;
  • 缺点:同样依赖词典,且分词效率随文本长度增加而降低,需频繁截取片段查词典。
3. 双向最大匹配法(BMM)

步骤
① 分别用正向、逆向最大匹配法分词,得到两组结果;
② 按规则选优:优先选分词数少的;若数量相同,选单字少的;若仍相同,选逆向结果(或自定义规则 )。

Python示例代码

def bidirectional_max_match(text, word_dict, max_len=5):forward_result = forward_max_match(text, word_dict, max_len)reverse_result = reverse_max_match(text, word_dict, max_len)# 选优规则:分词数少优先,再看单字数量def count_single_words(res):return sum(1 for w in res if len(w) == 1)if len(forward_result) != len(reverse_result):return forward_result if len(forward_result) < len(reverse_result) else reverse_resultelse:forward_single = count_single_words(forward_result)reverse_single = count_single_words(reverse_result)return forward_result if forward_single < reverse_single else reverse_resultword_dict = {"南京市", "长江", "大桥", "研究", "生命", "起源"}
text = "研究生命起源"
print(bidirectional_max_match(text, word_dict))  
# 正向可能 ['研究生', '命', '起源'],逆向 ['研究', '生命', '起源'],选逆向,输出: ['研究', '生命', '起源']

优缺点

  • 优点:通过双向匹配选优,降低歧义概率;
  • 缺点:需执行两次最大匹配,效率低于单一方向;规则选优可能无法覆盖所有复杂歧义场景。

三、基于统计的分词方法

(一)语言模型(n - gram模型)

基本思想:计算不同分词路径概率,选概率最大的结果,将分词转化为概率求解问题。

步骤
① 基于大规模语料,统计n - gram概率(如二元模型,统计相邻词共现概率 P ( w i ∣ w i − 1 ) P(w_i|w_{i - 1}) P(wiwi1) );
② 对文本生成所有可能分词路径,计算每条路径概率(路径概率为各词概率乘积 );
③ 选概率最大的路径作为分词结果。

Python示例(简化版,基于频次模拟概率)

from collections import defaultdict
import math# 模拟语料统计n - gram频次
corpus = ["机器学习 是 热门 领域", "机器 学习 很 重要", "我爱 机器学习"]
word_freq = defaultdict(int)
bigram_freq = defaultdict(int)
for sentence in corpus:words = sentence.split()for word in words:word_freq[word] += 1for i in range(len(words) - 1):bigram_freq[(words[i], words[i + 1])] += 1# 计算概率(简化为频次比)
def get_word_prob(word):return word_freq[word] / sum(word_freq.values()) if word_freq[word] else 0def get_bigram_prob(prev, curr):return bigram_freq[(prev, curr)] / word_freq[prev] if word_freq[prev] and bigram_freq[(prev, curr)] else 0# 分词路径概率计算(简化示例,仅演示逻辑)
def ngram_segment(text, possible_segments):best_path = Nonemax_prob = -math.inffor seg in possible_segments:prob = 1for i in range(len(seg) - 1):prob *= get_bigram_prob(seg[i], seg[i + 1])if prob > max_prob:max_prob = probbest_path = segreturn best_pathtext = "机器学习"
possible_segments = [["机器", "学习"], ["机", "器", "学习"]]
print(ngram_segment(text, possible_segments))  
# 输出: ['机器', '学习'](假设“机器 学习”概率更高)

优缺点

  • 优点:无需依赖固定词典,能适应新词;通过概率模型挖掘语义关联;
  • 缺点:需大规模语料训练,计算成本高;分词路径爆炸(长文本可能路径极多 ),实际应用需剪枝优化。

(二)隐马尔可夫模型(HMM)

基本思想:将分词转化为字的序列标注任务,定义隐藏状态(B - 词首、M - 词中、E - 词尾、S - 单字成词 ),用维特比算法求解最优状态序列。

步骤
① 标注训练语料,统计状态转移概率(如B→M、M→E等概率 )、发射概率(字→状态的概率,如“学”作为B状态的概率 );
② 对新文本,用维特比算法计算每个位置的状态概率,找到最优状态序列;
③ 依据状态序列分割文本(B开头、E结尾为一词,S单独成词 )。

Python示例(简化版,基于简单标注训练)

import numpy as np
from collections import defaultdict# 模拟训练语料标注(状态:B, M, E, S)
corpus = [("我", "S"), ("爱", "S"), ("自", "B"), ("然", "E"), ("语", "B"), ("言", "E"), ("处", "B"), ("理", "E")
]
state_trans = defaultdict(lambda: defaultdict(int))  # 状态转移计数
emission_prob = defaultdict(lambda: defaultdict(int))  # 发射概率计数
states = ["B", "M", "E", "S"]
prev_state = corpus[0][1]
for char, state in corpus[1:]:state_trans[prev_state][state] += 1emission_prob[state][char] += 1prev_state = state# 转化为概率(简化为频次比)
for state in states:total_trans = sum(state_trans[state].values())for next_state in states:state_trans[state][next_state] /= total_trans if total_trans else 0total_emission = sum(emission_prob[state].values())for char in emission_prob[state]:emission_prob[state][char] /= total_emission if total_emission else 0# 维特比算法求解最优状态序列
def viterbi(text, states, state_trans, emission_prob):dp = [{} for _ in range(len(text))]# 初始化第一个字for state in states:dp[0][state] = emission_prob[state].get(text[0], 0)# 递推计算for i in range(1, len(text)):for curr_state in states:dp[i][curr_state] = max(dp[i - 1][prev_state] * state_trans[prev_state].get(curr_state, 0) for prev_state in states) * emission_prob[curr_state].get(text[i], 0)# 找最优路径best_path = [max(dp[-1], key=dp[-1].get)]for i in range(len(text) - 2, -1, -1):best_path.insert(0, max(states, key=lambda s: dp[i][s] * state_trans[s].get(best_path[0], 0)))return best_pathtext = "我爱自然"
states_seq = viterbi(text, states, state_trans, emission_prob)
# 依据状态序列分词
seg_result = []
word = ""
for char, state in zip(text, states_seq):if state in ["B", "S"]:if word:seg_result.append(word)word = charelse:word += char
seg_result.append(word)
print(seg_result)  
# 输出: ['我', '爱', '自然'](假设状态序列匹配)

优缺点

  • 优点:能处理未登录词,通过序列标注挖掘字间关联;
  • 缺点:依赖高质量标注语料,训练成本高;状态定义和概率计算对分词效果影响大,复杂文本易出错。

四、混合分词:以jieba库为例

(一)原理

融合规则分词(词典匹配)与统计方法(HMM优化未登录词、歧义),先词典匹配,再用HMM校准。

(二)实例与代码

Python示例(jieba库使用)

import jieba# 加载自定义词典(可选,增强规则分词)
jieba.load_userdict("custom_dict.txt")  
text = "深度学习助力自然语言处理发展"
# 分词(混合模式,默认启用)
seg_result = jieba.lcut(text)
print(seg_result)  
# 输出: ['深度学习', '助力', '自然语言处理', '发展']

内部流程简化说明

  1. 规则分词:用内置/自定义词典,匹配“深度学习”“助力”等词;
  2. 统计优化:对未匹配部分(如新词),用HMM模型标注字状态,识别“自然语言处理”等词;
  3. 融合结果:结合规则与统计结果,输出最终分词。

优缺点

  • 优点:兼顾词典匹配高效性与统计方法对新词、歧义的适应性,实际场景(如新闻、社交文本)表现好;
  • 缺点:需维护词典,HMM模型依赖训练,极端领域(如专业医学文本 )需定制化优化。

五、总结

中文分词技术中,规则分词(MM/RMM/BMM )逻辑清晰但依赖词典;统计分词(n - gram/HMM )适应新词但成本高;混合分词(jieba为代表 )融合二者优势,成为实际应用主流。开发时,需根据场景选方法:词典覆盖度高的领域(如法律文本 )用规则分词;网络动态文本用混合分词;科研探索语义建模用统计分词。掌握各方法步骤、代码与优缺点,可精准应对NLP分词需求,为上层应用筑牢基础。

(注:文中代码为简化演示,实际工程需结合大规模语料、高效概率计算优化,如用jieba等成熟库处理复杂场景 。)。

五、总结

中文分词技术从基于规则的简单匹配,到基于统计的概率求解,再到混合策略的高效应用,各有优劣。基于规则的方法简单快速,但对新词和歧义处理不足;基于统计的方法能利用语料信息,但依赖数据且计算复杂;混合分词(如jieba库)融合两者优势,在实际NLP任务中应用广泛。在实践中,需根据文本特点(如领域、新词数量 )选择合适的分词方法,或结合多种方法优化分词效果,为后续的词性标注、文本理解等任务提供准确的词语单元,推动NLP应用的深入发展。

读者可尝试构建不同领域的词典,测试jieba库在专业文本(如医疗、金融文本 )中的分词效果,对比不同分词技术在实际任务(如文本分类 )中的影响,进一步深化对中文分词技术的理解与应用。

http://www.xdnf.cn/news/14936.html

相关文章:

  • 笨方法学python-习题12
  • Disruptor架构哲学
  • 结构体实战:用Rust编写矩形面积计算器
  • MySQL 中 InnoDB 存储引擎与 MyISAM 存储引擎的区别是什么?
  • 8.Docker镜像讲解
  • 阿里巴巴 Qwen 系列大模型发展时间线与主要特性
  • 数字图像处理学习笔记
  • C#.Net筑基-优雅LINQ的查询艺术
  • 算法-每日一题(DAY12)最长和谐子序列
  • TypeScript 安装使用教程
  • 电子面单系统开发全解析
  • 深度学习进阶:自然语言处理的推荐点评
  • 杭州来未来科技 Java 实习面经
  • STM32——代码开发顺序
  • 模型部署与推理--利用python版本onnxruntime模型部署与推理
  • 【仿muduo库实现并发服务器】Acceptor模块
  • 微信小程序21~30
  • grom使用mysql快速上手
  • nginx配置websocket
  • 如何在电脑上完全抹去历史记录
  • Ubuntu 20.04 下 OpenVINO 2024 安装与配置
  • 与后端现场联调mock数据
  • 内网ubuntu系统安装mysql
  • 直播 APP 开发需要多少成本
  • SpringBoot -- 自动配置原理
  • 回写缓存为何需要脏位?
  • 【MySQL基础】MySQL索引全面解析:从原理到实践
  • Linux 系统管理:自动化运维与容器化部署
  • AI编程实战:Cursor黑科技全解析
  • uniapp小程序蓝牙打印通用版(集成二维码打印)