diff --git a/src/2-two/postTagger/model/nouns/nouns.js b/src/2-two/postTagger/model/nouns/nouns.js new file mode 100644 index 0000000..0a05ccb --- /dev/null +++ b/src/2-two/postTagger/model/nouns/nouns.js @@ -0,0 +1,186 @@ +const infNouns = + '(feel|sense|process|rush|side|bomb|bully|challenge|cover|crush|dump|exchange|flow|function|issue|lecture|limit|march|process)' +export default [ + //'more' is not always an adverb + // any [more] + { match: '(the|any) [more]', group: 0, tag: 'Singular', reason: 'more-noun' }, + // [more] players + { match: '[more] #Noun', group: 0, tag: 'Adjective', reason: 'more-adj' }, + // [rights] of man + { match: '[(right|rights)] of .', group: 0, tag: 'Noun', reason: 'right-of' }, + // a [bit] + { match: 'a [bit]', group: 0, tag: 'Singular', reason: 'a-bit' }, + // a [must] + { match: 'a [must]', group: 0, tag: 'Singular', reason: 'a-must' }, + // we [all] + { match: '(we|us) [all]', group: 0, tag: 'Noun', reason: 'we-all' }, + // due to [weather] + { match: 'due to [#Verb]', group: 0, tag: 'Noun', reason: 'due-to' }, + + // my first [thought] + { match: '#Possessive #Ordinal [#PastTense]', group: 0, tag: 'Noun', reason: 'first-thought' }, + // the nice [walk] + { + match: '(the|this|those|these) #Adjective [%Noun|Verb%]', + group: 0, + tag: 'Noun', + notIf: '#Copula', + reason: 'adj-verb', + }, + // the truly nice [swim] + { match: '(the|this|those|these) #Adverb #Adjective [#Verb]', group: 0, tag: 'Noun', reason: 'det-adv-verb' }, + // the [message] from Danny + { match: 'the [#Verb] #Preposition .', group: 0, tag: 'Noun', reason: 'det-verb-prep' }, + // the [manufacture] of perfume + { match: '(a|an|the) [#Verb] of', group: 0, tag: 'Noun', reason: 'verb-of' }, + // a type of [shout] + { match: '#Determiner #Noun of [#Verb]', group: 0, tag: 'Noun', notIf: '#Gerund', reason: 'noun-of-noun' }, + // waited until [release] + { + match: '#PastTense #Preposition [#PresentTense]', + group: 0, + notIf: '#Gerund', + tag: 'Noun', + reason: 'ended-in-ruins', + }, + // and [u] + { match: '#Conjunction [u]', group: 0, tag: 'Pronoun', reason: 'conjunction-u' }, + // [u] made me smile + { match: '[u] #Verb', group: 0, tag: 'Pronoun', reason: 'u-verb' }, + // water-flows + { match: '(#Singular && @hasHyphen) #PresentTense', tag: 'Noun', reason: 'hyphen-verb' }, + // is no [going] back + { match: 'is no [#Verb]', group: 0, tag: 'Noun', reason: 'is-no-verb' }, + // do [so] + { match: 'do [so]', group: 0, tag: 'Adverb', reason: 'so-noun' }, + // what the [hell] + { match: '#Determiner [(shit|damn|hell)]', group: 0, tag: 'Noun', reason: 'swears-noun' }, + // go to [shit] + { match: 'to [(shit|hell)]', group: 0, tag: 'Noun', reason: 'to-swears' }, + // the [staff] were + { match: '(the|these) [#Singular] (were|are)', group: 0, tag: 'Plural', reason: 'sing-were' }, + // and check this out! a [walk-in] microwave. + { + match: '(the|those|these|a|an) #Adjective? [(#PresentTense && !#Gerund && !#Copula && !seem && !appear && !include) #Particle?]', + group: 0, + tag: 'Noun', + notIf: 'the (poor|rich|young|old|elderly|unemployed|homeless|disabled)', + reason: 'det-inf', + }, + + // ==== Actor ==== + // Aircraft designer + { match: '#Noun #Actor', tag: 'Actor', notIf: '(#Person|#Pronoun)', reason: 'thing-doer' }, + // lighting designer + { match: '#Gerund #Actor', tag: 'Actor', reason: 'ger-doer' }, + // captain sanders + // { match: '[#Actor+] #ProperNoun', group: 0, tag: 'Honorific', reason: 'sgt-kelly' }, + // co founder + { match: `co #Singular`, tag: 'Actor', reason: 'co-noun' }, + // [aircraft] designer + { + match: `[#Noun+] #Actor`, + group: 0, + tag: 'Actor', + notIf: '(#Honorific|#Pronoun|#Possessive)', + reason: 'air-traffic', + }, + // fine-artist + { + match: `(urban|cardiac|cardiovascular|respiratory|medical|clinical|visual|graphic|creative|dental|exotic|fine|certified|registered|technical|virtual|professional|amateur|junior|senior|special|pharmaceutical|theoretical)+ #Noun? #Actor`, + tag: 'Actor', + reason: 'fine-artist', + }, + // dance coach + { + match: `#Noun+ (coach|chef|king|engineer|fellow|personality|boy|girl|man|woman|master)`, + tag: 'Actor', + reason: 'dance-coach', + }, + // chief design officer + { match: `chief . officer`, tag: 'Actor', reason: 'chief-officer' }, + // chief of police + { match: `chief of #Noun+`, tag: 'Actor', reason: 'chief-police' }, + // president of marketing + { match: `senior? vice? president of #Noun+`, tag: 'Actor', reason: 'president-of' }, + + // ==== Singular ==== + // the [sun] + { match: '#Determiner [sun]', group: 0, tag: 'Singular', reason: 'sun' }, + // did a [900], paid a [20] + { match: '#Verb (a|an) [#Value]$', group: 0, tag: 'Singular', reason: 'did-a-value' }, + // the [can] + { match: 'the [(can|will|may)]', group: 0, tag: 'Singular', reason: 'can' }, + + // ==== Possessive ==== + // John Smith's + { match: '#FirstName #Acronym? (#Possessive && #LastName)', tag: 'Possessive', reason: 'name-poss' }, + // Microsoft Research's office + { match: '#Organization+ #Possessive', tag: 'Possessive', reason: 'org-poss' }, + // Los Angeles's fundraiser + { match: '#Place+ #Possessive', tag: 'Possessive', reason: 'place-poss' }, + // my butt smells + { match: '#Possessive #PresentTense #Particle?', notIf: '(#Gerund|her)', tag: 'Noun', reason: 'poss-verb' }, // anna's eating vs anna's eating lunch + // my [teachers] dog + { match: '(my|our|their|her|his|its) [(#Plural && #Actor)] #Noun', group: 0, tag: 'Possessive', reason: 'my-dads' }, + + // 10th of a [second] + { match: '#Value of a [second]', group: 0, unTag: 'Value', tag: 'Singular', reason: '10th-second' }, + // 10 [seconds] + { match: '#Value [seconds]', group: 0, unTag: 'Value', tag: 'Plural', reason: '10-seconds' }, + // in [love] + { match: 'in [#Infinitive]', group: 0, tag: 'Singular', reason: 'in-age' }, + // a [minor] in + { match: 'a [#Adjective] #Preposition', group: 0, tag: 'Noun', reason: 'a-minor-in' }, + // the [repairer] said + { match: '#Determiner [#Singular] said', group: 0, tag: 'Actor', reason: 'actor-said' }, + // the euro [sense] + { + match: `#Determiner #Noun [${infNouns}] !(#Preposition|to|#Adverb)?`, + group: 0, + tag: 'Noun', + reason: 'noun-sense', + }, + // [thanks] for the gift are overdue + { match: '[#PresentTense] (of|by|for) (a|an|the) #Noun #Copula', group: 0, tag: 'Plural', reason: 'photographs-of' }, + // You eat and [sleep] + { match: '#Infinitive and [%Noun|Verb%]', group: 0, tag: 'Infinitive', reason: 'fight-and-win' }, + // dogs and [running] and cats + { match: '#Noun and [#Verb] and #Noun', group: 0, tag: 'Noun', reason: 'and-flowers' }, + // the 1992 [classic] + { match: 'the #Cardinal [%Adj|Noun%]', group: 0, tag: 'Noun', reason: '1992-classic' }, + // This is the [premier] university in Virginia + { match: '#Copula the [%Adj|Noun%] #Noun', group: 0, tag: 'Adjective', reason: 'premier-uni' }, + + // i ate [me] sandwich (scottish slang) + { match: 'i #Verb [me] #Noun', group: 0, tag: 'Possessive', reason: 'scottish-me' }, + // [dance] music + { + match: '[(dance|rock|rap|swing)] (music|class|lesson|night|party|festival|league|ceremony)', + group: 0, + tag: 'Noun', + reason: 'dance-music', + }, + // [wit] it + { match: '[wit] (me|it)', group: 0, tag: 'Preposition', reason: 'wit-me' }, + // He bowed his [head] in prayer + { match: '#PastTense #Possessive [#Verb]', group: 0, tag: 'Noun', notIf: '(saw|made)', reason: 'left-her-boots' }, + // 35 [signs] + { match: '#Value [%Plural|Verb%]', group: 0, tag: 'Plural', notIf: '(one|1|a|an)', reason: '35-signs' }, + // had [time] + { match: 'had [%Noun|Verb%]', group: 0, tag: 'Noun', notIf: '(#Gerund|come|become)', reason: 'had-time' }, + // instant access + { match: '%Adj|Noun% %Noun|Verb%', tag: '#Adjective #Noun', notIf: '#ProperNoun #Noun', reason: 'instant-access' }, + // a [representative] to + { match: '#Determiner [%Adj|Noun%] #Conjunction', group: 0, tag: 'Noun', reason: 'a-rep-to' }, + // near death experiences, ambitious sales [targets] + { + match: '#Adjective #Noun [%Plural|Verb%]$', + group: 0, + tag: 'Plural', + notIf: '#Pronoun', + reason: 'near-death', + }, + // your guild [colors] + { match: '#Possessive #Noun [(colors|colours)]$', group: 0, tag: 'Plural', reason: 'guild-colors' }, +] diff --git a/tests/two/tagger/ambiguity/present-noun.test.js b/tests/two/tagger/ambiguity/present-noun.test.js new file mode 100644 index 0000000..8af2e10 --- /dev/null +++ b/tests/two/tagger/ambiguity/present-noun.test.js @@ -0,0 +1,192 @@ +import test from 'tape' +import nlp from '../../_lib.js' +const here = '[two/present-noun] ' + +const arr = [ + // present-plural + ['bakes', '#PresentTense'], + ['fakes', '#PresentTense'], + ['makes', '#PresentTense'], + ['mistakes', '#PresentTense'], + ['overtakes', '#PresentTense'], + ['retakes', '#PresentTense'], + ['forsakes', '#PresentTense'], + ['shakes', '#PresentTense'], + ['snakes', '#PresentTense'], + ['takes', '#PresentTense'], + ['undertakes', '#PresentTense'], + + [`i wish that`, 'i #Infinitive .'], + [`that wish`, '. #Singular'], + [`he changes`, `#Noun #PresentTense`], + [`his changes`, `#Noun #Plural`], + + // noun-verb + [`date the boy`, '#PresentTense #Determiner #Noun'], + [`date of birth`, '#Noun #Preposition #Noun'], + [`any flood`, '#Determiner #Noun'], + [`will flood`, '. #PresentTense'], + [`suddenly flood`, '. #PresentTense'], + [`not flood`, '. #PresentTense'], + [`we date`, '. #PresentTense'], + [`you flood`, '. #PresentTense'], + + // infinitive-singular + [`date spencer`, '#Verb .'], + [`flash the`, '#Verb .'], + [`flash his`, '#Verb .'], + [`flash around`, '#Verb .'], + [`flood you`, '#Verb .'], + [`my flood`, '. #Noun'], + [`one flood`, '. #Noun'], + [`flash could`, '#Noun .'], + [`flash is`, '#Noun .'], + + // the #Noun #Infinitive ->Noun + [`the planning [process]`, `the #Noun #Noun`], + [`the printing press`, `the #Noun #Noun`], + [`the tip line`, `the #Noun #Noun`], + [`the defence budget`, `the #Noun #Noun`], + [`the cross cook`, `the #Noun #Noun`], + [`the security guard`, `the #Noun #Noun`], + [`the intersection sign`, `the #Noun #Noun`], + + // the #Noun #Infinitive ->Verb + [`did the banana say`, `. the #Noun #Infinitive`], + // [`did the skeleten show`, `. the #Noun #Infinitive`], + [`does the king want`, `. the #Noun #Infinitive`], + [`does the writer say`, `. the #Noun #Infinitive`], + [`let the messiah go`, `. the #Noun #Infinitive`], + [`the critics keep writing`, `the #Noun #Verb #Verb`], + [`the critics be`, `the #Noun #Infinitive`], + [`the captain put himself`, `the #Noun #Infinitive himself`], + [`the parties dispute which`, `the #Noun #Infinitive which`], + [`the Princess thought`, `the #Noun #PastTense`], + [`the feet kick him`, `the #Noun #Infinitive him`], + [`the midnight knock`, `the #Noun #Noun`], + [`the universal process`, `the #Adjective #Singular`], + [`the collective budget`, `the #Adjective #Singular`], + [`the work stress`, `the #Noun #Singular`], + [`the american touch`, `the #Demonym #Singular`], + [`the road upgrade`, `the #Noun #Singular`], + [`the city strain`, `the #Noun #Singular`], + [`the software patch`, `the #Noun #Singular`], + [`the toronto fire`, `the #Noun #Singular`], + // [`The paving-stone`, `the #Noun #Singular`], + // -> plurals + [`the universal processes`, `the #Adjective #Plural`], + [`the collective budgets`, `the #Adjective #Plural`], + // [`the work stresses`, `the #Noun #Plural`], + [`the american touches`, `the #Noun #Plural`], + [`the road upgrades`, `the #Noun #Plural`], + [`the city strains`, `the #Noun #Plural`], + // [`the software patches`, `the #Noun #Plural`], + // [`the toronto fires`, `the #Noun #Plural`], + [`The paving-stones`, `the #Adjective #Plural`], + // [`cost of living`, `#PastTense #Preposition #Noun`], + [`The similar TORRO scale ranges from`, 'the #Adjective #Noun #Noun #PresentTense from'], + // [`New project crowdsources help for Toronto's homeless`, '#Adjective #Noun #PresentTense #Noun for #Possessive #Noun'], + [`Bharti initiates talks`, '#Noun #PresentTense #Plural'], + [`Grandma opens a present with a pair`, '#Noun #PresentTense a #Noun with a #Noun'], + + // [`a nice present`, 'a #Adjective #Noun'],//noun + [`present the trophy`, '#Verb the #Noun'],//verb + [`tony is present`, '#Person is #Adjective'],//adjective + + [`in every bite`, 'in #Determiner #Noun'], + [`There was a prison break and I saw it`, 'there #Copula a #Noun #Noun and I #Verb it'], + [`we gotta do, damage control.`, 'we have got to do #Noun #Noun'], + [`Go to the chicken farm and take the hatchet.`, '#Verb to the #Noun #Noun and #Verb the #Noun'], + // [`He split 2 1980 fights with Roberto Duran`, '#Pronoun #Verb #Value #Value #Plural with #Person #Person'], + // [`what are those, fish hooks?`, 'what are . #Noun #Plural'], + [`the sweet potato fries.`, '#Determiner sweet #Noun #Plural'], + [`my friend's house.`, 'my #Noun #Noun'], + [`major record labels.`, '#Adjective #Noun #Plural'], + [`our mission of progress.`, '#Possessive #Noun of #Noun'], + [`the .dat file`, 'the #Noun #Noun'], + [`the 9pm show`, '#Determiner #Time #Noun'], + [`no tones`, 'no #Plural'], + [`& other types`, 'and other #Plural'], + [`40 gallons of water a day`, '#Value #Plural of #Noun a #Noun'], + + ['3 trains were', '#Value #Noun #Verb'], + // ['help unmask the great slice', '#Verb #Verb the #Adjective #Noun'], + ['help Dubai heal', '#Verb #Noun #Verb'], + ['the euro sense', 'the #Noun #Noun'], + ['the lights come on', 'the #Plural #Verb #Particle'], + ['the letters concern', 'the #Plural #Verb'], + ['the thriving village', '#Determiner #Adjective #Noun'], + ['the roof got wet', 'the #Noun #Verb #Adjective'], + ['the aging process', 'the #Noun #Noun'], + ['the new start', 'the #Adjective #Noun'], + ['this cabinet post', '#Determiner #Noun #Noun'], + ['our drink', '#Possessive #Noun'], + ['our drinks', '#Possessive #Noun'], + ['mandatory spending', '#Adjective #Noun'], + // ['falling into diet traps', '#Gerund into #Noun #Plural'], + ['a flexible tape measure', 'a #Adjective #Noun #Noun'], + ['home-field advantage', '#Noun #Noun #Noun'], + ['while in this state', 'while in this #Noun'], + ['I’M camping', '#Pronoun #Copula #Gerund'], + ['dutch brewing giant', '#Noun #Noun #Noun'], + [`was running around stores.`, 'was #Gerund around #Plural'], + // ['mental age and calendar age', '#Noun #Noun and #Noun #Noun'], + ['side with traitors', '#Verb with #Plural'], + + //determiner-corrections + ['this rocks dude', '#Pronoun #Verb #Noun'], + // ['that rocks dude', '#Determiner #Verb #Noun'], + ['the rocks dude', '#Determiner #Plural #Noun'], + ['these rocks dude', '#Determiner #Plural #Noun'], + ['those rocks dude', '#Determiner #Plural #Noun'], + ['the test string', '#Determiner #Noun #Noun'], + + ['The stream really runs', '#Determiner #Noun #Adverb #Verb'], + ['The nice stream really runs', '#Determiner #Adjective #Noun #Adverb #Verb'], + ['there are reasons', '#There #Copula #Plural'], + ['there were many walks', '#There #Copula #Adjective #Plural'], + ['there were the phase', '#There #Copula #Determiner #Noun'], + ['book the flight', '#Verb #Determiner #Noun'], + ['the euro challenge to', '#Determiner #Noun #Singular to'], + ['the euro challenge', '#Determiner #Noun #Noun'], + [`appeal court`, `#Noun #Noun`], + // [`uncovered wounds heal faster`, '#Adjective #Noun #Verb #Comparative'], + // [`become overly weakened`, '#Verb #Adverb #PastTense'], + // [`a completely beaten man`, 'a #Adverb #Verb #Noun'], + // [`the said card`, 'the #Adjective #Noun'], + // [`one super strong character`, '. #Adverb #Adjective #Noun'], + // [`have given up on reason`, '#Auxiliary #PhrasalVerb #Particle on #Noun'], + // [`you have some valid points`, '#Noun #Verb some #Adjective #Plural'], + + [`he changes`, '. #PresentTense'], + [`our changes`, '. #Noun'], + [`then changes`, '. #PresentTense'], + [`quickly changes`, '. #PresentTense'], + [`seven changes`, '. #Noun'], + [`with changes`, '. #Noun'], + [`without changes`, '. #Noun'], + [`abrupt changes`, '. #Noun'], + [`and changes gears`, 'and #PresentTense .'], + [`changes the gears`, '#PresentTense . .'], + [`changes my gears`, '#PresentTense . .'], + [`changes are coming`, '#Noun . .'], + [`changes quickly`, '#PresentTense #Adverb'], + [`changes seven things`, '#PresentTense #Value #Plural'], + [`changes into batman`, '#PresentTense . .'], + + // two consecutive variables + // [`cut costs`, '#Verb #Plural'], + // ['The stream runs', '#Determiner #Noun #Verb'], + +] +test('match:', function (t) { + arr.forEach(function (a) { + const [str, match] = a + const doc = nlp(str).compute('tagRank') + const tags = doc.json()[0].terms.map(term => term.tagRank[0]) + const m = doc.match(match) + const msg = `'${(str + "' ").padEnd(20, ' ')} - '${tags.join(', ')}'` + t.equal(m.text(), doc.text(), here + msg) + }) + t.end() +})