Recommendation Guide

Recommendation Overview

Once a situation is detected it may be useful to make recommendations describing how to respond to the situation. Responses could take many forms:

The Vantiq automation services consider such responses to be recommendations and contains a rule based recommendation system to produce such recommendations.

The recommendation system may produce a single recommendation unambiguously describing a single response to the situation or it may produce a set of prioritized recommendations from which the user may choose the most appropriate response. Choosing among the prioritized recommendations may be the province of the client application or the end user interacting with the client system. The election is made by the application designer.

Conceptual Model

There are a number of possible models for producing recommendations. This document describes one such model that is relatively simple to build using the recommendation primitives provided by Vantiq.

Recommendations are chosen from a taxonomy of available recommendations. The taxonomy is stored as a type in the situational services data model. Each potential recommendation is an instance of the type.

The taxonomy is organized into categories with each category containing a collection of related recommendations. The taxonomy type MUST define a property that represents the category in which the recommendation is placed. All other properties of the taxonomy type are at the discretion of the system designer. The categories may be organized into hierarchies. The recommendation system will use the hierarchy to identify all candidate recommendations to be evaluated by a particular set of recommendation procedures.

Procedures evaluate the possible recommendations in the taxonomy searching for the recommendations that “best” fit the current situation. In general, the recommendation is constructed by an initiating procedure and a set of recommending procedures.

The initiating procedure looks up the named item supplied by the user, inspects it and uses its assigned category to select a set of recommending procedures. The initiating procedure may perform other preparatory processing. Once complete the initiating procedure invokes all the selected recommending procedures.

Each recommending procedure evaluates a set of candidate recommendations selected internally or provided by the initiating procedure. The simplest approach is to select the candidate recommendations based on the taxonomy category. If the category is a leaf node in the taxonomy, the recommendations assigned to that category are evaluated. If the category is a non-leaf node, all recommendations assigned to categories in the subtree rooted at the named category are evaluated.

Once the candidates have been chosen the Vantiq recommendation primitives are used to iterate over the candidates and apply the recommendation criteria to each candidate. If the candidate satisfies all criteria it is included in the result set. If it does not satisfy the criteria it is discarded.

On completion, each recommending procedure returns a set of chosen recommendations.

Example: Finding Optimal Packaging

An example will serve to make the use of the model more concrete. The example chosen is to find the optimal box in which to ship a product. In other words find the smallest available box in which the product will fit.

The example assumes we have a Product type that describes the physical attributes of each product and a Box type that contains the physical descriptions of available boxes. The Box type represents the potential recommendations.

Define Types

The Product type contains the physical description of each product.

Product {
    productId: String,
    length: Integer,
    width: Integer,
    height: Integer,
    capacity: Integer,
    color: String

Note the length, width and height attributes that will be used to determine the boxes that are big enough to hold the product.

The Box type contains a description of the available boxes.

Box {
    boxId: String,
    length: Integer,
    width: Integer,
    height: Integer

Since we only have a single category of recommendations (boxes) there is no need for a category property as described in the conceptual model.

Load Taxonomy Objects

Each box is represented by an object loaded into the Box type. The simplest approach for loading the box objects is to use the INSERT command of the REST API to load each box.

For example, to products into the Product type outlined above INSERT commands of the following form are used:

    "productId": "motor",
    "color": "green",
    "length": 6,
    "width": 12,
    "height": 3,
    "capacity": 216

The recommendation inventory must be loaded as well.

    "boxId": "small",
    "color": "green",
    "length": 7,
    "width": 14,
    "height": 5,
    "capacity": 216

Define Initiating Procedure

PROCEDURE recommendPackaging(productId) WITH properties = { recommend: "packaging" }

var product = SELECT * FROM Product WHERE productId == productId
var recommendations = EXECUTE PROCEDURE * (product.length, product.width, product.height)
    WHERE properties.type == 'box'
if (rec.candidates.size() > 0) {
    return ec.candidates[0]
} else {
    return null

Define Recommending Procedures

Recommendations are defined as procedures. The relevant syntax can be found in the Rule and Procedure Reference Guide. An example of a recommendation procedure for the selecting the optimal box:

PROCEDURE BestFittingPackaging(length, width, height)
    WITH properties = { type: "box" }

var candidates = SELECT * FROM Box

FILTER c in candidates RECOMMENDATIONS TO packagingRecommendations 
 UNTIL packagingRecommendations.size() < 10 DO
    MATCH {
        if (c.length >= length && c.width >= width && c.height >= height) {
            RECOMMEND c WITH relevance = c.length * c.width * c.height, reason = "Closest fitting packaging"
    MATCH {
        if (within(c.capacity, product.capacity, "10%") {
            RECOMMEND candidate WITH
                      relevance = candidate.capacity - target.capacity, 
                      reason = "Closest fitting packaging"
return packagingRecommendations

Essentially the procedure finds boxes that are large enough to enclose the product that represents the situation and then rank them by how closely they fit the product.

As you can see, the procedure is fairly self-explanatory with the first MATCH finding all boxes in which the product will fit and the second MATCH ranking the closest fitting boxes. The automation service supports a procedure extension model to create new rules that properly reflect the semantics of the situation.

Procedure details can be found in the Rule and Procedure Reference Guide.

Heterogeneous Catalogs

The previous example illustrated the case where all the products in the taxonomy can be described by a similar schema. It is also possible to produce recommendations for more complex catalog/taxonomy structures by utilizing the facilities available in the situational awareness data model.

For example, consider a catalog where the products in each category in the taxonomy are described by different schemas. Automobiles, books and clothes would be described by very different schemas in a general cataloging system. In such cases, the products would be better stored in different types, perhaps one type per taxonomy category. Similarly, the recommendation rules might be organized into a separate ruleSet for each taxonomy category in order to exploit the specific attributes of products in that category in producing the recommendations.

One way to approach this problem is to maintain two ancillary types to the product catalog itself. The first type, called ProductMap, contains a list of all products identified by their productId and the taxonomy category to which the product is assigned. The second type, called CategoryMap contains a list of taxonomy categories and the name of the type that stores products assigned to that category.

At run-time, recommendations are requested for a product. The first step in the recommendation process is to determine the taxonomy category in which the product has been placed. This is accomplished by looking up the productId in ProductMap to find its taxonomy category. The taxonomy category is then used to find the type that stores the catalog entries for the target category in Category Map. The recommendation request can now be re-issued on ProductMap or CategoryMap as desired.