自定义中文分词

本文介绍了中文分词的常见方法,包括基于规则的分词如正向匹配、逆向匹配和双向匹配,以及基于统计的分词,如一元和二元语言模型,还提到了序列模型分词中的HMM和CRF应用。

分词

常用的分词方法有:

  • 基于规则的分词:正向匹配、逆向匹配、双向匹配
  • 基于统计的分词:基于语言模型、基于序列模型
  • 混合分词:综合多种分词

基于规则的分词

基于规则的分词是通过维护字典的方法,在切分语句时将语句中的字符与词典进行逐一匹配去划分词语,是一种比较机械的分词方式

my_dict = ["江大桥", "研究", "生命科学", "南京市", "研究生", "大桥", "科学", "课题", "南京市长", "生命", "长江大桥", "南京", "市长"]
max_length = max([len(word) for word in my_dict])

前向匹配 MM (maximum match)

def word_cut_mm(sentence):
    """正向匹配"""

    sentence = sentence.strip()
    word_length = len(sentence)
    cut_word_list = []
    while word_length > 0:
        max_cut_length = min(max_length, word_length)
        sub_sentence = sentence[:max_cut_length]
        while max_cut_length > 0:
            if sub_sentence in my_dict or max_cut_length == 1:
                cut_word_list.append(sub_sentence)
                break
            else:
                max_cut_length = max_cut_length - 1
                sub_sentence = sentence[:max_cut_length]
        word_length = word_length - max_cut_length
        sentence = sentence[max_cut_length:]
    return cut_word_list

word = word_cut_mm("南京市长江大桥研究生课题是研究生命科学")
print(word)
# 输出:['南京市长', '江大桥', '研究生', '课题', '是', '研究生', '命', '科学']

后向匹配 RMM (reverse maximum match)

def word_cut_rmm(sentence):
    """逆向最大匹配"""
    cut_word_list = []
    sen_length = len(sentence)
    while sen_length > 0:
        for max_cut_length in range(max_length, 0, -1):
            if sen_length - max_cut_length < 0: continue
            sub_sentence = sentence[(sen_length - max_cut_length):sen_length]
            if sub_sentence in my_dict:
                cut_word_list.append(sub_sentence)
                sen_length -= max_cut_length
                break
            if max_cut_length == 1:
                cut_word_list.append(sub_sentence)
                sen_length -= 1
    return cut_word_list[::-1]    

word = word_cut_rmm("南京市长江大桥研究生课题是研究生命科学")
print(word)
# 输出:['南京市', '长江大桥', '研究生', '课题', '是', '研究', '生命科学']

双向匹配(bi-direction matching )

双向匹配是综合正了向匹配和逆向匹配

  • 如果正向匹配和逆向匹配分词结果不同,则返回词数较少的那个
  • 如果正向匹配和逆向匹配分词词数相同,则返回单字数量较少的那个

基于统计的分词

统计分词是以字为最小单位,相连的字在不同文本中出现的词次越多,说明成词的可能性越大。统计语料中相邻的各个字组合出现的频率,来确定此组字构成词的可靠度。

语言模型分词

  • 输入是一段文本:C=C1,C2,……,Cn
  • 输出是词串:S=W1,W2,……,Wm (其中m<=n)

一段文本通常有多种分隔方式 如:

C:结婚的和尚未结婚
S1:结婚/的/和尚/未/结婚
S2:结婚/的/和/尚未/结婚

求输入C的最大概率切分路径argmax P(S|C)(即要求的S1,S2…Sk的最大值。求最大概率也是求最佳路径的问题,一般采用的是动态规划求最佳路径)

根据贝叶斯公式P(S|C)=P(C|S)*P(S)/P©,则

P(S1|C)=P(C|S1)*P(S1)/P(C)
P(S2|C)=P(C|S2)*P(S2)/P(C)

对于P(S1|C)和P(S2|C)来说,P©是该句子在语料库中出现的概率,是一个定值;P(C|S1)和P(C|S2)为已知切分为S1、S2的情况下句子为C的概率也是定值,为1

因此比较P(S1|C)和P(S2|C)的大小就是比较P(S1)和P(S2)的大小

P(S1|C) = P(S1) =P(W1,W2...Wm1)
P(S2|C) = P(S2) =P(W1,W2...Wm2)
对于一元语言模型:
P(W1,W2...Wm1)≈P(W1).P(W2)...P(Wm1)
在W1,W2...Wm1中,如果某个词不存在,则其概率为零就导致相乘后所有的乘积都为零,一次一般会做 add-one Smoothing操作
W1,W2...Wm1都是大于0小于1的数,当序列比较长时,相乘后可能向下溢出变为0,因此一般会取单调递增 log函数

