赞
踩
目录
5、bidirectional_segment.py(双向最长匹配)
- # 导入pyhanlp库中的所有包
- from pyhanlp import *
-
- # 定义加载词典函数
- def load_dictionary():
- IOUtil = JClass('com.hankcs.hanlp.corpus.io.IOUtil')
- path = HanLP.Config.CoreDictionaryPath.replace('.txt', '.mini.txt')
- dic = IOUtil.loadDictionary([path])
- return set(dic.keySet())
-
- # 确保被import到其他文件时只导入前面的代码,而忽略后面的代码
- if __name__ == '__main__':
- # 加载词典
- dic = load_dictionary()
- # 输出词典中的词个数
- print(len(dic))
- # 将元组转换为列表,并输出列表中第一个单词(因此输出会有随机加载一个单词的效果)
- print(list(dic)[0])
- # 从utility.py中导入load_dictionary函数
- from utility import load_dictionary
-
- # 定义完全切分算法
- def fully_segment(text, dic):
- word_list = []
- for i in range(len(text)): # i 从 0 到text的最后一个字的下标遍历
- for j in range(i + 1, len(text) + 1): # j 遍历[i + 1, len(text)]区间
- word = text[i:j] # 取出连续区间[i, j]对应的字符串
- if word in dic: # 如果在词典中,则认为是一个词
- word_list.append(word)
- return word_list
-
- # 确保被import到其他文件时只导入前面的代码,而忽略后面的代码
- if __name__ == '__main__':
- # 加载词典
- dic = load_dictionary()
- # 进行完全分词并输出结果
- print(fully_segment('你不对劲', dic))
- print(fully_segment('中国的首都是北京', dic))
-
- # 从utility.py中导入load_dictionary函数
- from utility import load_dictionary
-
- # 定义正向最长匹配算法
- def forward_segment(text, dic):
- word_list = []
- i = 0
- while i < len(text):
- longest_word = text[i] # 当前扫描位置的单字
- for j in range(i + 1, len(text) + 1): # 所有可能的结尾
- word = text[i:j] # 从当前位置到结尾的连续字符串
- if word in dic: # 在词典中
- if len(word) > len(longest_word): # 并且更长
- longest_word = word # 则更优先输出
- word_list.append(longest_word) # 输出最长词
- i += len(longest_word) # 正向扫描
- return word_list
-
- # 确保被import到其他文件时只导入前面的代码,而忽略后面的代码
- if __name__ == '__main__':
- # 加载词典
- dic = load_dictionary()
- # 进行正向最长匹配分词并输出结果
- print(forward_segment('你不对劲', dic))
- print(forward_segment('中国的首都是北京', dic))
- # 从utility.py中导入load_dictionary函数
- from utility import load_dictionary
-
- # 定义逆向最长匹配算法
- def backward_segment(text, dic):
- word_list = []
- i = len(text) - 1
- while i >= 0: # 扫描位置作为终点
- longest_word = text[i] # 扫描位置的单字
- for j in range(0, i): # 遍历[0, i]区间作为待查询词语的起点
- word = text[j: i + 1] # 取出[j, i]区间作为待查询单词
- if word in dic:
- if len(word) > len(longest_word): # 越长优先级越高
- longest_word = word
- break
- word_list.insert(0, longest_word) # 逆向扫描,所以越先查出的单词在位置上越靠后
- i -= len(longest_word)
- return word_list
-
- # 确保被import到其他文件时只导入前面的代码,而忽略后面的代码
- if __name__ == '__main__':
- # 加载词典
- dic = load_dictionary()
- # 进行逆向最长匹配分词并输出结果
- print(backward_segment('你不对劲', dic))
- print(backward_segment('中国的首都是北京', dic))
- # 从backward_segment.py文件导入backward_segment函数
- from backward_segment import backward_segment
- # 从forward_segment.py文件导入forward_segment函数
- from forward_segment import forward_segment
- # 从utility.py中导入load_dictionary函数
- from utility import load_dictionary
-
- # 定义 统计单字成词的个数 函数
- def count_single_char(word_list: list):
- return sum(1 for word in word_list if len(word) == 1)
-
- # 定义双向最长匹配算法
- def bidirectional_segment(text, dic):
- f = forward_segment(text, dic)
- b = backward_segment(text, dic)
- if len(f) < len(b): # 词数更少优先级更高
- return f
- elif len(f) > len(b):
- return b
- else:
- if count_single_char(f) < count_single_char(b): # 单字更少优先级更高
- return f
- else:
- return b # 都相等时逆向匹配优先级更高
-
- # 确保被import到其他文件时只导入前面的代码,而忽略后面的代码
- if __name__ == '__main__':
- # 加载词典
- dic = load_dictionary()
- # 进行双向最长匹配分词并输出结果
- print(bidirectional_segment('你不对劲', dic))
- print(bidirectional_segment('中国的首都是北京', dic))
-
句子太长时,可以在字符串中某一位置键入“回车”,即可实现在编辑器中换行而在显示器中不换行的效果。
具体源代码可以查看下面“图灵社区”链接,下载资料
《自然语言处理入门》 by 何晗(@hankcs)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。