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: "&lt;ACTION&gt;"
+            macro: "{turn|switch|dial|control|let|set|get|put}"
+          - name: "&lt;ENTIRE_OPT&gt;"
+            macro: "{entire|full|whole|total|*}"
+          - name: "&lt;LIGHT&gt;"
+            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:
+              - "&lt;ENTIRE_OPT&gt; {upstairs|downstairs|*} {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} room}"
+              - "&lt;ENTIRE_OPT&gt; {upstairs|downstairs|*} {master|kid|children|child|guest|*} {bedroom|bathroom|washroom|storage} {closet|*}"
+              - "&lt;ENTIRE_OPT&gt; {house|home|building|{1st|first} floor|{2nd|second} floor}"
+        
+          - id: "ls:on"
+            groups:
+              - "act"
+            description: "Light switch ON action."
+            synonyms:
+              - "&lt;ACTION&gt; {on|up|*} &lt;LIGHT&gt; {on|up|*}"
+              - "&lt;LIGHT&gt; {on|up}"
+        
+          - id: "ls:off"
+            groups:
+              - "act"
+            description: "Light switch OFF action."
+            synonyms:
+              - "&lt;ACTION&gt; &lt;LIGHT&gt; {off|out}"
+              - "{&lt;ACTION&gt;|shut|kill|stop|eliminate} {off|out} &lt;LIGHT&gt;"
+              - "no &lt;LIGHT&gt;"
+        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