You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2020/11/17 00:50:42 UTC
[incubator-nlpcraft-website] 02/02: WIP.
This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft-website.git
commit ccf7ffc31b7bb375b3925b08de89a3bd81b713aa
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Mon Nov 16 16:50:29 2020 -0800
WIP.
---
_data/news.yml | 1 +
blogs/quick_intro_apache_nlpcraft.html | 363 +++++++++++++++++++++++++++++++++
2 files changed, 364 insertions(+)
diff --git a/_data/news.yml b/_data/news.yml
index 9db93d6..e060cf9 100644
--- a/_data/news.yml
+++ b/_data/news.yml
@@ -19,6 +19,7 @@
url: /blogs/quick_intro_apache_nlpcraft.html
excerpt: The goal of this project is unambiguously straightforward - provide an efficient & highly productive API to develop advanced NLP-based interfaces for modern applications.
author: Aaron Radzinski
+ avatar_url: images/lion.jpg
publish_date: November 16, 2020
twitter_id: aaron_radzinski
href_target: _self
diff --git a/blogs/quick_intro_apache_nlpcraft.html b/blogs/quick_intro_apache_nlpcraft.html
index 99fe739..2d19a6a 100644
--- a/blogs/quick_intro_apache_nlpcraft.html
+++ b/blogs/quick_intro_apache_nlpcraft.html
@@ -26,10 +26,373 @@ publish_date: November 16, 2020
-->
<section>
+ <div class="bq success">
+ This blog is an English adaptation of Sergey Kamov's <a target=habr href="https://habr.com/ru/post/526950/">blog</a> written in Russian.
+ </div>
<p>
In this short article I would like to introduce Apache NLPCraft - an open source library for adding Natural
Language Interface to any application. The goal of this project from its inception in 2017 was and still is
unambiguously straightforward - provide an efficient & highly productive API to develop advanced NLP-based
interfaces for modern applications.
</p>
+ <div class="bq info">
+ At the moment of this writing, the project undergoes incubation at <a target=asf href="https://apache.org/">Apache Software Foundation</a>, the
+ <a href="/download.html">latest version</a> of NLPCraft is <b>{{site.latest_version}}</b>.
+ </div>
+</section>
+<section>
+ <h2 class="section-title">Overview</h2>
+ <p>
+ These are some of the key features that should give you a flavor of what NLPCraft is and what it can do:
+ </p>
+ <div class="container-fluid" style="padding: 0">
+ <div class="row">
+ <div class="col-6">
+ <b>Semantic Modeling</b><br/>
+ <p>
+ NLPCraft uses advanced semantic modelling enabling deterministic natural language understanding without requiring deep learning and developing of large text corpora.
+ </p>
+ </div>
+ <div class="col-6">
+ <b>Java First</b><br/>
+ <p>
+ NLPCraft uses advanced semantic modelling enabling deterministic natural language understanding without requiring deep learning and developing of large text corpora.
+ </p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-6">
+ <b>Model-As-A-Code</b><br/>
+ <p>
+ Model-as-a-code convention natively supports any development life cycle tools and frameworks in the Java ecosystem.
+ </p>
+ </div>
+ <div class="col-6">
+ <b>Any Data Source</b><br/>
+ <p>
+ NLPCraft can work with any data source, device, or service - public or private. From databases and SaaS systems, to smart home devices, voice assistants and chatbots.
+ </p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-6">
+ <b>English Focused</b><br/>
+ <p>
+ NLPCraft focuses on processing English language delivering the ease of use and unparalleled comprehension for the language spoken by more than a billion people.
+ </p>
+ </div>
+ <div class="col-6">
+ <b>Advanced NLP Toolset</b><br/>
+ <p>
+ NLPCraft combines ease-of-use and development productivity with state-of-the-art NLP capabilities like short-term-memory (STM) support, advanced intent DSL with deterministic matching, and composable NEs.
+ </p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-6">
+ <b>Out-Of-The-Box Integration</b><br/>
+ <p>
+ NLPCraft natively integrates with 3rd party libraries for basic NLP processing and named entity recognition:
+ </p>
+ <div style="display: inline-block; margin-bottom: 20px">
+ <a style="margin-right: 10px" target="opennlp" href="https://opennlp.apache.org"><img src="/images/opennlp-logo.png" height="32px" alt=""></a>
+ <a style="margin-right: 10px" target="google" href="https://cloud.google.com/natural-language/"><img src="/images/google-cloud-logo-small.png" height="32px" alt=""></a>
+ <a style="margin-right: 10px" target="stanford" href="https://stanfordnlp.github.io/CoreNLP"><img src="/images/corenlp-logo.gif" height="48px" alt=""></a>
+ <a style="margin-right: 10px" target="spacy" href="https://spacy.io"><img src="/images/spacy-logo.png" height="32px" alt=""></a>
+ </div>
+ </div>
+ <div class="col-6">
+ </div>
+ </div>
+ </div>
+</section>
+<section>
+ <h2 class="section-title">Terminology</h2>
+ <p>
+ There are two terms that are important to define before we proceed:
+ </p>
+ <ul>
+ <li>
+ <b>Named Entity (NE)</b> - typically a real world object or entity that can be recognized in the input
+ text (see <a target=wikipedia href="https://www.wikiwand.com/en/Named_entity">https://www.wikiwand.com/en/Named_entity</a>
+ for details). Note that NEs can be universal, like country to city name, or domain specific for each model.
+ </li>
+ <li>
+ <b>Intent</b> - a template made out of NEs and a callback function to call when such template is found in the input text.
+ </li>
+ </ul>
+</section>
+<section>
+ <h2 class="section-title">Runtime Components</h2>
+ <p>
+ When working with NLPCraft you will be dealing with these three main components:
+ </p>
+ <ul>
+ <li>
+ <b>Data Model</b><br/>
+ Data Model encapsulates the NLPCraft’s model-as-a-code approach where the data model is simply an
+ implementation of NCDataModel interface. Typically, static model configuration and NE definitions are
+ abstracted out to an external YAML or JSON file.
+ </li>
+ <li>
+ <b>Data Probe</b><br/>
+ Data probe is a light-weight container that securely deploys and manages data models. You can have
+ multiple data probes and each data probe can host multiple models.
+ </li>
+ <li>
+ <b>REST Server</b><br/>
+ REST server provides URL endpoint for user applications to securely query data sources using natural
+ language. REST server routes such requests to a data probe that hosts the requested data model.
+ </li>
+ </ul>
+ <figure>
+ <img class="img-fluid" src="/images/homepage-fig1.1.png" alt="">
+ <figcaption><b>Fig 1.</b> NLPCraft Runtime Components</figcaption>
+ </figure>
+</section>
+<section>
+ <h2 class="section-title">Smart Home Example</h2>
+ <p>
+ Let’s see how NLPCraft works using a prototypical smart home NLP-based light switch as an example. We would
+ like to be able to say things like <code>"Turn off all the light in the house"</code> or
+ <code>"Light up the garage, please!"</code> to control our lights. Note that NLPCraft does not deal with
+ voice-to-text conversion - so this example deals only with the text regardless of its origin.
+ </p>
+ <p>
+ To accomplish that we need to first develop a data model that involves the following:
+ </p>
+ <ul>
+ <li>Determining which NEs we need and how to detect them in the text.</li>
+ <li>Use these NEs to define intents as well as code their callbacks for when such an intent is found in the input text.</li>
+ </ul>
+</section>
+<section>
+ <h2 class="section-title">Required Named Entities (NEs)</h2>
+ <p>
+ For our example we’ll need to define three NEs in our model:
+ </p>
+ <ul>
+ <li>A place where we need to turn on or off the lights like “kitchen” or “garage”.</li>
+ <li>Two actions: “on” and “off”.</li>
+ </ul>
+ <p>
+ If we can detect these NE in the input text we can perform the necessary operation.
+ </p>
+</section>
+<section>
+ <h2 class="section-title">Data Model</h2>
+ <p>
+ Once we have an idea of what NEs we’ll need - we can start building the data model that would define how
+ these NEs can be detected and ultimately what intents we are going to detecting using these NEs.
+ </p>
+ <p>
+ In NLPCraft the default built-in approach for detecting NEs is a synonym matching. For each NE you provide
+ a list of synonyms by which it will be found in the input text. To make this task really simple NLPCraft
+ comes with a set of tools including macros and Synonym DSL. Here’s the static model configuration for our
+ example as <code>lightswitch_model.yaml</code> file that includes NE definitions and one intent:
+ </p>
+ <pre class="brush: js, highlight: [14, 21, 29, 38]">
+ id: "nlpcraft.lightswitch.ex"
+ name: "Light Switch Example Model"
+ version: "1.0"
+ description: "NLI-powered light switch example model."
+ macros:
+ - name: "<ACTION>"
+ macro: "{turn|switch|dial|control|let|set|get|put}"
+ - name: "<ENTIRE_OPT>"
+ macro: "{entire|full|whole|total|*}"
+ - name: "<LIGHT>"
+ macro: "{all|*} {it|them|light|illumination|lamp|lamplight}"
+ enabledBuiltInTokens: [] # This example doesn't use any built-in tokens.
+ elements:
+ - id: "ls:loc"
+ description: "Location of lights."
+ synonyms:
+ - "<ENTIRE_OPT> {upstairs|downstairs|*} {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} room}"
+ - "<ENTIRE_OPT> {upstairs|downstairs|*} {master|kid|children|child|guest|*} {bedroom|bathroom|washroom|storage} {closet|*}"
+ - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+
+ - id: "ls:on"
+ groups:
+ - "act"
+ description: "Light switch ON action."
+ synonyms:
+ - "<ACTION> {on|up|*} <LIGHT> {on|up|*}"
+ - "<LIGHT> {on|up}"
+
+ - id: "ls:off"
+ groups:
+ - "act"
+ description: "Light switch OFF action."
+ synonyms:
+ - "<ACTION> <LIGHT> {off|out}"
+ - "{<ACTION>|shut|kill|stop|eliminate} {off|out} <LIGHT>"
+ - "no <LIGHT>"
+ intents:
+ - "intent=ls term(act)={groups @@ 'act'} term(loc)={id == 'ls:loc'}*"
+ </pre>
+ <p><b>NOTES:</b></p>
+ <ul>
+ <li>
+ We define 3 model elements (corresponding to the NEs we’ve come up with earlier):
+ <ul>
+ <li><code>"ls:loc"</code> to define the location.</li>
+ <li><code>"ls:on"</code> to define ON action.</li>
+ <li><code>"ls:off"</code> to define OFF action.</li>
+ </ul>
+ </li>
+ <li>
+ We grouped <code>"ls:on"</code> and <code>"ls:off"</code> into group <code>"act"</code> for easier use in intent.
+ </li>
+ <li>
+ Each model element is defined through synonyms using macros and Synonym DSL which is similar to Regular Expressions.
+ </li>
+ <li>
+ Intent <code>"ls"</code> uses Intent DSL. In short - this intent will match if we can detect one element
+ from the group <code>"act"</code> and zero or more <code>"ls:loc"</code> elements in any order.
+ </li>
+ </ul>
+ <p>
+ Notice that macros and Synonym DSL allow you to define hundreds and often thousands of synonyms for each model
+ element with just a few lines of YAML (or JSON). In the above model, for example, the three elements have <b>over
+ 7,700 unique synonyms</b> after all macros and Synonym DSL expansions.
+ </p>
+ <p>
+ Now, dealing with synonyms may sound limiting at first. It is, however, a surprisingly powerful and flexible mechanism
+ for the <em>domain-specific</em> applications:
+ </p>
+ <ul>
+ <li>
+ Synonyms can be easily developed, extended and tested using many tools that NLPCraft provides like
+ macros, Synonym DSL and synonym suggester (that uses Google’ BERT and Facebook fastText models).
+ </li>
+ <li>
+ Classic NLP problems like word-sense disambiguation (“bass” the fish, and “bass” the sound) are
+ not a real concern with semantic modelling for domain specific models.
+ </li>
+ <li>
+ Unlike neural networks-based approaches, synonym based NEs and intents don’t require expensive
+ and time consuming model training and creation of specialized large text corpora.
+ </li>
+ <li>
+ Synonym-based NE detection and Intent matching is fully deterministic (i.e. predictable) which
+ is a stark contrast to deep learning approaches that allow only for probabilistic results.
+ </li>
+ </ul>
+ <p>
+ It’s also important to note that if synonym based approach is not enough NLPCraft, of course, supports custom
+ NE resolvers that can use any desired approach and technique.
+ </p>
+</section>
+<section>
+ <h2 clas="section-title">Intent Matching</h2>
+ <p>
+ Although full explanation of the <a href="/intent-matching.html">intent matching</a> algorithm is outside the scope of this article, the basic workflow looks like this:
+ </p>
+ <ul>
+ <li>
+ User text is tokenized into individual words and tokens.
+ </li>
+ <li>
+ Each token gets lemmatized and stemmatized, and basic syntactic and grammatical information (such as POS tagging) being obtained.
+ </li>
+ <li>
+ Using these tokens the system tries to detect all NEs defined in the model.
+ </li>
+ <li>
+ Found NEs are matched against all model’s intents and the callback for the winning match, if any, is called.
+ </li>
+ </ul>
+</section>
+<section>
+ <h2 class="section-title">Model Implementation</h2>
+ <p>
+ Below is a full implementation of the data model in Scala (the same implementation in Java or Kotlin is practically identical):
+ </p>
+ <pre class="brush: java">
+ package org.apache.nlpcraft.examples.lightswitch
+
+ import org.apache.nlpcraft.model.{NCIntentTerm, _}
+
+ class LightSwitchModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/lightswitch/lightswitch_model.yaml") {
+ @NCIntentRef("ls")
+ def onMatch(
+ @NCIntentTerm("act") actTok: NCToken,
+ @NCIntentTerm("loc") locToks: List[NCToken]
+ ): NCResult = {
+ val status = if (actTok.getId == "ls:on") "on" else "off"
+ val locations =
+ if (locToks.isEmpty)
+ "entire house"
+ else
+ locToks.map(_.meta[String]("nlpcraft:nlp:origtext")).mkString(", ")
+
+ // Add HomeKit, Arduino or other integration here.
+
+ // By default - just return a descriptive action string.
+ NCResult.text(s"Lights are [$status] in [${locations.toLowerCase}].")
+ }
+ }
+ </pre>
+ <p><b>NOTES:</b></p>
+ <ul>
+ <li>
+ We use an <a target="javadoc" href="/apis/latest/org/apache/nlpcraft/model/NCModelFileAdapter.html">NCModelFileAdapter</a>
+ adapter that allows us to load our static model configuration from a YAML file.
+ </li>
+ <li>
+ Method <code>onMatch(...)</code> is a callback function for our intent <code>"ls"</code>
+ (define above in the <code>lightswitch_model.yaml</code> file).
+ </li>
+ <li>
+ Method <code>onMatch(...)</code> has two input parameters:
+ <ul>
+ <li>A single token from the <code>"act"</code> term.</li>
+ <li>A list of tokens (zero or more) from the <code>"loc"</code> term.</li>
+ </ul>
+ </li>
+ <li>
+ The body of the <code>onMatch(...)</code> method is pretty straightforward: it detects the
+ desired action from <code>"actTok"</code> and the places to operate the lights on
+ from <code>"locToks"</code> parameters.
+ </li>
+ </ul>
+ <p>
+ We’ll leave outside of this article the details of the particular integration with HomeKit or Arduino devices. We’ll also defer
+ to the NLPCraft <a href="/docs.html">documentation</a> to learn about other topics such as
+ <a href="/basic-concepts.html#stm">conversation management</a>,
+ details of <a href="/intent-matching.html">Intent and Synonym DSLs</a>,
+ built-in <a href="/tools/test_framework.html">testing tools</a>,
+ 3rd party NER <a href="/integrations.html">integrations</a>, etc.
+ </p>
+</section>
+<section>
+ <h2 class="section-title">Conclusion</h2>
+ <p>
+ In just a couple dozen lines of code we’ve created a non-trivial application that understands free-speech
+ natural language interface to operate a simple lightswitch. You can ask it many things like:
+ </p>
+ <ul>
+ <li><code>"Turn the lights off in the entire house."</code></li>
+ <li><code>"Switch on the illumination in the master bedroom closet."</code></li>
+ <li><code>"Get the lights on."</code></li>
+ <li><code>"Lights up in the kitchen."</code></li>
+ <li><code>"Please, put the light out in the upstairs bedroom."</code></li>
+ <li><code>"Set the lights on in the entire house."</code></li>
+ <li><code>"Turn the lights off in the guest bedroom."</code></li>
+ <li><code>"Could you please switch off all the lights?"</code></li>
+ <li><code>"Dial off illumination on the 2nd floor."</code></li>
+ <li><code>"Please, no lights!"</code></li>
+ <li><code>"Kill off all the lights now!"</code></li>
+ <li><code>"No lights in the bedroom, please."</code></li>
+ </ul>
+ <p>
+ You can also easily extend this model and support different locations or actions like dimming or brightening
+ the lights, etc. Model-as-a-code approach enables you to iterate on this in the matter of minutes without
+ heavy re-training cycles.
+ </p>
+ <p>
+ Hopefully, this short introduction to Apache NLPCraft gave you a hint of what it is capable of and
+ what you can do with it.
+ </p>
</section>
\ No newline at end of file