pyhanlp词典分词

目录

1、utility.py(加载词典)

2、fully_segment.py(完全切分)

3、forward_segment.py(正向最长匹配)

4、backward_segment.py(逆向最长匹配)

5、bidirectional_segment.py(双向最长匹配)

备注

参考文献


1、utility.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])

2、fully_segment.py(完全切分)

# 从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))

3、forward_segment.py(正向最长匹配)

# 从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))

4、backward_segment.py(逆向最长匹配)

# 从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))

5、bidirectional_segment.py(双向最长匹配)

# 从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)

posted @ 2022-05-28 00:13  tiansz  阅读(66)  评论(0编辑  收藏  举报