App App destinado a ilustrar como o Processamento de Linguagem Natural (PNL) , especificamente nomeado reconhecimento de entidade (NER), pode ser usado para melhorar a precisão das consultas do Elasticsearch e a experiência geral do usuário. Existem dois benefícios principais no uso da PNL juntamente com o Elasticsearch (ou qualquer outro mecanismo de pesquisa de texto completo):
Dada a consulta 'Black Jacket que custa menos de US $ 200' , podemos inferir a cor e o preço máximo e aplicar esses filtros de pesquisa para o usuário. Esse conceito pode ser estendido a outros campos (por exemplo, marca) e também suporta conjugações, por exemplo , 'jaqueta preta ou verde escura'
Imagine que você trabalha para uma loja de roupas e equipamentos ao ar livre. Você está construindo um recurso de pesquisa de catálogo. Dada a consulta 'Jacket Packable', como o banco de dados deve escolher entre uma 'rede de mosquitos compacíveis' e uma 'jaqueta leve'. Ambos os produtos correspondem parcialmente. O TF- IDF provavelmente selecionará a rede de mosquitos, pois haverá menos instâncias de 'empacotável' do que 'jaqueta' no corpus. No entanto, ao olhar para a consulta, fica claro que a jaqueta leve seria a melhor combinação.
Normalmente, resolvemos esse problema aumentando determinados campos de documentos, por exemplo, anexando mais peso ao título ou campos do tipo produto do que a descrição. Esse tipo de trabalho, mas a lógica está errada. Estamos essencialmente dizendo ao comprador "com base no que vendemos, é isso que achamos importante para você".
Os seres humanos entendem que, dada a consulta 'Jacket Packable', o comprador quer uma jaqueta em primeiro lugar. Isso porque entendemos que 'jaqueta' é um tipo de produto e 'embalável' é um atributo do produto. O processamento de linguagem natural (PNL) nos permite aplicar esse mesmo raciocínio programaticamente. Em termos simples, podemos realizar uma consulta de e elasticsearch bool na qual devemos ter uma correspondência para 'jaqueta' e devemos ter uma correspondência para 'empacotável'.
Em primeiro lugar, e o mais importante é que isso não é uma implementação de produção. O modelo de PNL usado para este exemplo é realmente básico. Para uso da produção, construímos algo muito mais robusto, treinado com dados históricos de pesquisa. Também empregaríamos parte da marcação de fala, juntamente com a análise de dependência para entender melhor as frases e fragmentos do texto.
Em segundo lugar, o código Elasticsearch é muito básico. Para uso da produção, queremos usar tokenizadores, analisadores e sinônimos personalizados. Obviamente, teríamos muitos outros campos e muito mais documentos.
Finalmente, não há tratamento de erros!.
Então, por favor, trate isso no espírito em que foi criado - uma prova de conceito!
O código Python precisa de um ambiente 3.9.7+. Eu recomendo executar isso em um virtualenv usando Venv ou 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.txtEu forneci um arquivo Docker-comppose.yml, para que você possa iniciar uma instância simples do Elasticsearch
$ docker-compose up -d elasticsearch-7As dependências e os caminhos do Python podem ser complicados, por isso forneci uma utilidade simples para verificar tudo o que está funcionando como esperado. NOTA: Elasticsearch pode levar alguns segundos para ficar online.
$ 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
...Eu criei um script de shell wrapper para disparar uvicorn/fastapi
$ bin/server.sh
uvicorn.error INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
...Faça uma solicitação de obter para http: // localhost: 8000 Passando um corpo JSON:
{
"query" : " lightweight black jacket less than $100 "
}Postman é provavelmente a melhor ferramenta para isso, mas também incluí um cliente simples:
$ 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: Se você optar por usar este script, inclua sua consulta de pesquisa em cotações únicas para evitar expansão variável.
Bata Ctrl + C
Não se preocupe com o asyncio.exceptions.CancelledError - Isso é causado pelo recurso de recarga a quente do 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_defaultEu forneci um Dockerfile, caso você queira executar tudo dentro do Docker
$ docker build -t nlp-search-poc .Em seguida, execute o Elasticsearch e o servidor
$ docker-compose up -dSe você também deseja usar o Docker para ingerir os dados do teste no Elasticsearch, você pode fazê -lo:
$ docker run -it --rm --network nlp-search-poc_default -e " ELASTIC_SEARCH_HOST=elasticsearch-7 " nlp-search-poc " python " " -m " " src.tools " " reset "Nota : o nome da rede é determinado pelas regras de rede do Docker
Docker-compose.yml expõe a porta 8000 do servidor, para que você possa consultar como antes:
$ python -m src.client ' packable jacket '