natural 6.10.2 → 6.10.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.
Files changed (44) hide show
  1. package/.gitconfig +3 -0
  2. package/.github/workflows/node.js.yml +1 -1
  3. package/.github/workflows/npm-publish.yml +4 -4
  4. package/lib/natural/brill_pos_tagger/index.d.ts +32 -26
  5. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tagger.js +33 -31
  6. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tester.js +33 -35
  7. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Trainer.js +326 -324
  8. package/lib/natural/brill_pos_tagger/lib/Corpus.js +140 -138
  9. package/lib/natural/brill_pos_tagger/lib/Lexicon.js +78 -76
  10. package/lib/natural/brill_pos_tagger/lib/Predicate.js +19 -17
  11. package/lib/natural/brill_pos_tagger/lib/RuleSet.js +58 -56
  12. package/lib/natural/brill_pos_tagger/lib/RuleTemplate.js +11 -9
  13. package/lib/natural/brill_pos_tagger/lib/Sentence.js +21 -20
  14. package/lib/natural/brill_pos_tagger/lib/TransformationRule.js +58 -58
  15. package/lib/natural/classifiers/bayes_classifier.js +24 -29
  16. package/lib/natural/classifiers/classifier.js +136 -121
  17. package/lib/natural/classifiers/logistic_regression_classifier.js +33 -37
  18. package/lib/natural/classifiers/maxent/Classifier.js +81 -79
  19. package/lib/natural/classifiers/maxent/Context.js +11 -9
  20. package/lib/natural/classifiers/maxent/Distribution.js +107 -105
  21. package/lib/natural/classifiers/maxent/Element.js +12 -10
  22. package/lib/natural/classifiers/maxent/Feature.js +56 -54
  23. package/lib/natural/classifiers/maxent/FeatureSet.js +40 -38
  24. package/lib/natural/classifiers/maxent/GISScaler.js +110 -109
  25. package/lib/natural/classifiers/maxent/POS/ME_Corpus.js +26 -31
  26. package/lib/natural/classifiers/maxent/POS/ME_Sentence.js +37 -42
  27. package/lib/natural/classifiers/maxent/POS/POS_Element.js +119 -124
  28. package/lib/natural/classifiers/maxent/Sample.js +96 -94
  29. package/lib/natural/classifiers/maxent/SimpleExample/SE_Element.js +14 -20
  30. package/lib/natural/inflectors/fr/count_inflector.js +1 -1
  31. package/lib/natural/inflectors/fr/noun_inflector.js +179 -196
  32. package/lib/natural/inflectors/ja/noun_inflector.js +67 -84
  33. package/lib/natural/inflectors/noun_inflector.js +124 -139
  34. package/lib/natural/inflectors/present_verb_inflector.js +34 -48
  35. package/lib/natural/inflectors/singular_plural_inflector.js +62 -61
  36. package/lib/natural/tfidf/tfidf.js +118 -114
  37. package/lib/natural/trie/trie.js +161 -159
  38. package/lib/natural/util/directed_edge.js +49 -0
  39. package/lib/natural/util/edge_weighted_digraph.js +54 -74
  40. package/lib/natural/util/index.js +1 -0
  41. package/lib/natural/util/longest_path_tree.js +54 -52
  42. package/lib/natural/util/shortest_path_tree.js +56 -54
  43. package/lib/natural/util/topological.js +17 -15
  44. package/package.json +1 -1
@@ -23,152 +23,147 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
 
24
24
  'use strict'
25
25
 
26
- const util = require('util')
27
26
  const Element = require('../Element')
28
27
  const Feature = require('../Feature')
29
28
 
