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/12/31 20:12:37 UTC

[incubator-nlpcraft] branch master updated: Logging & tests improvements for intent matcher.

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.git


The following commit(s) were added to refs/heads/master by this push:
     new 70598dc  Logging & tests improvements for intent matcher.
     new fa09364  Merge branch 'master' of https://github.com/apache/incubator-nlpcraft
70598dc is described below

commit 70598dc5dbb318fbfe893a71ebdd74cee3a644f5
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Thu Dec 31 12:11:12 2020 -0800

    Logging & tests improvements for intent matcher.
---
 .../model/intent/impl/NCIntentSolverEngine.scala   | 67 ++++++++++++++++------
 .../probe/mgrs/nlp/NCProbeEnrichmentManager.scala  | 22 +++----
 .../apache/nlpcraft/model/NCIntentDslSpec2.scala   | 28 ++++-----
 .../intent/impl/NCIntentSolverEngineSpec.scala     | 25 --------
 4 files changed, 75 insertions(+), 67 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
index 5058302..6e61415 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
@@ -277,28 +277,39 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
             )
 
             if (sorted.nonEmpty) {
-                val tbl = NCAsciiTable("Variant", "Intent", "Term Tokens")
+                val tbl = NCAsciiTable("Variant", "Intent", "Term Tokens", "Match Weight")
 
                 sorted.foreach(m ⇒ {
                     val im = m.intentMatch
+                    val w = im.weight.toSeq
+                    val ws = Seq(
+                        s"${y("XCT_VAL: ")}${w.head}",
+                        s"${y("SEN_TOK: ")}${w(1)}",
+                        s"${y("CNV_TOK: ")}${w(2)}",
+                        s"${y("SPC_MIN: ")}${w(3)}",
+                        s"${y("DLT_MAX: ")}${w(4)}",
+                        s"${y("NRM_MAX: ")}${w(5)}"
+                    )
 
                     if (m == sorted.head)
                         tbl += (
                             Seq(
                                 s"#${m.variantIdx + 1}",
-                                g(bo("'best match'"))
+                                g(bo("best match"))
                             ),
                             Seq(
                                 im.intent.id,
-                                g(bo("'best match'"))
+                                g(bo("best match"))
                             ),
-                            mkPickTokens(im)
+                            mkPickTokens(im),
+                            ws
                         )
                     else
                         tbl += (
                             s"#${m.variantIdx + 1}",
                             im.intent.id,
-                            mkPickTokens(im)
+                            mkPickTokens(im),
+                            ws
                         )
 
                     if (logHldr != null)
@@ -313,7 +324,7 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                         )
                 })
 
-                tbl.info(logger, Some(s"Found matching intents (sorted ${g(bo("best"))} to worst):"))
+                tbl.info(logger, Some(s"Found ${sorted.size} matching intents (sorted ${g(bo("best"))} to worst):"))
             }
             else
                 logger.info("No matching intent found.")
@@ -431,15 +442,22 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                             val w = termMatch.weight.toSeq
 
                             tbl += (s"${B}Intent ID$RST", s"$BO${intent.id}$RST")
-                            tbl += (s"${B}Term$RST", term.toString)
-                            tbl += (s"${B}Match tokens$RST", termMatch.usedTokens.map(t ⇒ {
+                            tbl += (s"${B}Matched Term$RST", term.toString)
+                            tbl += (s"${B}Matched tokens$RST", termMatch.usedTokens.map(t ⇒ {
                                 val txt = t.token.getOriginalText
                                 val idx = t.token.getIndex
 
                                 s"$txt${c("[" + idx + "]")}"
-                            }).mkString("|"))
-                            tbl += (s"${B}Match weight$RST",
-                                s"${y("STK:")}${w.head}, ${y("CDW:")}${w(1)}, ${y("MIN:")}${w(2)}, ${y("MAX:")}${w(3)}"
+                            }).mkString(" "))
+                            tbl += (
+                                s"${B}Match weight$RST",
+                                Seq(
+                                    s"${y("SEN_TOK: ")}${w.head}",
+                                    s"${y("CNV_TOK: ")}${w(1)}",
+                                    s"${y("SPC_MIN: ")}${w(2)}",
+                                    s"${y("DLT_MAX: ")}${w(3)}",
+                                    s"${y("NRM_MAX: ")}${w(4)}"
+                                )
                             )
 
                             tbl.info(logger, Some("Term match found:"))
@@ -515,16 +533,29 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                     term.getId,
                     usedToks,
                     if (usedToks.nonEmpty) {
-                        // Normalize max quantifier in case of unbound max.
-                        val max = if (term.getMax == Integer.MAX_VALUE) usedToks.size else term.getMax
-
-                        // If term is found (usedToks > 0) we add its quantifiers as additional weight.
-                        predWeight.append(term.getMin).append(max)
-                    } else
-                        predWeight.append(0).append(0)
+                        // If term match is non-empty we add the following weights:
+                        //   - min
+                        //   - delta between specified max and normalized max (how close the actual quantity was to the specified one).
+                        //   - normalized max
+                        predWeight
+                            .append(term.getMin)
+                            .append(-(term.getMax - usedToks.size))
+                            // Normalize max quantifier in case of unbound max.
+                            .append(if (term.getMax == Integer.MAX_VALUE) usedToks.size else term.getMax)
+                    } else {
+                        // Term is optional (found but empty).
+                        require(term.getMin == 0)
+
+                        predWeight
+                            .append(0)
+                            .append(-term.getMax)
+                            // Normalize max quantifier in case of unbound max.
+                            .append(if (term.getMax == Integer.MAX_VALUE) 0 else term.getMax)
+                    }
                 )
             )
 
