pragmatic_segmenter 0.3.21 → 0.3.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/NEWS +4 -0
- data/README.md +13 -0
- data/lib/pragmatic_segmenter/languages.rb +3 -1
- data/lib/pragmatic_segmenter/languages/kazakh.rb +44 -0
- data/lib/pragmatic_segmenter/version.rb +1 -1
- data/spec/pragmatic_segmenter/languages/deutsch_spec.rb +18 -0
- data/spec/pragmatic_segmenter/languages/kazakh_spec.rb +73 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77e3c8da3e5e184a5143dff774dbe851de58c385
|
4
|
+
data.tar.gz: f9f2803fb49a298b2015e206f7237b792be26e10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 050ea08ad001c6786f44c936581e4d82d05ebf2cc1ac5265a5b24c3af25d8cad4f562f3d7c241baf48d49a14374559d12e4888f7514f9edb23733645c49999d7
|
7
|
+
data.tar.gz: d5c39d307836ce2571f8c8b0507110dd907d5150a6efc686136d915e2ecef6bca43a262ac7fc76fa908a9f18e9a1344f59b4da9115806ddc6e24e536bea0bd7d
|
data/.gitignore
CHANGED
data/NEWS
CHANGED
data/README.md
CHANGED
@@ -433,6 +433,12 @@ Was sind die Konsequenzen der Abstimmung vom 12. Juni?
|
|
433
433
|
=> ["Was sind die Konsequenzen der Abstimmung vom 12. Juni?"]
|
434
434
|
```
|
435
435
|
|
436
|
+
4.) **Cardinal numbers at end of sentence** *Credit: Dr. Michael Ustaszewski*
|
437
|
+
```
|
438
|
+
Die Information steht auf Seite 12. Dort kannst du nachlesen.
|
439
|
+
=> ["Die Information steht auf Seite 12.", "Dort kannst du nachlesen."]
|
440
|
+
```
|
441
|
+
|
436
442
|
#### Golden Rules (Japanese)
|
437
443
|
|
438
444
|
1.) **Simple period to end sentence**
|
@@ -878,6 +884,9 @@ To test the relative performance of different segmentation tools and libraries I
|
|
878
884
|
* Add support for file formats
|
879
885
|
* Add support for numeric references at the end of a sentence (i.e. Wikipedia references)
|
880
886
|
|
887
|
+
**Version 0.3.22**
|
888
|
+
* Add initial support and tests for Kazakh
|
889
|
+
|
881
890
|
## Contributing
|
882
891
|
|
883
892
|
If you find a text that is incorrectly segmented using this gem, please submit an issue.
|
@@ -888,6 +897,10 @@ If you find a text that is incorrectly segmented using this gem, please submit a
|
|
888
897
|
4. Push to the branch (`git push origin my-new-feature`)
|
889
898
|
5. Create a new Pull Request
|
890
899
|
|
900
|
+
## Ports
|
901
|
+
|
902
|
+
* [C# - PragmaticSegmenterNet](https://github.com/UglyToad/PragmaticSegmenterNet)
|
903
|
+
|
891
904
|
## License
|
892
905
|
|
893
906
|
The MIT License (MIT)
|
@@ -26,6 +26,7 @@ require 'pragmatic_segmenter/languages/polish'
|
|
26
26
|
require 'pragmatic_segmenter/languages/chinese'
|
27
27
|
require 'pragmatic_segmenter/languages/bulgarian'
|
28
28
|
require 'pragmatic_segmenter/languages/danish'
|
29
|
+
require 'pragmatic_segmenter/languages/kazakh'
|
29
30
|
|
30
31
|
module PragmaticSegmenter
|
31
32
|
module Languages
|
@@ -49,7 +50,8 @@ module PragmaticSegmenter
|
|
49
50
|
'nl' => Dutch,
|
50
51
|
'pl' => Polish,
|
51
52
|
'zh' => Chinese,
|
52
|
-
'da' => Danish
|
53
|
+
'da' => Danish,
|
54
|
+
'kk' => Kazakh
|
53
55
|
}
|
54
56
|
|
55
57
|
def self.get_language_by_code(code)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PragmaticSegmenter
|
4
|
+
module Languages
|
5
|
+
module Kazakh
|
6
|
+
include Languages::Common
|
7
|
+
|
8
|
+
MULTI_PERIOD_ABBREVIATION_REGEX = /\b\p{Cyrillic}(?:\.\s?\p{Cyrillic})+[.]|b[a-z](?:\.[a-z])+[.]/i
|
9
|
+
|
10
|
+
module Abbreviation
|
11
|
+
ABBREVIATIONS = Set.new(['afp', 'anp', 'atp', 'bae', 'bg', 'bp', 'cam', 'cctv', 'cd', 'cez', 'cgi', 'cnpc', 'farc', 'fbi', 'eiti', 'epo', 'er', 'gp', 'gps', 'has', 'hiv', 'hrh', 'http', 'icu', 'idf', 'imd', 'ime', 'icu', 'idf', 'ip', 'iso', 'kaz', 'kpo', 'kpa', 'kz', 'kz', 'mri', 'nasa', 'nba', 'nbc', 'nds', 'ohl', 'omlt', 'ppm', 'pda', 'pkk', 'psm', 'psp', 'raf', 'rss', 'rtl', 'sas', 'sme', 'sms', 'tnt', 'udf', 'uefa', 'usb', 'utc', 'x', 'zdf', 'әқбк', 'әқбк', 'аақ', 'авг.', 'aбб', 'аек', 'ак', 'ақ', 'акцион.', 'акср', 'ақш', 'англ', 'аөсшк', 'апр', 'м.', 'а.', 'р.', 'ғ.', 'апр.', 'аум.', 'ацат', 'әч', 'т. б.', 'б. з. б.', 'б. з. б.', 'б. з. д.', 'б. з. д.', 'биікт.', 'б. т.', 'биол.', 'биохим', 'бө', 'б. э. д.', 'бта', 'бұұ', 'вич', 'всоонл', 'геогр.', 'геол.', 'гленкор', 'гэс', 'қк', 'км', 'г', 'млн', 'млрд', 'т', 'ғ. с.', 'ғ.', 'қ.', 'ғ.', 'дек.', 'днқ', 'дсұ', 'еақк', 'еқыұ', 'ембімұнайгаз', 'ео', 'еуразэқ', 'еуроодақ', 'еұу', 'ж.', 'ж.', 'жж.', 'жоо', 'жіө', 'жсдп', 'жшс', 'іім', 'инта', 'исаф', 'камаз', 'кгб', 'кеу', 'кг', 'км²', 'км²', 'км³', 'км³', 'кимеп', 'кср', 'ксро', 'кокп', 'кхдр', 'қазатомпром', 'қазкср', 'қазұу', 'қазмұнайгаз', 'қазпошта', 'қазтаг', 'қазұу', 'қкп', 'қмдб', 'қр', 'қхр', 'лат.', 'м²', 'м²', 'м³', 'м³', 'магатэ', 'май.', 'максам', 'мб', 'мвт', 'мемл', 'м', 'мсоп', 'мтк', 'мыс.', 'наса', 'нато', 'нквд', 'нояб.', 'обл.', 'огпу', 'окт.', 'оңт.', 'опек', 'оеб', 'өзенмұнайгаз', 'өф', 'пәк', 'пед.', 'ркфср', 'рнқ', 'рсфср', 'рф', 'свс', 'сву', 'сду', 'сес', 'сент.', 'см', 'снпс', 'солт.', 'солт.', 'сооно', 'ссро', 'сср', 'ссср', 'ссс', 'сэс', 'дк', 'т. б.', 'т', 'тв', 'тереңд.', 'тех.', 'тжқ', 'тмд', 'төм.', 'трлн', 'тр', 'т.', 'и.', 'м.', 'с.', 'ш.', 'т.', 'т. с. с.', 'тэц', 'уаз', 'уефа', 'еқыұ', 'ұқк', 'ұқшұ', 'февр.', 'фққ', 'фсб', 'хим.', 'хқко', 'шұар', 'шыұ', 'экон.', 'экспо', 'цтп', 'цас', 'янв.', 'dvd', 'жкт', 'ққс', 'км', 'ацат', 'юнеско', 'ббс', 'mgm', 'жск', 'зоо', 'бсн', 'өұқ', 'оар', 'боак', 'эөкк', 'хтқо', 'әөк', 'жэк', 'хдо', 'спбму', 'аф', 'сбд', 'амт', 'гсдп', 'гсбп', 'эыдұ', 'нұсжп', 'шыұ', 'жтсх', 'хдп', 'эқк', 'фкққ', 'пиқ', 'өгк', 'мбф', 'маж', 'кота', 'тж', 'ук', 'обб', 'сбл', 'жхл', 'кмс', 'бмтрк', 'жққ', 'бхооо', 'мқо', 'ржмб', 'гулаг', 'жко', 'еэы', 'еаэы', 'кхдр', 'рфкп', 'рлдп', 'хвқ', 'мр', 'мт', 'кту', 'ртж', 'тим', 'мемдум', 'ксро', 'т.с.с', 'с.ш.', 'ш.б.', 'б.б.', 'руб', 'мин', 'акад.', 'ғ.', 'мм', 'мм.']).freeze
|
12
|
+
PREPOSITIVE_ABBREVIATIONS = [].freeze
|
13
|
+
NUMBER_ABBREVIATIONS = [].freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
class Processor < PragmaticSegmenter::Processor
|
17
|
+
private
|
18
|
+
|
19
|
+
# Rubular: http://rubular.com/r/WRWy56Z5zp
|
20
|
+
QuestionMarkFollowedByDashLowercaseRule = Rule.new(/(?<=\p{Ll})\?(?=\s*[-—]\s*\p{Ll})/, '&ᓷ&')
|
21
|
+
# Rubular: http://rubular.com/r/lixxP7puSa
|
22
|
+
ExclamationMarkFollowedByDashLowercaseRule = Rule.new(/(?<=\p{Ll})!(?=\s*[-—]\s*\p{Ll})/, '&ᓴ&')
|
23
|
+
|
24
|
+
def between_punctuation(txt)
|
25
|
+
super(txt)
|
26
|
+
txt.apply(QuestionMarkFollowedByDashLowercaseRule, ExclamationMarkFollowedByDashLowercaseRule)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class AbbreviationReplacer < AbbreviationReplacer
|
31
|
+
SENTENCE_STARTERS = [].freeze
|
32
|
+
|
33
|
+
SingleUpperCaseCyrillicLetterAtStartOfLineRule = Rule.new(/(?<=^[А-ЯЁ])\.(?=\s)/, '∯')
|
34
|
+
SingleUpperCaseCyrillicLetterRule = Rule.new(/(?<=\s[А-ЯЁ])\.(?=\s)/, '∯')
|
35
|
+
|
36
|
+
def replace
|
37
|
+
super
|
38
|
+
@text.apply(SingleUpperCaseCyrillicLetterAtStartOfLineRule, SingleUpperCaseCyrillicLetterRule)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -17,6 +17,24 @@ RSpec.describe PragmaticSegmenter::Languages::Deutsch, "(de)" do
|
|
17
17
|
ps = PragmaticSegmenter::Segmenter.new(text: "Was sind die Konsequenzen der Abstimmung vom 12. Juni?", language: "de")
|
18
18
|
expect(ps.segment).to eq(["Was sind die Konsequenzen der Abstimmung vom 12. Juni?"])
|
19
19
|
end
|
20
|
+
|
21
|
+
it "Numbers #004" do
|
22
|
+
# Credit: Dr. Michael Ustaszewski
|
23
|
+
# A numeral followed by a dot within the sentence should not be treated as a sentence,
|
24
|
+
# because the meaning of numeral + dot is that of an ordinal number.
|
25
|
+
# However, if the numeral + dot is in the last position of the sentence, then it is not an ordinal,
|
26
|
+
# but a cardinal number and thus a sentence break should be made. See the following example:
|
27
|
+
|
28
|
+
# <INPUT>Die Information steht auf Seite 12. Dort kannst du nachlesen.</INPUT>
|
29
|
+
# <SHOULDBE>["Die Information steht auf Seite 12.", "Dort kannst du nachlesen."]</SHOULDBE>
|
30
|
+
# The sentence translates as "The information can be found on page 12. You can read it there".
|
31
|
+
|
32
|
+
# That's a tricky one I guess, because the capitalisation of the word following the dot is not necessarily a clue,
|
33
|
+
# since German nouns are usually always capitalised.
|
34
|
+
skip "NOT IMPLEMENTED"
|
35
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Die Information steht auf Seite 12. Dort kannst du nachlesen.", language: "de")
|
36
|
+
expect(ps.segment).to eq(["Die Information steht auf Seite 12.", "Dort kannst du nachlesen."])
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
40
|
# Thanks to Silvia Busse for the German test examples.
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe PragmaticSegmenter::Languages::Kazakh, "(kk)" do
|
4
|
+
|
5
|
+
context "Golden Rules" do
|
6
|
+
it "Simple period to end sentence #001" do
|
7
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Мұхитқа тікелей шыға алмайтын мемлекеттердің ішінде Қазақстан - ең үлкені.", language: "kk")
|
8
|
+
expect(ps.segment).to eq(["Мұхитқа тікелей шыға алмайтын мемлекеттердің ішінде Қазақстан - ең үлкені."])
|
9
|
+
end
|
10
|
+
|
11
|
+
it "Question mark to end sentence #002" do
|
12
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Оқушылар үйі, Достық даңғылы, Абай даналығы, ауыл шаруашылығы – кім? не?", language: "kk")
|
13
|
+
expect(ps.segment).to eq(["Оқушылар үйі, Достық даңғылы, Абай даналығы, ауыл шаруашылығы – кім?", "не?"])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "Parenthetical inside sentence #003" do
|
17
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Әр түрлі өлшемнің атауы болып табылатын м (метр), см (сантиметр), кг (киллограмм), т (тонна), га (гектар), ц (центнер), т. б. (тағы басқа), тәрізді белгілер де қысқарған сөздер болып табылады.", language: "kk")
|
18
|
+
expect(ps.segment).to eq(["Әр түрлі өлшемнің атауы болып табылатын м (метр), см (сантиметр), кг (киллограмм), т (тонна), га (гектар), ц (центнер), т. б. (тағы басқа), тәрізді белгілер де қысқарған сөздер болып табылады."])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "Two letter abbreviation to end sentence #004" do
|
22
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Мысалы: обкомға (облыстық комитетке) барды, ауаткомда (аудандық атқару комитетінде) болды, педучилищеге (педагогтік училищеге) түсті, медпункттің (медициналық пункттің) алдында т. б.", language: "kk")
|
23
|
+
expect(ps.segment).to eq(["Мысалы: обкомға (облыстық комитетке) барды, ауаткомда (аудандық атқару комитетінде) болды, педучилищеге (педагогтік училищеге) түсті, медпункттің (медициналық пункттің) алдында т. б."])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "Number as non sentence boundary #005" do
|
27
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Елдің жалпы ішкі өнімі ЖІӨ (номинал) = $225.619 млрд (2014)", language: "kk")
|
28
|
+
expect(ps.segment).to eq(["Елдің жалпы ішкі өнімі ЖІӨ (номинал) = $225.619 млрд (2014)"])
|
29
|
+
end
|
30
|
+
|
31
|
+
it "No whitespace between sentence boundary #006" do
|
32
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Ресейдiң әлеуметтiк-экономикалық жағдайы.XVIII ғасырдың бiрiншi ширегiнде Ресейге тән нәрсе.", language: "kk")
|
33
|
+
expect(ps.segment).to eq(["Ресейдiң әлеуметтiк-экономикалық жағдайы.", "XVIII ғасырдың бiрiншi ширегiнде Ресейге тән нәрсе."])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "Dates within sentence #007" do
|
37
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "(«Егемен Қазақстан», 7 қыркүйек 2012 жыл. №590-591); Бұл туралы кеше санпедқадағалау комитетінің облыыстық департаменті хабарлады. («Айқын», 23 сəуір 2010 жыл. № 70).", language: "kk")
|
38
|
+
expect(ps.segment).to eq(["(«Егемен Қазақстан», 7 қыркүйек 2012 жыл. №590-591); Бұл туралы кеше санпедқадағалау комитетінің облыыстық департаменті хабарлады.", "(«Айқын», 23 сəуір 2010 жыл. № 70)."])
|
39
|
+
end
|
40
|
+
|
41
|
+
it "Multi period abbreviation within sentence #008" do
|
42
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Иран революциясы (1905 — 11) және азаматтық қозғалыс (1918 — 21) кезінде А. Фарахани, М. Кермани, М. Т. Бехар, т.б. ақындар демократиялық идеяның жыршысы болды.", language: "kk")
|
43
|
+
expect(ps.segment).to eq(["Иран революциясы (1905 — 11) және азаматтық қозғалыс (1918 — 21) кезінде А. Фарахани, М. Кермани, М. Т. Бехар, т.б. ақындар демократиялық идеяның жыршысы болды."])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Web addresses #009" do
|
47
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Владимир Федосеев: Аттар магиясы енді жоқ http://www.vremya.ru/2003/179/10/80980.html", language: "kk")
|
48
|
+
expect(ps.segment).to eq(["Владимир Федосеев: Аттар магиясы енді жоқ http://www.vremya.ru/2003/179/10/80980.html"])
|
49
|
+
end
|
50
|
+
|
51
|
+
it "Question mark not at end of sentence #010" do
|
52
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Бірақ оның енді не керегі бар? — деді.", language: "kk")
|
53
|
+
expect(ps.segment).to eq(["Бірақ оның енді не керегі бар? — деді."])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "Exclamation mark not at end of sentence #011" do
|
57
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Сондықтан шапаныма жегізіп отырғаным! - деп, жауап береді.", language: "kk")
|
58
|
+
expect(ps.segment).to eq(["Сондықтан шапаныма жегізіп отырғаным! - деп, жауап береді."])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#segment' do
|
63
|
+
it 'correctly segments text #001' do
|
64
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "Б.з.б. 6 – 3 ғасырларда конфуцийшілдік, моизм, легизм мектептерінің қалыптасуы нәтижесінде Қытай философиясы пайда болды.", language: 'kk')
|
65
|
+
expect(ps.segment).to eq(["Б.з.б. 6 – 3 ғасырларда конфуцийшілдік, моизм, легизм мектептерінің қалыптасуы нәтижесінде Қытай философиясы пайда болды."])
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'correctly segments text #002' do
|
69
|
+
ps = PragmaticSegmenter::Segmenter.new(text: "'Та марбута' тек сөз соңында екі түрде жазылады:", language: "kk")
|
70
|
+
expect(ps.segment).to eq(["'Та марбута' тек сөз соңында екі түрде жазылады:"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pragmatic_segmenter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin S. Dias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: unicode
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/pragmatic_segmenter/languages/hindi.rb
|
125
125
|
- lib/pragmatic_segmenter/languages/italian.rb
|
126
126
|
- lib/pragmatic_segmenter/languages/japanese.rb
|
127
|
+
- lib/pragmatic_segmenter/languages/kazakh.rb
|
127
128
|
- lib/pragmatic_segmenter/languages/persian.rb
|
128
129
|
- lib/pragmatic_segmenter/languages/polish.rb
|
129
130
|
- lib/pragmatic_segmenter/languages/russian.rb
|
@@ -152,6 +153,7 @@ files:
|
|
152
153
|
- spec/pragmatic_segmenter/languages/hindi_spec.rb
|
153
154
|
- spec/pragmatic_segmenter/languages/italian_spec.rb
|
154
155
|
- spec/pragmatic_segmenter/languages/japanese_spec.rb
|
156
|
+
- spec/pragmatic_segmenter/languages/kazakh_spec.rb
|
155
157
|
- spec/pragmatic_segmenter/languages/persian_spec.rb
|
156
158
|
- spec/pragmatic_segmenter/languages/polish_spec.rb
|
157
159
|
- spec/pragmatic_segmenter/languages/russian_spec.rb
|
@@ -202,6 +204,7 @@ test_files:
|
|
202
204
|
- spec/pragmatic_segmenter/languages/hindi_spec.rb
|
203
205
|
- spec/pragmatic_segmenter/languages/italian_spec.rb
|
204
206
|
- spec/pragmatic_segmenter/languages/japanese_spec.rb
|
207
|
+
- spec/pragmatic_segmenter/languages/kazakh_spec.rb
|
205
208
|
- spec/pragmatic_segmenter/languages/persian_spec.rb
|
206
209
|
- spec/pragmatic_segmenter/languages/polish_spec.rb
|
207
210
|
- spec/pragmatic_segmenter/languages/russian_spec.rb
|