petrovich 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +101 -37
- data/Rakefile +14 -8
- data/lib/petrovich.rb +8 -8
- data/lib/tasks/evaluate.rake +89 -0
- metadata +9 -6
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
![Petrovich Logo](
|
1
|
+
![Petrovich Logo](petrovich.png)
|
2
2
|
|
3
|
-
Склонение падежей русских имён, фамилий и отчеств. Вы задаёте начальное имя
|
3
|
+
Склонение падежей русских имён, фамилий и отчеств. Вы задаёте начальное имя
|
4
|
+
в именительном падеже, а получаете в нужном вам.
|
4
5
|
|
5
6
|
[![Build Status](https://secure.travis-ci.org/rocsci/petrovich.png)](http://travis-ci.org/rocsci/petrovich)
|
6
7
|
|
@@ -10,36 +11,47 @@
|
|
10
11
|
|
11
12
|
gem 'petrovich'
|
12
13
|
|
13
|
-
Установите
|
14
|
+
Установите гем cредствами Bundler:
|
14
15
|
|
15
16
|
$ bundle
|
16
17
|
|
17
|
-
|
18
|
+
Или установите его отдельно:
|
18
19
|
|
19
20
|
$ gem install petrovich
|
20
21
|
|
21
|
-
##
|
22
|
+
## Зависимости
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
Для работы гема требуется Ruby не младше версии 1.9.1. Petrovich не
|
25
|
+
привязан к Ruby on Rails и может свободно использоваться практически
|
26
|
+
в любых приложениях и библиотеках на Ruby.
|
25
27
|
|
26
28
|
## Использование
|
27
29
|
|
28
|
-
Вы задаёте начальные значения (фамилию, имя и отчество) в именительном
|
30
|
+
Вы задаёте начальные значения (фамилию, имя и отчество) в именительном
|
31
|
+
падеже.
|
29
32
|
|
30
33
|
```ruby
|
31
|
-
# Указание пола снижает количество отказов
|
32
34
|
p = Petrovich.new(:male)
|
33
35
|
p.lastname('Иванов', :dative) # => Иванову
|
34
36
|
p.firstname('Пётр', :dative) # => Петру
|
35
37
|
p.middlename('Сергеевич', :dative) # => Сергеевичу
|
36
38
|
```
|
37
39
|
|
38
|
-
Конструктор класса `Petrovich` принимает пол в качестве единственного
|
40
|
+
Конструктор класса `Petrovich` принимает пол в качестве единственного
|
41
|
+
аргумента. Пол может принимать значения `:male`, `:female` или
|
42
|
+
`:androgynous`. Последнее означает, что слово не склоняется по родам.
|
43
|
+
По нормам языка, некоторые фамилии не склоняются. Например, такие
|
44
|
+
украинские фамилии, как Симоненко, а также заимствованные фамилии,
|
45
|
+
такие как Нельсон.
|
46
|
+
|
47
|
+
Важно понимать, что явное указание пола повышает точность обработки слов.
|
48
|
+
Если пол не известен, однако известно отчество, то гем постарается
|
49
|
+
определить по пол отчеству на основе простой эвристики.
|
39
50
|
|
40
51
|
### Продвинутое использование
|
41
52
|
|
42
|
-
Вы можете подмешать модуль `Petrovich::Extension` в любой класс. Это
|
53
|
+
Вы можете подмешать модуль `Petrovich::Extension` в любой класс. Это
|
54
|
+
особенно полезно при использовании ActiveRecord и подобных ORM.
|
43
55
|
|
44
56
|
```ruby
|
45
57
|
class User < ActiveRecord::Base
|
@@ -71,7 +83,8 @@ class User < ActiveRecord::Base
|
|
71
83
|
end
|
72
84
|
```
|
73
85
|
|
74
|
-
|
86
|
+
Ничего не мешает подмешать модуль `Petrovich::Extension` в самый обычный
|
87
|
+
класс.
|
75
88
|
|
76
89
|
```ruby
|
77
90
|
class Person
|
@@ -96,7 +109,13 @@ class Person
|
|
96
109
|
end
|
97
110
|
```
|
98
111
|
|
99
|
-
|
112
|
+
При помощи метода `petrovich` указываются методы, представляющие фамилию,
|
113
|
+
имя и отчество. В данном примере указано, что метод `name` представляет
|
114
|
+
имя, метод `lastname` представляет фамилию, метод `patronymic` представляет
|
115
|
+
отчество.
|
116
|
+
|
117
|
+
После конфигурации Petrovich можно легко выполнять склонение необходимых
|
118
|
+
строк.
|
100
119
|
|
101
120
|
```ruby
|
102
121
|
user = User.new
|
@@ -107,8 +126,6 @@ user.my_middlename_dative # => Петровичу
|
|
107
126
|
user.my_lastname_dative # => Петренко
|
108
127
|
```
|
109
128
|
|
110
|
-
и для второго примера:
|
111
|
-
|
112
129
|
```ruby
|
113
130
|
person = Person.new
|
114
131
|
person.name # => Иван
|
@@ -117,44 +134,91 @@ person.my_firstname_dative # => Ивану
|
|
117
134
|
person.my_middlename_dative # => Олеговичу
|
118
135
|
person.my_lastname_dative # => Сафронову
|
119
136
|
```
|
120
|
-
Изначальное имя должно быть в именительнои падеже. Вы просто добавляете `_падеж` в конец имени оригинального метода и получаете нужное значение. Вот список суффиксов, которые вы можете добавить к имени оригинального метода, чтобы получить имя в нужном падаже:
|
121
137
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
* instrumentative - творительный
|
126
|
-
* prepositional - предложный
|
138
|
+
Базовое имя должно быть в именительном падеже. Вы просто добавляете
|
139
|
+
`_падеж` в конец имени оригинального метода и получаете заданное имя
|
140
|
+
в требуемом падеже.
|
127
141
|
|
128
|
-
|
142
|
+
Вот список суффиксов, которые вы можете добавить к имени метода, чтобы
|
143
|
+
получить имя в нужном падеже:
|
129
144
|
|
130
|
-
*
|
131
|
-
*
|
145
|
+
* genitive — родительный;
|
146
|
+
* dative — дательный;
|
147
|
+
* accusative — винительный;
|
148
|
+
* instrumental — творительный;
|
149
|
+
* prepositional — предложный.
|
132
150
|
|
133
|
-
##
|
151
|
+
## Оценка точности
|
134
152
|
|
135
|
-
|
153
|
+
Тестирование гема при склонении коллекции фамилий из морфологического
|
154
|
+
словаря [АОТ] показало точность около 99%. Оригинальный словарь
|
155
|
+
распространяется по лицензии LGPL версии 2.1, однако используется
|
156
|
+
только в задаче оценки точности данного гема.
|
136
157
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
* Веб-интерфейс для проверки имён (ф.и.о) и их логгирования, для улучшения правил распознавания.
|
141
|
-
* Проверка работы с mongoid и mongo-mapper
|
158
|
+
Для оценки точности достаточно выполнить команду `rake evaluate`. После
|
159
|
+
выполнения этой команды в поток стандартного вывода будут напечатаны
|
160
|
+
результаты оценки с данными в словаре АОТ.
|
142
161
|
|
143
|
-
|
162
|
+
```
|
163
|
+
Pr(nominative|male) = 100.0000%
|
164
|
+
Pr(genitive|male) = 99.6763%
|
165
|
+
Pr(dative|male) = 99.7012%
|
166
|
+
Pr(accusative|male) = 99.7261%
|
167
|
+
Pr(instrumental|male) = 97.9485%
|
168
|
+
Pr(prepositional|male) = 99.6888%
|
169
|
+
```
|
170
|
+
```
|
171
|
+
Pr(nominative|female) = 100.0000%
|
172
|
+
Pr(genitive|female) = 99.8652%
|
173
|
+
Pr(dative|female) = 99.8952%
|
174
|
+
Pr(accusative|female) = 99.9251%
|
175
|
+
Pr(instrumental|female) = 99.4189%
|
176
|
+
Pr(prepositional|female) = 99.8952%
|
177
|
+
```
|
144
178
|
|
145
|
-
|
179
|
+
В настоящий момент наблюдается точность в 99.6275% на основе обработки
|
180
|
+
88314 примеров.
|
146
181
|
|
147
|
-
|
182
|
+
[АОТ]: http://seman.svn.sourceforge.net/viewvc/seman/trunk/Docs/Morph_UNIX.txt?revision=HEAD&view=markup
|
148
183
|
|
149
|
-
|
184
|
+
## Модульные тесты
|
185
|
+
|
186
|
+
Чтобы запустить тесты, тестирующие фамилии, нужно установить переменную
|
187
|
+
окружения `TEST_SURNAMES`:
|
188
|
+
|
189
|
+
```shell
|
150
190
|
TEST_SURNAMES=1 rspec
|
151
191
|
```
|
152
192
|
|
193
|
+
## Разработчики
|
194
|
+
|
195
|
+
* [Андрей Козлов](https://github.com/tanraya) — идея, реализация.
|
196
|
+
* [Дмитрий Усталов](http://eveel.ru) — неоценимая помощь.
|
197
|
+
|
198
|
+
## Дальнейшее развитие
|
199
|
+
|
200
|
+
Мы планируем и далее улучшать этот проект. Поэтому нам важен отклик от
|
201
|
+
пользователей данного гема. Вот наши планы:
|
202
|
+
|
203
|
+
* добавить отладочный режим, чтобы видеть, какое именно правило было
|
204
|
+
использовано при словообразовании;
|
205
|
+
* интерфейс командной строки, чтобы работать с гемом из командной строки;
|
206
|
+
* Web-интерфейс для обработки ФИО;
|
207
|
+
* проверка совместимости с различными ORM и сторонними библиотеками.
|
208
|
+
|
209
|
+
Если вы хотите помочь этому проекту, вы можете реализовать любую
|
210
|
+
вышеперечисленную идею. Перед этим желательно связаться с нами,
|
211
|
+
чтобы мы были в курсе.
|
212
|
+
|
153
213
|
## Содействие
|
154
214
|
|
155
|
-
Если вы нашли баги, как программной части, так и в
|
215
|
+
Если вы нашли баги, как программной части, так и в базе правил, то вы всегда
|
216
|
+
можете форкнуть репозиторий и внести необходимые изменения. Ваша помощь не
|
217
|
+
останется незамеченной! Если вы заметили ошибки при склонении падежей имён,
|
218
|
+
фамилий или отчеств, можете написать об этом в Issues на GitHub.
|
219
|
+
Проблема будет сразу же исследована и, по возможности, решена.
|
156
220
|
|
157
|
-
Не стесняйтесь добавлять улучшения.
|
221
|
+
Не стесняйтесь добавлять улучшения.
|
158
222
|
|
159
223
|
1. Fork it
|
160
224
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/Rakefile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
|
7
6
|
begin
|
8
7
|
require 'rdoc/task'
|
9
8
|
rescue LoadError
|
@@ -12,7 +11,14 @@ rescue LoadError
|
|
12
11
|
RDoc::Task = Rake::RDocTask
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :petrovich do
|
18
|
+
require 'petrovich'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Run tests and perform evaluation by default
|
22
|
+
task :default => [:spec, :evaluate]
|
17
23
|
|
18
|
-
|
24
|
+
Dir.glob('lib/tasks/*.rake').each { |r| import r }
|
data/lib/petrovich.rb
CHANGED
@@ -31,18 +31,18 @@ require 'petrovich/extension'
|
|
31
31
|
# * +:genitive+ - родительный
|
32
32
|
# * +:dative+ - дательный
|
33
33
|
# * +:accusative+ - винительный
|
34
|
-
# * +:
|
34
|
+
# * +:instrumental+ - творительный
|
35
35
|
# * +:prepositional+ - предложный
|
36
36
|
#
|
37
37
|
class Petrovich
|
38
|
-
CASES = [:nominative, :genitive, :dative, :accusative, :
|
38
|
+
CASES = [:nominative, :genitive, :dative, :accusative, :instrumental, :prepositional]
|
39
39
|
|
40
|
-
NOMINATIVE = :nominative
|
41
|
-
GENITIVE = :genitive
|
42
|
-
DATIVE = :dative
|
43
|
-
ACCUSATIVE = :accusative
|
44
|
-
INSTRUMENTATIVE = :
|
45
|
-
PREPOSITIONAL = :prepositional
|
40
|
+
NOMINATIVE = :nominative # именительный
|
41
|
+
GENITIVE = :genitive # родительный
|
42
|
+
DATIVE = :dative # дательный
|
43
|
+
ACCUSATIVE = :accusative # винительный
|
44
|
+
INSTRUMENTATIVE = :instrumental # творительный
|
45
|
+
PREPOSITIONAL = :prepositional # предложный
|
46
46
|
|
47
47
|
def initialize(gender = nil)
|
48
48
|
@gender = gender.to_s
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
|
5
|
+
CASES = [
|
6
|
+
:nominative,
|
7
|
+
:genitive,
|
8
|
+
:dative,
|
9
|
+
:accusative,
|
10
|
+
:instrumental,
|
11
|
+
:prepositional
|
12
|
+
]
|
13
|
+
|
14
|
+
def check!(errors, correct, total, lemma, gender, gcase, expected)
|
15
|
+
inflector = Petrovich.new(gender)
|
16
|
+
inflection = begin
|
17
|
+
UnicodeUtils.upcase(inflector.lastname(lemma, gcase))
|
18
|
+
rescue
|
19
|
+
''
|
20
|
+
end
|
21
|
+
|
22
|
+
total[[gender, gcase]] += 1
|
23
|
+
|
24
|
+
if inflection == expected
|
25
|
+
correct[[gender, gcase]] += 1
|
26
|
+
true
|
27
|
+
else
|
28
|
+
errors << [lemma, expected, inflection, [gender, gcase]]
|
29
|
+
inflection
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Evaluate the inflector on surnames'
|
34
|
+
task :evaluate => :petrovich do
|
35
|
+
filename = File.expand_path('../../../spec/data/surnames.tsv', __FILE__)
|
36
|
+
errors_filename = ENV['errors'] || 'errors.tsv'
|
37
|
+
|
38
|
+
correct, total = Hash.new(0), Hash.new(0)
|
39
|
+
|
40
|
+
puts 'I will evaluate the inflector on "%s" ' \
|
41
|
+
'and store errors to "%s".' % [filename, errors_filename]
|
42
|
+
|
43
|
+
CSV.open(errors_filename, 'w', col_sep: "\t") do |errors|
|
44
|
+
errors << %w(lemma expected actual params)
|
45
|
+
|
46
|
+
CSV.open(filename, col_sep: "\t", headers: true).each do |row|
|
47
|
+
word = row['word'].force_encoding('UTF-8')
|
48
|
+
lemma = row['lemma'].force_encoding('UTF-8')
|
49
|
+
|
50
|
+
grammemes = if row['grammemes']
|
51
|
+
row['grammemes'].force_encoding('UTF-8').split(',')
|
52
|
+
else
|
53
|
+
[]
|
54
|
+
end
|
55
|
+
|
56
|
+
gender = grammemes.include?('мр') ? :male : :female
|
57
|
+
|
58
|
+
if grammemes.include? '0'
|
59
|
+
# some words are aptotic so we have to ensure that
|
60
|
+
CASES.each do |gcase|
|
61
|
+
check! errors, correct, total, lemma, gender, gcase, word
|
62
|
+
end
|
63
|
+
elsif grammemes.include? 'им'
|
64
|
+
check! errors, correct, total, lemma, gender, :nominative, word
|
65
|
+
elsif grammemes.include? 'рд'
|
66
|
+
check! errors, correct, total, lemma, gender, :genitive, word
|
67
|
+
elsif grammemes.include? 'дт'
|
68
|
+
check! errors, correct, total, lemma, gender, :dative, word
|
69
|
+
elsif grammemes.include? 'вн'
|
70
|
+
check! errors, correct, total, lemma, gender, :accusative, word
|
71
|
+
elsif grammemes.include? 'тв'
|
72
|
+
# actually, it's called the instrumetal case
|
73
|
+
check! errors, correct, total, lemma, gender, :instrumental, word
|
74
|
+
elsif grammemes.include? 'пр'
|
75
|
+
check! errors, correct, total, lemma, gender, :prepositional, word
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
total.each do |(gender, gcase), correct_count|
|
81
|
+
precision = correct[[gender, gcase]] / correct_count.to_f * 100
|
82
|
+
puts "\tPr(%s|%s) = %.4f%%" % [gcase, gender, precision]
|
83
|
+
end
|
84
|
+
|
85
|
+
correct_size = correct.values.inject(&:+)
|
86
|
+
total_size = total.values.inject(&:+)
|
87
|
+
puts 'Well, the precision on %d examples is about %.4f%%.' %
|
88
|
+
[total_size, (correct_size / total_size.to_f * 100)]
|
89
|
+
end
|
metadata
CHANGED
@@ -1,32 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: petrovich
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Andrew Kozloff
|
9
|
+
- Dmitry Ustalov
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2013-
|
13
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: unicode_utils
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
17
18
|
none: false
|
18
19
|
requirements:
|
19
|
-
- -
|
20
|
+
- - ~>
|
20
21
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.4
|
22
|
+
version: '1.4'
|
22
23
|
type: :runtime
|
23
24
|
prerelease: false
|
24
25
|
version_requirements: !ruby/object:Gem::Requirement
|
25
26
|
none: false
|
26
27
|
requirements:
|
27
|
-
- -
|
28
|
+
- - ~>
|
28
29
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.4
|
30
|
+
version: '1.4'
|
30
31
|
- !ruby/object:Gem::Dependency
|
31
32
|
name: rspec
|
32
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,6 +64,7 @@ description: Вы задаёте начальное имя в именитель
|
|
63
64
|
вам
|
64
65
|
email:
|
65
66
|
- demerest@gmail.com
|
67
|
+
- dmitry@eveel.ru
|
66
68
|
executables: []
|
67
69
|
extensions: []
|
68
70
|
extra_rdoc_files: []
|
@@ -71,6 +73,7 @@ files:
|
|
71
73
|
- lib/petrovich/rules.rb
|
72
74
|
- lib/petrovich/rules.yml
|
73
75
|
- lib/petrovich.rb
|
76
|
+
- lib/tasks/evaluate.rake
|
74
77
|
- MIT-LICENSE
|
75
78
|
- Rakefile
|
76
79
|
- README.md
|