自然语言处理中算法设计有两大部分:分而治之 和 转化 思想。一个是将大问题简化为小问题,另一个是将问题抽象化,向向已知转化。前者的例子:归并排序;后者的例子:判断相邻元素是否相同(与排序)。
这次总结的自然语言中常用的一些基本算法,算是入个门了。
递归
使用递归速度上会受影响,但是便于理解算法深层嵌套对象。而一些函数式编程语言会将尾递归优化为迭代。
如果要计算n个词有多少种组合方式?按照阶乘定义:n! = n*(n-1)*…*1
def func(wordlist):
length = len(wordlist)
if length==1:
return 1
else:
return func(wordlist[1:])*length
如果要寻找word下位词的大小,并且将他们加和。
from nltk.corpus import wordnet as wn
def func(s):#s是WordNet里面的对象
return 1+sum(func(child) for child in s.hyponyms())
dog = wn.synset('dog.n.01')
print(func(dog))
构建一个字母查找树
建立一个嵌套的字典结构,每一级的嵌套包含既定前缀的所有单词。而子查找树含有所有可能的后续词。
def WordTree(trie,key,value):
if key:
first , rest = key[0],key[1:]
if first not in trie:
trie[first] = {}
WordTree(trie[first],rest,value)
else:
trie['value'] = value
WordDict = {}
WordTree(WordDict,'cat','cat')
WordTree(WordDict,'dog','dog')
print(WordDict)
贪婪算法:不确定边界自然语言的分割问题(退火算法的非确定性搜索)
爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。
import nltk
from random import randint
#text = 'doyou'
#segs = '01000'
def segment(text,segs):#根据segs,返回切割好的词链表
words = []
last = 0
for i in range(len(segs)):
if segs[i]=='