engtagger 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +4 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +43 -0
- data/Gemfile +1 -0
- data/LICENSE +0 -22
- data/README.md +5 -1
- data/engtagger.gemspec +17 -4
- data/lib/engtagger/version.rb +1 -1
- data/lib/engtagger.rb +26 -24
- metadata +16 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c5c2c223bf80febf6a9130399b5d2a54dbdb043b0c9964289d98863d38572ce
|
|
4
|
+
data.tar.gz: 02ddd1ddee60893ffbd9ae686b382238ef99f6487b7eca38448cae39ec8f5c15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91f5bfaee891d1c455e1a361ccd556714708d60a7c66e3ae0a24780cf2ce66c2fc975433da5b053453444701299b523254ba47bf89e62786368e6ae95300cc42
|
|
7
|
+
data.tar.gz: 8af44f088a545afe81b23009d77cd119949b27e027fdcee13344f68667768f2fd12a5eb89de189ae46ed5cc6f15a30acdcf2e07964b0efad0bc89664f79f1db0
|
data/.gitattributes
ADDED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.4 (2026-08-14)
|
|
4
|
+
|
|
5
|
+
This is the final planned release of the 0.4 line. Version 2.0 replaces the
|
|
6
|
+
HMM engine with an averaged perceptron and does not ship the Penn
|
|
7
|
+
Treebank-derived probability tables, so its tagging output differs. Pin
|
|
8
|
+
`gem "engtagger", "~> 0.4"` to stay on this line; it will receive critical
|
|
9
|
+
fixes only.
|
|
10
|
+
|
|
11
|
+
- Fix the test suite silently rewriting the bundled lexicon files
|
|
12
|
+
(`lib/engtagger/*.hash`) on every run: a path-join bug in the test setup made
|
|
13
|
+
the existence check always fail, so `install` ran before each test. This was
|
|
14
|
+
also the enabler of the 0600-permission contamination behind #20. Tests are
|
|
15
|
+
~6x faster as a result.
|
|
16
|
+
- `get_sentences` now applies its intended punctuation cleanup. Four of its
|
|
17
|
+
five reattachment rules had discarded their results since the original port
|
|
18
|
+
(only the leading-backquote rule was ever applied), and their regexes were
|
|
19
|
+
corrupted by string escaping (`\W` matched a literal "W"). Sentences returned
|
|
20
|
+
by this method now read naturally (`"Lisa Raines, a lawyer,"`,`"$3"`).
|
|
21
|
+
Known limitation carried over from the tokenizer: contractions other than
|
|
22
|
+
possessives remain space-separated (`"I 'm"`, `"is n't"`).
|
|
23
|
+
- Fix the public `WORD` constant, whose regex was corrupted by the same
|
|
24
|
+
escaping problem and matched only `<w>`-style tags.
|
|
25
|
+
- Tag regexes produced by `EngTagger.get_ext` (NUM, NN, SEN, etc.) now end with
|
|
26
|
+
a real `\s*`, so they consume trailing whitespace including newlines instead
|
|
27
|
+
of spaces only.
|
|
28
|
+
- `assign_tag` no longer raises `NoMethodError` for words absent from the
|
|
29
|
+
lexicon; it returns `""` so callers fall back to `"nn"` as designed.
|
|
30
|
+
- `EngTagger::VERSION` is now defined at runtime (`engtagger/version` was not
|
|
31
|
+
required by the library itself).
|
|
32
|
+
- Read and write the Marshal lexicon files in binary mode to avoid corruption
|
|
33
|
+
on Windows.
|
|
34
|
+
- Remove the stray shebang and executable bit from `lib/engtagger.rb`, and the
|
|
35
|
+
obsolete `require "rubygems"`.
|
|
36
|
+
- Clarify licensing: the LICENSE file had a stray MIT license appended after
|
|
37
|
+
the GPLv2 text. The library is licensed as GPL-2.0-or-later; the MIT tail has
|
|
38
|
+
been removed and the gemspec now declares the SPDX identifier.
|
|
39
|
+
- Gemspec: use the https homepage URL, add `metadata` URIs, and drop the
|
|
40
|
+
obsolete `test_files`.
|
|
41
|
+
- Fix a dead test (`text_get_ext` typo) that had never run and would have
|
|
42
|
+
failed if enabled.
|
|
43
|
+
- Note in the README that 0.4.x carries Penn Treebank-derived probability
|
|
44
|
+
tables; 2.x is trained on openly licensed data instead.
|
|
45
|
+
|
|
3
46
|
## 0.4.3
|
|
4
47
|
|
|
5
48
|
- Fix gem packaging that produced files with owner-only (0600) permissions,
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
|
@@ -338,25 +338,3 @@ proprietary programs. If your program is a subroutine library, you may
|
|
|
338
338
|
consider it more useful to permit linking proprietary applications with the
|
|
339
339
|
library. If this is what you want to do, use the GNU Library General
|
|
340
340
|
Public License instead of this License.
|
|
341
|
-
Copyright (c) 2012 Yoichiro Hasebe
|
|
342
|
-
|
|
343
|
-
MIT License
|
|
344
|
-
|
|
345
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
346
|
-
a copy of this software and associated documentation files (the
|
|
347
|
-
"Software"), to deal in the Software without restriction, including
|
|
348
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
349
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
350
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
351
|
-
the following conditions:
|
|
352
|
-
|
|
353
|
-
The above copyright notice and this permission notice shall be
|
|
354
|
-
included in all copies or substantial portions of the Software.
|
|
355
|
-
|
|
356
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
357
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
358
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
359
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
360
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
361
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
362
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
|
@@ -174,4 +174,8 @@ Aaron Coburn, the author of the original Perl version.
|
|
|
174
174
|
|
|
175
175
|
## License
|
|
176
176
|
|
|
177
|
-
This library is distributed under the GPL. Please see the LICENSE file.
|
|
177
|
+
This library is distributed under the GPL (GPL-2.0-or-later). Please see the LICENSE file.
|
|
178
|
+
|
|
179
|
+
The 0.4 line ships probability tables derived from the Penn Treebank. Version
|
|
180
|
+
2.0 drops them in favour of a model trained on openly licensed corpora; if the
|
|
181
|
+
provenance of the bundled data matters for your use, prefer 2.x.
|
data/engtagger.gemspec
CHANGED
|
@@ -7,16 +7,29 @@ Gem::Specification.new do |gem|
|
|
|
7
7
|
gem.email = ["yohasebe@gmail.com"]
|
|
8
8
|
gem.summary = "A probability based, corpus-trained English POS tagger"
|
|
9
9
|
gem.description = "A Ruby port of Perl Lingua::EN::Tagger, a probability based, corpus-trained tagger that assigns POS tags to English text based on a lookup dictionary and a set of probability values."
|
|
10
|
-
gem.homepage = "
|
|
11
|
-
gem.license = "GPL"
|
|
10
|
+
gem.homepage = "https://github.com/yohasebe/engtagger"
|
|
11
|
+
gem.license = "GPL-2.0-or-later"
|
|
12
12
|
gem.required_ruby_version = Gem::Requirement.new(">= 2.6")
|
|
13
13
|
gem.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
14
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
14
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|tools|docs)/}) }
|
|
15
15
|
end
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
17
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
17
|
gem.name = "engtagger"
|
|
18
|
+
gem.metadata = {
|
|
19
|
+
"source_code_uri" => "https://github.com/yohasebe/engtagger",
|
|
20
|
+
"changelog_uri" => "https://github.com/yohasebe/engtagger/blob/master/CHANGELOG.md",
|
|
21
|
+
"bug_tracker_uri" => "https://github.com/yohasebe/engtagger/issues"
|
|
22
|
+
}
|
|
19
23
|
gem.require_paths = ["lib"]
|
|
20
24
|
gem.version = EngTagger::VERSION
|
|
21
25
|
gem.add_dependency "sin_lru_redux"
|
|
26
|
+
gem.post_install_message = <<~MESSAGE
|
|
27
|
+
EngTagger 0.4.4 is the final planned release of the 0.4 line.
|
|
28
|
+
|
|
29
|
+
Version 2.0 replaces the HMM engine with an averaged perceptron trained on
|
|
30
|
+
openly licensed data. It is considerably more accurate, and its tagging
|
|
31
|
+
output differs, so treat it as a rewrite rather than an upgrade.
|
|
32
|
+
|
|
33
|
+
To stay on this line, pin it: gem "engtagger", "~> 0.4"
|
|
34
|
+
MESSAGE
|
|
22
35
|
end
|
data/lib/engtagger/version.rb
CHANGED
data/lib/engtagger.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
1
|
# frozen_string_literal: true
|
|
4
2
|
|
|
5
|
-
require "rubygems"
|
|
6
3
|
require "lru_redux"
|
|
7
|
-
require_relative "
|
|
4
|
+
require_relative "engtagger/version"
|
|
5
|
+
require_relative "engtagger/porter"
|
|
8
6
|
|
|
9
7
|
module BoundedSpaceMemoizable
|
|
10
8
|
def memoize(method, max_cache_size = 100_000)
|
|
@@ -52,7 +50,7 @@ class EngTagger
|
|
|
52
50
|
def self.get_ext(tag = nil)
|
|
53
51
|
return nil unless tag
|
|
54
52
|
|
|
55
|
-
Regexp.new("<#{tag}>[^<]+</#{tag}
|
|
53
|
+
Regexp.new("<#{tag}>[^<]+</#{tag}>\\s*")
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
# Regexps to match XML-style part-of-speech tags
|
|
@@ -66,7 +64,7 @@ class EngTagger
|
|
|
66
64
|
PAREN = get_ext("[lr]rb")
|
|
67
65
|
QUOT = get_ext("ppr")
|
|
68
66
|
SEN = get_ext("pp")
|
|
69
|
-
WORD = get_ext("
|
|
67
|
+
WORD = get_ext("\\w+")
|
|
70
68
|
VB = get_ext("vb")
|
|
71
69
|
VBG = get_ext("vbg")
|
|
72
70
|
VBD = get_ext("vbd")
|
|
@@ -97,7 +95,7 @@ class EngTagger
|
|
|
97
95
|
TAGS[tag] || tag
|
|
98
96
|
end
|
|
99
97
|
|
|
100
|
-
# The
|
|
98
|
+
# The following is to make a hash to convert a pos tag to its definition
|
|
101
99
|
# used by the explain_tag method
|
|
102
100
|
tags = [
|
|
103
101
|
"CC", "Conjunction, coordinating",
|
|
@@ -157,7 +155,7 @@ class EngTagger
|
|
|
157
155
|
# => (Boolean) Stem single words using Porter module
|
|
158
156
|
# * :weight_noun_phrases
|
|
159
157
|
# => (Boolean) When returning occurrence counts for a noun phrase, multiply
|
|
160
|
-
# the
|
|
158
|
+
# the value by the number of words in the NP.
|
|
161
159
|
# * :longest_noun_phrase
|
|
162
160
|
# => (Integer) Will ignore noun phrases longer than this threshold. This
|
|
163
161
|
# affects only the get_words() and get_nouns() methods.
|
|
@@ -200,7 +198,7 @@ class EngTagger
|
|
|
200
198
|
@conf[:word_path] = DEFAULT_WORDPATH
|
|
201
199
|
@conf[:tag_path] = DEFAULT_TAGPATH
|
|
202
200
|
@conf[:debug] = false
|
|
203
|
-
# assuming that we start analyzing from the
|
|
201
|
+
# assuming that we start analyzing from the beginning of a new sentence...
|
|
204
202
|
@conf[:current_tag] = "pp"
|
|
205
203
|
@conf.merge!(params) if params
|
|
206
204
|
if !File.exist?(@conf[:word_path]) || !File.exist?(@conf[:tag_path])
|
|
@@ -208,10 +206,10 @@ class EngTagger
|
|
|
208
206
|
@@hmm = {}
|
|
209
207
|
@@lexicon = {}
|
|
210
208
|
else
|
|
211
|
-
lexf = File.open(@conf[:word_path], "
|
|
209
|
+
lexf = File.open(@conf[:word_path], "rb")
|
|
212
210
|
@@lexicon = Marshal.load(lexf)
|
|
213
211
|
lexf.close
|
|
214
|
-
hmmf = File.open(@conf[:tag_path], "
|
|
212
|
+
hmmf = File.open(@conf[:tag_path], "rb")
|
|
215
213
|
@@hmm = Marshal.load(hmmf)
|
|
216
214
|
hmmf.close
|
|
217
215
|
end
|
|
@@ -304,12 +302,16 @@ class EngTagger
|
|
|
304
302
|
tagged.split(%r{</pp>}).each do |line|
|
|
305
303
|
sentences << strip_tags(line)
|
|
306
304
|
end
|
|
307
|
-
sentences
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
sentence.gsub(
|
|
305
|
+
sentences.map do |sentence|
|
|
306
|
+
# Reattach punctuation to the neighboring word: opening quotes/brackets
|
|
307
|
+
# and currency signs join the following word, everything else (commas,
|
|
308
|
+
# closing marks, possessives) joins the preceding word. (These gsub
|
|
309
|
+
# results used to be discarded, so none of this cleanup was applied.)
|
|
310
|
+
sentence.gsub(/ ('s?) /) { "#{$1} " }
|
|
311
|
+
.gsub(/ ([`(\[{$]+) /) { " #{$1}" }
|
|
312
|
+
.gsub(/ ([^\w\s`(\[{$]+) /) { "#{$1} " }
|
|
313
|
+
.gsub(/ ([^\w\s]+)\z/) { $1 }
|
|
314
|
+
.gsub(/\A([`(\[{$]+) /) { $1 }
|
|
313
315
|
end
|
|
314
316
|
end
|
|
315
317
|
|
|
@@ -360,7 +362,7 @@ class EngTagger
|
|
|
360
362
|
build_matches_hash(build_trimmed(tagged, tags))
|
|
361
363
|
end
|
|
362
364
|
|
|
363
|
-
# Returns all types of verbs and does not
|
|
365
|
+
# Returns all types of verbs and does not discriminate between the
|
|
364
366
|
# various kinds. Combines all other verb methods listed in this
|
|
365
367
|
# class.
|
|
366
368
|
#
|
|
@@ -588,10 +590,10 @@ class EngTagger
|
|
|
588
590
|
load_tags(@conf[:tag_lex])
|
|
589
591
|
load_words(@conf[:word_lex])
|
|
590
592
|
load_words(@conf[:unknown_lex])
|
|
591
|
-
File.open(@conf[:word_path], "
|
|
593
|
+
File.open(@conf[:word_path], "wb") do |f|
|
|
592
594
|
Marshal.dump(@@lexicon, f)
|
|
593
595
|
end
|
|
594
|
-
File.open(@conf[:tag_path], "
|
|
596
|
+
File.open(@conf[:tag_path], "wb") do |f|
|
|
595
597
|
Marshal.dump(@@hmm, f)
|
|
596
598
|
end
|
|
597
599
|
end
|
|
@@ -635,7 +637,7 @@ class EngTagger
|
|
|
635
637
|
@conf[:stem] ? word.stem : word
|
|
636
638
|
end
|
|
637
639
|
|
|
638
|
-
# This method will reset the
|
|
640
|
+
# This method will reset the preceding tag to a sentence ender (PP).
|
|
639
641
|
# This prepares the first word of a new sentence to be tagged correctly.
|
|
640
642
|
def reset
|
|
641
643
|
@conf[:current_tag] = "pp"
|
|
@@ -705,7 +707,7 @@ class EngTagger
|
|
|
705
707
|
end
|
|
706
708
|
words = []
|
|
707
709
|
tokenized.each_with_index do |_, i|
|
|
708
|
-
if tokenized[i + 1] && tokenized
|
|
710
|
+
if tokenized[i + 1] && tokenized[i + 1] =~ /[A-Z\W]/ && tokenized[i] =~ /\A(.+)\.\z/
|
|
709
711
|
w = $1
|
|
710
712
|
# Don't separate the period off words that
|
|
711
713
|
# meet any of the following conditions:
|
|
@@ -772,13 +774,13 @@ class EngTagger
|
|
|
772
774
|
return "sym"
|
|
773
775
|
end
|
|
774
776
|
best_so_far = 0
|
|
775
|
-
w = @@lexicon[word]
|
|
777
|
+
w = @@lexicon[word] || {}
|
|
776
778
|
t = @@hmm
|
|
777
779
|
|
|
778
780
|
# TAG THE TEXT: What follows is a modified version of the Viterbi algorithm
|
|
779
781
|
# which is used in most POS taggers
|
|
780
782
|
best_tag = ""
|
|
781
|
-
t[prev_tag].each_key do |tag|
|
|
783
|
+
(t[prev_tag] || {}).each_key do |tag|
|
|
782
784
|
# With @config[:relax] set, this method
|
|
783
785
|
# will also include any `open classes' of POS tags
|
|
784
786
|
pw = 0
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: engtagger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yoichiro Hasebe
|
|
@@ -32,6 +32,7 @@ executables: []
|
|
|
32
32
|
extensions: []
|
|
33
33
|
extra_rdoc_files: []
|
|
34
34
|
files:
|
|
35
|
+
- ".gitattributes"
|
|
35
36
|
- ".gitignore"
|
|
36
37
|
- ".rubocop.yml"
|
|
37
38
|
- ".solargraph.yml"
|
|
@@ -50,10 +51,21 @@ files:
|
|
|
50
51
|
- lib/engtagger/unknown.yml
|
|
51
52
|
- lib/engtagger/version.rb
|
|
52
53
|
- lib/engtagger/words.yml
|
|
53
|
-
homepage:
|
|
54
|
+
homepage: https://github.com/yohasebe/engtagger
|
|
54
55
|
licenses:
|
|
55
|
-
- GPL
|
|
56
|
-
metadata:
|
|
56
|
+
- GPL-2.0-or-later
|
|
57
|
+
metadata:
|
|
58
|
+
source_code_uri: https://github.com/yohasebe/engtagger
|
|
59
|
+
changelog_uri: https://github.com/yohasebe/engtagger/blob/master/CHANGELOG.md
|
|
60
|
+
bug_tracker_uri: https://github.com/yohasebe/engtagger/issues
|
|
61
|
+
post_install_message: |
|
|
62
|
+
EngTagger 0.4.4 is the final planned release of the 0.4 line.
|
|
63
|
+
|
|
64
|
+
Version 2.0 replaces the HMM engine with an averaged perceptron trained on
|
|
65
|
+
openly licensed data. It is considerably more accurate, and its tagging
|
|
66
|
+
output differs, so treat it as a rewrite rather than an upgrade.
|
|
67
|
+
|
|
68
|
+
To stay on this line, pin it: gem "engtagger", "~> 0.4"
|
|
57
69
|
rdoc_options: []
|
|
58
70
|
require_paths:
|
|
59
71
|
- lib
|