Python自然语言处理—分割

分割其实包含了分词、断句等等,分词对于中文文本是十分重要的。本章我也只关注分词,当然本章最后介绍的分词方法过去简单,仅供参考。

1. 分割, 按照01组成的序列对字符串进行拆分

def segment(text, segs):  # 利用01数据将 str切分开

      words = []

      last = 0

      for i in range(len(segs)):  # 循环找到1所在的位置

          if segs[i] == '1':

              words.append(text[last:i+1])  # 把两个1之间的字母放一起

              last = i+1

      words.append(text[last:])

      return words

text = "doyouseethekittyseethedoggydoyoulikethekittylikethedoggy"

seg1 = "0000000000000001000000000010000000000000000100000000000"

segment(text, seg1)

结果如下 ['doyouseethekitty', 'seethedoggy', 'doyoulikethekitty', 'likethedoggy']

2. 评价,分词既不能分的过细又不能太粗

def evaluate(text, segs):  # 评价切分的好坏

      words = segment(text, segs)

      text_size = len(words)  # 切出的词有多少个,保证分词不会太细

      lexicon_size = len(' '.join(list(set(words))))  # 切出非重复词的长度,注意这里是长度不是个数,保证切出的词不会太粗,文章前后能切出相同的词

      return text_size + lexicon_size  # 数值越小越好,简单理解就是一篇文章被切出的词应该前后统一,但是词又不能切的太细。
  
text = "doyouseethekittyseethedoggydoyoulikethekittylikethedoggy"

seg1 = "0000000000000001000000000010000000000000000100000000000"
evaluate(text, seg1)

结果是63

3. 寻找最优分词方法

本方法真的是随机试出来的,程序跑n次能有m种分词结果。可以发现核心内容就是根据当前温度n 随机在01序列上互换n个位置的01,然后评价本次随机改动是不是比现有最好的分词方法要好。



from random import randint

def anneal(text, segs, iterations, cooling_rate):

  temperature = float(len(segs))

  while temperature > 0.5:  # 退火算法,程序随着运行温度原来越低,低到0.5以下就结束循环

      best_segs, best = segs, evaluate(text, segs)  # 先存一个暂时最优分词结果

      for i in range(iterations):  # 开始循环

          guess = flip_n(segs, int(round(temperature)))  # 利用随机算法猜测一个分词方法,真的是猜,完全的随机的猜。请注意每一次猜测的变动原来越小。

          score = evaluate(text, guess)  # 评估以下猜测结果

          if score < best:  # 如果猜的比暂时最优的要好,保存本次结果

              best, best_segs = score, guess

      score, segs = best, best_segs

      temperature = temperature / cooling_rate  # 退火的速度

      print (evaluate(text, segs), segment(text, segs))  #打印最优结果

  return segs


def flip_n(segs, n):  # segs上随机选n个位置进行01互换,n会随着热度

  for i in range(n):

      segs = flip(segs, randint(0,len(segs)-1))

  return segs

def flip(segs, pos):  # 将segs的某一个位置上的01互换

  return segs[:pos] + str(1-int(segs[pos])) + segs[pos+1:]


text = "doyouseethekittyseethedoggydoyoulikethekittylikethedoggy"
seg1 = "0000000000000001000000000010000000000000000100000000000"
anneal(text, seg1, 5000, 1.2)

结果如下,结果是随机的。后面我会专门整理几个中文分词的方法,供大家参考。

猜你喜欢

转载自blog.csdn.net/m0_38126215/article/details/84023643