在现实生活中, 你有没有对一段文字特别不理解呢? 通常我们的做法即使拆封, 如果实在不行, 新华字典, 词典全部上场, 哈哈, 对了, 我们已经不是上学了, 处于互联网高速发展的=当下, 百度一下, 谷歌一下, 这点事还能难得倒谁?
可还是你有没有想过, 网络的如此便利, 也是需要人去进行呵护, 精心设计的, 本文小编将给大家介绍一下对于文本类, 计算机是如何理解的.
在文本处理的流程当中分词是一项表重要的流程, 我们先看一个简单的例子, 来直观感受一下分词到底能干啥
>>> import jieba
>>> seg_list=jieba.cut("陕西汉中人计算机学院欢迎您",cut_all=False)
>>> seg_list
<generator object Tokenizer.cut at 0x10f56fcd0>
>>> "/".join(seg_list)
'陕西/汉中/人民/计算机/学院/欢迎您'
>>> jieba.add_word("计算机学院")
>>> seg_list=jieba.cut("陕西汉中人民计算机学院欢迎您",cut_all=False)
>>> "/".join(seg_list)
'陕西/汉中/人民/计算机学院/欢迎您'
上,看这个例子很简单, 但是它足以告诉你分词分成撒样了.
看到上面的例子, 好奇的你的是否也想一展身手, 自己玩玩分词怎么制作. 其实他并没有什么技术含量, 而且看完后或许并不会感到方法有什么独特之处. 在这篇文章中我将介绍前向最大匹配和后项最大匹配
什么是前向最大匹配
前向最大匹配(forward- max matching)先设定扫描的窗口大小maxLen(最好是字典最长的单词长度),从左向右取待切分汉语句的maxLen个字符作为匹配字段。查找词典并进行匹配。若匹配成功,则将这个匹配字段作为一个词切分出来,并将窗口向右移动这个单词的长度。若匹配不成功,则将这个匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词为止。
我们先举一个中文例子:微信公众号码龙社传播视觉和自然语言技术. 那么我们进行手工抽取词典,
词典:[“微信”,“公众号”,“码龙社”,“传播”,“视觉”,“自然”,“语言”,“技术”]
加入我们吧最大距离设置为Max_len=5, 那么所有的情况如下:
[微信公众号|码龙社传播视觉和自然语言技术]
[微信公众]
[微信公]
[微信]--> 那么第一个词<微信>就选出来了, 然后我没重复上面步骤
[公众号码龙|社传播视觉和自然语言技术]
[公众号]--〉那么第二个词语<公众号>存在于我们的词典当中, 于是选出来
[码龙社传播|视觉和自然语言技术]
[码龙社传播]
[码龙社传]
[码龙社]-->那么第三个词语<码龙社>存在于我们的词典当中, 于是选出来
......
dict_word = ['微信', '公众号', '码龙社', '传播', '视觉,', '和', '自然语言', '技术']
text = "微信公众号码龙社传播视觉和自然语言技术"
window_size=5
def left_cut(text,dict_word):
result = []
index = 0
text_length = len(text)
while text_length > index:
for size in range(window_size+index,index,-1):
piece = text[index:size]
if piece in dict_word:
index = size -1
break
index = index +1
result.append(piece)
return result
写到这里会许你已经完全知道怎么写后向最大匹配了吧, 但是我还是想在写一下
后向最大匹配(backward- max matching)
该算法是正向的逆向算法,区别是窗口是从后向左扫描,若匹配不成功,则去掉第一个字符,重复上述的匹配步骤。
我们还是用上一个中文例子:微信公众号码龙社传播视觉和自然语言技术. 那么我们进行手工抽取词典,
词典:[“微信”,“公众号”,“码龙社”,“传播”,“视觉”,“自然”,“语言”,“技术”]
加入我们吧最大距离设置为Max_len=5, 那么所有的情况如下:
[微信公众号码龙社传播视觉和自|然语言技术]
[然语言技术]
[语言技术]
[言技术]
[技术] -->那么第一个词语<技术>存在于我们的词典当中, 于是选出来
后续我就不一一列举了
def right_cut(text,dict_word):
result = []
index = len(text)
while index>0:
for size in range(index-window_size,index):
piece = text[size:index]
if piece in dict_word:
index = size +1
break
index = index -1
result.append(piece)
result.reverse()
return result
好了这就是完整的前后西安切词, 但是对于一些有歧义的词语, 并不能很好的解决, 还好可以利用双向进行切词, 大致代码如下:
def central_cut(left_result, right_result):
if len(left_result) == len(right_result):
if right_result == left_result:
res = right_result
else:
temp_right = []
for i in right_result:
if len(i) == 1:
temp_right.append(i)
temp_left = []
for j in left_result:
if len(j) == 1:
temp_left.append(i)
res = [
right_result
if len(temp_right) < len(temp_left) else left_result
]
else:
res = [
right_result
if len(right_result) < len(left_result) else left_result
]
return res
感兴趣的朋友可以可以在这里看到完整代码, 你当然也可以加入我的team, 第一时间看到我分享的各种案例
https://github.com/DragonYong/Jun--Dragon/blob/master/cut_word_left_right_central.ipynb
当然了,随着技术的发展, 这种切词的技术已经远远不能满足人们的日常需求, 而且他的算法复杂度不是很好的运行觉果, 于是人们开始寻找更加好的算法来解决问题.
好了, 这就是本文介绍的基于前后向匹配,亦所谓的贪心思想来完成的. 下一期, 我将介绍更加好用的维特比算法来决绝这种带有切词歧义的情况.
让我们一起分享,共同成长,分享使我们在编程路上并不孤独。快来扫描二维码,与博主一起快乐学习吧!
网友评论