+            // Term not found at all.
             case None ⇒ None
         }
     
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
index 207aad0..87b4614 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
@@ -335,17 +335,19 @@ object NCProbeEnrichmentManager extends NCService with NCOpenCensusModelStats {
             NCConnectionManager.send(msg, span)
             
             if (errMsg.isEmpty)
-                logger.info(s"OK result sent back to server [" +
-                    s"srvReqId=${rv(g(srvReqId))}, " +
-                    s"type=${resType.getOrElse("")}" +
-                s"]" +
-                s"\n\n<<${bo("===========")} ${g("OK")} ${bo("===========")}>>\n")
+                logger.info(s"" +
+                    s"\n" +
+                    s"${g("|")}\n" +
+                    s"${g("|")} ${bo(g("SUCCESS"))} result sent back to server [srvReqId=${rv(g(srvReqId))}, type=${resType.getOrElse("")}]\n" +
+                    s"${g("|")}"
+                )
             else
-                logger.info(s"REJECT response sent back to server [" +
-                    s"srvReqId=${rv(g(srvReqId))}, " +
-                    s"response=${errMsg.get}" +
-                s"]" +
-                s"\n\n<<${bo("===========")} ${r("REJECT")} ${bo("===========")}>>\n")
+                logger.info(s"" +
+                    s"\n" +
+                    s"${r("|")}\n" +
+                    s"${r("|")} ${bo(r("REJECT"))} result sent back to server [srvReqId=${rv(g(srvReqId))}, response=${errMsg.get}]\n" +
+                    s"${r("|")}"
+                )
         }
 
         val mdl = NCModelManager.getModel(mdlId, span)
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentDslSpec2.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentDslSpec2.scala
index aab2f28..06f1610 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentDslSpec2.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentDslSpec2.scala
@@ -34,23 +34,22 @@ class NCIntentDslSpecModel2 extends NCModelAdapter(
     private implicit def convert(s: String): NCResult = NCResult.text(s)
 
     override def getElements: util.Set[NCElement] =
-        Set("a", "b", "c", "d", "e").map(id ⇒ new NCElement { override def getId: String = id }).asJava
+        Set("a").map(id ⇒ new NCElement { override def getId: String = id }).asJava
 
-    // a. Mandatory, List, +, *, ?
     @NCIntent("intent=a_11 term(a)={id == 'a'}")
-    private def aMandatory(ctx: NCIntentMatch): NCResult = "OK"
+    private def a11(ctx: NCIntentMatch): NCResult = "OK"
 
-    @NCIntent("intent=a_13 term(a)={id == 'a'}[1,3]")
-    private def aList(ctx: NCIntentMatch): NCResult = "OK"
+    @NCIntent("intent=a_23 term(a)={id == 'a'}[2,3]")
+    private def a23(ctx: NCIntentMatch): NCResult = "OK"
+
+    @NCIntent("intent=a_15 term(a)={id == 'a'}[1,5]")
+    private def a15(ctx: NCIntentMatch): NCResult = "OK"
 
     @NCIntent("intent=a_plus term(a)={id == 'a'}+")
-    private def aPlus(ctx: NCIntentMatch): NCResult = "OK"
+    private def a1Inf(ctx: NCIntentMatch): NCResult = "OK"
 
     @NCIntent("intent=a_star term(a)={id == 'a'}*")
-    private def aAsterisk(ctx: NCIntentMatch): NCResult = "OK"
-
-    @NCIntent("intent=a_01 term(a)~{id == 'a'}?")
-    private def aOptional(ctx: NCIntentMatch): NCResult = "OK"
+    private def a0Inf(ctx: NCIntentMatch): NCResult = "OK"
 }
 
 /**
@@ -68,10 +67,11 @@ class NCIntentDslSpec2 extends NCTestContext {
 
     @Test
     def test(): Unit = {
-        check("a", "a_13")
-        check("a a", "a_13")
-        check("a a a", "a_13")
-        check("a a a a", "a_plus")
+        check("a", "a_11")
+        check("a a", "a_23")
+        check("a a a", "a_23")
+        check("a a a a", "a_15")
+        check("a a a a a a ", "a_plus")
     }
 }
 
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngineSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngineSpec.scala
deleted file mode 100644
index 401c501..0000000
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngineSpec.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nlpcraft.model.intent.impl
-
-/**
- * Unit tests for intent solver engine.
- */
-class NCIntentSolverEngineSpec  {
-    // TODO
-}