30
- function POSElement (a, b) {
31
- POSElement.super_.call(this, a, b)
32
- }
33
-
34
- util.inherits(POSElement, Element)
35
-
36
- POSElement.prototype.generateFeatures = function (featureSet) {
37
- const context = this.b.data
38
- const tag = this.a
39
- const token = context.wordWindow['0']
29
+ class POSElement extends Element {
30
+ generateFeatures (featureSet) {
31
+ const context = this.b.data
32
+ const tag = this.a
33
+ const token = context.wordWindow['0']
40
34
 
41
- // Feature for the current word
42
- function currentWord (x) {
43
- if ((x.b.data.wordWindow['0'] === token) &&
44
- (x.a === tag)) {
45
- return 1
46
- }
47
- return 0
48
- }
49
- featureSet.addFeature(new Feature(currentWord, 'wordFeature', ['0', token, '0', tag]))
50
-
51
- // Feature for previous bigram (previous two tags), positions -2, -1
52
- if (context.tagWindow['-2']) {
53
- const prevPrevTag = context.tagWindow['-2']
54
- const prevTag = context.tagWindow['-1']
55
- function prevBigram (x) {
56
- if ((x.a === tag) &&
57
- (x.b.data.tagWindow['-2'] === prevPrevTag) &&
58
- (x.b.data.tagWindow['-1'] === prevTag)) {
35
+ // Feature for the current word
36
+ function currentWord (x) {
37
+ if ((x.b.data.wordWindow['0'] === token) &&
38
+ (x.a === tag)) {
59
39
  return 1
60
40
  }
61
41
  return 0
62
42
  }
63
- featureSet.addFeature(new Feature(prevBigram, 'prevBigram', ['0', tag, '-2', prevPrevTag, '-1', prevTag]))
64
- }
65
-
66
- /*
67
- // Feature for left bigram, positions -1, 0
68
- if (context.tagWindow["-1"]) {
69
- var prevTag = context.tagWindow["-1"];
70
- function leftBigram(x) {
71
- if ((x.b.data.tagWindow["-1"] === prevTag) &&
72
- (x.a === tag)) {
73
- return 1;
43
+ featureSet.addFeature(new Feature(currentWord, 'wordFeature', ['0', token, '0', tag]))
44
+
45
+ // Feature for previous bigram (previous two tags), positions -2, -1
46
+ if (context.tagWindow['-2']) {
47
+ const prevPrevTag = context.tagWindow['-2']
48
+ const prevTag = context.tagWindow['-1']
49
+ function prevBigram (x) {
50
+ if ((x.a === tag) &&
51
+ (x.b.data.tagWindow['-2'] === prevPrevTag) &&
52
+ (x.b.data.tagWindow['-1'] === prevTag)) {
53
+ return 1
74
54
  }
75
- return 0;
55
+ return 0
56
+ }
57
+ featureSet.addFeature(new Feature(prevBigram, 'prevBigram', ['0', tag, '-2', prevPrevTag, '-1', prevTag]))
76
58
  }
77
- featureSet.addFeature(new Feature(leftBigram, "leftBigram", ["0", tag, "-1", prevTag]));
78
- }
79
- */
80
59
 
81
- /*
82
-
83
- // Feature for right bigram, positions 0, 1
84
- if (context.tagWindow["1"]) {
85
- var nextTag = context.tagWindow["1"];
86
- function rightBigram(x) {
87
- if ((x.a === tag) &&
88
- (x.b.data.tagWindow["1"] === nextTag)) {
89
- return 1;
90
- }
91
- return 0;
60
+ /*
61
+ // Feature for left bigram, positions -1, 0
62
+ if (context.tagWindow["-1"]) {
63
+ var prevTag = context.tagWindow["-1"];
64
+ function leftBigram(x) {
65
+ if ((x.b.data.tagWindow["-1"] === prevTag) &&
66
+ (x.a === tag)) {
67
+ return 1;
68
+ }
69
+ return 0;
70
+ }
71
+ featureSet.addFeature(new Feature(leftBigram, "leftBigram", ["0", tag, "-1", prevTag]));
92
72
  }
93
- featureSet.addFeature(new Feature(rightBigram, "rightBigram", ["0", tag, "1", nextTag]));
94
- }
95
- */
96
- /*
97
- // Feature for next bigram (next two tags), positions 1 and 2
98
- if (context.tagWindow["2"]) {
99
- var nextTag = context.tagWindow["1"];
100
- var nextNextTag = context.tagWindow["2"];
101
- function nextBigram(x) {
102
- if ((x.a === tag) &&
103
- (x.b.data.tagWindow["1"] === nextTag) &&
104
- (x.b.data.tagWindow["2"] === nextNextTag)) {
105
- return 1;
106
- }
107
- return 0;
73
+ */
74
+
75
+ /*
76
+
77
+ // Feature for right bigram, positions 0, 1
78
+ if (context.tagWindow["1"]) {
79
+ var nextTag = context.tagWindow["1"];
80
+ function rightBigram(x) {
81
+ if ((x.a === tag) &&
82
+ (x.b.data.tagWindow["1"] === nextTag)) {
83
+ return 1;
84
+ }
85
+ return 0;
86
+ }
87
+ featureSet.addFeature(new Feature(rightBigram, "rightBigram", ["0", tag, "1", nextTag]));
108
88
  }
109
- featureSet.addFeature(new Feature(nextBigram, "nextBigram", ["0", tag, "1", nextTag, "2", nextNextTag]));
110
- }
111
-
112
- // Feature that looks at the left bigram words
113
- if (context.wordWindow["-1"]) {
114
- var prevWord = context.wordWindow["-1"];
115
- function leftBigramWords(x) {
116
- if ((x.a === tag) &&
117
- (x.b.data.wordWindow["0"] === token) &&
118
- (x.b.data.wordWindow["-1"] === prevWord)) {
119
- return 1;
120
- }
121
- return 0;
89
+ */
90
+ /*
91
+ // Feature for next bigram (next two tags), positions 1 and 2
92
+ if (context.tagWindow["2"]) {
93
+ var nextTag = context.tagWindow["1"];
94
+ var nextNextTag = context.tagWindow["2"];
95
+ function nextBigram(x) {
96
+ if ((x.a === tag) &&
97
+ (x.b.data.tagWindow["1"] === nextTag) &&
98
+ (x.b.data.tagWindow["2"] === nextNextTag)) {
99
+ return 1;
100
+ }
101
+ return 0;
102
+ }
103
+ featureSet.addFeature(new Feature(nextBigram, "nextBigram", ["0", tag, "1", nextTag, "2", nextNextTag]));
122
104
  }
123
- featureSet.addFeature(new Feature(leftBigramWords, "leftBigramWords", ["0", tag, "0", token, "-1", prevWord]));
124
- }
125
105
 
126
- // Feature that looks at the right bigram words
127
- if (context.wordWindow["1"]) {
128
- var nextWord = context.wordWindow["1"];
129
- function rightBigramWords(x) {
130
- if ((x.a === tag) &&
131
- (x.b.data.wordWindow["0"] === token) &&
132
- (x.b.data.wordWindow["1"] === nextWord)) {
133
- return 1;
134
- }
135
- return 0;
106
+ // Feature that looks at the left bigram words
107
+ if (context.wordWindow["-1"]) {
108
+ var prevWord = context.wordWindow["-1"];
109
+ function leftBigramWords(x) {
110
+ if ((x.a === tag) &&
111
+ (x.b.data.wordWindow["0"] === token) &&
112
+ (x.b.data.wordWindow["-1"] === prevWord)) {
113
+ return 1;
114
+ }
115
+ return 0;
116
+ }
117
+ featureSet.addFeature(new Feature(leftBigramWords, "leftBigramWords", ["0", tag, "0", token, "-1", prevWord]));
136
118
  }
137
- featureSet.addFeature(new Feature(rightBigramWords, "rightBigramWords", ["0", tag, "0", token, "1", nextWord]));
138
- }
139
- */
140
119
 
141
- // Feature that looks at the previous word and its category
142
- if (context.wordWindow['-1']) {
143
- const prevWord = context.wordWindow['-1']
144
- const prevTag = context.tagWindow['-1']
145
- function prevWordAndCat (x) {
146
- if ((x.a === tag) &&
147
- (x.b.data.wordWindow['-1'] === prevWord) &&
148
- (x.b.data.tagWindow['-1'] === prevTag)) {
149
- return 1
120
+ // Feature that looks at the right bigram words
121
+ if (context.wordWindow["1"]) {
122
+ var nextWord = context.wordWindow["1"];
123
+ function rightBigramWords(x) {
124
+ if ((x.a === tag) &&
125
+ (x.b.data.wordWindow["0"] === token) &&
126
+ (x.b.data.wordWindow["1"] === nextWord)) {
127
+ return 1;
128
+ }
129
+ return 0;
150
130
  }
151
- return 0
131
+ featureSet.addFeature(new Feature(rightBigramWords, "rightBigramWords", ["0", tag, "0", token, "1", nextWord]));
152
132
  }
153
- featureSet.addFeature(new Feature(prevWordAndCat, 'prevWordAndCat', ['0', tag, '-1', prevWord, '-1', prevTag]))
154
- }
155
-
156
- /*
157
- // Feature that looks at the next word and its category
158
- if (context.wordWindow["1"]) {
159
- var nextWord = context.wordWindow["1"];
160
- var nextTag = context.tagWindow["1"];
161
- function nextWordAndCat(x) {
162
- if ((x.a === tag) &&
163
- (x.b.data.wordWindow["1"] === nextWord) &&
164
- (x.b.data.tagWindow["1"] === nextTag)) {
165
- return 1;
133
+ */
134
+
135
+ // Feature that looks at the previous word and its category
136
+ if (context.wordWindow['-1']) {
137
+ const prevWord = context.wordWindow['-1']
138
+ const prevTag = context.tagWindow['-1']
139
+ function prevWordAndCat (x) {
140
+ if ((x.a === tag) &&
141
+ (x.b.data.wordWindow['-1'] === prevWord) &&
142
+ (x.b.data.tagWindow['-1'] === prevTag)) {
143
+ return 1
166
144
  }
167
- return 0;
145
+ return 0
146
+ }
147
+ featureSet.addFeature(new Feature(prevWordAndCat, 'prevWordAndCat', ['0', tag, '-1', prevWord, '-1', prevTag]))
168
148
  }
169
- featureSet.addFeature(new Feature(nextWordAndCat, "nextWordAndCat", ["0", tag, "1", nextWord, "1", nextTag]));
149
+
150
+ /*
151
+ // Feature that looks at the next word and its category
152
+ if (context.wordWindow["1"]) {
153
+ var nextWord = context.wordWindow["1"];
154
+ var nextTag = context.tagWindow["1"];
155
+ function nextWordAndCat(x) {
156
+ if ((x.a === tag) &&
157
+ (x.b.data.wordWindow["1"] === nextWord) &&
158
+ (x.b.data.tagWindow["1"] === nextTag)) {
159
+ return 1;
160
+ }
161
+ return 0;
162
+ }
163
+ featureSet.addFeature(new Feature(nextWordAndCat, "nextWordAndCat", ["0", tag, "1", nextWord, "1", nextTag]));
164
+ }
165
+ */
170
166
  }
171
- */
172
167
  }
173
168
 
174
169
  module.exports = POSElement
@@ -27,117 +27,119 @@ const Context = require('./Context')
27
27
 
28
28
  const fs = require('fs')
29
29
 
30
- function Sample (elements) {
31
- this.frequencyOfContext = {}
32
- this.frequency = {}
33
- this.classes = []
34
- if (elements) {
35
- this.elements = elements
36
- this.analyse()
37
- } else {
38
- this.elements = []
30
+ class Sample {
31
+ constructor (elements) {
32
+ this.frequencyOfContext = {}
33
+ this.frequency = {}
34
+ this.classes = []
35
+ if (elements) {
36
+ this.elements = elements
37
+ this.analyse()
38
+ } else {
39
+ this.elements = []
40
+ }
39
41
  }
40
- }
41
42
 
42
- // Extracts classes and frequencies
43
- Sample.prototype.analyse = function () {
44
- const that = this
45
- this.elements.forEach(function (x) {
46
- if (this.classes.indexOf(x.a) === -1) {
47
- this.classes.push(x.a)
43
+ // Extracts classes and frequencies
44
+ analyse () {
45
+ const that = this
46
+ this.elements.forEach(function (x) {
47
+ if (this.classes.indexOf(x.a) === -1) {
48
+ this.classes.push(x.a)
49
+ }
50
+ if (!that.frequencyOfContext[x.b.toString()]) {
51
+ that.frequencyOfContext[x.b.toString()] = 0
52
+ }
53
+ that.frequencyOfContext[x.b.toString()]++
54
+ if (!that.frequency[x.toString()]) {
55
+ that.frequency[x.toString()] = 0
56
+ }
57
+ that.frequency[x.toString()]++
58
+ })
59
+ }
60
+
61
+ addElement (x) {
62
+ this.elements.push(x)
63
+ // Update frequencies
64
+ if (!this.frequencyOfContext[x.b.toString()]) {
65
+ this.frequencyOfContext[x.b.toString()] = 0
48
66
  }
49
- if (!that.frequencyOfContext[x.b.toString()]) {
50
- that.frequencyOfContext[x.b.toString()] = 0
67
+ this.frequencyOfContext[x.b.toString()]++
68
+ if (!this.frequency[x.toString()]) {
69
+ this.frequency[x.toString()] = 0
51
70
  }
52
- that.frequencyOfContext[x.b.toString()]++
53
- if (!that.frequency[x.toString()]) {
54
- that.frequency[x.toString()] = 0
71
+ this.frequency[x.toString()]++
72
+ // Update classes
73
+ if (this.classes.indexOf(x.a) === -1) {
74
+ this.classes.push(x.a)
55
75
  }
56
- that.frequency[x.toString()]++
57
- })
58
- }
59
-
60
- Sample.prototype.addElement = function (x) {
61
- this.elements.push(x)
62
- // Update frequencies
63
- if (!this.frequencyOfContext[x.b.toString()]) {
64
- this.frequencyOfContext[x.b.toString()] = 0
65
- }
66
- this.frequencyOfContext[x.b.toString()]++
67
- if (!this.frequency[x.toString()]) {
68
- this.frequency[x.toString()] = 0
69
76
  }
70
- this.frequency[x.toString()]++
71
- // Update classes
72
- if (this.classes.indexOf(x.a) === -1) {
73
- this.classes.push(x.a)
74
- }
75
- }
76
77
 
77
- Sample.prototype.observedProbabilityOfContext = function (context) {
78
- if (this.frequencyOfContext[context.toString()]) {
79
- return this.frequencyOfContext[context.toString()] / this.elements.length
80
- } else {
81
- return 0
78
+ observedProbabilityOfContext (context) {
79
+ if (this.frequencyOfContext[context.toString()]) {
80
+ return this.frequencyOfContext[context.toString()] / this.elements.length
81
+ } else {
82
+ return 0
83
+ }
82
84
  }
83
- }
84
85
 
85
- Sample.prototype.observedProbability = function (x) {
86
- if (this.frequency[x.toString()]) {
87
- return this.frequency[x.toString()] / this.elements.length
88
- } else {
89
- return 0
86
+ observedProbability (x) {
87
+ if (this.frequency[x.toString()]) {
88
+ return this.frequency[x.toString()] / this.elements.length
89
+ } else {
90
+ return 0
91
+ }
90
92
  }
91
- }
92
-
93
- Sample.prototype.size = function () {
94
- return this.elements.length
95
- }
96
93
 
97
- Sample.prototype.getClasses = function () {
98
- return this.classes
99
- }
94
+ size () {
95
+ return this.elements.length
96
+ }
100
97
 
101
- Sample.prototype.generateFeatures = function (featureSet) {
102
- this.elements.forEach(function (x) {
103
- x.generateFeatures(featureSet)
104
- })
105
- }
98
+ getClasses () {
99
+ return this.classes
100
+ }
106
101
 
107
- Sample.prototype.save = function (filename, callback) {
108
- const sample = this
109
- const data = JSON.stringify(this, null, 2)
110
- fs.writeFile(filename, data, 'utf8', function (err) {
111
- // console.log('Sample written')
112
- if (callback) {
113
- callback(err, err ? null : sample)
114
- }
115
- })
116
- }
102
+ generateFeatures (featureSet) {
103
+ this.elements.forEach(function (x) {
104
+ x.generateFeatures(featureSet)
105
+ })
106
+ }
117
107
 
118
- // Loads a sample from file and revives the right classes, i.e. Sample and
119
- // Element classes.
120
- Sample.prototype.load = function (filename, ElementClass, callback) {
121
- fs.readFile(filename, 'utf8', function (err, data) {
122
- if (!err) {
123
- const sampleData = JSON.parse(data)
124
- const sample = new Sample()
125
- sampleData.elements.forEach(function (elementData) {
126
- const elt = new ElementClass(elementData.a, new Context(elementData.b.data))
127
- sample.addElement(elt)
128
- })
129
- if (!sample.frequency || !sample.frequencyOfContext) {
130
- sample.analyse()
131
- }
108
+ save (filename, callback) {
109
+ const sample = this
110
+ const data = JSON.stringify(this, null, 2)
111
+ fs.writeFile(filename, data, 'utf8', function (err) {
112
+ // console.log('Sample written')
132
113
  if (callback) {
133
- callback(err, sample)
114
+ callback(err, err ? null : sample)
134
115
  }
135
- } else {
136
- if (callback) {
137
- callback(err)
116
+ })
117
+ }
118
+
119
+ // Loads a sample from file and revives the right classes, i.e. Sample and
120
+ // Element classes.
121
+ load (filename, ElementClass, callback) {
122
+ fs.readFile(filename, 'utf8', function (err, data) {
123
+ if (!err) {
124
+ const sampleData = JSON.parse(data)
125
+ const sample = new Sample()
126
+ sampleData.elements.forEach(function (elementData) {
127
+ const elt = new ElementClass(elementData.a, new Context(elementData.b.data))
128
+ sample.addElement(elt)
129
+ })
130
+ if (!sample.frequency || !sample.frequencyOfContext) {
131
+ sample.analyse()
132
+ }
133
+ if (callback) {
134
+ callback(err, sample)
135
+ }
136
+ } else {
137
+ if (callback) {
138
+ callback(err)
139
+ }
138
140
  }
139
- }
140
- })
141
+ })
142
+ }
141
143
  }
142
144
 
143
145
  module.exports = Sample
@@ -23,33 +23,27 @@ THE SOFTWARE.
23
23
 
24
24
  'use strict'
25
25
 
26
- const util = require('util')
27
-
28
26
  const Element = require('../Element')
29
27
  const Feature = require('../Feature')
30
28
 
31
- function SEElement (a, b) {
32
- SEElement.super_.call(this, a, b)
33
- }
34
-
35
- util.inherits(SEElement, Element)
36
-
37
- SEElement.prototype.generateFeatures = function (featureSet) {
38
- function isZero (x) {
39
- if ((x.a === 'x') && (x.b.data === '0')) {
40
- return 1
29
+ class SEElement extends Element {
30
+ generateFeatures (featureSet) {
31
+ function isZero (x) {
32
+ if ((x.a === 'x') && (x.b.data === '0')) {
33
+ return 1
34
+ }
35
+ return 0
41
36
  }
42
- return 0
43
- }
44
- featureSet.addFeature(new Feature(isZero, 'isZero', ['0']))
37
+ featureSet.addFeature(new Feature(isZero, 'isZero', ['0']))
45
38
 
46
- function isOne (x) {
47
- if ((x.a === 'y') && (x.b.data === '1')) {
48
- return 1
39
+ function isOne (x) {
40
+ if ((x.a === 'y') && (x.b.data === '1')) {
41
+ return 1
42
+ }
43
+ return 0
49
44
  }
50
- return 0
45
+ featureSet.addFeature(new Feature(isOne, 'isOne', ['1']))
51
46
  }
52
- featureSet.addFeature(new Feature(isOne, 'isOne', ['1']))
53
47
  }
54
48
 
55
49
  module.exports = SEElement
@@ -26,7 +26,7 @@ THE SOFTWARE.
26
26
  * Numeral inflector for French.
27
27
  * @see http://fr.wikipedia.org/wiki/Ier_si%C3%A8cle
28
28
  *
29
- * Also handles roman numerals as a bonus. The rules are the same than for their
29
+ * Also handles roman numerals as a bonus. The rules are the same as for their
30
30
  * arabic numerals equivalent.
31
31
  *
32
32
  * \@todo Add inflector for gender and number. Ex: