natural 0.1.27 → 0.2.1

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 (134) hide show
  1. package/.editorconfig +7 -0
  2. package/LICENSE.txt +0 -0
  3. package/Makefile +0 -0
  4. package/README.md +237 -24
  5. package/benchmarks/index.js +1 -1
  6. package/benchmarks/metaphone.js +0 -0
  7. package/benchmarks/soundex.js +0 -0
  8. package/examples/classification/basic.js +0 -0
  9. package/examples/classification/recall.js +0 -0
  10. package/examples/classification/store.js +0 -0
  11. package/examples/inflection/count.js +0 -0
  12. package/examples/inflection/noun.js +0 -0
  13. package/examples/inflection/noun_attach.js +0 -0
  14. package/examples/phonetics/compare.js +0 -0
  15. package/examples/phonetics/sounds_like.js +0 -0
  16. package/examples/phonetics/tokenize_and_phoneticize.js +0 -0
  17. package/examples/stemming/stem_corpus.js +0 -0
  18. package/examples/stemming/stem_word.js +0 -0
  19. package/examples/tfidf/array_example.js +0 -0
  20. package/examples/tfidf/multiple_terms.js +0 -0
  21. package/examples/tfidf/tfidf_example.js +0 -0
  22. package/index.js +0 -0
  23. package/io_spec/test_data/tfidf/one +0 -0
  24. package/io_spec/test_data/tfidf/two +0 -0
  25. package/io_spec/tfidf_spec.js +0 -0
  26. package/io_spec/wordnet_spec.js +0 -0
  27. package/lib/natural/analyzers/sentence_analyzer.js +16 -13
  28. package/lib/natural/classifiers/bayes_classifier.js +6 -2
  29. package/lib/natural/classifiers/classifier.js +0 -0
  30. package/lib/natural/classifiers/logistic_regression_classifier.js +0 -0
  31. package/lib/natural/distance/dice_coefficient.js +0 -0
  32. package/lib/natural/distance/jaro-winkler_distance.js +13 -8
  33. package/lib/natural/distance/levenshtein_distance.js +0 -0
  34. package/lib/natural/index.js +8 -0
  35. package/lib/natural/inflectors/count_inflector.js +0 -0
  36. package/lib/natural/inflectors/form_set.js +0 -0
  37. package/lib/natural/inflectors/fr/count_inflector.js +0 -0
  38. package/lib/natural/inflectors/fr/noun_inflector.js +0 -0
  39. package/lib/natural/inflectors/ja/noun_inflector.js +0 -0
  40. package/lib/natural/inflectors/noun_inflector.js +0 -0
  41. package/lib/natural/inflectors/present_verb_inflector.js +1 -0
  42. package/lib/natural/inflectors/singular_plural_inflector.js +1 -2
  43. package/lib/natural/ngrams/ngrams.js +45 -8
  44. package/lib/natural/ngrams/ngrams_zh.js +83 -0
  45. package/lib/natural/normalizers/normalizer.js +30 -38
  46. package/lib/natural/normalizers/normalizer_ja.js +26 -8
  47. package/lib/natural/normalizers/normalizer_no.js +59 -0
  48. package/lib/natural/phonetics/double_metaphone.js +9 -4
  49. package/lib/natural/phonetics/metaphone.js +6 -1
  50. package/lib/natural/phonetics/phonetic.js +0 -0
  51. package/lib/natural/phonetics/soundex.js +11 -7
  52. package/lib/natural/spellcheck/spellcheck.js +80 -0
  53. package/lib/natural/stemmers/lancaster_rules.js +4 -4
  54. package/lib/natural/stemmers/lancaster_stemmer.js +0 -0
  55. package/lib/natural/stemmers/porter_stemmer.js +90 -63
  56. package/lib/natural/stemmers/porter_stemmer_es.js +22 -23
  57. package/lib/natural/stemmers/porter_stemmer_fr.js +377 -0
  58. package/lib/natural/stemmers/porter_stemmer_no.js +155 -0
  59. package/lib/natural/stemmers/porter_stemmer_pt.js +302 -0
  60. package/lib/natural/stemmers/stemmer.js +0 -0
  61. package/lib/natural/stemmers/stemmer_fr.js +58 -0
  62. package/lib/natural/stemmers/stemmer_no.js +61 -0
  63. package/lib/natural/stemmers/stemmer_pt.js +65 -0
  64. package/lib/natural/stemmers/token.js +163 -0
  65. package/lib/natural/tfidf/tfidf.js +50 -19
  66. package/lib/natural/tokenizers/aggressive_tokenizer.js +0 -0
  67. package/lib/natural/tokenizers/aggressive_tokenizer_es.js +0 -0
  68. package/lib/natural/tokenizers/aggressive_tokenizer_fr.js +36 -0
  69. package/lib/natural/tokenizers/aggressive_tokenizer_nl.js +0 -0
  70. package/lib/natural/tokenizers/aggressive_tokenizer_no.js +39 -0
  71. package/lib/natural/tokenizers/aggressive_tokenizer_pt.js +0 -0
  72. package/lib/natural/tokenizers/regexp_tokenizer.js +0 -0
  73. package/lib/natural/tokenizers/tokenizer.js +2 -2
  74. package/lib/natural/tokenizers/treebank_word_tokenizer.js +0 -0
  75. package/lib/natural/trie/trie.js +47 -0
  76. package/lib/natural/util/bag.js +50 -0
  77. package/lib/natural/util/edge_weighted_digraph.js +112 -0
  78. package/lib/natural/util/longest_path_tree.js +99 -0
  79. package/lib/natural/util/shortest_path_tree.js +100 -0
  80. package/lib/natural/util/stopwords.js +0 -0
  81. package/lib/natural/util/stopwords_fr.js +194 -0
  82. package/lib/natural/util/stopwords_nl.js +43 -0
  83. package/lib/natural/util/stopwords_no.js +42 -0
  84. package/lib/natural/util/stopwords_pt.js +136 -0
  85. package/lib/natural/util/topological.js +98 -0
  86. package/lib/natural/wordnet/data_file.js +0 -0
  87. package/lib/natural/wordnet/index_file.js +0 -0
  88. package/lib/natural/wordnet/wordnet.js +0 -0
  89. package/lib/natural/wordnet/wordnet_file.js +0 -0
  90. package/package.json +2 -2
  91. package/spec/aggressive_tokenizer_fr_spec.js +101 -0
  92. package/spec/aggressive_tokenizer_pt_spec.js +0 -0
  93. package/spec/aggressive_tokenizer_spec.js +0 -0
  94. package/spec/bayes_classifier_spec.js +12 -0
  95. package/spec/classifier_spec.js +84 -0
  96. package/spec/count_inflector_fr_spec.js +0 -0
  97. package/spec/count_inflector_spec.js +0 -0
  98. package/spec/dice_coefficient_spec.js +0 -0
  99. package/spec/double_metaphone_spec.js +10 -1
  100. package/spec/jaro-winkler_spec.js +0 -0
  101. package/spec/lancaster_stemmer_spec.js +10 -1
  102. package/spec/levenshtein_spec.js +0 -0
  103. package/spec/logistic_regression_classifier_spec.js +0 -0
  104. package/spec/longest_path_tree_spec.js +102 -0
  105. package/spec/metaphone_spec.js +10 -0
  106. package/spec/ngram_spec.js +61 -0
  107. package/spec/ngram_zh_spec.js +122 -0
  108. package/spec/normalizer_ja_spec.js +9 -3
  109. package/spec/normalizer_no_spec.js +111 -0
  110. package/spec/normalizer_spec.js +26 -5
  111. package/spec/noun_inflector_fr_spec.js +0 -0
  112. package/spec/noun_inflector_ja_spec.js +0 -0
  113. package/spec/noun_inflector_spec.js +0 -0
  114. package/spec/porter_stemmer_fr_spec.js +101 -0
  115. package/spec/porter_stemmer_no_spec.js +143 -0
  116. package/spec/porter_stemmer_pt_spec.js +50 -0
  117. package/spec/porter_stemmer_spec.js +49 -0
  118. package/spec/present_verb_inflector_spec.js +3 -0
  119. package/spec/remove_diacritics_spec.js +31 -0
  120. package/spec/sentence_analyzer_spec.js +248 -0
  121. package/spec/shortest_path_tree_spec.js +132 -0
  122. package/spec/soundex_spec.js +13 -9
  123. package/spec/spellcheck_spec.js +92 -0
  124. package/spec/stemmer_token_spec.js +161 -0
  125. package/spec/test_data/snowball_fr.txt +20402 -0
  126. package/spec/test_data/snowball_no.txt +20628 -0
  127. package/spec/test_data/snowball_pt.txt +32016 -0
  128. package/spec/test_data/tfdif_testcorpus.txt +0 -0
  129. package/spec/test_data/tfidf_teststopwords.txt +0 -0
  130. package/spec/test_data/wordnet_mini.sql +0 -0
  131. package/spec/tfidf_spec.js +153 -28
  132. package/spec/tokenizer_ja_spec.js +0 -0
  133. package/spec/treebank_word_tokenizer_spec.js +0 -0
  134. package/spec/trie_spec.js +27 -3
