【语言处理与Python】3.8分割
分词是一个更普遍的分割问题的一个实例。在这里我们还会看到分割问题的另外两个实例2.
断句
#NLTK的Punkt句子分割器 sent_tokenizer=nltk.data.load(‘tokenizers/punkt/english.pickle’) text=nltk.corpus.gutenberg.raw(‘chesterton-thursday.txt’) sents=sent_tokenizer.tokenize(text) #注意:断句其实是困难的,因为在一些缩写里面也包括标记句子结束的句号。(6.2中还有一种断句方法)
分词
比如,会遇到这样的例子:
a. doyouseethekitty
b.seethedoggy
c.doyoulikethekitty
D.likethedoggy
我们可以给每个字符标注一个布尔值来指示这个字符后面是否有一个分词标识。
为了解决这个问题,请看下面的例子:
>>>text = "doyouseethekittyseethedoggydoyoulikethekittylikethedoggy" >>>seg1= "0000000000000001000000000010000000000000000100000000000" >>>seg2= "0100100100100001001001000010100100010010000100010010000"
看看我们如何通过下面这个函数,根据01来达到分割的作用的:
def segment(text,segs): words=[] last=0 for i in range(len(segs)): if segs[i]==’1’: words.append(text[last:i+1]) last=i+1 words.append(text[last:]) return words
让我们看看,这个函数运行的效果:
>>>segment(text, seg1) ['doyouseethekitty', 'seethedoggy', 'doyoulikethekitty', 'likethedoggy'] >>>segment(text, seg2) ['do', 'you', 'see', 'the', 'kitty', 'see', 'the', 'doggy', 'do', 'you', 'like', 'the', kitty', 'like', 'the', 'doggy']
到这里看出来了,如果有这样一个序列,那么我们就可以达到分词的效果。所以现在面临的问题就是如何生成一个序列。
对此,我们可以定义一个目标函数,这个目标函数可以用来打分。这个分值决定了这个分词结果的好坏程度。
具体的算法如图:
这个函数是这样工作的:
1、给定一个假设的源文本的分词序列
2、根据这个序列推导出一个词典和推导表
3、然后合计每个词项(包括边界标志)与推导表的字符数
4、最后相加,得到得分值(这个值越小越好)
def evaluate(text, segs): words= segment(text, segs) text_size = len(words) lexicon_size = len(' '.join(list(set(words)))) return text_size + lexicon_size
最终,如何从一个整串最终划分为分词,由模拟退火算法来完成。主要思想是随机的扰动0和1的值,到达一定程度的时候,就停止运算,得到最终结果。对于此算法的其他详细的讲解,可以自行搜索相关资料。
关于退火模拟算法的网址:
http://www.cnblogs.com/createMoMo/archive/2013/05/14/3078296.html