于是可得:

P(S1) = P(W1,W2...Wm1) = P(W1).P(W2)...P(Wm1)
P(Wi)=Wi在语料库出现的词数/词库中的总数
logP(Wi) = log(Wi在语料库出现的次数/词库中的总词数) = log(Wi在语料库出现的次数)-log(词库中的总词数)=log(freq Wi) - logN
P(S1) = P(W1).P(W2)...P(Wm1)∝logP(W1)+logP(W2)+...+logP(Wm) 
	  = (log(freq W1) - logN).(log(freq W2) - logN)...(log(freq Wm1) - logN)

同理可以求出S2,比较S1和S2的大小,最终获得分词效果

对于二元语言模型

P(W1,W2…Wm1)≈P(W1).P(W2|W1).P(W3|W2)…P(Wm1|Wm-1)∝logP(W1)+logP(W2|W1)+logP(W3|W2)+…+logP(Wm|wM-1)

根据条件概率公式:
P(Wm1|Wm-1) = P(Wm1,Wm-1)/P(Wm-1)
根据大数定律:
P(Wm1,Wm-1) = count(Wm1,Wm-1)/count(*)
P(Wm-1) = count(Wm-1)/count(*) 
于是可得:
P(Wm1|Wm-1) = P(Wm1,Wm-1)/P(Wm-1) =  count(Wm1,Wm-1)/count(Wm-1)
logP(Wm1|Wm-1) = logP(Wm1|Wm-1)= log(count(Wm1,Wm-1)/count(Wm-1)) = log(count(Wm1,Wm-1)) - log(count(Wm-1))

把logP(Wm1|Wm-1)代入logP(W1)+logP(W2|W1)+logP(W3|W2)+…+logP(Wm|wM-1)即可求出S1的概率值

序列模型分词

把分词转换为对句子序列中每个字的标注,根据标注对文本进行分词,最常用的就是HMM和CRF

B:标注要么是一个词的开始
M:一个词的中间位置
E:一个词的结束位置
S:单个字的词


π是初始状态概率向量
A隐含状态转移概率矩阵
B发射概率矩阵
所有的状态序列集合:S = {S1,S2,...,Sn}
所有的观测序列集合:O = {O1,O2,...,Om}
长度为t的状态序列I:I = {i1,i2,...,it}
I对应的观测序列Q:Q = {q1,q2,...,qt}

在模型训练阶段,已知观测序列O={O1,O2,…,Om},使用Baum-Welch算法估计模型λ=πAB的参数(或通过统计的方法获得参数π、A、B),使得P(O|λ)的概率最大

在预测阶段,已知观测序列并利用训练阶段求的的参数λ=πAB,使用Viterbi求给定观测序列条件概率P(I|λO)最大状态序列I

### Elasticsearch 中文分词自定义配置 #### 安装 IK 分词器 为了更好地支持中文分词,通常会选择安装 `IK` 分词器。该分词器能够更精确地解析中文文本。 对于特定版本的 Elasticsearch (例如 7.8.0),可以从官方 GitHub 发布页面下载对应版本的 IK 插件包[^2]: ```bash wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip ``` 解压文件并将插件放置到 Elasticsearch 的 plugins 文件夹下,重启服务使新加载的组件生效。 #### 创建自定义 Analyzer 创建一个新的索引时可以指定使用 IK 分词器作为默认或自定义分析链的一部分。下面展示了一个 JSON 请求体的例子用于设置名为 "my_index" 的索引及其关联的映射结构[^3]: ```json PUT /my_index { "settings": { "analysis": { "analyzer": { "custom_ik_analyzer": { "type": "custom", "tokenizer": "ik_max_word", "filter": ["lowercase"] } } } }, "mappings": { "_doc": { "properties": { "content": { "type": "text", "analyzer": "custom_ik_analyzer" } } } } } ``` 此配置中,“custom_ik_analyzer” 是基于 “ik_max_word” 进行最大粒度切分,并应用了大小写转换过滤器以增强查询灵活性[^4]。 #### 测试分词效果 通过 `_analyze` API 可以即时查看某个字符串经过所选分词器后的实际分割情况: ```json POST my_index/_analyze { "analyzer": "custom_ik_analyzer", "text": "这是一个测试例子" } ``` 上述命令会返回由“custom_ik_analyzer” 处理过的词条列表,帮助确认分词逻辑是否符合预期。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值