natural 6.10.2 → 6.10.3
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/.github/workflows/node.js.yml +1 -1
- package/.github/workflows/npm-publish.yml +4 -4
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Feature set class for administrating a set of unique
|
|
3
|
-
Copyright (C) 2017 Hugo W.L. ter Doest
|
|
2
|
+
Feature set class for administrating a set of unique features
|
|
3
|
+
Copyright (C) 2017, 2023 Hugo W.L. ter Doest
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -23,49 +23,51 @@ THE SOFTWARE.
|
|
|
23
23
|
|
|
24
24
|
'use strict'
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
class FeatureSet {
|
|
27
|
+
constructor () {
|
|
28
|
+
this.features = []
|
|
29
|
+
this.map = {}
|
|
30
|
+
}
|
|
30
31
|
|
|
31
|
-
// Returns true if the feature did not exist and was added
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
// Returns true if the feature did not exist and was added
|
|
33
|
+
addFeature (feature) {
|
|
34
|
+
if (!this.featureExists(feature)) {
|
|
35
|
+
this.map[feature.name + ' | ' + feature.parametersKey] = true
|
|
36
|
+
this.features.push(feature)
|
|
37
|
+
// console.log("FeatureSet.addFeature: feature added: " + feature.name + " - " + feature.parametersKey);
|
|
38
|
+
return true
|
|
39
|
+
} else {
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
|
-
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
featureExists (feature) {
|
|
45
|
+
if (this.map[feature.name + ' | ' + feature.parametersKey]) {
|
|
46
|
+
// console.log("FeatureSet.featureExists: feature already exists: " +
|
|
47
|
+
// feature.name + " - " + feature.parameters);
|
|
48
|
+
return true
|
|
49
|
+
} else {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
|
-
}
|
|
52
53
|
|
|
53
|
-
// Returns an array of features
|
|
54
|
-
// If the available array this.features is up to date it is returned immediately
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
54
|
+
// Returns an array of features
|
|
55
|
+
// If the available array this.features is up to date it is returned immediately
|
|
56
|
+
getFeatures () {
|
|
57
|
+
return this.features
|
|
58
|
+
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
60
|
+
size () {
|
|
61
|
+
return this.features.length
|
|
62
|
+
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
prettyPrint () {
|
|
65
|
+
let s = ''
|
|
66
|
+
Object.keys(this.map).forEach(function (key) {
|
|
67
|
+
s += key + '\n'
|
|
68
|
+
})
|
|
69
|
+
return s
|
|
70
|
+
}
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
module.exports = FeatureSet
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
GISScaler class that finds parameters of features
|
|
3
|
-
Copyright (C) 2017 Hugo W.L. ter Doest
|
|
3
|
+
Copyright (C) 2017, 2023 Hugo W.L. ter Doest
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -26,125 +26,126 @@ THE SOFTWARE.
|
|
|
26
26
|
const Feature = require('./Feature')
|
|
27
27
|
const Distribution = require('./Distribution')
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
// features is an array of feature functions
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
29
|
+
class GISScaler {
|
|
30
|
+
// features is an array of feature functions
|
|
31
|
+
constructor (featureSet, sample) {
|
|
32
|
+
this.featureSet = featureSet
|
|
33
|
+
this.sample = sample
|
|
34
|
+
}
|
|
35
35
|
|
|
36
|
-
// Returns true if a correction feature is necessary
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
36
|
+
// Returns true if a correction feature is necessary
|
|
37
|
+
calculateMaxSumOfFeatures () {
|
|
38
|
+
const that = this
|
|
39
|
+
this.C = 0
|
|
40
|
+
this.featureSums = {}
|
|
41
|
+
const listOfSumValues = []
|
|
42
|
+
|
|
43
|
+
// Since feature functions are derived from the sample
|
|
44
|
+
// we can use the sample to calculate the max sum
|
|
45
|
+
// We look at each sample element only once
|
|
46
|
+
this.sample.elements.forEach(function (x) {
|
|
47
|
+
if (!that.featureSums[x.toString()]) {
|
|
48
|
+
let sum = 0
|
|
49
|
+
that.featureSet.getFeatures().forEach(function (f) {
|
|
50
|
+
sum += f.apply(x)
|
|
51
|
+
})
|
|
52
|
+
if (sum > that.C) {
|
|
53
|
+
that.C = sum
|
|
54
|
+
}
|
|
55
|
+
that.featureSums[x.toString()] = sum
|
|
56
|
+
listOfSumValues.push(sum)
|
|
54
57
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
// console.log("GISScaler:calculateMaxSumOfFeatures:maxSum is " + this.C);
|
|
60
|
-
|
|
61
|
-
// Check if a correction feature is necessary
|
|
62
|
-
listOfSumValues.sort(function (a, b) {
|
|
63
|
-
return a - b
|
|
64
|
-
})
|
|
65
|
-
return (listOfSumValues[0] !== listOfSumValues[listOfSumValues.length - 1])
|
|
66
|
-
}
|
|
58
|
+
})
|
|
59
|
+
// console.log("GISScaler:calculateMaxSumOfFeatures:maxSum is " + this.C);
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
61
|
+
// Check if a correction feature is necessary
|
|
62
|
+
listOfSumValues.sort(function (a, b) {
|
|
63
|
+
return a - b
|
|
64
|
+
})
|
|
65
|
+
return (listOfSumValues[0] !== listOfSumValues[listOfSumValues.length - 1])
|
|
66
|
+
}
|
|
72
67
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
addCorrectionFeature () {
|
|
69
|
+
if (this.calculateMaxSumOfFeatures()) {
|
|
70
|
+
// console.log("GISScaler:addCorrectionFeature:C is " + this.C);
|
|
71
|
+
const that = this
|
|
72
|
+
|
|
73
|
+
function f (x) {
|
|
74
|
+
if (that.featureSums[x.toString()] !== undefined) {
|
|
75
|
+
return that.C - that.featureSums[x.toString()]
|
|
76
|
+
}
|
|
77
|
+
return 0
|
|
76
78
|
}
|
|
77
|
-
return 0
|
|
78
|
-
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
const correctionFeature = new Feature(f, 'Correction feature', [])
|
|
81
|
+
// console.log("GISScaler:addCorrectionFeature:correctionFeature " + JSON.stringify(correctionFeature));
|
|
82
|
+
this.featureSet.addFeature(correctionFeature)
|
|
83
|
+
} else {
|
|
84
|
+
// console.log("Correction feature not needed");
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
|
-
}
|
|
87
87
|
|
|
88
|
-
// This is the Generalised Iterative Scaling algorithm
|
|
89
|
-
// It ends if the improvement in likelihood of the distribution does not
|
|
90
|
-
// improve more than minImprovement or if the maximum number of iterations is
|
|
91
|
-
// reached.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
const p = new Distribution(alpha, this.featureSet, this.sample)
|
|
103
|
-
// console.log("Distribution created");
|
|
104
|
-
p.prepare()
|
|
105
|
-
// console.log("Distribution prepared");
|
|
106
|
-
let KLDistance = p.KullbackLieblerDistance()
|
|
107
|
-
|
|
108
|
-
const newAlpha = new Array(this.featureSet.size())
|
|
109
|
-
let observedExpectation = 0
|
|
110
|
-
let expectationApprox = 0
|
|
111
|
-
do {
|
|
112
|
-
// console.log("Iteration " + this.iteration + " - Log likelihood of sample: " + likelihood + " - Entropy: " + p.entropy());
|
|
113
|
-
for (let i = 0; i < this.featureSet.size(); i++) {
|
|
114
|
-
observedExpectation = this.featureSet.getFeatures()[i].observedExpectation(this.sample)
|
|
115
|
-
expectationApprox = this.featureSet.getFeatures()[i].expectationApprox(p, this.sample)
|
|
116
|
-
// console.log("Iteration " + this.iteration + " - Feature " + i);
|
|
117
|
-
newAlpha[i] = p.alpha[i] * Math.pow(observedExpectation / expectationApprox, 1 / this.C)
|
|
118
|
-
|
|
119
|
-
// console.log("GISScaler.run: old alpha[" + i + "]: " + p.alpha[i]);
|
|
120
|
-
// console.log("GISScaler.run: new alpha[" + i + "]: " + newAlpha[i]);
|
|
88
|
+
// This is the Generalised Iterative Scaling algorithm
|
|
89
|
+
// It ends if the improvement in likelihood of the distribution does not
|
|
90
|
+
// improve more than minImprovement or if the maximum number of iterations is
|
|
91
|
+
// reached.
|
|
92
|
+
run (maxIterations, minImprovement) {
|
|
93
|
+
this.iteration = 0
|
|
94
|
+
this.improvement = 0
|
|
95
|
+
|
|
96
|
+
this.addCorrectionFeature()
|
|
97
|
+
// Build up the distribution p
|
|
98
|
+
const alpha = new Array(this.featureSet.size())
|
|
99
|
+
for (let i = 0; i < alpha.length; i++) {
|
|
100
|
+
alpha[i] = 1
|
|
121
101
|
}
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
newAlpha.forEach(function (newAlphaj, j) {
|
|
125
|
-
p.alpha[j] = newAlphaj
|
|
126
|
-
})
|
|
127
|
-
// Recalculate a priori and a posteriori probabilities
|
|
102
|
+
const p = new Distribution(alpha, this.featureSet, this.sample)
|
|
103
|
+
// console.log("Distribution created");
|
|
128
104
|
p.prepare()
|
|
105
|
+
// console.log("Distribution prepared");
|
|
106
|
+
let KLDistance = p.KullbackLieblerDistance()
|
|
107
|
+
|
|
108
|
+
const newAlpha = new Array(this.featureSet.size())
|
|
109
|
+
let observedExpectation = 0
|
|
110
|
+
let expectationApprox = 0
|
|
111
|
+
do {
|
|
112
|
+
// console.log("Iteration " + this.iteration + " - Log likelihood of sample: " + likelihood + " - Entropy: " + p.entropy());
|
|
113
|
+
for (let i = 0; i < this.featureSet.size(); i++) {
|
|
114
|
+
observedExpectation = this.featureSet.getFeatures()[i].observedExpectation(this.sample)
|
|
115
|
+
expectationApprox = this.featureSet.getFeatures()[i].expectationApprox(p, this.sample)
|
|
116
|
+
// console.log("Iteration " + this.iteration + " - Feature " + i);
|
|
117
|
+
newAlpha[i] = p.alpha[i] * Math.pow(observedExpectation / expectationApprox, 1 / this.C)
|
|
118
|
+
|
|
119
|
+
// console.log("GISScaler.run: old alpha[" + i + "]: " + p.alpha[i]);
|
|
120
|
+
// console.log("GISScaler.run: new alpha[" + i + "]: " + newAlpha[i]);
|
|
121
|
+
}
|
|
129
122
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
123
|
+
// Make the newly calculated parameters current parameters
|
|
124
|
+
newAlpha.forEach(function (newAlphaj, j) {
|
|
125
|
+
p.alpha[j] = newAlphaj
|
|
126
|
+
})
|
|
127
|
+
// Recalculate a priori and a posteriori probabilities
|
|
128
|
+
p.prepare()
|
|
129
|
+
|
|
130
|
+
this.iteration++
|
|
131
|
+
const newKLDistance = p.KullbackLieblerDistance()
|
|
132
|
+
this.improvement = KLDistance - newKLDistance
|
|
133
|
+
// console.log("Iteration " + this.iteration + " - Old likelihood: " + likelihood + " - New likelihood: " + newLikelihood);
|
|
134
|
+
// console.log("Iteration " + this.iteration + " - Old KL: " + KLDistance + " - New KL: " + newKLDistance);
|
|
135
|
+
|
|
136
|
+
KLDistance = newKLDistance
|
|
137
|
+
} while ((this.iteration < maxIterations) && (this.improvement > minImprovement))
|
|
138
|
+
// } while (iteration < maxIterations);
|
|
139
|
+
/*
|
|
140
|
+
var that = this;
|
|
141
|
+
this.featureSet.getFeatures().forEach(function(f, j) {
|
|
142
|
+
console.log("Observed expectation of feature " + j + ": " + f.observedExpectation(that.sample) +
|
|
143
|
+
" - Expectation of feature according to p: " + f.expectationApprox(p, that.sample));
|
|
144
|
+
});
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
return p
|
|
148
|
+
}
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
module.exports = GISScaler
|
|
@@ -23,40 +23,35 @@ THE SOFTWARE.
|
|
|
23
23
|
|
|
24
24
|
'use strict'
|
|
25
25
|
|
|
26
|
-
const util = require('util')
|
|
27
26
|
const Sample = require('../Sample')
|
|
28
27
|
const Corpus = require('../../../brill_pos_tagger/lib/Corpus')
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
corpusTest.sentences.push(sentence)
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
return [corpusTrain, corpusTest]
|
|
29
|
+
class MECorpus extends Corpus {
|
|
30
|
+
generateSample () {
|
|
31
|
+
const sample = new Sample([])
|
|
32
|
+
this.sentences.forEach(function (sentence) {
|
|
33
|
+
sentence.generateSampleElements(sample)
|
|
34
|
+
})
|
|
35
|
+
return sample
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Splits the corpus in a training and testing set.
|
|
39
|
+
// percentageTrain is the size of the training corpus in percent
|
|
40
|
+
// Returns an array with two elements: training corpus, testing corpus
|
|
41
|
+
splitInTrainAndTest (percentageTrain) {
|
|
42
|
+
const corpusTrain = new MECorpus()
|
|
43
|
+
const corpusTest = new MECorpus()
|
|
44
|
+
|
|
45
|
+
const p = percentageTrain / 100
|
|
46
|
+
this.sentences.forEach(function (sentence, i) {
|
|
47
|
+
if (Math.random() < p) {
|
|
48
|
+
corpusTrain.sentences.push(sentence)
|
|
49
|
+
} else {
|
|
50
|
+
corpusTest.sentences.push(sentence)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
return [corpusTrain, corpusTest]
|
|
54
|
+
}
|
|
60
55
|
}
|
|
61
56
|
|
|
62
57
|
module.exports = MECorpus
|
|
@@ -23,58 +23,53 @@ THE SOFTWARE.
|
|
|
23
23
|
|
|
24
24
|
'use strict'
|
|
25
25
|
|
|
26
|
-
const util = require('util')
|
|
27
26
|
const Context = require('../Context')
|
|
28
27
|
const Sentence = require('../../../brill_pos_tagger/lib/Sentence')
|
|
29
28
|
const Element = require('./POS_Element')
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
new Context({
|
|
43
|
-
wordWindow: {},
|
|
44
|
-
tagWindow: {}
|
|
45
|
-
})
|
|
46
|
-
)
|
|
30
|
+
class MESentence extends Sentence {
|
|
31
|
+
generateSampleElements (sample) {
|
|
32
|
+
const sentence = this.taggedWords
|
|
33
|
+
sentence.forEach(function (token, index) {
|
|
34
|
+
const x = new Element(
|
|
35
|
+
token.tag,
|
|
36
|
+
new Context({
|
|
37
|
+
wordWindow: {},
|
|
38
|
+
tagWindow: {}
|
|
39
|
+
})
|
|
40
|
+
)
|
|
47
41
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
// Current word and tag
|
|
43
|
+
x.b.data.wordWindow['0'] = token.token
|
|
44
|
+
x.b.data.tagWindow['0'] = sentence[index].tag
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
// Previous bigram
|
|
47
|
+
if (index > 1) {
|
|
48
|
+
x.b.data.tagWindow['-2'] = sentence[index - 2].tag
|
|
49
|
+
x.b.data.wordWindow['-2'] = sentence[index - 2].token
|
|
50
|
+
}
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
// Left bigram
|
|
53
|
+
if (index > 0) {
|
|
54
|
+
x.b.data.tagWindow['-1'] = sentence[index - 1].tag
|
|
55
|
+
x.b.data.wordWindow['-1'] = sentence[index - 1].token
|
|
56
|
+
}
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
// Right bigram
|
|
59
|
+
if (index < sentence.length - 1) {
|
|
60
|
+
x.b.data.tagWindow['1'] = sentence[index + 1].tag
|
|
61
|
+
x.b.data.wordWindow['1'] = sentence[index + 1].token
|
|
62
|
+
}
|
|
69
63
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
// Next bigram
|
|
65
|
+
if (index < sentence.length - 2) {
|
|
66
|
+
x.b.data.tagWindow['2'] = sentence[index + 2].tag
|
|
67
|
+
x.b.data.wordWindow['2'] = sentence[index + 2].token
|
|
68
|
+
}
|
|
75
69
|
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
sample.addElement(x)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
78
73
|
}
|
|
79
74
|
|
|
80
75
|
module.exports = MESentence
|