python实现分词(普通&维特比算法)

普通方法

思路:

读入词典中的词,每个词对应一个概率;
读入句子,得到所有可能的句子的划分,返回unigram得分最大的一个分割;

其中得到所有可能的分割采用递归的方法,当前词在词典中,就继续递归划分后半段;

概率原理:P(x1,x2,x3,xn)=P(x1)* P(x2)*…*P(xn)
可以转化成-log的加法,返回最小值

代码:

#切割代码
def seg_all(string):
#     string:读入的待分割的句子,递归进行
    def to_seg(string,start,seg):
    #  start是子字符串开始下标 seg是string已经切割部分
        if start >= len(string):
            segments.append(list(seg))
            print("segments_all",segments_all)
            return True
            # 遍历当前位置所有可能的切割
        for i in range(start+1,len(string)
维特比算法是一种用于概率和统计模型中的序列标注的算法。在自然语言处理领域,维特比算法常用于分词、词性标注等任务。 在Python中,我们可以使用NLTK(Natural Language Toolkit)中的维特比算法来进行中文分词。具体步骤如下: 1. 首先,需要从NLTK库中导入维特比器(Viterbi)和ProbDistI(概率分布接口)两个类: ``` from nltk.probability import ProbDistI from nltk.tag import viterbi ``` 2. 然后,我们需要定义一个概率分布类,用于计算各个状态的概率。这里我们可以使用词频统计,定义一个函数实现: ``` class SimpleGoodTuringProbDist(ProbDistI): def __init__(self, freqdist, bins=None): if not bins: bins = freqdist.B() + 1 self._freqdist = freqdist self._bins = bins self._p1 = freqdist.freq(1) self._N = freqdist.N() self._Z = self._Z() def _Z(self): Z = 0.0 for r in range(1, self._bins): Nr = self._freqdist.freq(r) Nrr = self._freqdist.freq(r+1) if Nrr: Z += (r+1) * Nrr * Nr / self._N return Z def prob(self, sample): return self._prob(sample)*self._Z def _prob(self, sample): if self._freqdist[sample]: return (self._freqdist[sample]+1) / (self._N+self._bins*self._p1) else: return self._p1 / (self._N+self._bins*self._p1) ``` 3. 接着,我们需要将中文文本转换成概率分布形式。这里我们可以使用nltk里的FreqDist函数,把每个词语的出现次数当成概率分布的数值,计算各个状态的概率: ``` import jieba import re from collections import defaultdict from nltk.probability import FreqDist def jieba_seg(text): words = jieba.cut(text) words = list(words) words = filter(lambda x: not re.match('\s', x), words) words = filter(lambda x: not re.match('\d', x), words) return list(words) text = "今天天气真好,我想出去玩。" words = jieba_seg(text) fd = FreqDist(words) pdist = SimpleGoodTuringProbDist(fd) ``` 4. 最后,我们可以用viterbi函数计算出最大概率分割路径,从而得到分词结果: ``` cut, tags = viterbi(words, pdist) seg_text = ''.join([cut[i] + '/' for i in range(len(cut))])[:-1] print(seg_text) ``` 使用维特比算法进行中文分词,需要注意词语出现次数分布对结果的影响,越常出现的词语其状态概率越高,需要使用正确的概率分布函数进行概率计算,这里我们使用的是SimpleGoodTuringProbDist,可以根据具体情况选择其他的概率分布函数。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值