@@ -21,8 +21,20 @@ THE SOFTWARE.
21
21
  */
22
22
 
23
23
  var natural = require('lib/natural');
24
+ var baseClassifier = require('lib/natural/classifiers/classifier.js');
25
+ var fs = require('fs');
24
26
 
25
27
  describe('classifier', function () {
28
+
29
+ describe('addDocument', function () {
30
+
31
+ it('should ignore an empty document', function () {
32
+ var classifier = new natural.BayesClassifier();
33
+ classifier.addDocument('', 'philosophy');
34
+ expect(classifier.docs.length).toBe(0);
35
+ });
36
+ });
37
+
26
38
  describe('events emitters', function () {
27
39
 
28
40
  it('should be emitted when a document is classified', function () {
@@ -88,4 +100,76 @@ describe('classifier', function () {
88
100
  });
89
101
 
90
102
  });
103
+
104
+ describe('removeDocument', function () {
105
+
106
+ var classifier;
107
+ beforeEach(function () {
108
+ classifier = new natural.BayesClassifier();
109
+ classifier.addDocument('i fixed the box', 'computing');
110
+ classifier.addDocument('i write code', 'computing');
111
+ classifier.addDocument('write a book', 'literature');
112
+ classifier.addDocument('study the books', 'literature');
113
+ });
114
+
115
+ it('should do nothing if text is not a string', function () {
116
+ expect(classifier.docs.length).toBe(4);
117
+ classifier.removeDocument(['write a book'], 'literature');
118
+ classifier.removeDocument(['study the books'], 'literature');
119
+ expect(classifier.docs.length).toBe(4);
120
+ });
121
+
122
+ it('should do nothing if text is not a match', function () {
123
+ expect(classifier.docs.length).toBe(4);
124
+ classifier.removeDocument('something else', 'literature');
125
+ classifier.removeDocument('another thing', 'literature');
126
+ expect(classifier.docs.length).toBe(4);
127
+ });
128
+ });
129
+
130
+ describe('save', function () {
131
+
132
+ var tmpFilename = '/spec/test_data/deleteMe';
133
+ var nonExistentFilename = '/nonExistentDir/deleteMe';
134
+ var classifier;
135
+
136
+ beforeEach(function () {
137
+ classifier = new natural.BayesClassifier();
138
+ classifier.addDocument('I went to see the doctor of', 'philosophy');
139
+ });
140
+
141
+ afterEach(function () {
142
+ if (fs.existsSync(tmpFilename)) {
143
+ fs.unlinkSync(tmpFilename);
144
+ fs.unlinkSync(nonExistentFilename);
145
+ }
146
+ });
147
+
148
+ it('does nothing if called without a callback', function () {
149
+ classifier.save(tmpFilename);
150
+ expect(fs.existsSync(tmpFilename)).toBe(false);
151
+ });
152
+
153
+ it('fails if writing to a file fails', function () {
154
+ classifier.save(nonExistentFilename, function (err) {
155
+ expect(err).toBe.ok;
156
+ expect(fs.existsSync(tmpFilename)).toBe(false);
157
+ });
158
+ });
159
+ });
160
+
161
+ describe('load', function () {
162
+
163
+ it('does nothing if called without a callback', function () {
164
+ result = baseClassifier.load('/spec/test_data/tfidf_document1.txt');
165
+ expect(result).not.toBe.ok;
166
+ });
167
+
168
+ it('does nothing if called without a callback', function () {
169
+ result = baseClassifier.load('/nonexistentFilename', function (err, newClassifier){
170
+ expect(err).toBe.ok;
171
+ expect(newClassifier).not.toBe.ok;
172
+ });
173
+ });
174
+ });
91
175
  });
File without changes
File without changes
File without changes
@@ -737,7 +737,16 @@ describe('double metaphone', function() {
737
737
 
738
738
  describe('issue #34', function() {
739
739
  it('terminate words ending in H', function() {
740
- expect(doubleMetaphone.process('ptah')).toEqual(['PT', 'PT']);
740
+ expect(doubleMetaphone.process('ptah')).toEqual(['PT', 'PT']);
741
741
  });
742
742
  });
743
+
744
+ describe('issue #173', function() {
745
+ it('handle initial cons correctly', function() {
746
+ expect(doubleMetaphone.process('ceasar')).toEqual(['SSR', 'SSR']);
747
+ expect(doubleMetaphone.process('ach')).toEqual(['AK', 'AK']);
748
+ expect(doubleMetaphone.process('chemical')).toEqual(['KMKL', 'KMKL']);
749
+ expect(doubleMetaphone.process('choral')).toEqual(['KRL', 'KRL']);
750
+ });
751
+ });
743
752
  });
File without changes
@@ -54,11 +54,20 @@ describe('lancaster_stemmer', function() {
54
54
  });
55
55
 
56
56
  it('should apply intact rules only to intact string', function() {
57
- stemmer.attach();
57
+ stemmer.attach();
58
58
 
59
59
  expect('maximum'.stem()).toBe('maxim');
60
60
  expect('presumably'.stem()).toBe('presum');
61
61
  expect('MAXIMUM'.stem()).toBe('maxim');
62
62
  expect('PRESUMABLY'.stem()).toBe('presum');
63
63
  });
64
+
65
+ it('#171 and #174, exceed, anguish, affluxion, discept', function() {
66
+ stemmer.attach();
67
+
68
+ expect('exceed'.stem()).toBe('excess');
69
+ expect('anguish'.stem()).toBe('anct');
70
+ expect('affluxion'.stem()).toBe('affluct');
71
+ expect('discept'.stem()).toBe('disceiv');
72
+ });
64
73
  });
