这是一个中文句子切割工具。
sentence-spliter的Python项目详细描述
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
fromsentence_spliterimportspliterparagraph="在很久很久以前......。。... 有座山,山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。"result=spliter.cut_to_sentences(paragraph)print(result)# outputs['在很久很久以前......。。...',' 有座山,山里有座庙啊!!!!!!!','庙里竟然有个老和尚!?。。。。']
切句支持以整片文章为输入。
如果输入太长,终端会自动显示百分比process cutting 87.5%
4.2. Demo in detail
切句工具默认有三种逻辑
4.2.1. 简单切句
fromsentence_spliter.logic_graphimportsimple_cuterfromautomata.state_machineimportStateMachinefromautomata.sequenceimportStrSequence# -- 初始化 状态机器 -- #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. 长短处理切句
fromsentence_spliter.logic_graphimportlong_short_cuterfromautomata.state_machineimportStateMachinefromautomata.sequenceimportStrSequence# -- 初始化 状态机器 -- #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']
fromsentence_spliter.logic_graphimportlong_short_cuterfromautomata.state_machineimportStateMachinefromautomata.sequenceimportStrSequence# -- 初始化 状态机器 -- #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. 特殊处理切句+长短切句
fromsentence_spliter.logic_graphimportspecial_cuterfromautomata.state_machineimportStateMachinefromautomata.sequenceimportStrSequence# -- 初始化 状态机器 -- #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. 定义一个简单的切句规则
规则如下:
- 如果遇到断句标点 执行切句
代码:
fromautomataimportcondition,operationfromautomata.state_machineimportStateMachinefromautomata.sequenceimportStrSequence# 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
就可以放在状态机中运行
这里不再做演示
- 项目
标签: