natural 6.8.1 → 6.9.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.
@@ -40,6 +40,7 @@ export let PorterStemmerIt: Stemmer
40
40
  export let PorterStemmerNl: Stemmer
41
41
  export let PorterStemmerNo: Stemmer
42
42
  export let PorterStemmerPt: Stemmer
43
+ export let PorterStemmerUk: Stemmer
43
44
  export let PorterStemmerRu: Stemmer
44
45
  export let PorterStemmerSv: Stemmer
45
46
  export let StemmerId: Stemmer
@@ -27,6 +27,7 @@ exports.PorterStemmerFa = require('./porter_stemmer_fa')
27
27
  exports.PorterStemmerFr = require('./porter_stemmer_fr')
28
28
  exports.CarryStemmerFr = require('./Carry')
29
29
  exports.PorterStemmerDe = require('./porter_stemmer_de')
30
+ exports.PorterStemmerUk = require('./porter_stemmer_uk')
30
31
  exports.PorterStemmerRu = require('./porter_stemmer_ru')
31
32
  exports.PorterStemmerEs = require('./porter_stemmer_es')
32
33
  exports.PorterStemmerIt = require('./porter_stemmer_it')
@@ -0,0 +1,129 @@
1
+ 'use strict'
2
+
3
+ const Stemmer = require('./stemmer_uk')
4
+
5
+ const PorterStemmer = new Stemmer()
6
+ module.exports = PorterStemmer
7
+
8
+ function attemptReplacePatterns (token, patterns) {
9
+ let replacement = null
10
+ let i = 0; let isReplaced = false
11
+ while ((i < patterns.length) && !isReplaced) {
12
+ if (patterns[i][0].test(token)) {
13
+ replacement = token.replace(patterns[i][0], patterns[i][1])
14
+ isReplaced = true
15
+ }
16
+ i++
17
+ }
18
+ return replacement
19
+ }
20
+
21
+ function perfectiveGerund (token) {
22
+ const result = attemptReplacePatterns(token, [
23
+ [/[ая]в(ши|шись)$/g, ''],
24
+ [/(ив|ивши|ившись)$/g, '']
25
+ ])
26
+ return result
27
+ }
28
+
29
+ function adjectival (token) {
30
+ let result = adjective(token)
31
+ if (result != null) {
32
+ const pariticipleResult = participle(result)
33
+ result = pariticipleResult || result
34
+ }
35
+ return result
36
+ }
37
+
38
+ function adjective (token) {
39
+ const result = attemptReplacePatterns(token, [
40
+ [/(ими|ій|ий|а|е|ова|ове|ів|є|їй|єє|еє|я|ім|ем|им|ім|их|іх|ою|йми|іми|у|ю|ого|ому|ої)$/g, '']
41
+ ])
42
+ return result
43
+ }
44
+
45
+ function participle (token) { // edit
46
+ const result = attemptReplacePatterns(token, [
47
+ [/(ий|ого|ому|им|ім|а|ій|у|ою|ій|і|их|йми|их)$/g, '']
48
+ ])
49
+ return result
50
+ }
51
+
52
+ function reflexive (token) {
53
+ const result = attemptReplacePatterns(token, [
54
+ [/(с[яьи])$/g, '']
55
+ ])
56
+ return result
57
+ }
58
+
59
+ function verb (token) {
60
+ const result = attemptReplacePatterns(token, [
61
+ [/(сь|ся|ив|ать|ять|у|ю|ав|али|учи|ячи|вши|ши|е|ме|ати|яти|є)$/g, '']
62
+ ])
63
+ return result
64
+ }
65
+
66
+ function noun (token) {
67
+ const result = attemptReplacePatterns(token, [
68
+ [/(а|ев|ов|е|ями|ами|еи|и|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я|і|ові|ї|ею|єю|ою|є|еві|ем|єм|ів|їв|ю)$/g, '']
69
+ ])
70
+ return result
71
+ }
72
+
73
+ function superlative (token) {
74
+ const result = attemptReplacePatterns(token, [
75
+ [/(ейш|ейше)$/g, '']
76
+ ])
77
+ return result
78
+ }
79
+
80
+ function derivational (token) {
81
+ const result = attemptReplacePatterns(token, [
82
+ [/[^аеиоуюяіїє][аеиоуюяіїє]+[^аеиоуюяіїє]+[аеиоуюяіїє].*(?<=о)сть?$/g, '']
83
+ ])
84
+ return result
85
+ }
86
+
87
+ // perform full stemming algorithm on a single word
88
+ PorterStemmer.stem = function (token) {
89
+ token = token.toLowerCase()
90
+ const volwesRegexp = /^(.*?[аеиоуюяіїє])(.*)$/g
91
+ let RV = volwesRegexp.exec(token)
92
+ if (!RV || RV.length < 3) {
93
+ return token
94
+ }
95
+ const head = RV[1]
96
+ RV = RV[2]
97
+ volwesRegexp.lastIndex = 0
98
+ const R2 = volwesRegexp.exec(RV)
99
+ let result = perfectiveGerund(RV)
100
+ if (result === null) {
101
+ const resultReflexive = reflexive(RV) || RV
102
+ result = adjectival(resultReflexive)
103
+ if (result === null) {
104
+ result = verb(resultReflexive)
105
+ if (result === null) {
106
+ result = noun(resultReflexive)
107
+ if (result === null) {
108
+ result = resultReflexive
109
+ }
110
+ }
111
+ }
112
+ }
113
+ result = result.replace(/и$/g, '')
114
+ let derivationalResult = result
115
+ if (R2 && R2[2]) {
116
+ derivationalResult = derivational(R2[2])
117
+ if (derivationalResult != null) {
118
+ derivationalResult = derivational(result)
119
+ } else {
120
+ derivationalResult = result
121
+ }
122
+ }
123
+
124
+ let superlativeResult = superlative(derivationalResult) || derivationalResult
125
+
126
+ superlativeResult = superlativeResult.replace(/(н)н/g, '$1')
127
+ superlativeResult = superlativeResult.replace(/ь$/g, '')
128
+ return head + superlativeResult
129
+ }
@@ -0,0 +1,28 @@
1
+ 'use strict'
2
+
3
+ const stopwords = require('../util/stopwords_uk')
4
+ const Tokenizer = require('../tokenizers/aggressive_tokenizer_uk')
5
+
6
+ module.exports = function () {
7
+ const stemmer = this
8
+
9
+ stemmer.stem = function (token) {
10
+ return token
11
+ }
12
+
13
+ stemmer.tokenizeAndStem = function (text, keepStops) {
14
+ const stemmedTokens = []
15
+
16
+ new Tokenizer().tokenize(text).forEach(function (token) {
17
+ if (keepStops || stopwords.words.indexOf(token) === -1) {
18
+ let resultToken = token.toLowerCase()
19
+ if (resultToken.match(/[а-яґєії0-9]+/gi)) {
20
+ resultToken = stemmer.stem(resultToken)
21
+ }
22
+ stemmedTokens.push(resultToken)
23
+ }
24
+ })
25
+
26
+ return stemmedTokens
27
+ }
28
+ }
@@ -0,0 +1,25 @@
1
+ 'use strict'
2
+
3
+ const Tokenizer = require('./tokenizer')
4
+ const util = require('util')
5
+
6
+ const AggressiveTokenizer = function () {
7
+ Tokenizer.call(this)
8
+ }
9
+
10
+ util.inherits(AggressiveTokenizer, Tokenizer)
11
+
12
+ module.exports = AggressiveTokenizer
13
+
14
+ AggressiveTokenizer.prototype.withoutEmpty = function (array) {
15
+ return array.filter(function (a) { return a })
16
+ }
17
+
18
+ AggressiveTokenizer.prototype.clearText = function (text) {
19
+ return text.replace(/[^a-zа-яґєії0-9]/gi, ' ').replace(/[\s\n]+/g, ' ').trim()
20
+ }
21
+
22
+ AggressiveTokenizer.prototype.tokenize = function (text) {
23
+ // break a string up into an array of tokens by anything non-word
24
+ return this.withoutEmpty(this.clearText(text).split(' '))
25
+ }
@@ -34,7 +34,8 @@ util.inherits(SentenceTokenizer, Tokenizer)
34
34
 
35
35
  SentenceTokenizer.prototype.tokenize = function (text) {
36
36
  // break string up in to sentences based on punctation and quotation marks
37
- let tokens = text.match(/(?<=\s+|^)["'‘“'"[({⟨]?(.*?[.?!…]|[^.?!…]+)(\s[.?!…])*["'’”'"\])}⟩]?(?=\s+|$)/g)
37
+ // let tokens = text.match(/(?<=\s+|^)["'‘“'"[({⟨]?.*?[.?!…](\s[.?!…])*["'’”'"\])}⟩]?(?=\s+|$)/g)
38
+ let tokens = text.match(/(?<=\s+|^)["'‘“'"[({⟨]?(.*?[.?!…]|.+)(\s[.?!…])*["'’”'"\])}⟩]?(?=\s+|$)/g)
38
39
 
39
40
  DEBUG && console.log('SentenceTokenizer.tokenize: ' + tokens)
40
41
 
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+
3
+ // a list of commonly used words that have little meaning and can be excluded
4
+ // from analysis.
5
+ const words = [
6
+ 'о', 'після', 'всі', 'також', 'і', 'інші', 'все', 'як', 'в', 'бути',
7
+ 'тому', 'був', 'до', 'є', 'між', 'вся', 'але', 'від', 'іди', 'можу',
8
+ 'підійди', 'міг', 'робив', 'роблю', 'кожен', 'для', 'звідки', 'мав',
9
+ 'він', 'має', 'її', 'тут', 'його', 'якщо', 'у', 'воно', 'за',
10
+ 'робити', 'багато', 'може бути', 'самий', 'повинен',
11
+ 'мій', 'ніколи', 'зараз', 'із', 'на', 'тільки', 'або', 'наше', 'поза',
12
+ 'кінець', 'сказав', 'сказала', 'бачив', 'з',
13
+ 'трохи', 'все ще', 'так', 'потім', 'той', 'їх', 'там', 'цей', 'вони', 'те',
14
+ 'через', 'теж', 'під', 'над', 'дуже', 'був', 'добре',
15
+ 'що', 'де', 'який', 'доки', 'хто', 'хотів би',
16
+ 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'й', 'ї', 'к',
17
+ 'л', 'м', 'н', 'o', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ',
18
+ 'ь', 'ю', 'я', '$', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_']
19
+
20
+ // tell the world about the noise words.
21
+ exports.words = words
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "natural",
3
3
  "description": "General natural language (tokenizing, stemming (English, Russian, Spanish), part-of-speech tagging, sentiment analysis, classification, inflection, phonetics, tfidf, WordNet, jaro-winkler, Levenshtein distance, Dice's Coefficient) facilities for node.",
4
- "version": "6.8.1",
4
+ "version": "6.9.1",
5
5
  "homepage": "https://github.com/NaturalNode/natural",
6
6
  "repository": {
7
7
  "type": "git",