File without changes
File without changes
@@ -0,0 +1,102 @@
1
+ /*
2
+ Copyright (c) 2014, Lee Wenzhu
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+ 'use strict';
23
+
24
+ var LPT = require('../lib/natural/util/longest_path_tree'),
25
+ Topological = require('../lib/natural/util/topological'),
26
+ EdgeWeightedDigraph = require('../lib/natural/util/edge_weighted_digraph');
27
+
28
+ describe("shortest path tree", function() {
29
+ var digraph = new EdgeWeightedDigraph();
30
+ digraph.add(5,4,0.35);
31
+ digraph.add(4,7,0.37);
32
+ digraph.add(5,7,0.28);
33
+ digraph.add(5,1,0.32);
34
+ digraph.add(4,0,0.38);
35
+ digraph.add(0,2,0.26);
36
+ digraph.add(3,7,0.39);
37
+ digraph.add(1,3,0.29);
38
+ digraph.add(7,2,0.34);
39
+ digraph.add(6,2,0.40);
40
+ digraph.add(3,6,0.52);
41
+ digraph.add(6,0,0.58);
42
+ digraph.add(6,4,0.93);
43
+ describe("edge weighted digraph normal operations", function() {
44
+ it("should get the numbers of vertexs", function() {
45
+ expect(digraph.v()).toBe(8);
46
+ });
47
+ it("should get the numbers of edges", function() {
48
+ expect(digraph.e()).toBe(13);
49
+ });
50
+ it("should print all item in digraph", function() {
51
+ expect(digraph.toString()).toBe('0 -> 2, 0.26\n' +
52
+ '1 -> 3, 0.29\n' +
53
+ '3 -> 7, 0.39\n' +
54
+ '3 -> 6, 0.52\n' +
55
+ '4 -> 7, 0.37\n' +
56
+ '4 -> 0, 0.38\n' +
57
+ '5 -> 4, 0.35\n' +
58
+ '5 -> 7, 0.28\n' +
59
+ '5 -> 1, 0.32\n' +
60
+ '6 -> 2, 0.4\n' +
61
+ '6 -> 0, 0.58\n' +
62
+ '6 -> 4, 0.93\n' +
63
+ '7 -> 2, 0.34');
64
+ });
65
+ });
66
+
67
+ describe("topo sort for digraph", function() {
68
+ it("should sort all the vertexs", function() {
69
+ var topoSort = new Topological(digraph);
70
+ expect(topoSort.isDAG()).toBe(true);
71
+ expect(topoSort.order()).toEqual([ 5, 1, 3, 6, 4, 7, 0, 2 ]);
72
+ });
73
+ });
74
+
75
+ describe("shortest path tree normal operations", function() {
76
+ var lpt = new LPT(digraph, 5);
77
+ expect(lpt.hasPathTo(0)).toBe(true);
78
+ expect(lpt.hasPathTo(1)).toBe(true);
79
+ expect(lpt.hasPathTo(2)).toBe(true);
80
+ expect(lpt.hasPathTo(3)).toBe(true);
81
+ expect(lpt.hasPathTo(4)).toBe(true);
82
+ expect(lpt.hasPathTo(5)).toBe(false);
83
+ expect(lpt.hasPathTo(6)).toBe(true);
84
+ expect(lpt.hasPathTo(7)).toBe(true);
85
+ expect(lpt.pathTo(0)).toEqual([ 5, 1, 3, 6, 4, 0 ]);
86
+ expect(lpt.pathTo(1)).toEqual([ 5, 1 ]);
87
+ expect(lpt.pathTo(2)).toEqual([ 5, 1, 3, 6, 4, 7, 2 ]);
88
+ expect(lpt.pathTo(3)).toEqual([ 5, 1, 3 ]);
89
+ expect(lpt.pathTo(4)).toEqual([ 5, 1, 3, 6, 4 ]);
90
+ expect(lpt.pathTo(5)).toEqual([ ]);
91
+ expect(lpt.pathTo(6)).toEqual([ 5, 1, 3, 6 ]);
92
+ expect(lpt.pathTo(7)).toEqual([ 5, 1, 3, 6, 4, 7 ]);
93
+ expect(lpt.getDistTo(0)).toBe(2.44);
94
+ expect(lpt.getDistTo(1)).toBe(0.32);
95
+ expect(lpt.getDistTo(2)).toBe(2.77);
96
+ expect(lpt.getDistTo(3)).toBe(0.61);
97
+ expect(lpt.getDistTo(4)).toBe(2.06);
98
+ expect(lpt.getDistTo(5)).toBe(0);
99
+ expect(lpt.getDistTo(6)).toBe(1.13);
100
+ expect(lpt.getDistTo(7)).toBe(2.43);
101
+ });
102
+ });
@@ -211,6 +211,11 @@ describe('metaphone', function() {
211
211
  expect(metaphone.compare('PHONETICS', 'garbonzo')).toBeFalsy();
212
212
  });
213
213
 
214
+ it('#173', function() {
215
+ //expect(metaphone.process('caesar')).toBe('KSR');
216
+ //expect(metaphone.process('chemical')).toBe('KMKL');
217
+ });
218
+
214
219
  it('should compare strings with string patch', function() {
215
220
  metaphone.attach();
216
221
  expect('phonetics'.soundsLike('fonetix')).toBeTruthy();
@@ -224,6 +229,11 @@ describe('metaphone', function() {
224
229
  expect('phonetics'.phonetics()).toBe('FNTKS');
225
230
  expect('PHONETICS'.phonetics()).toBe('FNTKS');
226
231
  });
232
+
233
+ it('should transform PH to F #169', function() {
234
+ expect('pharaoh'.phonetics()).toBe('FR');
235
+ expect('tough'.phonetics()).toBe('TF');
236
+ });
227
237
 
228
238
  it('should tokenize and return string phonetics with string patch', function() {
229
239
  metaphone.attach();
@@ -66,4 +66,65 @@ describe('ngrams', function() {
66
66
  ['are', 'some', 'words']]);
67
67
  });
68
68
  });
69
+
70
+ // New Start/End Symbols Feature
71
+ it('should bigram a string with start and end symbols', function() {
72
+ expect(NGrams.ngrams('these are some words', 2, "[start]", "[end]")).toEqual([
73
+ ['[start]', 'these'],
74
+ ['these', 'are'],
75
+ ['are', 'some' ],
76
+ ['some', 'words'],
77
+ ['words', '[end]']
78
+ ]);
79
+ });
80
+
81
+ it('should bigram a string with start symbols only', function() {
82
+ expect(NGrams.ngrams('these are some words', 2, "[start]")).toEqual([
83
+ ['[start]', 'these'],
84
+ ['these', 'are'],
85
+ ['are', 'some' ],
86
+ ['some', 'words']
87
+ ]);
88
+ });
89
+
90
+
91
+ it('should bigram a string with end symbols only', function() {
92
+ expect(NGrams.ngrams('these are some words', 2, null, "[end]")).toEqual([
93
+ ['these', 'are'],
94
+ ['are', 'some' ],
95
+ ['some', 'words'],
96
+ ['words', '[end]']
97
+ ]);
98
+ });
99
+
100
+ it('should trigram a string with start and end symbols', function() {
101
+ expect(NGrams.ngrams('these are some words', 3, '[start]', '[end]')).toEqual([
102
+ ['[start]', '[start]', 'these'],
103
+ ['[start]', 'these', 'are'],
104
+ ['these', 'are', 'some'],
105
+ ['are', 'some', 'words'],
106
+ ['some', 'words', '[end]'],
107
+ ['words', '[end]', '[end]']
108
+ ]);
109
+ });
110
+
111
+ it('should 4-gram a string with start and end symbols', function() {
112
+ expect(NGrams.ngrams('these are some words', 4, '[start]', '[end]')).toEqual([
113
+ ['[start]', '[start]', '[start]', 'these'],
114
+ ['[start]', '[start]', 'these', 'are'],
115
+ ['[start]', 'these', 'are', 'some'],
116
+ ['these', 'are', 'some', 'words'],
117
+ ['are', 'some', 'words', '[end]'],
118
+ ['some', 'words', '[end]', '[end]'],
119
+ ['words', '[end]', '[end]', '[end]']
120
+ ]);
121
+ });
122
+
123
+ it('should use french tokenizer', function(){
124
+ var T = require('../lib/natural/tokenizers/aggressive_tokenizer_fr');
125
+ var t = new T();
126
+ NGrams.setTokenizer(t);
127
+ expect(NGrams.ngrams('Un Éléphant rouge', 2)).toEqual([['Un', 'Éléphant'],
128
+ ['Éléphant', 'rouge' ]]);
129
+ });
69
130
  });
@@ -0,0 +1,122 @@
1
+ /*
2
+ Copyright (c) 2014, Lee Wenzhu
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+
23
+ var NGramsZH = require('../lib/natural/ngrams/ngrams_zh');
24
+
25
+ describe('ngrams', function() {
26
+ it('should bigram a string via ngrams', function() {
27
+ expect(NGramsZH.ngrams('中文文本测试', 2)).toEqual([['中', '文'],
28
+ ['文', '文' ], ['文', '本'], ['本','测'], ['测', '试']]);
29
+ });
30
+
31
+ it('should bigram an array via ngrams', function() {
32
+ expect(NGramsZH.ngrams(['中','文','文','本','测','试'], 2)).toEqual([['中', '文'],
33
+ ['文', '文' ], ['文', '本'], ['本','测'], ['测', '试']]);
34
+ });
35
+
36
+ it('should trigram a string via ngrams', function() {
37
+ expect(NGramsZH.ngrams('中文文本测试', 3)).toEqual([['中', '文', '文'],
38
+ ['文', '文', '本'],['文','本','测'],['本','测','试']]);
39
+ });
40
+
41
+ it('should trigram an array via ngrams', function() {
42
+ expect(NGramsZH.ngrams(['中','文','文','本','测','试'], 3)).toEqual([['中', '文', '文'],
43
+ ['文', '文', '本'],['文','本','测'],['本','测','试']]);
44
+ });
45
+
46
+ describe('bigrams', function() {
47
+ it('should bigram a string', function() {
48
+ expect(NGramsZH.bigrams('中文文本测试')).toEqual([['中', '文'],
49
+ ['文', '文' ], ['文', '本'], ['本','测'], ['测', '试']]);
50
+ });
51
+
52
+ it('should bigram an array', function() {
53
+ expect(NGramsZH.bigrams(['中','文','文','本','测','试'])).toEqual([['中', '文'],
54
+ ['文', '文' ], ['文', '本'], ['本','测'], ['测', '试']]);
55
+ });
56
+ });
57
+
58
+ describe('trigrams', function() {
59
+ it('should trigram a string', function() {
60
+ expect(NGramsZH.ngrams('中文文本测试', 3)).toEqual([['中', '文', '文'],
61
+ ['文', '文', '本'],['文','本','测'],['本','测','试']]);
62
+ });
63
+
64
+ it('should bigram an array', function() {
65
+ expect(NGramsZH.ngrams(['中','文','文','本','测','试'], 3)).toEqual([['中', '文', '文'],
66
+ ['文', '文', '本'],['文','本','测'],['本','测','试']]);
67
+ });
68
+ });
69
+
70
+ it('should bigram a string with start and end symbols', function() {
71
+ expect(NGramsZH.ngrams('中文测试', 2, "[start]", "[end]")).toEqual([
72
+ ['[start]', '中'],
73
+ ['中', '文'],
74
+ ['文', '测' ],
75
+ ['测', '试'],
76
+ ['试', '[end]']
77
+ ]);
78
+ });
79
+
80
+ it('should bigram a string with start symbols only', function() {
81
+ expect(NGramsZH.ngrams('中文测试', 2, "[start]")).toEqual([
82
+ ['[start]', '中'],
83
+ ['中', '文'],
84
+ ['文', '测' ],
85
+ ['测', '试']
86
+ ]);
87
+ });
88
+
89
+
90
+ it('should bigram a string with end symbols only', function() {
91
+ expect(NGramsZH.ngrams('中文测试', 2, null, "[end]")).toEqual([
92
+ ['中', '文'],
93
+ ['文', '测' ],
94
+ ['测', '试'],
95
+ ['试', '[end]']
96
+ ]);
97
+ });
98
+
99
+ it('should trigram a string with start and end symbols', function() {
100
+ expect(NGramsZH.ngrams('中文测试', 3, '[start]', '[end]')).toEqual([
101
+ ['[start]', '[start]', '中'],
102
+ ['[start]', '中', '文'],
103
+ ['中', '文', '测'],
104
+ ['文', '测', '试'],
105
+ ['测', '试', '[end]'],
106
+ ['试', '[end]', '[end]']
107
+ ]);
108
+ });
109
+
110
+ it('should 4-gram a string with start and end symbols', function() {
111
+ expect(NGramsZH.ngrams('中文测试', 4, '[start]', '[end]')).toEqual([
112
+ ['[start]', '[start]', '[start]', '中'],
113
+ ['[start]', '[start]', '中', '文'],
114
+ ['[start]', '中', '文', '测'],
115
+ ['中', '文', '测', '试'],
116
+ ['文', '测', '试', '[end]'],
117
+ ['测', '试', '[end]', '[end]'],
118
+ ['试', '[end]', '[end]', '[end]']
119
+ ]);
120
+ });
121
+
122
+ });
@@ -54,8 +54,14 @@ describe('normalize_ja', function() {
54
54
 
55
55
  it('should transform halfwidth punctuation signs to fullwidth', function() {
56
56
  // Taken from http://unicode.org/cldr/trac/browser/trunk/common/main/ja.xml
57
- expect(normalize_ja('‾ __ -- ‐ — ― 〜 ・ ・ ,, 、、 ;; :: !! ?? .. ‥ … 。。 '\ ‘ ’ "" “ ” (( )) [[ ]] {{ }} 〈 〉 《 》 「「 」」 『 』 【 】 〔 〕 ‖ § ¶ @@ ++ ^^ $$ ** // \\\ && ## %% ‰ † ‡ ′ ″ 〃 ※'))
58
- .toEqual('‾ __ ─- ‐ — ― 〜 ・ ・ ,, 、、 ;; :: !! ?? .. ‥ … 。。 '\ ‘ ’ "" “ ” (( )) [[ ]] {{ }} 〈 〉 《 》 「「 」」 『 』 【 】 〔 〕 ‖ § ¶ @@ ++ ^^ $$ ** // \\ && ## %% ‰ † ‡ ′ ″ 〃 ※');
57
+ expect(normalize_ja('〜 ・ ・ 、、 。。 「「 」」'))
58
+ .toEqual('〜 ・ ・ 、、 。。 「「 」」');
59
+ });
60
+
61
+ it('should transform fullwidth symbols to halfwidth', function() {
62
+ // Taken from http://unicode.org/cldr/trac/browser/trunk/common/main/ja.xml
63
+ expect(normalize_ja('‾ __ -- ‐ — ― ,, ;; :: !! ?? .. ‥ … '\ ‘ ’ "" “ ” (( )) [[ ]] {{ }} 〈 〉 《 》 『 』 【 】 〔 〕 ‖ § ¶ @@ ++ ^^ $$ ** // \\\ && ## %% ‰ † ‡ ′ ″ 〃 ※'))
64
+ .toEqual('‾ __ -- ‐ — ― ,, ;; :: !! ?? .. ‥ … '\\ ‘ ’ "" “ ” (( )) [[ ]] {{ }} 〈 〉 《 》 『 』 【 】 〔 〕 ‖ § ¶ @@ ++ ^^ $$ ** // \\\\ && ## %% ‰ † ‡ ′ ″ 〃 ※');
59
65
  });
60
66
 
61
67
  it('should replace repeat characters', function() {
@@ -65,7 +71,7 @@ describe('normalize_ja', function() {
65
71
 
66
72
  it('should replace composite symbols', function() {
67
73
  expect(normalize_ja('㍼54年㋃㏪')).toEqual('昭和54年4月11日');
68
- expect(normalize_ja('㍧~㍬')).toEqual('15点~20点');
74
+ expect(normalize_ja('㍧〜㍬')).toEqual('15点〜20点');
69
75
  expect(normalize_ja('カンパニー㍿')).toEqual('カンパニー株式会社');
70
76
  expect(normalize_ja('100㌫')).toEqual('100パーセント');
71
77
  expect(normalize_ja('70㌔')).toEqual('70キロ');
@@ -0,0 +1,111 @@
1
+ /*
2
+ Copyright (c) 2014, Kristoffer Brabrand
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+
23
+ var normalizer = require("../lib/natural/normalizers/normalizer_no.js");
24
+
25
+ describe('normalizer_no', function() {
26
+
27
+ /**
28
+ * Test character normalization
29
+ **/
30
+ describe("Normalization of diacritical marks", function(){
31
+ it("should leave uppercase and lowercase ä's untouched", function() {
32
+ expect(normalizer.remove_diacritics('ä')).toBe('ä');
33
+ expect(normalizer.remove_diacritics('Ä')).toBe('Ä');
34
+ });
35
+
36
+ it("should leave uppercase and lowercase ö's untouched", function() {
37
+ expect(normalizer.remove_diacritics('ö')).toBe('ö');
38
+ expect(normalizer.remove_diacritics('Ö')).toBe('Ö');
39
+ });
40
+
41
+ it("should leave uppercase and lowercase ü's untouched", function() {
42
+ expect(normalizer.remove_diacritics('ü')).toBe('ü');
43
+ expect(normalizer.remove_diacritics('Ü')).toBe('Ü');
44
+ });
45
+
46
+ it("should correctly normalize uppercase and lowercase a's with grave accents", function(){
47
+ expect(normalizer.remove_diacritics('à')).toBe('a');
48
+ expect(normalizer.remove_diacritics('À')).toBe('A');
49
+ });
50
+
51
+ it("should correctly normalize uppercase and lowercase a's with acute accents", function(){
52
+ expect(normalizer.remove_diacritics('á')).toBe('a');
53
+ expect(normalizer.remove_diacritics('Á')).toBe('A');
54
+ });
55
+
56
+ it("should correctly normalize uppercase and lowercase a's with circumflex accents", function(){
57
+ expect(normalizer.remove_diacritics('â')).toBe('a');
58
+ expect(normalizer.remove_diacritics('Â')).toBe('A');
59
+ });
60
+
61
+ it("should correctly normalize uppercase and lowercase c's with cedillas", function(){
62
+ expect(normalizer.remove_diacritics('ç')).toBe('c');
63
+ expect(normalizer.remove_diacritics('Ç')).toBe('C');
64
+ });
65
+
66
+ it("should correctly normalize uppercase and lowercase e's with grave accents", function(){
67
+ expect(normalizer.remove_diacritics('è')).toBe('e');
68
+ expect(normalizer.remove_diacritics('È')).toBe('E');
69
+ });
70
+
71
+ it("should correctly normalize uppercase and lowercase e's with acute accents", function(){
72
+ expect(normalizer.remove_diacritics('é')).toBe('e');
73
+ expect(normalizer.remove_diacritics('É')).toBe('E');
74
+ });
75
+
76
+ it("should correctly normalize uppercase and lowercase e's with circumflex accents", function(){
77
+ expect(normalizer.remove_diacritics('ê')).toBe('e');
78
+ expect(normalizer.remove_diacritics('Ê')).toBe('E');
79
+ });
80
+
81
+ it("should correctly normalize uppercase and lowercase i's with circumflex accents", function(){
82
+ expect(normalizer.remove_diacritics('î')).toBe('i');
83
+ expect(normalizer.remove_diacritics('Î')).toBe('I');
84
+ });
85
+
86
+ it("should correctly normalize uppercase and lowercase n's with tildes", function(){
87
+ expect(normalizer.remove_diacritics('ñ')).toBe('n');
88
+ expect(normalizer.remove_diacritics('Ñ')).toBe('N');
89
+ });
90
+
91
+ it("should correctly normalize uppercase and lowercase o's with acute accents", function(){
92
+ expect(normalizer.remove_diacritics('ó')).toBe('o');
93
+ expect(normalizer.remove_diacritics('Ó')).toBe('O');
94
+ });
95
+
96
+ it("should correctly normalize uppercase and lowercase o's with circumflex accents", function(){
97
+ expect(normalizer.remove_diacritics('ô')).toBe('o');
98
+ expect(normalizer.remove_diacritics('Ô')).toBe('O');
99
+ });
100
+
101
+ it("should correctly normalize uppercase and lowercase u's with circumflex accents", function(){
102
+ expect(normalizer.remove_diacritics('û')).toBe('u');
103
+ expect(normalizer.remove_diacritics('Û')).toBe('U');
104
+ });
105
+
106
+ it("should correctly normalize uppercase and lowercase s's with caron/wedge accents", function(){
107
+ expect(normalizer.remove_diacritics('š')).toBe('s');
108
+ expect(normalizer.remove_diacritics('Š')).toBe('S');
109
+ });
110
+ });
111
+ });