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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a13bc873b763cc68e4bfebcd0c291d3eab12a429
4
- data.tar.gz: 85666c4d354ba1a0e5118c0e3e23b9c4d1978ae4
3
+ metadata.gz: 77e3c8da3e5e184a5143dff774dbe851de58c385
4
+ data.tar.gz: f9f2803fb49a298b2015e206f7237b792be26e10
5
5
  SHA512:
6
- metadata.gz: f3c211daa3aaf71d4ff1d363ee15711c8979db6fa3cf9fb87d84108466f0d8fe9ee7b9694ad32a6439a79c471ab013e70f536601d951a7e9400addb954f35c76
7
- data.tar.gz: de40f070a216d90cff094bb6cfdb83b1f1c108774ff67da18e58846fc69aab78decc234f0b0c7fda7931ffcc7e8ca1e427d28fd495922a28aa91df02981917e6
6
+ metadata.gz: 050ea08ad001c6786f44c936581e4d82d05ebf2cc1ac5265a5b24c3af25d8cad4f562f3d7c241baf48d49a14374559d12e4888f7514f9edb23733645c49999d7
7
+ data.tar.gz: d5c39d307836ce2571f8c8b0507110dd907d5150a6efc686136d915e2ecef6bca43a262ac7fc76fa908a9f18e9a1344f59b4da9115806ddc6e24e536bea0bd7d
data/.gitignore CHANGED
@@ -12,4 +12,5 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
- .DS_Store
15
+ .DS_Store
16
+ .vscode/launch.json
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 0.3.22 (2018-09-23):
2
+
3
+ * Improvement: Initial support for Kazakh
4
+
1
5
  0.3.21 (2018-08-30):
2
6
 
3
7
  * Improvement: Add support for file formats
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
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PragmaticSegmenter
4
- VERSION = "0.3.21"
4
+ VERSION = "0.3.22"
5
5
  end
@@ -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.21
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-08-29 00:00:00.000000000 Z
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