Bienvenidos sean a este post, hoy veremos como se analiza un query.
Este modulo tiene como tarea base el separar cada palabra con un espacio. Veamos como puede ser la clase base del analizador de query:
class QueryParser
{
public:
static Query parse(const std::string& query_string) {
auto tokens = QueryParser::tokenizar(query_string);
// construye el objeto del query y lo devuelve
}
private:
static std::vector<Token> tokenizar(const std::string& raw_query) {
// devuelve cadena del query tokenizado
}
};
Esta sera la base de la clase para analizar los queries. Observen que en la parte publica tenemos el metodo para analizar (parse) y en la parte privada tenemos el metodo para tokenizar al query. Ya tenemos la base, veamos los datos que puede contener un query y para ello usaremos el siguiente struct:
struct Query
{
std::string raw_query;
std::string normalizado_query;
std::vector<Token> tokens;
std::string id_dialogo;
};
El primer campo sera para el query o solicitud recibida por parte del usuario. El siguiente sera para contener el dato anterior normalizado, recuerden que normalizar es establecer valores estandares para cada palabra. El tercer campo es donde se almacenaran cada uno de los tokens generados desde el query o solicitud. Y el ultimo campo, es utilizado para asignar un ID y ser utilizado por el analizador de dialogos. En esta clase, el tercer campo tiene un tipo llamado Tokens y este tambien debe ser definido:
struct Token
{
using Palabra = std::string;
using Peso = int;
Palabra valor;
std::unordered_map<Palabra, Peso> relacion;
};
Aqui tenemos dos tipos como son la Palabra y el Peso, en realidad son alias para el string e int respectivaente, el primero sera la palabra tokenizada para ser utilizada y el segundo es el peso que mencionamos en el post anterior, el cual se usa para representar cuan relacionado esta un nodo con otro en la grafica de conocimiento. En este caso los usaremos para un map donde pasaremos esos valores y relacionarlos entre si. Esto nos puede ser util, especialmente si tenemos que comparar similitudes entre palabras. Por ejemplo, podemos pasar la palabra mejor o bueno, ambas son similares semanticamente y pueden ser utilizadas como recomendaciones para una misma solicitud. Con nuestros tipos que podemos usar, pasemos a ver como se puede definir a la clase encargada de analizar:
class QueryParser
{
public:
static Query parse(const std::string& query_string,
const std::string& id_dialogo = "")
{
Query qr;
qr.raw_query = query_string;
qr.id_dialogo = id_dialogo;
qr.tokens = QueryParser::tokenizar(query_string);
QueryParser::get_palabra_relaciones(qr.tokens);
return qr;
}
private:
static std::vector<Token> tokenizar(const std::string& raw_string) {
// 1. separa raw_string por espacios
// 2. construye por cada palabra un Token
// 3. devuelve una lista de tokens
}
static void get_palabra_relaciones(std::vector<Token>& tokens) {
// por cada token, solicita a la Base de Conocimiento
// recupera las relaciones y actualiza las listas de tokens
}
};
Ahora el metodo para analizar (parse) recibira dos valores en lugar de uno,, el primero sera la solicitud o query de usuario y el segundo sera el id del analizador de dialogos, si no se pasa uno se lo establece como vacio. Lo primero que haremos sera crear el objeto que manipulara el query, en la propiedad del query crudo le asignamos el recibido, establecemos el valor para id_dialogo del objeto (en caso de pasar uno), en la propiedad tokens asignaremos el resultado devuelto por el metodo tokenizar, luego llamamos al metodo get_palabra_relaciones pero ya hablaremos en un momento, y finalmente devolvemos el objeto creado.
En la parte privada, seguimos teniendo el metodo tokenizar que toma el query recibido,, lo separa por espacios, construye por cada palabra un token, y una vez finalizado devuelve la lista de tokens creados. El otro metodo es el encargado de recuperar las relaciones entre las palabras, esto lo hace solicitando a la base de conocimiento, recupera las relaciones y actualiza la lista de tokens. Todo esto se encarga de normalizar y tokenizar el query para poder pasar al procesador de query pero de esto hablaremos en el proximo post.
En resumen, hoy hemos visto a analizador de query, que es, para que sirve, un ejemplo practico para ver como se aplica, y algunos detalles mas. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
