Skip to main content

sentence cutting tool CHINESE ONLY

Project description

sentence-spliter

[toc]

1. 介绍

sentence-spliter 句子切分工具,将一个长的句子,切分为短句的 List 。支持自然切分,最长句切分,最短句合并。

目前支持语言:中文

2. 项目结构

├── README.md
├── automata             	# 存放切句的基本单元   ├── abc.py           	# 定义状态机与图的基本单元   ├── condition.py		 	# 切句条件   ├── operation.py     	# 切句操作   ├── sequence.py			 	# 封装状态传递的数据   ├── state_machine.py  # 状态机   └── symbols.py        # 保存标点符号
└── sentence_spliter
    ├── logic_graph.py    # 逻辑图
    └── spliter.py				# 主要函数,调用切句

3. Setup

PYPI 安装

pip install sentence_spliter

本地安装

git clone git@git.yy.com:aimodel/nlp/sentence-spliter.git
cd sentence-spliter
python setup.py install

4. Demo

4.1. Simple Demo

from sentence_spliter import spliter

paragraph = "在很久很久以前......。。... 有座山,山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。"
result =  spliter.cut_to_sentences(paragraph)
print(result)

# outputs
['在很久很久以前......。。...', ' 有座山,山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。']

切句支持以整片文章为输入。

如果输入太长,终端会自动显示百分比process cutting 87.5%

4.2. Demo in detail

切句工具默认有三种逻辑

4.2.1. 简单切句

from sentence_spliter.logic_graph import simple_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence

# -- 初始化 状态机器 -- #
cuter = StateMachine(simple_cuter())

# -- 处理句子 -- #
paragraph = "在很久很久以前1.2.3......。。... 有座山。山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。www.baidu.com"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)

# outputs
['在很久很久以前1.2.3......。。...', ' 有座山。', '山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。', 'www.baidu.com']

基本逻辑:

  • 遇到断句标点(。?!)准备切句:
    • 如果短句标点出现在引号括号书名号不执行切句
    • 其他情况下执行切句

4.2.2. 长短处理切句

from sentence_spliter.logic_graph import long_short_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence

# -- 初始化 状态机器 -- #
cuter = StateMachine(long_short_cuter(hard_max = 128, max_len= 128, min_len = 15))

# -- 处理句子 -- #
paragraph = "在很久很久以前1.2.3......。。... 有座山。山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。www.baidu.com"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)
['在很久很久以前1.2.3......。。...', ' 有座山。山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。', 'www.baidu.com']
from sentence_spliter.logic_graph import long_short_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence

# -- 初始化 状态机器 -- #
cuter = StateMachine(long_short_cuter(hard_max = 2, max_len= 2, min_len = 1))

# -- 处理句子 -- #
paragraph = "在很久很久以前1.2.3......。。... 有座山。山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。www.baidu.com"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)
['在很', '久很', '久以', '前1', '.2', '.3', '..', '..', '..', '。。', '..', '.', ' 有', '座山', '。', '山里', '有座', '庙啊', '!!', '!!', '!!', '!', '庙里', '竟然', '有个', '老和', '尚!', '?。', '。。', '。', 'ww', 'w.', 'ba', 'id', 'u.', 'com']

需要参数:

  • hard_max (默认300): 最大可接受长度,要保证所有句子(除了最后一句)<= hard_max
  • max_len (默认128): 长句判断条件,如果句子大于 max_len则为长句
    • max_len 可以等于 hard_max
  • min_len (默认15): 短句判断条件,如果句子小于min_len则为短句

基本逻辑:

  • 如果是短句:则该句子与右边句子合并
  • 如果是长句:
    • 优先基于断句标点做二次切句
    • 再机遇逗号做二次切句

4.2.3. 特殊处理切句+长短切句

from sentence_spliter.logic_graph import special_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence

# -- 初始化 状态机器 -- #
cuter = StateMachine(special_cuter(hard_max = 128, max_len= 128, min_len = 15))

# -- 处理句子 -- #
paragraph = "“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”“你知道么?CNN你们总是制造假新闻。。。”"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)
['“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”', '“你知道么?CNN你们总是制造假新闻。。。”']

# -- 处理句子 -- #
paragraph = "“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”      “你知道么?CNN你们总是制造假新闻。。。”"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)
['“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”', '“你知道么?CNN你们总是制造假新闻。。。”']

# -- 处理句子 -- #
paragraph = "张晓风笑着说道,“我们这些年可比过去强多了!“过去吃不起饭,穿不暖衣服。 现在呢?要啥有啥!"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()

# -- 展示结果 -- #
print(out)
['张晓风笑着说道,“我们这些年可比过去强多了!', '“过去吃不起饭,穿不暖衣服。 现在呢?要啥有啥!']

基本逻辑:

除了支持长短句以外,增加双引号处理特殊规则

  1. 右边引号后面跟有左引号,切句
  2. 中文中只有做引号,从第二个做引号开始切句

5. 自定义规则

切句规则都是基于图来实现的,其中

  • automata/condition.py 存放图的边
  • automata/operation.py 存放节点

5.1. 定义一个简单的切句规则

规则如下:

  • 如果遇到断句标点 执行切句

代码:

from automata import condition, operation
from automata.state_machine import StateMachine
from automata.sequence import StrSequence

# step 1: 初始所以需要的边和节点

edges = {
    'is_end_symbol': condition.IsEndSymbol(),
    'is_end_state': condition.IsEndState(),
}

nodes = {
    'init': operation.Indolent(),
    'do_cut': operation.Normal(),
    'end': operation.EndState()
}

# step 2: 构建图

simple_logic = {
    nodes['init']: [
        {'edge': edges['is_end_state'],
         'node': nodes['end']},

        {'edge': edges['is_end_symbol'],
         'node': nodes['do_cut']}
    ],
    nodes['do_cut']: [
        {'edge': edges['is_end_state'],
         'node': nodes['end']},

        {'edge': None,
         'node': nodes['init']}  # else 状态

    ],
}

# step 3: 初始化状态机
machine = StateMachine(simple_logic)

# step 4: 切句测试
sentences = '万壑树参天,千山响杜鹃。山中一夜雨,树杪百重泉。汉女输橦布,巴人讼芋田。文翁翻教授,不敢倚先贤。'

out = machine.run(StrSequence(sentences))

print('\n'.join(out.sentence_list()))

输出:

万壑树参天,千山响杜鹃。
山中一夜雨,树杪百重泉。
汉女输橦布,巴人讼芋田。
文翁翻教授,不敢倚先贤。

注意:

  • machine 是从 Indolent状态开始便利,遍历顺序从上倒下
  • 每个状态必须先有end_state条件否则报错

5.2. 自定义节点和边

  • 节点要保证输入和输出都是 sequece.StrSequence就可以放在状态机中运行
  • 边要保证输入是 sequece.StrSequence输出是bool就可以放在状态机中运行

这里不再做演示

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentence_spliter-1.0.10.tar.gz (14.3 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page