Guía de inicio rápido: construcción de un knowledge Mammut
Esta guía de inicio rápido describe el método a seguir para crear una estructura de knowledge para un bot Mammut. Esta estructura es descrita en el artículo knowledge and ontology de la sección de 'conceptos'.
Un knowledge permite que un bot pueda tener acceso a información estructurada que necesita para conseguir respuestas oportunas. El knowledge puede contener cualquier tipo de información necesaria para interactuar en un ambiente o situación, o puede almacenar información solicitada al usuario. El knowledge se concibe como una memoria a largo plazo a la que tiene acceso un bot.
Requisitos previos
- Instalación del Mammmut Services (MS).
- Spreadsheet de Google con un corpusM.
Recomendamos la lectura de los siguientes temas antes de comenzar:
Ontology, knowledge y conversación
Una ontology es una estructura de datos relacionados semánticamente. Se trata de una organización del conocimiento en vertices (también llamadas clases) y properties relacionados por medio de edges (que describen el tipo de relación de dos vertices, o entre un vertex y una property). Por ejemplo, el dominio "films" se podría formalizar por medio de la siguiente ontology:
graph TD
director-- tiene varios -->movie
movie(película)-- tiene una -->director(director)
movie-- tiene un -->release(año de estreno)
release-- se estrenó -->movie
style movie fill:#f97,stroke:#333,stroke-width:1px
style director fill:#f97,stroke:#333,stroke-width:1px
Figura 1. Ejemplo de una ontology.
En la figura 1 de puede observar que una película (un vertex) tiene un director (pero un director puede haber dirigido varias películas) y un año de estreno (una property).
Una ontology estructura relaciones generales entre vertices y properties. Cuando se introducen en los vertices y properties las instances, estamos frente a un knowledge:
graph TD
director1([Christopher Nolan])-.->director
movie(película)-- tiene un -->director(director)
director-- tiene varias -->movie
movie-- tiene un -->release(año de estreno)
release-- se estrenó -->movie
movie1([Batman Begins])-.->movie
release1([2005])-.->release
style movie fill:#f97,stroke:#333,stroke-width:1px
style director fill:#f97,stroke:#333,stroke-width:1px
Figura 2. Ejemplo de knowledge.
En la figura 2 los óvalos representan tres instances: Batman Begins, Christopher Nolan y 2006 (en óvalos). Estas tres instances juntas definen una película en el knowledge (quedan por fuera algunos detalles para simplificar la explicación).
El knowledge puede utilizarse para responder a solicitudes de un user. Las properties de los vertices son elementos que forman parte (o que pueden formar parte) del conocimiento que tiene el bot sobre un tema o asunto.
Veamos esto con un ejemplo.
sequenceDiagram
autonumber
participant User
participant Bot
User->>Bot: ¿Tienen películas de Christopher Nolan?
Note over User,Bot: (pregunta sobre un director)
Bot-->>User: ¡Por supuesto! ¿Quieres que te sugiera una?
User->>Bot: Sí
Bot-->>User: Te puedo recomendar Batman Begins (2005)
Note over User,Bot: (relación director-película)
Figura 3. Ejemplo de conversación entre un user y un bot.
El user le pregunta al bot por películas relacionadas con Christopher Nolan. El bot tiene esta información en su knowledge, y por lo tanto puede responder a la solicitud, ya que conoce los siguientes "hechos":
- Christopher Nolan tiene varias películas.
- Una de esas películas es Batman Begins.
- Puede incluir el año de la película en la respuesta, ya que es una property de la instance.
Los pasos que seguiremos para construir un knowledge en esta guía serán los siguientes:
- Creación de vertices.
- Configuración de properties.
- Configuración de un entry point.
- Configuración de edges.
- Configuración de defaults.
1. Creación de vertices
Vamos a crear dos vertices: movie y director.
graph LR
movie(película)
director(director)
style movie fill:#f97,stroke:#333,stroke-width:1px
style director fill:#f97,stroke:#333,stroke-width:1px
Figura 4. Los dos vertices que se van a crear.
Un vertex es una estructura de datos que contiene toda la información de una clase en particular. Esta estructura tiene el formato de una table en la cual cada columna es una property, y cada fila una instance del vertex. Por ejemplo, en el caso de un vertex movie, las instances podrían ser Batman Begins, Batman, The Dark Knight y Batman, The Dark Knight Rises. Y las properties para movie serán name, description y genre. La única property para director será name. En la figura 5 se pueden observar estas relaciones.
graph LR
name1(name) -.- movie2
description(description) -.- movie2
genre(genre) -.- movie2
movie2([Batman, The Dark Knight]) --- movie
director --- movie(película)
director1([Christopher Nolan]) --- director(director)
name2(name) -.- director1
style movie fill:#f97,stroke:#333,stroke-width:1px
style director fill:#f97,stroke:#333,stroke-width:1px
Figura 5. Vertices e instances (sin edges).
Recuerda que en la tabla para un vertex las properties son señaladas en los títulos de las columnas y las instances como registros de la tabla. La tabla 1 muestra como quedaría el vertex movie.
id | hidden | name | description | genre |
---|---|---|---|---|
M_1 | Batman Begins | Batman se disfraza. | acción | |
M_2 | Batman, The Dark Knight | El Joker gana. | thriller | |
M_3 | Batman, The Dark Knight Rises | Batman renuncia | acción |
Tabla 1. Vertex movie.
Las dos primeras propiedades, id
y hidden
son especiales. id
es una clave única para la instance. hidden
se utiliza para desactivar o "esconder" la instance (basta con poner una x
en ese campo). El id
puede ser lo que quieras, pero te recomendamos que uses alguna convención. Recuerda también que debe ser una clave única en la tabla del vertex.
Observa que las propiedades se definen para cada instance. Por ejemplo, la película M_2 tiene como name
el texto Batman, The Dark Knight, como description
El Joker gana. y como genre
thriller.
Ahora vamos con el vertex de director (tabla 2):
id | hidden | name |
---|---|---|
D_1 | Christopher Nolan |
Tabla 2. Vertex director.
Nota: Las tables se introducen como sheets en un Google Spreadsheet. En el Spreadsheet, crea dos sheets: movie y director e introduce la información que presentamos en las tablas 1 y 2 (respectivamente).
En resumen:
- Cada vertex es una tabla que junta las properties con las instances.
- La única property obligatoria es
id
. - La property
hidden
esconde la instance. - Cada property se define en una columna.
- Cada instance se define en una fila.
A continuación vamos a configurar los property type y cardinality de cada property.
2. Configuración de properties
Cada property de una instance debe ser definido en una table especial denominada properties. Esta tabla debe tener como columnas los campos name
, property type
y cardinality
. Estos campos se utilizan para determinar dos características de cada property utilizada en la ontology:
Característica | Descripción | Valores |
---|---|---|
name |
Nombre del property en los vertices | |
property type |
Tipo de dato de la property | String , StringToUpper , OpeningHours |
cardinality |
Tipo de relación de la property con los vertices | SINGLE , SET , LIST |
Tabla 3. Valores posibles para la table properties.
Para más detalles sobre estas características, te recomendamos consultar la referencia general, en particular el artículo sobre properties.
Vamos a crear una table con la definición de las properties para la ontology de películas. Tu table properties debería quedar así (tabla 4).
name | property type | cardinality |
---|---|---|
id | StringToUpper | SINGLE |
name | String | SINGLE |
description | String | SINGLE |
genre | String | SINGLE |
Tabla 4. Table properties.
Esto básicamente dice que la ontology tiene 4 tipos de properties: id, name, description y genre. Y que las últimas 3 son de tipo String
. La cardinality SINGLE
implica que cada una de estas properties se puede describir en su totalidad como un solo valor.
Aunque hemos terminado de darle forma a cada property, todavía no las hemos conectado con los vertices. Antes de eso, vamos a configurar primero un entry point.
3. Configuración de un entry point
El entry point es el punto más "alto" del knowledge. Es un punto en donde se inicia toda la estructura. Por lo general, recomendamos que sea un vertex con información sobre la entidad que provee la información requerida por el bot. Por ejemplo, nuestra ontology de films podría utilizarse para un sistema de recomendaciones (podríamos llamarlo ReachFlix).
graph TD
recommend(ReachFlix)-- recomienda varias -->movie(película)
recommend-. tiene una .->recommend_contact(contacto)
recommend-. tiene una .->recommend_webpage(webpage)
style movie fill:#f97,stroke:#333,stroke-width:1px
style recommend fill:#f97,stroke:#333,stroke-width:1px
Figura 6. Entry point.
El entry point de la figura 6 se utiliza para almacenar información general sobre el uso de la ontology. En este caso, información de contacto y página web del portal de recomendaciones que usará la ontology.
Nota: Siempre hay de que definir un entry point en las ontologies de Mammut. Los vertices que no estén conectados directa o indirectamente con el entry point no será tomados en cuenta en el knowlege.
El formato de la table para el entry point es distinto al del resto de los vertices ya que dispone los datos en un formato vertical (un registro es una columna y no una fila). La tabla 5 presenta un ejemplo.
A | B |
---|---|
id | ReachFlix_1 |
name | ReachFlix |
contact | reachflix@mail.com |
webpage | reach-flix.io |
recommend_several | movies |
Tabla 5. Estructura de ejemplo de un entry point.
Con el entry point definido, ya podemos conectar todos los vertices y properties usando edges. Puedes encontrar más información en el artículo de entry point en las referencias.
4. Configuración de los edges
Un edge tiene como propósito vincular un vertice con otro vertice (uno o varios). También especifica el tipo de relación entre ellos (más información en el documento edges). Esta relación es determinada por el desarrollador pero, en términos generales, puede ser de dos tipos:
Tipo | Descripción |
---|---|
ONE2ONE | Un vertice se conecta con otro vertice o con una propiedad. |
ONE2MANY | Un vertice se conecta uno o más vertex distintos. |
Estas relaciones se especifican en la table edges.
Nota: Si estás usando un spreadsheet, los edges se definen en un sheet llamado edges.
La table edges debe contener los siguientes campos: name y multiplicity. En la tabla 6 se presenta un ejemplo.
name | multiplicity |
---|---|
tiene_un | ONE2ONE |
tiene_varios | ONE2MANY |
se_estrenó_en | ONE2ONE |
actúa_en | ONE2MANY |
Tabla 6. Estructura de ejemplo de edges.
Una vez definidas estas relaciones generales, debe asignarse cada una para los pares de vertices relacionados entre sí. Esto se hace en la table vertices (más información en el artículo edges.md de la sección conceptos).
Nota: En la table edges solo se define la naturaleza ONE2ONE o ONE2MANY del name de una relación. Para realmente relacionar dos vertices específicos, hay que hacerlo desde la table vertices (sheet vertices).
ONE2ONE
Una relación ONE2ONE une inequívocamente dos instances del knowledge. Por ejemplo, una película solo puede tener un año de estreno, así que será considerada ONE2ONE. El nombre de la relación como tal lo define el desarrollador, pero aconsejamos que sea claro y que siga el patrón acción_relación (por ejemplo, sell_several, has_one, has_several, etc.)
graph LR
movie(película) -- tiene_un --> director(director)
style movie fill:#f97,stroke:#333,stroke-width:1px
graph LR
movie([Batman Begins]) --> director([Christopher Nolan])
style movie fill:#f97,stroke:#333,stroke-width:1px
Figura 7. Edge ONE2ONE.
Nota: No olvides que en este documento los óvalos representan instancias de los vertices.
En la figura 7 la relación ONE2ONE representada por el edge has_one implica que una película tiene un único director (no siempre es así, pero vamos a asumirlo para el ejemplo). Si lo vemos a nivel de instances, Batman Begins tiene como director a Christopher Nolan.
En la table vertices, el ejemplo de la figura 7 se configuraría de la siguiente manera:
name | element_type | property_predicate | element_name | edge_head | optional | default_property | entry_point | reverse_predicate | sink |
---|---|---|---|---|---|---|---|---|---|
película | EDGE | tiene_un | director |
Tabla 7. Configuración de un edge ONE2ONE en la table vertices
Nota: Recuerda que la table vertices es el lugar donde se configuran las relaciones entre los vertices de la ontología.
Como se puede observar en la tabla 7, dos vertices (película
y director
) se vinculan por medio de un EDGE
llamado tiene_un
. Y de la tabla 6 sabemos que tiene_un es una relación ONE2ONE.
Puedes consultar el valor de cada campo de esta table en el documento vertices.
ONE2MANY
Una relación ONE2MANY vincula una instance con otras (una o más). Por ejemplo, si quisiéramos relacionar una película con sus actores, tendríamos una ontology como la de la figura 8.
graph LR
movie(película) -- tiene_varios --> actor(actor)
style movie fill:#f97,stroke:#333,stroke-width:1px
graph LR
movie([Batman Begins]) --> actor1([Christian Bale])
movie([Batman Begins]) --> actor2([Katie Holmes])
style movie fill:#f97,stroke:#333,stroke-width:1px
Figura 8. Edge ONE2MANY.
Una relación ONE2MANY entre dos vertices de una ontology implica que a nivel de instances (knowledge), una de las instances se puede vincular con varias instances de otro vertex. Esta configuración se hace en la table vertices.
name | element_type | property_predicate | element_name | edge_head | optional | default_property | entry_point | reverse_predicate | sink |
---|---|---|---|---|---|---|---|---|---|
película | EDGE | tiene_varios | actor |
Tabla 8. Configuración de un edge ONE2MANY en la table vertices
En la tabla 8 se observa cómo se configura una relación ONE2MANY para un par de vertices. En este caso película
tiene un vínculo EDGE
de tipo tiene_varios
con el vertex actor
. Y sabemos, de la tabla 6, que tiene_varios es un edge de tipo ONE2MANY.
Definición de properties
Aunque las relaciones entre una instance y sus properties no son edges propiamente dichos, igualmente se definirán en la table edges. En este sentido, debemos definir si una property de un vertex es ONE2ONE (la propiedad contiene solamente un valor) o si dicha property es ONE2MANY (la propiedad tiene varios valores separados por comas).
La tabla 9 presenta un ejemplo.
name | element_type | property_predicate | element_name | edge_head | optional | default_property | entry_point | reverse_predicate | sink |
---|---|---|---|---|---|---|---|---|---|
película | PROPERTY | tiene_un | nombre | ||||||
película | PROPERTY | tiene_un | descripción | ||||||
película | PROPERTY | tiene_varios | género |
Figura 9. Configuración de varias properties en la table vertices
En la figura 9 se observan tres properties del vertex película
: nombre
, descripción
y género
. El último, género, puede ser una propiedad con varios valores: acción, suspenso y superhéroes, así que será una relación ONE2MANY.
5. Ontology y knowledge
Una vez configurados los vertices, edges y properties, le hemos dado forma a la ontology. Nuestra ontology de películas quedaría finalmente así:
graph LR
entry_point(entry point)-- recomienda varias -->movie(película)
entry_point-. tiene un .->recommend_contact(contacto)
entry_point-. tiene una .->recommend_webpage(webpage)
subgraph PELÍCULA
movie -- tiene un --> director(director)
movie -. tiene un .-> name(nombre)
movie -. tiene una .-> description(descripción)
movie -. tiene un .-> year(año)
movie -- tiene varios --> actor(actor)
end
actor -. tiene un .-> name3(nombre)
director -. tiene un .-> name2(nombre)
style director fill:#f97,stroke:#333,stroke-width:1px
style movie fill:#f97,stroke:#333,stroke-width:1px
style entry_point fill:#f97,stroke:#333,stroke-width:1px
style actor fill:#f97,stroke:#333,stroke-width:1px
style PELÍCULA fill:#e1dacd,stroke:#333,stroke-width:1px
Figura 10. Forma de la ontology Películas
Las líneas sólidas representan la relación entre dos vertices. Las líneas punteadas, el vínculo entre un vertex y una property.
En la figura 11 damos un ejemplo de cómo se verían dos películas utilizando esta estructura a nivel de knowledge.
graph LR
movie1([Batman Begins]) -- tiene un --> director1(director)
movie1 -.-> description(Primera película de una trilogía.)
movie1 -.-> year(2005)
movie1 -- tiene varios --> actor(actor)
actor -.-> name3([Katie Holmes])
actor -.-> name4([Christian Bale])
director1 -.-> name2([Christopher Nolan])
movie2([Joker]) -- tiene un --> director2(director)
movie2 -.-> description2(El Joker la protagoniza.)
movie2 -.-> year2(2019)
movie2 -- tiene varios --> actor2(actor)
actor2 -.-> name5([Robert De Niro])
actor2 -.-> name6([Joaquin Phoenix])
director2 -.-> name7([Todd Phillips])
style director1 fill:#f97,stroke:#333,stroke-width:1px
style director2 fill:#f97,stroke:#333,stroke-width:1px
style movie1 fill:#f97,stroke:#333,stroke-width:1px
style movie2 fill:#f97,stroke:#333,stroke-width:1px
style actor fill:#f97,stroke:#333,stroke-width:1px
style actor2 fill:#f97,stroke:#333,stroke-width:1px
Figura 11. Ejemplos de la ontology con dos películas.
El diseño de la ontology dependerá tanto de la organización del conocimiento como del diseño conversacional del bot. Recomendamos empezar siempre con algunas conversaciones de ejemplo para extraer tanto las entidades claves que se van a organizar en la ontology como las relaciones entre dichas entidades. Si, por ejemplo, nuestro sistema de recomendación de películas recibe como primera petición del usuario "Recomiéndame una película de acción", entonces lo mejor sería empezar la organización de la ontología alrededor de los conceptos película y género de la película.