Closed BLKSerene closed 6 years ago
由于网络文本不规范,很多人一逗到底,所以默认拆到最细。看以先用com.hankcs.hanlp.utility.SentencesUtil#toSentenceList(java.lang.String, boolean)
拆分句子,后执行分词。
感谢反馈,已经修复,请参考上面的commit。 如果还有问题,欢迎重开issue。
我发现在python版本中无法调用enableIndexMode这个方法,提示RuntimeError: Ambiguous overloads found: (Lcom/hankcs/hanlp/seg/Viterbi/ViterbiSegment;I) vs (Lcom/hankcs/hanlp/seg/Viterbi/ViterbiSegment;Z) at native/common/jp_method.cpp:117,我看了你们的源码,在java代码中有两个enableIndexMode方法,这里后期可以解决吗?
@main1015 你好!我用pyhanlp中enableIndexMode遇到了同样的问题,请教如何解决?
这里,空格也会使其对句子进行拆分。举例如下:
原文
聚合集群
聚合集群用于不同配置的集群之间的故障切换,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时 0.1s 的集群到连接超时 1s 的集群等。聚合集群通过在 配置 中引用它们的名称松散地耦合多个集群。降级优先级由 集群列表 中的排序隐式定义。
聚合集群使用分层负载均衡。负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。
hanlp 代码
import jpype
import pyhanlp
standard_tokenizer = jpype.JClass('com.hankcs.hanlp.tokenizer.StandardTokenizer')
paragraph = '''聚合集群
聚合集群用于不同配置的集群之间的故障切换,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时 0.1s 的集群到连接超时 1s 的集群等。聚合集群通过在 配置 中引用它们的名称松散地耦合多个集群。降级优先级由 集群列表 中的排序隐式定义。
聚合集群使用分层负载均衡。负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。'''
for sentence in standard_tokenizer.seg2sentence(paragraph, False):
print(sentence)
hanlp 分解后的结果
[聚合/vi, 集群/nz]
[聚合/vi, 集群/nz, 用于/v, 不同/a, 配置/vn, 的/ude1, 集群/nz, 之间/f, 的/ude1, 故障/n, 切换/vn, ,/w]
[例如/v, ,/w]
[从/p, EDS/nx, 上游/f, 集群/nz, 到/v, STRICT_DNS/nx, 上游/f, 集群/nz, ,/w]
[从/p, 使用/v, ROUND_ROBIN/nx, 负载/n, 均衡/a, 策略/n, 的/ude1, 集群/nz, 到/v, 使用/v]
[MAGLEV/nx]
[的/ude1, 集群/nz, ,/w]
[从/p, 连接/v, 超时/v]
[0.1/m, s/nx]
[的/ude1, 集群/nz, 到/v, 连接/v, 超时/v]
[1/m, s/nx]
[的/ude1, 集群/nz, 等/udeng, 。/w]
[聚合/vi, 集群/nz, 通过/p, 在/p, 配置/vn, 中/f, 引用/v, 它们/rr, 的/ude1, 名称/n, 松散地/n, 耦合/vn, 多/a, 个/q, 集群/nz, 。/w]
[降级/vi, 优先级/n, 由/p]
[集群/nz, 列表/vi]
[中的/v, 排序/vi, 隐/v, 式/k, 定义/n, 。/w]
[聚合/vi, 集群/nz, 使用/v, 分层/v, 负载/n, 均衡/a, 。/w]
[负载/n, 均衡器/gi, 首先/d, 选择/v, 集群/nz, 和/cc, 优先级/n, ,/w]
[然后/c, 将/d, 负载/n, 均衡/a, 委托/vn, 给/p, 所选/v, 集群/nz, 的/ude1, 负载/n, 均衡器/gi, 。/w]
[顶层/f, 负载/n, 均衡器/gi, 通过/p, 将/d, 多/a, 个/q, 集群/nz, 的/ude1, 优先级/n, 集/q, 线性/n, 化为/v, 一个/mq, 集群/nz, ,/w]
[重用/v, 现有/v, 的/ude1, 负载/n, 均衡/a, 算法/n, 。/w]
stanza 代码
import stanza
# stanza.download('zh') # This downloads the English models for the neural pipeline
nlp = stanza.Pipeline('zh', use_gpu=False) # This sets up a default neural pipeline in English
paragraph = '''聚合集群
聚合集群用于不同配置的集群之间的故障切换,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时 0.1s 的集群到连接超时 1s 的集群等。聚合集群通过在 配置 中引用它们的名称松散地耦合多个集群。降级优先级由 集群列表 中的排序隐式定义。
聚合集群使用分层负载均衡。负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。'''
doc = nlp(paragraph)
for s in doc.sentences:
print('sentence', s.text)
stanza 结果
sentence 聚合集群
聚合集群用于不同配置的集群之间的故障切换,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时 0.1s 的集群到连接超时 1s 的集群等。
sentence 聚合集群通过在 配置 中引用它们的名称松散地耦合多个集群。
sentence 降级优先级由 集群列表 中的排序隐式定义。
sentence 聚合集群使用分层负载均衡。
sentence 负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。
sentence 顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。
建议使用2.x的各种API: RESTful:https://hanlp.hankcs.com/docs/api/restful.html#hanlp_restful.HanLPClient.tokenize 本地模型:https://github.com/hankcs/HanLP/blob/master/plugins/hanlp_demo/hanlp_demo/sent_split.py 本地规则:https://github.com/hankcs/HanLP/blob/master/hanlp/utils/rules.py#L19
针对中文做了很多优化,应该比stanza要好。
注意事项
请确认下列注意事项:
版本号
当前最新版本号是:1.6.8 我使用的版本是:1.6.8
我的问题
这个问题 Issue 876 里提到过 但是被关闭了 目前 StandardTokenizer, BasicTokenizer, NLPTokenizer, SpeedTokenizer 提供的 seg2sentence 分句接口(其他分词器比如 TraditionalChineseTokenizer, URLTokenizer, CRFLexicalAnalyzer, PerceptronLexicalAnalyzer, DijkstraSegment, NShortSegment, ViterbiSegment 我大致看了下没找到分句的接口 不知道是不是一样的表现)会把逗号也切分为一句话 不知这个功能是否是为了后期其他文本处理的考虑才这样切分的?
如果是用于生产环境的分句的话 感觉逗号肯定不能切成一句 按照最新的国家标准: 中华人民共和国国家标准GB/T15834-2011标点符号用法 3.1.1 一节中所述 只有句号 问号 叹号 这三个标点符号才算一句话 所以严格来说 分号也不能算
触发代码
因为我不会 Java 只会 Python 所以用的 pyhanlp 就用 StandardTokenizer 举个例子 其他分词器的结果类似
期望输出
实际输出