首页 > 其他分享 >NLP基础-准确分词(使用工具分词)

NLP基础-准确分词(使用工具分词)

时间:2023-02-06 16:35:31浏览次数:51  
标签:NLP jieba pos len result line hanlp 分词 准确


关于NLP相关包安装配置,可以参考:
​NLP工具包安装配置​​关于分词的原理可以参考:
自然语言处理NLP-隐马尔科夫)

NLP基础-准确分词(使用工具分词)_加载

1. 加载字典来保证词可以分准

对一些专业的名词来说,使用原有的词库可能无法很好的将词分开,比如在对医疗文本进行分类时,诸如:联合奥沙利铂、氟尿嘧啶单药等专用的药品名词。

jieba中自定义词典的加载

将开始没分准确的词放入字典中,就可以对其正确分词

jieba中的词典,通过json.loads进行加载:

jieba.load_userdict("dict.txt")

例:

import jieba
seg_list = jieba.cut("辅助治疗中的氟尿嘧啶单药或联合奥沙利铂,并未直接纳入TNM分期系统", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))

NLP基础-准确分词(使用工具分词)_词频_02


加载字典后:

import jieba
jieba.load_userdict("dict.txt")
seg_list = jieba.cut("辅助治疗中的氟尿嘧啶单药或联合奥沙利铂,并未直接纳入TNM分期系统", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精确模式

NLP基础-准确分词(使用工具分词)_NLP_03

hanlp中自定义词典的加载

hanlp的自定义字典的目录:E:\NLP\hanlp\data\dictionary\custom

由hanlp.properties文件可以看到,其中自定义词典的加载为:resume_nouns.txt文件

NLP基础-准确分词(使用工具分词)_准确分词_04


在改动之前,先把CustomDictionary.txt.bin的文件删除,否则加载的都是txt.bin文件

NLP基础-准确分词(使用工具分词)_NLP_05


我们可以看到hanlp的词典和jieba中词典的区别是hanlp的词典中包括词、词性、词频组成,jieba的词典中只是词。

2. 通过正则匹配的方法来将词进行分开

适用于数字等百分号的匹配,无法准确的一一加入字典准确分词的形式,则可以通过正则匹配进行准确分词:

根本原理就是使用正则表达式匹配替换后,再把正则匹配上替换的词替换为原来的词。

cut_data.py:

import jieba
import re
from tokenizer import cut_hanlp

def merge_two_list(a, b):
c=[]
len_a, len_b = len(a), len(b)
minlen = min(len_a, len_b)
for i in range(minlen):
c.append(a[i])
c.append(b[i])

if len_a > len_b:
for i in range(minlen, len_a):
c.append(a[i])
else:
for i in range(minlen, len_b):
c.append(b[i])
return c

if __name__=="__main__":
# 第一步首先打开需要分词的文件
fp=open("text.txt","r",encoding="utf8")
# 第二步创建需要保存分词后结果的文件
fout=open("result_cut.txt","w",encoding="utf8")
# 第三步使用正则进行清洗,将一些词进行处理
# 匹配出非汉字的情况,并且限制在5个字符
regex1=u'(?:[^\u4e00-\u9fa5()*&……%¥$,,。.@! !]){1,5}期'
# 这个正则用来匹配百分号的小数{1-3}表示3位,[0-9]表示10个数字
# 小数点.后打上问号,表示1个或者0个
regex2=r'(?:[0-9]{1,3}[.]?[0-9]{1,3})%'
p1=re.compile(regex1)
p2=re.compile(regex2)
# 读取每一行
for line in fp.readlines():
result1=p1.findall(line)
# 将正则匹配的词进行替换
if result1:
regex_re1=result1
line=p1.sub("FLAG1",line)
result2=p2.findall(line)
if result2:
line=p2.sub("FLAG2",line)
# 开始切完词后是迭代器类型,还需要join进行显示
words=jieba.cut(line)
words1=cut_hanlp(line)
result=" ".join(words1)
# 再把正则匹配上替换的词替换为原来的词
if "FLAG1" in result:
# 先通过split方法拆分为列表
result=result.split("FLAG1")
# 再通过merge方法将两个列表合并
result=merge_two_list(result,result1)
result ="".join(result)
if "FLAG2" in result:
result=result.split("FLAG2")
result=merge_two_list(result,result2)
result="".join(result)
fout.write(result)
fout.close()

tokenizer.py:

import os,gc,re,sys

from jpype import *

startJVM(getDefaultJVMPath(),r"-Djava.class.path=E:\NLP\hanlp\hanlp-1.5.0.jar;E:\NLP\hanlp",
"-Xms1g",
"-Xmx1g")

Tokenizer = JClass('com.hankcs.hanlp.tokenizer.StandardTokenizer')

def to_string(sentence,return_generator=False):
if return_generator:
return (word_pos_item.toString().split('/') for word_pos_item in Tokenizer.segment(sentence))
else:
return " ".join([word_pos_item.toString().split('/')[0] for word_pos_item in Tokenizer.segment(sentence)] )

def seg_sentences(sentence,with_filter=True,return_generator=False):
segs=to_string(sentence,return_generator=return_generator)
if with_filter:
g = [word_pos_pair[0] for word_pos_pair in segs if len(word_pos_pair)==2 and word_pos_pair[0]!=' ' and word_pos_pair[1] not in drop_pos_set]
else:
g = [word_pos_pair[0] for word_pos_pair in segs if len(word_pos_pair)==2 and word_pos_pair[0]!=' ']
return iter(g) if return_generator else g

def cut_hanlp(raw_sentence,return_list=True):
if len(raw_sentence.strip())>0:
return to_string(raw_sentence) if return_list else iter(to_string(raw_sentence))

3. 动态调整字典词频

有时会出现字典已经加载,但是词不一定能分得开的情况,这时就需要通过改变词频率的方法进行动态调整。

jieba中调整词频

jieba.suggest_freq('台中' , tune=True)
import jieba
jieba.load_userdict("dict.txt")
jieba.suggest_freq('台中' , tune=True)
if __name__ = "__main__":
string = "台中正确应该不会被切开"
words = jieba.cut(string,HMM=False)
result = " ".join(words)
print(result)

但在实际应用中,不可能一句话一句话进行加载,那这样就可以采用先open打开这个字典文件,再对字典文件中的词进行一一遍历,如下:

fp = open("dict.txt", 'r' , encoding = 'utf8')
for line in fp:
lline = ine.strip()
jieba.suggest_freq(line, true = True)

为了让运行更高效些,将for循环改为列表生成式:

[jieba.suggest_freq(line.strip(), tune=True) for line in open("dict.txt",'r',encoding='utf8')]

hanlp中调整词频

对于hanlp切词而言,因为hanlp的词典是同时记录单词、词性、词频数的,如果出现了相同词频数的单词,该如何进行选择切分?如:

NLP基础-准确分词(使用工具分词)_NLP_06


这里我们默认最长匹配原则,即优先对len长的进行切分,而Hanlp切词时会按照字典加载的顺序进行切词,单词如果优先加载,就会被切除。故我们需要先对词典中的词按照长度进行排序。

sort_dict_by_len.py:

import os
# 第一步先打开文件
dict_file=open(r"E:\NLP\hanlp\data\dictionary\custom"+os.sep+"resume_nouns.txt",'r',encoding='utf8')
d={}
# 第二步把单词取出,对每个词和每个长度建立一个字典
[d.update({line:len(line.split(" ")[0])}) for line in dict_file]
f=sorted(d.items(), key=lambda x:x[1], reverse=True)
dict_file=open(r"E:\NLP\hanlp\data\dictionary\custom"+os.sep+"resume_nouns1.txt",'w',encoding='utf8')
[dict_file.write(item[0]) for item in f]
dict_file.close()

再进行hanlp切词后结果如下:

from tokenizer import cut_hanlp
if __name__=="__main__":
string="台中正确应该不会被切开。"
words=cut_hanlp(string)
print(words)

NLP基础-准确分词(使用工具分词)_NLP_07


标签:NLP,jieba,pos,len,result,line,hanlp,分词,准确
From: https://blog.51cto.com/u_15955938/6039479

相关文章

  • NLP基础-词性标注应用去除停用词
    词性标注-去除停用词词性标注就是对分词后的词性进行标识,通常分词后其词性也就直接输出了,而词性标注的应用就是可以通过词性来进行过滤(去除助词停用词等),从而得到更有效的......
  • NLP基础-命名实体识别(一)基于规则
    命名实体识别命名实体识别(NamedEntityRecognition,简称NER)与自动分词,词性标注一样,命名实体识别也是自然语言处理中的一个基础任务,其目的是识别语料中的人名、地名、组织机......
  • 2023计算机领域顶会(A类)以及ACL 2023自然语言处理(NLP)研究子方向领域汇总
    2023年的计算语言学协会年会(ACL2023)共包含26个领域,代表着当前前计算语言学和自然语言处理研究的不同方面。每个领域都有一组相关联的关键字来描述其潜在的子领域,这些子领......
  • NLP之预训练语言模型GPT
    目录1引言GPT适配下游任务GPT代码例子调用huggingface的模型微调用在其他任务上1引言在自然语言处理领域中,预训练模型通常指代的是预训练语言模型。广义上的预训练语言模......
  • python 识别图片验证码/滑块验证码准确率极高的 ddddorc 库
    前言验证码的种类有很多,它是常用的一种反爬手段,包括:图片验证码,滑块验证码,等一些常见的验证码场景。识别验证码的python库有很多,用起来也并不简单,这里推荐一个简单实用的......
  • 准确判断一个变量的数据类型
    准确判断一个变量的数据类型犹豫typeof无法判断引用数据类型所以需要调用Object.prototype.toString.call上的方法/***获取变量准确类型的函数*@param{*}t......
  • 使用Pinyin4j进行拼音分词
    使用maven引入相关的jar<dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency>创建Pinyin4......
  • NLP入门1——李宏毅网课笔记
    近日因为项目需要,开始恶补预习NLP的相关知识。以前也看过两本相关书籍,但是都十分浅显。这次准备详细的学一下并记录。李宏毅老师的网课是DeepLearningforHumanLangua......
  • NLP之引言
    目录自然语言发展史第一代统计学习第二代深度学习和词向量第三代大模型预训练加微调绪论自然语言处理的难点自然语言处理任务体系任务层级任务类别研究对象与层次转到了NL......
  • 【如何提高IT运维效率】深度解读京东云基于NLP的运维日志异常检测AIOps落地实践
    作者:京东科技 张宪波、张静、李东江基于NLP技术对运维日志聚类,从日志角度快速发现线上业务问题日志在IT行业中被广泛使用,日志的异常检测对于识别系统的运行状态至关重......