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
package/.editorconfig ADDED
@@ -0,0 +1,7 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+ indent_style = space
7
+ indent_size = 2
package/LICENSE.txt CHANGED
File without changes
package/Makefile CHANGED
File without changes
package/README.md CHANGED
@@ -18,15 +18,6 @@ will be in order. Thanks to Polyakov Vladimir, Russian stemming has been added!,
18
18
 
19
19
  Aside from this README, the only documentation is [this DZone article](http://www.dzone.com/links/r/using_natural_a_nlp_module_for_nodejs.html) and [here on my blog](http://www.chrisumbel.com/article/node_js_natural_language_porter_stemmer_lancaster_bayes_naive_metaphone_soundex), which is a bit older.
20
20
 
21
- Looking for Help Maintaining Natural!
22
- -------------------------------------
23
-
24
- I'm having trouble devoting the time necessary to maintain natural. While I'm certainly not
25
- leaving the project I'd like someone to take over the day-to-day maintenance of dealing with
26
- issues, pull requests and driving the direction of the software moving forward. Please contact
27
- chris@chrisumbel.com if you're interested!
28
-
29
-
30
21
  Installation
31
22
  ------------
32
23
 
@@ -47,24 +38,24 @@ arrays of tokens:
47
38
  ```javascript
48
39
  var natural = require('natural'),
49
40
  tokenizer = new natural.WordTokenizer();
50
- console.log(tokenizer.tokenize("your dog has flees."));
51
- // [ 'your', 'dog', 'has', 'flees' ]
41
+ console.log(tokenizer.tokenize("your dog has fleas."));
42
+ // [ 'your', 'dog', 'has', 'fleas' ]
52
43
  ```
53
44
 
54
45
  The other tokenizers follow a similar pattern:
55
46
 
56
47
  ```javascript
57
48
  tokenizer = new natural.TreebankWordTokenizer();
58
- console.log(tokenizer.tokenize("my dog hasn't any flees."));
59
- // [ 'my', 'dog', 'has', 'n\'t', 'any', 'flees', '.' ]
49
+ console.log(tokenizer.tokenize("my dog hasn't any fleas."));
50
+ // [ 'my', 'dog', 'has', 'n\'t', 'any', 'fleas', '.' ]
60
51
 
61
52
  tokenizer = new natural.RegexpTokenizer({pattern: /\-/});
62
- console.log(tokenizer.tokenize("flee-dog"));
63
- // [ 'flee', 'dog' ]
53
+ console.log(tokenizer.tokenize("flea-dog"));
54
+ // [ 'flea', 'dog' ]
64
55
 
65
56
  tokenizer = new natural.WordPunctTokenizer();
66
- console.log(tokenizer.tokenize("my dog hasn't any flees."));
67
- // [ 'my', 'dog', 'hasn', '\'', 't', 'any', 'flees', '.' ]
57
+ console.log(tokenizer.tokenize("my dog hasn't any fleas."));
58
+ // [ 'my', 'dog', 'hasn', '\'', 't', 'any', 'fleas', '.' ]
68
59
  ```
69
60
 
70
61
  String Distance
@@ -193,7 +184,7 @@ tokenize and stem the text.
193
184
 
194
185
  ```javascript
195
186
  classifier.addDocument('i am long qqqq', 'buy');
196
- classifier.addDocument('buy the q''s', 'buy');
187
+ classifier.addDocument('buy the q\'s', 'buy');
197
188
  classifier.addDocument('short gold', 'sell');
198
189
  classifier.addDocument('sell gold', 'sell');
199
190
 
@@ -217,8 +208,8 @@ You have access to the set of matched classes and the associated value from the
217
208
  Outputs:
218
209
 
219
210
  ```javascript
220
- [ { label: 'sell', value: 0.39999999999999997 },
221
- { label: 'buy', value: 0.19999999999999998 } ]
211
+ [ { label: 'buy', value: 0.39999999999999997 },
212
+ { label: 'sell', value: 0.19999999999999998 } ]
222
213
  ```
223
214
 
224
215
  From this:
@@ -492,6 +483,57 @@ The above outputs: `[ [ 'some', 'other', 'words', 'here' ],
492
483
  [ 'other', 'words', 'here', 'for' ],
493
484
  [ 'words', 'here', 'for', 'you' ] ]`
494
485
 
486
+ ### padding
487
+
488
+ n-grams can also be returned with left or right padding by passing a start and/or end symbol to the bigrams, trigrams or ngrams.
489
+
490
+ ```javascript
491
+ console.log(NGrams.ngrams('some other words here for you', 4, '[start]', '[end]'));
492
+ ```
493
+
494
+ The above will output:
495
+ ```
496
+ [ [ '[start]', '[start]', '[start]', 'some' ],
497
+ [ '[start]', '[start]', 'some', 'other' ],
498
+ [ '[start]', 'some', 'other', 'words' ],
499
+ [ 'some', 'other', 'words', 'here' ],
500
+ [ 'other', 'words', 'here', 'for' ],
501
+ [ 'words', 'here', 'for', 'you' ],
502
+ [ 'here', 'for', 'you', '[end]' ],
503
+ [ 'for', 'you', '[end]', '[end]' ],
504
+ [ 'you', '[end]', '[end]', '[end]' ] ]
505
+ ```
506
+
507
+ For only end symbols, pass `null` for the start symbol, for instance:
508
+ ```javascript
509
+ console.log(NGrams.ngrams('some other words here for you', 4, null, '[end]'));
510
+ ```
511
+
512
+ Will output:
513
+ ```
514
+ [ [ 'some', 'other', 'words', 'here' ],
515
+ [ 'other', 'words', 'here', 'for' ],
516
+ [ 'words', 'here', 'for', 'you' ],
517
+ [ 'here', 'for', 'you', '[end]' ],
518
+ [ 'for', 'you', '[end]', '[end]' ],
519
+ [ 'you', '[end]', '[end]', '[end]' ] ]
520
+ ```
521
+
522
+ ### NGramsZH
523
+
524
+ For Chinese like languages, you can use NGramsZH to do a n-gram, and all apis are the same:
525
+
526
+ ```javascript
527
+ var NGramsZH = natural.NGramsZH;
528
+ console.log(NGramsZH.bigrams('中文测试'));
529
+ console.log(NGramsZH.bigrams(['中', '文', '测', '试']));
530
+ console.log(NGramsZH.trigrams('中文测试'));
531
+ console.log(NGramsZH.trigrams(['中', '文', '测', '试']));
532
+ console.log(NGramsZH.ngrams('一个中文测试', 4));
533
+ console.log(NGramsZH.ngrams(['一', '个', '中', '文', '测',
534
+ '试'], 4));
535
+ ```
536
+
495
537
  tf-idf
496
538
  -----
497
539
 
@@ -555,7 +597,7 @@ tfidf.addFileSync('data_files/two.txt');
555
597
 
556
598
  Multiple terms can be measured as well, with their weights being added into
557
599
  a single measure value. The following example determines that the last document
558
- is the most relevent to the words "node" and "ruby".
600
+ is the most relevant to the words "node" and "ruby".
559
601
 
560
602
  ```javascript
561
603
  var natural = require('natural'),
@@ -608,7 +650,7 @@ tfidf.listTerms(0 /*document index*/).forEach(function(item) {
608
650
  });
609
651
  ```
610
652
 
611
- A TfIdf instance can also be serialized and deserialzed for save and recall.
653
+ A TfIdf instance can also be serialized and deserialized for save and recall.
612
654
 
613
655
  ```javascript
614
656
  var tfidf = new TfIdf();
@@ -625,8 +667,8 @@ Tries
625
667
  -----
626
668
 
627
669
  Tries are a very efficient data structure used for prefix-based searches.
628
- Natural comes packaged with a basic Trie implementation wich can support match collection along a path,
629
- existance search and prefix search.
670
+ Natural comes packaged with a basic Trie implementation which can support match collection along a path,
671
+ existence search and prefix search.
630
672
 
631
673
  ### Building The Trie
632
674
 
@@ -677,6 +719,14 @@ trie.addString("est");
677
719
  console.log(trie.findMatchesOnPath("tester")); // ['tes', 'test'];
678
720
  ```
679
721
 
722
+ ### All Keys with Prefix
723
+
724
+ This search will return all of the words in the Trie with the given prefix, or [ ] if not found.
725
+
726
+ ```javascript
727
+ console.log(trie.keysWithPrefix("string")); // ["string1", "string2", "string3"]
728
+ ```
729
+
680
730
  ### Case-Sensitivity
681
731
 
682
732
  By default the trie is case-sensitive, you can use it in case-_in_sensitive mode by passing `false`
@@ -691,6 +741,144 @@ ciTrie.contains("TEsT"); // true
691
741
  ```
692
742
  In the case of the searches which return strings, all strings returned will be in lower case if you are in case-_in_sensitive mode.
693
743
 
744
+ EdgeWeightedDigraph
745
+ -------------------
746
+ EdgeWeightedDigraph represents a digraph, you can add an edge, get the number vertexes, edges, get all edges and use toString to print the Digraph.
747
+
748
+ initialize a digraph:
749
+
750
+ ```javascript
751
+ var EdgeWeightedDigraph = natural.EdgeWeightedDigraph;
752
+ var digraph = new EdgeWeightedDigraph();
753
+ digraph.add(5,4,0.35);
754
+ digraph.add(5,1,0.32);
755
+ digraph.add(1,3,0.29);
756
+ digraph.add(6,2,0.40);
757
+ digraph.add(3,6,0.52);
758
+ digraph.add(6,4,0.93);
759
+ ```
760
+ the api used is: add(from, to, weight).
761
+
762
+ get the number of vertexes:
763
+
764
+ ```javascript
765
+ console.log(digraph.v());
766
+ ```
767
+ you will get 5.
768
+
769
+ get the number of edges:
770
+
771
+ ```javascript
772
+ console.log(digraph.e());
773
+ ```
774
+ you will get 5.
775
+
776
+
777
+
778
+ ShortestPathTree
779
+ ----------------
780
+
781
+ ShortestPathTree represents a data type for solving the single-source shortest paths problem in
782
+ edge-weighted directed acyclic graphs (DAGs).
783
+ The edge weights can be positive, negative, or zero. There are three APIs:
784
+ getDistTo(vertex),
785
+ hasPathTo(vertex),
786
+ pathTo(vertex).
787
+
788
+ ```javascript
789
+ var ShortestPathTree = natural.ShortestPathTree;
790
+ var spt = new ShortestPathTree(digraph, 5);
791
+ ```
792
+ digraph is an instance of EdgeWeightedDigraph, the second param is the start vertex of DAG.
793
+
794
+ ### getDistTo(vertex)
795
+
796
+ Will return the dist to vertex.
797
+
798
+ ```javascript
799
+ console.log(spt.getDistTo(4));
800
+ ```
801
+ the output will be: 0.35
802
+
803
+ ### hasDistTo(vertex)
804
+
805
+ ```javascript
806
+ console.log(spt.hasDistTo(4));
807
+ console.log(spt.hasDistTo(5));
808
+ ```
809
+
810
+ output will be:
811
+
812
+ ```javascript
813
+ true
814
+ false
815
+ ```
816
+
817
+ ### pathTo(vertex)
818
+ this will return a shortest path:
819
+
820
+ ```javascript
821
+ console.log(spt.pathTo(4));
822
+ ```
823
+
824
+ output will be:
825
+
826
+ ```javascript
827
+ [5, 4]
828
+ ```
829
+
830
+ LongestPathTree
831
+ ----------------
832
+
833
+ LongestPathTree represents a data type for solving the single-source shortest paths problem in
834
+ edge-weighted directed acyclic graphs (DAGs).
835
+ The edge weights can be positive, negative, or zero. There are three APIs same as ShortestPathTree:
836
+ getDistTo(vertex),
837
+ hasPathTo(vertex),
838
+ pathTo(vertex).
839
+
840
+ ```javascript
841
+ var ShortestPathTree = natural.ShortestPathTree;
842
+ var spt = new ShortestPathTree(digraph, 5);
843
+ ```
844
+ digraph is an instance of EdgeWeightedDigraph, the second param is the start vertex of DAG.
845
+
846
+ ### getDistTo(vertex)
847
+
848
+ Will return the dist to vertex.
849
+
850
+ ```javascript
851
+ console.log(spt.getDistTo(4));
852
+ ```
853
+ the output will be: 2.06
854
+
855
+ ### hasDistTo(vertex)
856
+
857
+ ```javascript
858
+ console.log(spt.hasDistTo(4));
859
+ console.log(spt.hasDistTo(5));
860
+ ```
861
+
862
+ output will be:
863
+
864
+ ```javascript
865
+ true
866
+ false
867
+ ```
868
+
869
+ ### pathTo(vertex)
870
+ this will return a shortest path:
871
+
872
+ ```javascript
873
+ console.log(spt.pathTo(4));
874
+ ```
875
+
876
+ output will be:
877
+
878
+ ```javascript
879
+ [5, 1, 3, 6, 4]
880
+ ```
881
+
694
882
  WordNet
695
883
  -------
696
884
 
@@ -747,6 +935,31 @@ As of v0.1.11, WordNet data files are no longer automatically downloaded.
747
935
 
748
936
  Princeton University "About WordNet." WordNet. Princeton University. 2010. <http://wordnet.princeton.edu>
749
937
 
938
+ Spellcheck
939
+ ------------
940
+ A probabilistic spellchecker based on http://norvig.com/spell-correct.html
941
+
942
+ This is best constructed with an array of tokens from a corpus, but a simple list of words from a dictionary will work.
943
+
944
+ ```javascript
945
+ var corpus = ['something', 'soothing'];
946
+ var spellcheck = new Spellcheck(corpus);
947
+ ```
948
+
949
+ It uses the trie datastructure for fast boolean lookup of a word
950
+
951
+ ```javascript
952
+ spellcheck.isCorrect('cat'); // false
953
+ ```
954
+
955
+ It suggests corrections (sorted by probability in descending order) that are up to a maximum edit distance away from the input word. According to Norvig, a max distance of 1 will cover 80% to 95% of spelling mistakes. After a distance of 2, it becomes very slow.
956
+
957
+ ```javascript
958
+ spellcheck.getCorrections('soemthing', 1); // ['something']
959
+ spellcheck.getCorrections('soemthing', 2); // ['something', 'soothing']
960
+ ```
961
+
962
+
750
963
  Development
751
964
  -----------
752
965
  When developing, please:
@@ -29,4 +29,4 @@ suite = new uubench.Suite({
29
29
  require('./metaphone');
30
30
  require('./soundex');
31
31
 
32
- suite.run();
32
+ suite.run();
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/index.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -46,7 +46,7 @@ var Sentences = function(pos, callback) {
46
46
  this.posObj = pos;
47
47
  this.senType = null;
48
48
  callback(this);
49
- }
49
+ };
50
50
 
51
51
  Sentences.prototype.part = function(callback) {
52
52
  var subject = [],
@@ -88,7 +88,7 @@ Sentences.prototype.part = function(callback) {
88
88
  }
89
89
 
90
90
  callback(this);
91
- }
91
+ };
92
92
 
93
93
  // Takes POS and removes IN to NN or NNS
94
94
  // Adds a PP for each prepositionPhrases
@@ -108,15 +108,15 @@ Sentences.prototype.prepositionPhrases = function() {
108
108
  remove = false;
109
109
  }
110
110
  }
