This is a sentence cutting tool that supports long sentence segmentation and short sentence merging.
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)
['张晓风笑着说道,“我们这些年可比过去强多了!', '“过去吃不起饭,穿不暖衣服。 现在呢?要啥有啥!']
基本逻辑:
除了支持长短句以外,增加
双引号
处理特殊规则
- 右边引号后面跟有左引号,切句
- 中文中只有做引号,从第二个做引号开始切句
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
Release history Release notifications | RSS feed
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.2.tar.gz
(7.5 kB
view hashes)
Built Distribution
Close
Hashes for sentence_spliter-1.0.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | de9963747d3c9db8192799f77e6a4216463a4218c620b464e206383d24101bf1 |
|
MD5 | 62bec4ba450e1149338b33a794b5d8d2 |
|
BLAKE2b-256 | ca522c7025e53042ceccbe4955ad977d9851c2839f73628533c036eee65b0a88 |