La aplicación de muestra destinada a ilustrar cómo el procesamiento del lenguaje natural (PNL) , nombrado reconocimiento de entidad específicamente (NER), puede usarse para mejorar la precisión de las consultas de ElasticSearch y la experiencia general del usuario. Hay dos beneficios clave para usar NLP junto con ElasticSearch (o cualquier otro motor de búsqueda de texto completo):
Dada la consulta 'Chaqueta negra que cuesta menos de $ 200' , podemos inferir el color y el precio máximo, y aplicar estos filtros de búsqueda para el usuario. Este concepto se puede extender a otros campos (por ejemplo, marca) y también admite conjugaciones, por ejemplo , 'chaqueta de barro de color negro o verde oscuro'
Imagine que trabaja para una tienda de ropa y equipos al aire libre. Estás construyendo una función de búsqueda de catálogo. Dada la consulta 'Chaqueta empacable', ¿cómo debe elegir la base de datos entre una 'red de mosquitos empacable' y una 'chaqueta liviana'? Ambos productos coinciden parcialmente. TF- IDF probablemente seleccionará la red de mosquitos, ya que habrá menos instancias de 'empacable' que 'chaqueta' en el corpus. Sin embargo, al mirar la consulta, está claro que la chaqueta liviana sería la mejor combinación.
Por lo general, resolvemos este problema aumentando ciertos campos de documentos, por ejemplo, adjuntando más peso a los campos de título o tipo de producto que la descripción. Este tipo de funciona, pero la lógica está mal. Básicamente le estamos diciendo al comprador "basado en lo que vendemos, esto es lo que creemos que es importante para usted".
Los humanos entienden que dada la consulta 'chaqueta empacable', el comprador quiere una chaqueta en primer lugar. Esto se debe a que entendemos que 'Jacket' es un tipo de producto y 'empacable' es un atributo del producto. El procesamiento del lenguaje natural (NLP) nos permite aplicar este mismo razonamiento mediante programación. En términos simples, podemos realizar una consulta de bool Elasticsearch en la que debemos tener una coincidencia para 'chaqueta' y debemos tener una coincidencia para 'empacable'.
En primer lugar, y lo más importante, esta no es una implementación de producción. El modelo NLP utilizado para este ejemplo es realmente básico. Para el uso de la producción, construiríamos algo mucho más robusto, capacitado con datos de búsqueda históricos. También emplearíamos parte del etiquetado del habla junto con el análisis de la dependencia para comprender mejor las oraciones y fragmentos de texto.
En segundo lugar, el código Elasticsearch es muy básico. Para el uso de la producción, queremos usar tokenizadores personalizados, analizadores y sinónimos. Por supuesto, tendríamos muchos más campos y muchos más documentos.
¡Finalmente, no hay manejo de errores!.
Así que por favor trate esto en el espíritu en el que fue creado, ¡ una prueba de concepto!
El código Python necesita un entorno 3.9.7+. Recomiendo ejecutar esto en Virtualenv usando Venv o Pyenv/VirtualEnv
$ pyenv install 3.9.7
$ pyenv virtualenv 3.9.7 nlp-search-poc
$ pyenv local nlp-search-poc
$ pip install -U pip
$ pip install -r requirements.txtHe proporcionado un archivo Docker-Compose.yml, para que pueda encender una simple instancia de Elasticsearch
$ docker-compose up -d elasticsearch-7Las dependencias y rutas de Python pueden ser complicados, por lo que proporcioné una utilidad simple para verificar que todo funcione como se esperaba. Nota: Elasticsearch puede tardar unos segundos en conectarse.
$ python -m src.tools ping
Elasticsearch alive: True$ python -m src.tools create
productRepository INFO Creating products index
productRepository INFO products created
$ python -m src.tools ingest
productRepository INFO Ingesting lightweight black jacket
productRepository INFO Ingesting midweight black jacket
...Creé un script de shell de envoltura para encender Uvicorn/Fastapi
$ bin/server.sh
uvicorn.error INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
...Realice una solicitud GET a http: // localhost: 8000 pasando un cuerpo json:
{
"query" : " lightweight black jacket less than $100 "
}Postman es probablemente la mejor herramienta para esto, pero también he incluido un cliente simple:
$ python -m src.client ' lightweight black jacket less than $100 ' {
"ner_prediction" : {
"text" : " lightweight black jacket less than $100 " ,
"product" : " jacket " ,
"price_from" : null ,
"price_to" : 100 ,
"colors" : [
" black "
],
"attrs" : [
" lightweight "
]
},
"results" : [
{
"title" : " lightweight black jacket " ,
"product_type" : " jacket " ,
"price" : 100 ,
"colors" : [
" black "
],
"attrs" : [
" lightweight "
]
}
]
}IMPORTANTE: Si elige usar este script, debe adjuntar su consulta de búsqueda en cotizaciones individuales para evitar la expansión variable.
Golpear ctrl + c
No se preocupe por asyncio.exceptions.CancelledError : es causada por la función de recarga caliente del servidor UVICORN.
$ python -m src.tools drop
productRepository INFO Dropping products index
productRepository INFO products dropped$ docker-compose down
Stopping elasticsearch-7 ... done
Removing elasticsearch-7 ... done
Removing network nlp-search-poc_defaultHe proporcionado un Dockerfile en caso de que quieras ejecutar todo dentro de Docker
$ docker build -t nlp-search-poc .Luego ejecute Elasticsearch y el servidor
$ docker-compose up -dSi también desea usar Docker para ingerir los datos de prueba en Elasticsearch, puede hacerlo:
$ docker run -it --rm --network nlp-search-poc_default -e " ELASTIC_SEARCH_HOST=elasticsearch-7 " nlp-search-poc " python " " -m " " src.tools " " reset "Nota : El nombre de la red está determinado por las reglas de redes de Docker
Docker-compose.yml expone el puerto 8000 del servidor, por lo que puede consultar como antes:
$ python -m src.client ' packable jacket '