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.
- package/.gitconfig +3 -0
- package/.github/workflows/node.js.yml +1 -1
- package/.github/workflows/npm-publish.yml +4 -4
- package/lib/natural/brill_pos_tagger/index.d.ts +32 -26
- package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tagger.js +33 -31
- package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tester.js +33 -35
- package/lib/natural/brill_pos_tagger/lib/Brill_POS_Trainer.js +326 -324
- package/lib/natural/brill_pos_tagger/lib/Corpus.js +140 -138
- package/lib/natural/brill_pos_tagger/lib/Lexicon.js +78 -76
- package/lib/natural/brill_pos_tagger/lib/Predicate.js +19 -17
- package/lib/natural/brill_pos_tagger/lib/RuleSet.js +58 -56
- package/lib/natural/brill_pos_tagger/lib/RuleTemplate.js +11 -9
- package/lib/natural/brill_pos_tagger/lib/Sentence.js +21 -20
- package/lib/natural/brill_pos_tagger/lib/TransformationRule.js +58 -58
- package/lib/natural/classifiers/bayes_classifier.js +24 -29
- package/lib/natural/classifiers/classifier.js +136 -121
- package/lib/natural/classifiers/logistic_regression_classifier.js +33 -37
- package/lib/natural/classifiers/maxent/Classifier.js +81 -79
- package/lib/natural/classifiers/maxent/Context.js +11 -9
- package/lib/natural/classifiers/maxent/Distribution.js +107 -105
- package/lib/natural/classifiers/maxent/Element.js +12 -10
- package/lib/natural/classifiers/maxent/Feature.js +56 -54
- package/lib/natural/classifiers/maxent/FeatureSet.js +40 -38
- package/lib/natural/classifiers/maxent/GISScaler.js +110 -109
- package/lib/natural/classifiers/maxent/POS/ME_Corpus.js +26 -31
- package/lib/natural/classifiers/maxent/POS/ME_Sentence.js +37 -42
- package/lib/natural/classifiers/maxent/POS/POS_Element.js +119 -124
- package/lib/natural/classifiers/maxent/Sample.js +96 -94
- package/lib/natural/classifiers/maxent/SimpleExample/SE_Element.js +14 -20
- package/lib/natural/inflectors/fr/count_inflector.js +1 -1
- package/lib/natural/inflectors/fr/noun_inflector.js +179 -196
- package/lib/natural/inflectors/ja/noun_inflector.js +67 -84
- package/lib/natural/inflectors/noun_inflector.js +124 -139
- package/lib/natural/inflectors/present_verb_inflector.js +34 -48
- package/lib/natural/inflectors/singular_plural_inflector.js +62 -61
- package/lib/natural/tfidf/tfidf.js +118 -114
- package/lib/natural/trie/trie.js +161 -159
- package/lib/natural/util/directed_edge.js +49 -0
- package/lib/natural/util/edge_weighted_digraph.js +54 -74
- package/lib/natural/util/index.js +1 -0
- package/lib/natural/util/longest_path_tree.js +54 -52
- package/lib/natural/util/shortest_path_tree.js +56 -54
- package/lib/natural/util/topological.js +17 -15
- package/package.json +1 -1
|
@@ -26,165 +26,167 @@ const JSON = 2
|
|
|
26
26
|
// sentences: an array of annotated sentences
|
|
27
27
|
// A sentence is an array of annotated tokens
|
|
28
28
|
// A token is an object with (token, tag, testTag, ruleList)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
class Corpus {
|
|
30
|
+
constructor (data, typeOfCorpus, SentenceClass) {
|
|
31
|
+
this.wordCount = 0
|
|
32
|
+
this.sentences = []
|
|
33
|
+
const that = this
|
|
34
|
+
if (data) {
|
|
35
|
+
// For other types of corpora add a case here and supply a parsing method
|
|
36
|
+
switch (typeOfCorpus) {
|
|
37
|
+
case BROWN:
|
|
38
|
+
this.parseBrownCorpus(data, SentenceClass)
|
|
39
|
+
break
|
|
40
|
+
case JSON:
|
|
41
|
+
// Assume it is a JSON object of a corpus
|
|
42
|
+
data.sentences.forEach(function (s) {
|
|
43
|
+
const taggedSentence = new SentenceClass(s.taggedWords)
|
|
44
|
+
that.sentences.push(taggedSentence)
|
|
45
|
+
that.wordCount += s.taggedWords.length
|
|
46
|
+
})
|
|
47
|
+
break
|
|
48
|
+
}
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// data is raw text
|
|
52
|
-
// A corpus parsing method should split the corpus in sentences each of which
|
|
53
|
-
// consist of an array of tokens.
|
|
54
|
-
Corpus.prototype.parseBrownCorpus = function (data, SentenceClass) {
|
|
55
|
-
const that = this
|
|
56
|
-
|
|
57
|
-
const lines = data.split('\n')
|
|
58
|
-
lines.forEach(function (line) {
|
|
59
|
-
const trimmedLine = line.trim()
|
|
60
|
-
// Only parse lines that contain characters
|
|
61
|
-
if (trimmedLine !== '') {
|
|
62
|
-
const taggedSentence = new SentenceClass()
|
|
63
|
-
const tokens = line.trim().split(/\s+/)
|
|
64
|
-
tokens.forEach(function (token) {
|
|
65
|
-
that.wordCount++
|
|
66
|
-
// Create a tagged sentences consisting of tokens
|
|
67
|
-
const wordPlusTag = token.split('_')
|
|
68
|
-
taggedSentence.addTaggedWord(wordPlusTag[0], wordPlusTag[1])
|
|
69
|
-
})
|
|
70
51
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
52
|
+
// data is raw text
|
|
53
|
+
// A corpus parsing method should split the corpus in sentences each of which
|
|
54
|
+
// consist of an array of tokens.
|
|
55
|
+
parseBrownCorpus (data, SentenceClass) {
|
|
56
|
+
const that = this
|
|
57
|
+
|
|
58
|
+
const lines = data.split('\n')
|
|
59
|
+
lines.forEach(function (line) {
|
|
60
|
+
const trimmedLine = line.trim()
|
|
61
|
+
// Only parse lines that contain characters
|
|
62
|
+
if (trimmedLine !== '') {
|
|
63
|
+
const taggedSentence = new SentenceClass()
|
|
64
|
+
const tokens = line.trim().split(/\s+/)
|
|
65
|
+
tokens.forEach(function (token) {
|
|
66
|
+
that.wordCount++
|
|
67
|
+
// Create a tagged sentences consisting of tokens
|
|
68
|
+
const wordPlusTag = token.split('_')
|
|
69
|
+
taggedSentence.addTaggedWord(wordPlusTag[0], wordPlusTag[1])
|
|
70
|
+
})
|
|
76
71
|
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
72
|
+
// Add the sentence to the corpus
|
|
73
|
+
that.sentences.push(taggedSentence)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
}
|
|
81
77
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const corpusTrain = new Corpus()
|
|
87
|
-
const corpusTest = new Corpus()
|
|
88
|
-
|
|
89
|
-
const p = percentageTrain / 100
|
|
90
|
-
this.sentences.forEach(function (sentence, i) {
|
|
91
|
-
if (Math.random() < p) {
|
|
92
|
-
corpusTrain.sentences.push(sentence)
|
|
93
|
-
} else {
|
|
94
|
-
corpusTest.sentences.push(sentence)
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
return [corpusTrain, corpusTest]
|
|
98
|
-
}
|
|
78
|
+
// Returns an array of all POS tags used in the corpus
|
|
79
|
+
getTags () {
|
|
80
|
+
return Object.keys(this.posTags)
|
|
81
|
+
}
|
|
99
82
|
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// Register the tags used in the corpus
|
|
114
|
-
that.posTags[token.tag] = true
|
|
115
|
-
|
|
116
|
-
// Register the frequency of the tag
|
|
117
|
-
if (!that.tagFrequencies[token.token]) {
|
|
118
|
-
that.tagFrequencies[token.token] = {}
|
|
119
|
-
}
|
|
120
|
-
if (!that.tagFrequencies[token.token][token.tag]) {
|
|
121
|
-
that.tagFrequencies[token.token][token.tag] = 0
|
|
83
|
+
// Splits the corpus in a training and testing set.
|
|
84
|
+
// percentageTrain is the size of the training corpus in percent
|
|
85
|
+
// Returns an array with two elements: training corpus, testing corpus
|
|
86
|
+
splitInTrainAndTest (percentageTrain) {
|
|
87
|
+
const corpusTrain = new Corpus()
|
|
88
|
+
const corpusTest = new Corpus()
|
|
89
|
+
|
|
90
|
+
const p = percentageTrain / 100
|
|
91
|
+
this.sentences.forEach(function (sentence, i) {
|
|
92
|
+
if (Math.random() < p) {
|
|
93
|
+
corpusTrain.sentences.push(sentence)
|
|
94
|
+
} else {
|
|
95
|
+
corpusTest.sentences.push(sentence)
|
|
122
96
|
}
|
|
123
|
-
that.tagFrequencies[token.token][token.tag]++
|
|
124
97
|
})
|
|
125
|
-
|
|
126
|
-
}
|
|
98
|
+
return [corpusTrain, corpusTest]
|
|
99
|
+
}
|
|
127
100
|
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
101
|
+
// Analyses the corpus:
|
|
102
|
+
// - registers used POS tags
|
|
103
|
+
// - records the frequency of POS tag for each word
|
|
104
|
+
analyse () {
|
|
105
|
+
this.tagFrequencies = {}
|
|
106
|
+
this.posTags = {}
|
|
107
|
+
this.wordCount = 0
|
|
108
|
+
|
|
109
|
+
const that = this
|
|
110
|
+
this.sentences.forEach(function (sentence) {
|
|
111
|
+
sentence.taggedWords.forEach(function (token) {
|
|
112
|
+
that.wordCount++
|
|
133
113
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const catToFreq = that.tagFrequencies[token]
|
|
137
|
-
const categories = Object.keys(catToFreq)
|
|
114
|
+
// Register the tags used in the corpus
|
|
115
|
+
that.posTags[token.tag] = true
|
|
138
116
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
|
|
117
|
+
// Register the frequency of the tag
|
|
118
|
+
if (!that.tagFrequencies[token.token]) {
|
|
119
|
+
that.tagFrequencies[token.token] = {}
|
|
120
|
+
}
|
|
121
|
+
if (!that.tagFrequencies[token.token][token.tag]) {
|
|
122
|
+
that.tagFrequencies[token.token][token.tag] = 0
|
|
123
|
+
}
|
|
124
|
+
that.tagFrequencies[token.token][token.tag]++
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Creates a lexicon by taking the most frequently occurring tag of a word
|
|
130
|
+
// as the right tag
|
|
131
|
+
buildLexicon () {
|
|
132
|
+
const lexicon = new Lexicon()
|
|
133
|
+
const that = this
|
|
134
|
+
|
|
135
|
+
this.analyse()
|
|
136
|
+
Object.keys(this.tagFrequencies).forEach(function (token) {
|
|
137
|
+
const catToFreq = that.tagFrequencies[token]
|
|
138
|
+
const categories = Object.keys(catToFreq)
|
|
139
|
+
|
|
140
|
+
function compareByFrequency (a, b) {
|
|
141
|
+
if (catToFreq[a] > catToFreq[b]) {
|
|
142
|
+
return -1
|
|
145
143
|
} else {
|
|
146
|
-
|
|
144
|
+
if (catToFreq[a] < catToFreq[b]) {
|
|
145
|
+
return 1
|
|
146
|
+
} else {
|
|
147
|
+
return 0
|
|
148
|
+
}
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
|
-
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
152
|
+
const sortedCategories = categories.sort(compareByFrequency)
|
|
153
|
+
lexicon.addWord(token, sortedCategories)
|
|
154
|
+
})
|
|
155
|
+
return lexicon
|
|
156
|
+
}
|
|
156
157
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
tag (lexicon) {
|
|
159
|
+
this.sentences.forEach(function (sentence) {
|
|
160
|
+
sentence.taggedWords.forEach(function (token) {
|
|
161
|
+
// tagWord returns a list of categories, take the first category
|
|
162
|
+
token.testTag = lexicon.tagWord(token.token)[0]
|
|
163
|
+
})
|
|
162
164
|
})
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
+
}
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
167
|
+
nrSentences () {
|
|
168
|
+
return this.sentences.length
|
|
169
|
+
}
|
|
169
170
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
171
|
+
nrWords () {
|
|
172
|
+
return this.wordCount
|
|
173
|
+
}
|
|
173
174
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
175
|
+
generateFeatures () {
|
|
176
|
+
let features = []
|
|
177
|
+
this.sentences.forEach(function (sentence) {
|
|
178
|
+
features = sentence.generateFeatures(features)
|
|
179
|
+
})
|
|
180
|
+
// console.log(JSON.stringify(features));
|
|
181
|
+
return features
|
|
182
|
+
}
|
|
182
183
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
prettyPrint () {
|
|
185
|
+
this.sentences.forEach(function (sentence, index) {
|
|
186
|
+
// logger.debug("sentence no " + index + "\n" +
|
|
187
|
+
// JSON.stringify(sentence, null, 2));
|
|
188
|
+
})
|
|
189
|
+
}
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
module.exports = Corpus
|
|
@@ -23,97 +23,99 @@ const dutchLexicon = require('../data/Dutch/brill_Lexicon.json')
|
|
|
23
23
|
|
|
24
24
|
const DEBUG = false
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
class Lexicon {
|
|
27
|
+
// Constructor creates a Lexicon for language
|
|
28
|
+
constructor (language, defaultCategory, defaultCategoryCapitalised, extendedLexicon) {
|
|
29
|
+
const lexicon = (() => {
|
|
30
|
+
switch (language) {
|
|
31
|
+
case 'EN':
|
|
32
|
+
return englishLexicon
|
|
33
|
+
case 'DU':
|
|
34
|
+
return dutchLexicon
|
|
35
|
+
default:
|
|
36
|
+
return dutchLexicon
|
|
37
|
+
}
|
|
38
|
+
})()
|
|
39
|
+
|
|
40
|
+
this.lexicon = Object.assign(lexicon, extendedLexicon || {})
|
|
41
|
+
|
|
42
|
+
if (defaultCategory) {
|
|
43
|
+
this.defaultCategory = defaultCategory
|
|
44
|
+
if (defaultCategoryCapitalised) {
|
|
45
|
+
this.defaultCategoryCapitalised = defaultCategoryCapitalised
|
|
46
|
+
}
|
|
36
47
|
}
|
|
37
|
-
}
|
|
48
|
+
}
|
|
38
49
|
|
|
39
|
-
|
|
50
|
+
// Parses a lexicon in text format: word cat1 cat2 ... catn
|
|
51
|
+
parseLexicon (data) {
|
|
52
|
+
// Split into an array of non-empty lines
|
|
53
|
+
const arrayOfLines = data.match(/[^\r\n]+/g)
|
|
54
|
+
this.lexicon = {} // Object.create(null);
|
|
55
|
+
const that = this
|
|
56
|
+
arrayOfLines.forEach(function (line) {
|
|
57
|
+
// Split line by whitespace
|
|
58
|
+
const elements = line.trim().split(/\s+/)
|
|
59
|
+
if (elements.length > 0) {
|
|
60
|
+
that.lexicon[elements[0]] = elements.slice(1)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
40
64
|
|
|
41
|
-
|
|
42
|
-
this.
|
|
43
|
-
|
|
44
|
-
this.defaultCategoryCapitalised
|
|
65
|
+
tagWordWithDefaults (word) {
|
|
66
|
+
if (/[A-Z]/.test(word[0]) && this.defaultCategoryCapitalised) {
|
|
67
|
+
// Capitalised
|
|
68
|
+
return this.defaultCategoryCapitalised
|
|
69
|
+
} else {
|
|
70
|
+
// If not found assign default_category
|
|
71
|
+
return this.defaultCategory
|
|
45
72
|
}
|
|
46
73
|
}
|
|
47
|
-
}
|
|
48
74
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
arrayOfLines.forEach(function (line) {
|
|
56
|
-
// Split line by whitespace
|
|
57
|
-
const elements = line.trim().split(/\s+/)
|
|
58
|
-
if (elements.length > 0) {
|
|
59
|
-
that.lexicon[elements[0]] = elements.slice(1)
|
|
75
|
+
// Returns a list of categories for word
|
|
76
|
+
tagWord (word) {
|
|
77
|
+
let categories = this.lexicon[word]
|
|
78
|
+
DEBUG && console.log(categories)
|
|
79
|
+
if (!categories || (typeof categories === 'function')) {
|
|
80
|
+
categories = this.lexicon[word.toLowerCase()]
|
|
60
81
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (/[A-Z]/.test(word[0]) && this.defaultCategoryCapitalised) {
|
|
66
|
-
// Capitalised
|
|
67
|
-
return this.defaultCategoryCapitalised
|
|
68
|
-
} else {
|
|
69
|
-
// If not found assign default_category
|
|
70
|
-
return this.defaultCategory
|
|
82
|
+
if (!categories || (typeof categories === 'function')) {
|
|
83
|
+
categories = [this.tagWordWithDefaults(word)]
|
|
84
|
+
}
|
|
85
|
+
return (categories)
|
|
71
86
|
}
|
|
72
|
-
}
|
|
73
87
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
DEBUG && console.log(categories)
|
|
78
|
-
if (!categories || (typeof categories === 'function')) {
|
|
79
|
-
categories = this.lexicon[word.toLowerCase()]
|
|
88
|
+
// Adds a word to the lexicon. NB simply replaces the entry
|
|
89
|
+
addWord (word, categories) {
|
|
90
|
+
this.lexicon[word] = categories
|
|
80
91
|
}
|
|
81
|
-
if (!categories || (typeof categories === 'function')) {
|
|
82
|
-
categories = [this.tagWordWithDefaults(word)]
|
|
83
|
-
}
|
|
84
|
-
return (categories)
|
|
85
|
-
}
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
result += token + '\t'
|
|
97
|
-
that.lexicon[token].forEach(function (cat) {
|
|
98
|
-
result += cat + '\t'
|
|
93
|
+
prettyPrint () {
|
|
94
|
+
let result = ''
|
|
95
|
+
const that = this
|
|
96
|
+
Object.keys(this.lexicon).forEach(function (token) {
|
|
97
|
+
result += token + '\t'
|
|
98
|
+
that.lexicon[token].forEach(function (cat) {
|
|
99
|
+
result += cat + '\t'
|
|
100
|
+
})
|
|
101
|
+
result += '\n'
|
|
99
102
|
})
|
|
100
|
-
result
|
|
101
|
-
}
|
|
102
|
-
return result
|
|
103
|
-
}
|
|
103
|
+
return result
|
|
104
|
+
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
106
|
+
nrEntries () {
|
|
107
|
+
return Object.keys(this.lexicon).length
|
|
108
|
+
}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
110
|
+
size () {
|
|
111
|
+
return this.nrEntries()
|
|
112
|
+
}
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
setDefaultCategories (category, categoryCapitalised) {
|
|
115
|
+
this.defaultCategory = category
|
|
116
|
+
if (categoryCapitalised) {
|
|
117
|
+
this.defaultCategoryCapitalised = categoryCapitalised
|
|
118
|
+
}
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -23,25 +23,27 @@ const DEBUG = false
|
|
|
23
23
|
const predicates = require('./RuleTemplates')
|
|
24
24
|
DEBUG && console.log('RuleSet loaded predicates: ' + predicates)
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.meta
|
|
26
|
+
class Predicate {
|
|
27
|
+
constructor (name, parameter1, parameter2) {
|
|
28
|
+
this.name = name
|
|
29
|
+
this.meta = predicates[name]
|
|
30
|
+
if (!this.meta) {
|
|
31
|
+
this.meta = predicates.DEFAULT
|
|
32
|
+
}
|
|
33
|
+
// if (this.meta.nrParameters > 0) {
|
|
34
|
+
this.parameter1 = parameter1
|
|
35
|
+
// }
|
|
36
|
+
// if (this.meta.nrParameters > 1) {
|
|
37
|
+
this.parameter2 = parameter2
|
|
38
|
+
// }
|
|
39
|
+
DEBUG && console.log('Predicate\n' + JSON.toString(this.meta, null, 2))
|
|
31
40
|
}
|
|
32
|
-
// if (this.meta.nrParameters > 0) {
|
|
33
|
-
this.parameter1 = parameter1
|
|
34
|
-
// }
|
|
35
|
-
// if (this.meta.nrParameters > 1) {
|
|
36
|
-
this.parameter2 = parameter2
|
|
37
|
-
// }
|
|
38
|
-
DEBUG && console.log('Predicate\n' + JSON.toString(this.meta, null, 2))
|
|
39
|
-
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
evaluate (sentence, position) {
|
|
43
|
+
DEBUG && console.log('Predicate.evalute: ' + this.name)
|
|
44
|
+
const predicate = this.meta.function
|
|
45
|
+
return (predicate(sentence, position, this.parameter1, this.parameter2))
|
|
46
|
+
}
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
module.exports = Predicate
|
|
@@ -25,72 +25,74 @@ const englishRuleSet = require('../data/English/tr_from_posjs.json')
|
|
|
25
25
|
|
|
26
26
|
const DEBUG = false
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
class RuleSet {
|
|
29
|
+
// Constructor takes a language abbreviation and loads the right rule set
|
|
30
|
+
constructor (language) {
|
|
31
|
+
let data = englishRuleSet
|
|
32
|
+
DEBUG && console.log(data)
|
|
33
|
+
switch (language) {
|
|
34
|
+
case 'EN':
|
|
35
|
+
data = englishRuleSet
|
|
36
|
+
break
|
|
37
|
+
case 'DU':
|
|
38
|
+
data = dutchRuleSet
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
if (data.rules) {
|
|
42
|
+
this.rules = {}
|
|
43
|
+
const that = this
|
|
44
|
+
data.rules.forEach(function (ruleString) {
|
|
45
|
+
that.addRule(TFParser.parse(ruleString))
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
DEBUG && console.log(this.rules)
|
|
49
|
+
DEBUG && console.log('Brill_POS_Tagger.read_transformation_rules: number of transformation rules read: ' + Object.keys(this.rules).length)
|
|
39
50
|
}
|
|
40
|
-
if (data.rules) {
|
|
41
|
-
this.rules = {}
|
|
42
|
-
const that = this
|
|
43
|
-
data.rules.forEach(function (ruleString) {
|
|
44
|
-
that.addRule(TFParser.parse(ruleString))
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
DEBUG && console.log(this.rules)
|
|
48
|
-
DEBUG && console.log('Brill_POS_Tagger.read_transformation_rules: number of transformation rules read: ' + Object.keys(this.rules).length)
|
|
49
|
-
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
addRule (rule) {
|
|
53
|
+
// this.rules.push(rule);
|
|
54
|
+
if (!this.rules[rule.key()]) {
|
|
55
|
+
this.rules[rule.key()] = rule
|
|
56
|
+
return true
|
|
57
|
+
} else {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
|
-
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
removeRule (rule) {
|
|
63
|
+
if (this.rules[rule.key()]) {
|
|
64
|
+
delete this.rules[rule.key()]
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
|
-
}
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
68
|
+
getRules () {
|
|
69
|
+
const that = this
|
|
70
|
+
return Object.keys(this.rules).map(function (key) {
|
|
71
|
+
return that.rules[key]
|
|
72
|
+
})
|
|
73
|
+
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
75
|
+
nrRules () {
|
|
76
|
+
return Object.keys(this.rules).length
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
hasRule (rule) {
|
|
80
|
+
if (this.rules[rule.key()]) {
|
|
81
|
+
return true
|
|
82
|
+
} else {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
83
85
|
}
|
|
84
|
-
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
prettyPrint () {
|
|
88
|
+
let result = ''
|
|
89
|
+
const that = this
|
|
90
|
+
Object.keys(this.rules).forEach(function (key) {
|
|
91
|
+
const rule = that.rules[key]
|
|
92
|
+
result += rule.prettyPrint() + '\n'
|
|
93
|
+
})
|
|
94
|
+
return result
|
|
95
|
+
}
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
module.exports = RuleSet
|