Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seg2sentence() 把逗号和分号也分割为一句话 #1018

Closed
1 task done
BLKSerene opened this issue Nov 10, 2018 · 6 comments
Closed
1 task done

seg2sentence() 把逗号和分号也分割为一句话 #1018

BLKSerene opened this issue Nov 10, 2018 · 6 comments

Comments

@BLKSerene
Copy link

BLKSerene commented Nov 10, 2018

注意事项

请确认下列注意事项:

  • 我已仔细阅读下列文档,都没有找到答案:
  • 我已经通过Googleissue区检索功能搜索了我的问题,也没有找到答案。
  • 我明白开源社区是出于兴趣爱好聚集起来的自由社区,不承担任何责任或义务。我会礼貌发言,向每一个帮助我的人表示感谢。
  • 我在此括号内输入x打钩,代表上述事项确认完毕。

版本号

当前最新版本号是: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 举个例子 其他分词器的结果类似

import jpype
import pyhanlp

standard_tokenizer = jpype.JClass('com.hankcs.hanlp.tokenizer.StandardTokenizer')

for sentence in standard_tokenizer.seg2sentence('这是一句用来测试的句子,中间有个逗号。'): 
    print(sentence)

期望输出

[这/rzv, 是/vshi, 一/m, 句/q, 用来/v, 测试/vn, 的/ude1, 句子/n, ,/w, 中间/f, 有/vyou, 个/q, 逗号/n, 。/w]

实际输出

[这/rzv, 是/vshi, 一/m, 句/q, 用来/v, 测试/vn, 的/ude1, 句子/n, ,/w]
[中间/f, 有/vyou, 个/q, 逗号/n, 。/w]
@BLKSerene BLKSerene changed the title seg2sentence 逗号 分号也分割一句话 seg2sentence() 把逗号和分号也分割为一句话 Nov 10, 2018
@hankcs
Copy link
Owner

hankcs commented Nov 10, 2018

由于网络文本不规范,很多人一逗到底,所以默认拆到最细。看以先用com.hankcs.hanlp.utility.SentencesUtil#toSentenceList(java.lang.String, boolean)拆分句子,后执行分词。

@hankcs
Copy link
Owner

hankcs commented Nov 10, 2018

感谢反馈,已经修复,请参考上面的commit。
如果还有问题,欢迎重开issue。

@main1015
Copy link

我发现在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方法,这里后期可以解决吗?

@lfzhagn
Copy link

lfzhagn commented Apr 16, 2019

@main1015 你好!我用pyhanlp中enableIndexMode遇到了同样的问题,请教如何解决?

@LuoRongLuoRong
Copy link

LuoRongLuoRong commented Jan 6, 2022

这里,空格也会使其对句子进行拆分。举例如下:

原文

聚合集群
聚合集群用于不同配置的集群之间的故障切换,例如,从 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 顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。

@hankcs
Copy link
Owner

hankcs commented Jan 6, 2022

建议使用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要好。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants