词典

词典

hanlp词典

希望	v	386	n	96	vn	25	nz	1
希特勒	nr	3
希玛	nz	1
希罕	a	1
希翼	v	1
希腊	ns	19

    词类 词频

词典加载

from pyhanlp import *
def load_dictionary():
    """
    加载HanLP中的mini词库
    :return: 一个set形式的词库
    """
    IOUtil = JClass('com.hankcs.hanlp.corpus.io.IOUtil')
    path = HanLP.Config.CoreDictionaryPath.replace('.txt', '.mini.txt')
    dic = IOUtil.loadDictionary([path])
    return set(dic.keySet())


dic = load_dictionary()
print(len(dic))
print(list(dic)[0])

----
85584
公心

切分算法

###完全切分
from pyhanlp import *

def fully_segment(text,dic):
    word_list = []
    for i in range(len(text)):			##i遍历test中从0到最后一个字
        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

dic = load_dictionary()
print(fully_segment('商品和服务',dic))

----
['商', '商品', '品', '和', '和服', '服', '服务', '务']
###正向最长

	优先输出更长的词汇,一般越长的词汇表达意义越丰富
	正向:从前往后

from pyhanlp import *

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

dic = load_dictionary()
print(forward_segment('中华人民共和国',dic))
print(forward_segment('研究自然语言处理',dic))
print(forward_segment('研究生命起源',dic))

----
['中华人民共和国']
['研究', '自然', '语言', '处理']
['研究生', '命', '起源']
###逆向最长匹配
from pyhanlp import *

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

dic = load_dictionary()

print(backward_segment('研究生命起源',dic))
print(backward_segment('项目的研究',dic))

---
['研究', '生命', '起源']
['项', '目的', '研究']
##双向最长匹配
	融合了前两个方向匹配的复杂规则集
	
	若两者返回次数不同,取次数最少的那个
	若相同,取单词数更少的那个
	否则优先返回逆向最长匹配
	
from pyhanlp import *

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
        
dic = load_dictionary()
print(bidirectional_segment('项目的研究',dic))
print(bidirectional_segment('商品和服务',dic))
print(bidirectional_segment('研究生命起源',dic))
print(bidirectional_segment('当下雨天地面积水',dic))
print(bidirectional_segment('结婚的和尚未结婚的',dic))
print(bidirectional_segment('欢迎新老师生前来就餐',dic))


----
['项', '目的', '研究']
['商品', '和', '服务']
['研究', '生命', '起源']
['当下', '雨天', '地面', '积水']
['结婚', '的', '和', '尚未', '结婚', '的']
['欢', '迎新', '老', '师生', '前来', '就餐']

###注意:
forward_segment和backward_segment是上面创建的正向最长和逆向最长匹配函数

速度测评


import time 
def evaluate_speed(segment,text,dic):
    start_time = time.time()
    for i in range(pressure):
        segment(text,dic)
    elapsed_time = time.time() - start_time
    print('%.2f 万字/秒' %(len(text)*pressure / 10000/elapsed_time))
    
text = "江西鄱阳湖干枯,中国最大淡水湖变成大草原"
pressure = 10000
dic = load_dictionary()

print('由于JPype调用开销巨大,以下速度显著慢于原生Java')
evaluate_speed(forward_segment, text, dic)
evaluate_speed(backward_segment, text, dic)
evaluate_speed(bidirectional_segment, text, dic)


-----
由于JPype调用开销巨大,以下速度显著慢于原生Java
98.99 万字/秒
94.32 万字/秒
44.14 万字/秒
posted @ 2023-04-07 22:50  idazhi  阅读(59)  评论(0编辑  收藏  举报