111
- }
111
+ };
112
112
 
113
113
  Sentences.prototype.subjectToString = function() {
114
114
  return this.posObj.tags.map(function(t){ if (t.spos == "SP" || t.spos == "S" ) return t.token }).join(' ');
115
- }
115
+ };
116
116
 
117
117
  Sentences.prototype.predicateToString = function() {
118
118
  return this.posObj.tags.map(function(t){ if (t.spos == "PP" || t.spos == "P" ) return t.token }).join(' ');
119
- }
119
+ };
120
120
 
121
121
  Sentences.prototype.implicitYou = function() {
122
122
  for (var i = 0; i < this.posObj.tags.length;i++) {
@@ -126,22 +126,25 @@ Sentences.prototype.implicitYou = function() {
126
126
  }
127
127
 
128
128
  return false;
129
- }
129
+ };
130
130
 
131
131
  Sentences.prototype.toString = function() {
132
132
  return this.posObj.tags.map(function(t){return t.token}).join(' ');
133
- }
133
+ };
134
134
 
135
135
  // This is quick and incomplete.
136
136
  Sentences.prototype.type = function(callback) {
137
137
  var callback = callback || false;
138
-
138
+
139
+ // Check for implicit you before popping a tag.
140
+ var implicitYou = this.implicitYou();
141
+
139
142
  // FIXME - punct seems useless
140
143
  var lastElement = this.posObj.punct();
141
144
  lastElement = (lastElement.length != 0) ? lastElement.pop() : this.posObj.tags.pop();
142
-
145
+
143
146
  if (lastElement.pos !== ".") {
144
- if (this.implicitYou()) {
147
+ if (implicitYou) {
145
148
  this.senType = "COMMAND";
146
149
  } else if (_(["WDT","WP","WP$","WRB"]).contains(this.posObj.tags[0].pos)) {
147
150
  // Sentences that start with: who, what where when why and how, then they are questions
@@ -158,8 +161,8 @@ Sentences.prototype.type = function(callback) {
158
161
  } else {
159
162
  switch(lastElement.token) {
160
163
  case "?": this.senType = "INTERROGATIVE"; break;
161
- case "!": this.senType = (this.implicitYou()) ? "COMMAND":"EXCLAMATORY"; break;
162
- case ".": this.senType = (this.implicitYou()) ? "COMMAND":"DECLARATIVE"; break;
164
+ case "!": this.senType = (implicitYou) ? "COMMAND":"EXCLAMATORY"; break;
165
+ case ".": this.senType = (implicitYou) ? "COMMAND":"DECLARATIVE"; break;
163
166
  }
164
167
  }
165
168
 
@@ -168,6 +171,6 @@ Sentences.prototype.type = function(callback) {
168
171
  } else {
169
172
  return this.senType;
170
173
  }
171
- }
174
+ };
172
175
 
173
176
  module.exports = Sentences;
@@ -25,8 +25,12 @@ util = require('util'),
25
25
  Classifier = require('./classifier'),
26
26
  ApparatusBayesClassifier = require('apparatus').BayesClassifier;
27
27
 
28
- var BayesClassifier = function(stemmer) {
29
- Classifier.call(this, new ApparatusBayesClassifier(), stemmer);
28
+ var BayesClassifier = function(stemmer, smoothing) {
29
+ var abc = new ApparatusBayesClassifier();
30
+ if (smoothing && isFinite(smoothing)) {
31
+ abc = new ApparatusBayesClassifier(smoothing);
32
+ }
33
+ Classifier.call(this, abc, stemmer);
30
34
  };
31
35
 
32
36
  util.inherits(BayesClassifier, Classifier);
File without changes
File without changes
@@ -99,13 +99,18 @@ function distance(s1, s2) {
99
99
  // s2 is the second string to compare
100
100
  // dj is the Jaro Distance (if you've already computed it), leave blank and the method handles it
101
101
  function JaroWinklerDistance(s1, s2, dj) {
102
- var jaro;
103
- (typeof(dj) == 'undefined')? jaro = distance(s1,s2) : jaro = dj;
104
- var p = 0.1; //
105
- var l = 0 // length of the matching prefix
106
- while(s1[l] == s2[l] && l < 4)
107
- l++;
108
-
109
- return jaro + l * p * (1 - jaro);
102
+ if (s1 == s2) {
103
+ return 1
104
+ }
105
+ else {
106
+ var jaro;
107
+ (typeof(dj) == 'undefined')? jaro = distance(s1,s2) : jaro = dj;
108
+ var p = 0.1; //
109
+ var l = 0 // length of the matching prefix
110
+ while(s1[l] == s2[l] && l < 4)
111
+ l++;
112
+
113
+ return jaro + l * p * (1 - jaro);
114
+ }
110
115
  }
111
116
  module.exports = JaroWinklerDistance;
File without changes
@@ -26,10 +26,13 @@ exports.DoubleMetaphone = require('./phonetics/double_metaphone');
26
26
  exports.SoundExDM = require('./phonetics/dm_soundex');
27
27
  exports.PorterStemmer = require('./stemmers/porter_stemmer');
28
28
  exports.PorterStemmerFa = require('./stemmers/porter_stemmer_fa');
29
+ exports.PorterStemmerFr = require('./stemmers/porter_stemmer_fr');
29
30
  exports.PorterStemmerRu = require('./stemmers/porter_stemmer_ru');
30
31
  exports.PorterStemmerEs = require('./stemmers/porter_stemmer_es');
31
32
  exports.PorterStemmerIt = require('./stemmers/porter_stemmer_it');
33
+ exports.PorterStemmerNo = require('./stemmers/porter_stemmer_no');
32
34
  exports.LancasterStemmer = require('./stemmers/lancaster_stemmer');
35
+ exports.StemmerFr = require('./stemmers/stemmer_fr');
33
36
  exports.StemmerPl = require('./stemmers/stemmer_pl');
34
37
  exports.StemmerJa = require('./stemmers/stemmer_ja');
35
38
  exports.AggressiveTokenizerNl = require('./tokenizers/aggressive_tokenizer_nl');
@@ -39,6 +42,7 @@ exports.AggressiveTokenizerEs = require('./tokenizers/aggressive_tokenizer_es');
39
42
  exports.AggressiveTokenizerIt = require('./tokenizers/aggressive_tokenizer_it');
40
43
  exports.AggressiveTokenizerPl = require('./tokenizers/aggressive_tokenizer_pl');
41
44
  exports.AggressiveTokenizerPt = require('./tokenizers/aggressive_tokenizer_pt');
45
+ exports.AggressiveTokenizerNo = require('./tokenizers/aggressive_tokenizer_no');
42
46
  exports.AggressiveTokenizer = require('./tokenizers/aggressive_tokenizer');
43
47
  exports.RegexpTokenizer = require('./tokenizers/regexp_tokenizer').RegexpTokenizer;
44
48
  exports.WordTokenizer = require('./tokenizers/regexp_tokenizer').WordTokenizer;
@@ -57,7 +61,11 @@ exports.TfIdf = require('./tfidf/tfidf');
57
61
  exports.Trie = require('./trie/trie');
58
62
  exports.SentenceAnalyzer = require('./analyzers/sentence_analyzer');
59
63
  exports.stopwords = require('./util/stopwords').words;
64
+ exports.ShortestPathTree = require('./util/shortest_path_tree');
65
+ exports.LongestPathTree = require('./util/longest_path_tree');
66
+ exports.EdgeWeightedDigraph = require('./util/edge_weighted_digraph');
60
67
  exports.NGrams = require('./ngrams/ngrams');
68
+ exports.NGramsZH = require('./ngrams/ngrams_zh');
61
69
  exports.JaroWinklerDistance = require('./distance/jaro-winkler_distance');
62
70
  exports.LevenshteinDistance = require('./distance/levenshtein_distance');
63
71
  exports.DiceCoefficient = require('./distance/dice_coefficient');
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -51,6 +51,7 @@ var VerbInflector = function() {
51
51
  this.addIrregular("am", "are");
52
52
  this.addIrregular("is", "are");
53
53
  this.addIrregular("was", "were");
54
+ this.addIrregular("has", "have");
54
55
 
55
56
  this.singularForms.regularForms.push([/ed$/i, 'ed']);
56
57
  this.singularForms.regularForms.push([/ss$/i, 'sses']);
@@ -77,8 +77,7 @@ TenseInflector.prototype.restoreCase = function(token) {
77
77
 
78
78
  TenseInflector.prototype.izeRegulars = function(token, formSet) {
79
79
  token = token.toLowerCase();
80
-
81
- if(formSet.irregularForms[token])
80
+ if(formSet.irregularForms.hasOwnProperty(token) && formSet.irregularForms[token])
82
81
  return formSet.irregularForms[token];
83
82
 
84
83
  return false;