compromise README

The project's README from github.com/spencermountain/compromise. As one markdown file: README.md.

compromise
modest natural language processing
npm install compromise
by Spencer Kelly and many contributors
french • german • italian • spanish
don't you find it strange,
    how easy text is to make,

     ↬ᔐᖜ↬   and how hard it is to actually parse and use?

compromise tries its best to turn text into data.
it makes limited and sensible decisions.
it's not as smart as you'd think.
import nlp from 'compromise'

let doc = nlp('she sells seashells by the seashore.')
doc.verbs().toPastTense()
doc.text()
// 'she sold seashells by the seashore.'
don't be fancy, at all:
if (doc.has('simon says #Verb')) {
  return true
}
grab parts of the text:
let doc = nlp(entireNovel)
doc.match('the #Adjective of times').text()
// "the blurst of times?"
match docs

and get data:

import plg from 'compromise-speech'
nlp.extend(plg)

let doc = nlp('Milwaukee has certainly had its share of visitors..')
doc.compute('syllables')
doc.places().json()
/*
[{
  "text": "Milwaukee",
  "terms": [{
    "normal": "milwaukee",
    "syllables": ["mil", "wau", "kee"]
  }]
}]
*/
json docs

avoid the problems of brittle parsers:

let doc = nlp("we're not gonna take it..")

doc.has('gonna') // true
doc.has('going to') // true (implicit)

// transform
doc.contractions().expand()
doc.text()
// 'we are not going to take it..'
contraction docs

and whip stuff around like it's data:

let doc = nlp('ninety five thousand and fifty two')
doc.numbers().add(20)
doc.text()
// 'ninety five thousand and seventy two'
number docs

-because it actually is-

let doc = nlp('the purple dinosaur')
doc.nouns().toPlural()
doc.text()
// 'the purple dinosaurs'
noun docs

Use it on the client-side:

<script src="https://unpkg.com/compromise"></script>
<script>
  var doc = nlp('two bottles of beer')
  doc.numbers().minus(1)
  document.body.innerHTML = doc.text()
  // 'one bottle of beer'
</script>

or likewise:

import nlp from 'compromise'

var doc = nlp('London is calling')
doc.verbs().toNegative()
// 'London is not calling'

compromise is ~250kb (minified):

it's pretty fast. It can run on keypress:

it works mainly by conjugating all forms of a basic word list.

The final lexicon is ~14,000 words:

you can read more about how it works, here. it's weird.

okay -

compromise/one

A tokenizer of words, sentences, and punctuation.

import nlp from 'compromise/one'

let doc = nlp("Wayne's World, party time")
let data = doc.json()
/* [{
  normal:"wayne's world party time",
    terms:[{ text: "Wayne's", normal: "wayne" },
      ...
      ]
  }]
*/
tokenizer docs

compromise/one splits your text up, wraps it in a handy API,

/one is quick - most sentences take a 10th of a millisecond.

It can do ~1mb of text a second - or 10 wikipedia pages.

Infinite jest takes 3s.

You can also parallelize, or stream text to it with compromise-speed.

compromise/two

A part-of-speech tagger, and grammar-interpreter.

import nlp from 'compromise/two'

let doc = nlp("Wayne's World, party time")
let str = doc.match('#Possessive #Noun').text()
// "Wayne's World"
tagger docs

compromise/two automatically calculates the very basic grammar of each word.

this is more useful than people sometimes realize.

Light grammar helps you write cleaner templates, and get closer to the information.

compromise has 83 tags, arranged in a handsome graph.

#FirstName → #Person → #ProperNoun → #Noun

you can see the grammar of each word by running doc.debug()

you can see the reasoning for each tag with nlp.verbose('tagger').

if you prefer Penn tags, you can derive them with:

let doc = nlp('welcome thrillho')
doc.compute('penn')
doc.json()

compromise/three

Phrase and sentence tooling.

import nlp from 'compromise/three'

let doc = nlp("Wayne's World, party time")
let str = doc.people().normalize().text()
// "wayne"
selection docs

compromise/three is a set of tooling to zoom into and operate on parts of a text.

.numbers() grabs all the numbers in a document, for example - and extends it with new methods, like .subtract().

When you have a phrase, or group of words, you can see additional metadata about it with .json()

let doc = nlp('four out of five dentists')
console.log(doc.fractions().json())
/*[{
    text: 'four out of five',
    terms: [ [Object], [Object], [Object], [Object] ],
    fraction: { numerator: 4, denominator: 5, decimal: 0.8 }
  }
]*/
let doc = nlp('$4.09CAD')
doc.money().json()
/*[{
    text: '$4.09CAD',
    terms: [ [Object] ],
    number: { prefix: '$', num: 4.09, suffix: 'cad'}
  }
]*/

🤖 For AI agents & LLMs

Plain-text, copy-paste docs that render without JavaScript live in this repo:

API

Compromise/one

Output
Utils
Accessors
Match

(match methods use the match-syntax.)

compromise (spencermountain/compromise)

Searching Database…

Что это такое?Compromise — это легковесная библиотека на JavaScript для обработки естественного языка. Она разбирает текст на структурированные данные: разбивает его на слова и предложения, размечает части речи и позволяет искать в тексте фразы вроде чисел, имён или дат.
Это фреймворк или библиотека?Это библиотека, которую подключают к проекту на JS. Она состоит из трёх слоёв: 'one' для токенизации, 'two' для разметки частей речи и грамматики и 'three' для работы с фразами и предложениями.
Как добавить её в проект?Установите её через npm, затем вызовите nlp(text), чтобы получить документ, с которым можно работать: искать в нём и преобразовывать.
Нужно ли сначала установить Python или другую среду выполнения?Нет, это чистый JavaScript с несколькими небольшими зависимостями из npm (efrt, grad-school, suffix-thumb). При использовании на сервере нужна Node 12 или новее.
Разметка точная или это просто быстрая эвристика?Она опирается на простой список слов и облегчённые эвристики, а не на обученную модель, поэтому разметка работает быстро, но приблизительно. Уверенность можно проверить через .confidence(), а отладить — через doc.debug().
Работает ли она в браузере или только в Node?Она работает везде, где работает JavaScript, в том числе в браузере, в обработчиках нажатия клавиш, так как не имеет нативных зависимостей.
Насколько она быстрая?compromise/one может токенизировать около 1 МБ текста в секунду (примерно 10 страниц Wikipedia), большинство предложений разбирается за одну десятую миллисекунды; Infinite Jest обрабатывается примерно за 3 секунды.
Как работает разметка грамматики?compromise/two присваивает каждому слову один из 83 тегов части речи, которые расположены в иерархии (например, #FirstName → #Person → #ProperNoun → #Noun). Это помогает извлекать из текста чистые данные.
Можно ли извлекать из текста конкретные вещи, например числа или даты?Да, compromise/three добавляет инструменты для работы с фразами, например .numbers(), который извлекает все числа из документа, а также методы .subtract() и .json() для метаданных найденных фраз.
Size
61 MB
Stars
12.2K
Age
15y
Commits · 90 Days