샘플 앱은 NLP (Natural Language Processing) , 특히 NER (Entity Recognition)을 사용하여 Elasticsearch 쿼리의 정확도와 전반적인 사용자 경험을 향상시키는 방법을 설명하기위한 것입니다. Elasticsearch (또는 기타 전체 텍스트 검색 엔진)와 함께 NLP를 사용하는 데 두 가지 주요 이점이 있습니다.
쿼리 '블랙 재킷이 200 달러 미만' 이라는 쿼리를 감안할 때 색상과 최대 가격을 유추하고 사용자에게 이러한 검색 필터를 적용 할 수 있습니다. 이 개념은 다른 분야 (예 : 브랜드)로 확장 될 수 있으며 '검은 색 또는 짙은 녹색 바버 쿠스 재킷' 도 컨쥬 게이션을 지원할 수 있습니다.
야외 의류 및 장비 상점에서 일한다고 상상해보십시오. 카탈로그 검색 기능을 구축하고 있습니다. 쿼리 '포장 가능한 재킷'이 주어지면 데이터베이스는 '포장 가능한 모기장'과 '가벼운 재킷'중에서 어떻게 선택해야합니까? 두 제품 모두 부분적으로 일치합니다. TF- IDF는 코퍼스에 '재킷'보다 '패키 가능한'사례가 적기 때문에 모기 그물을 선택할 것입니다. 그러나 쿼리를 볼 때 경량 재킷이 더 나은 일치가 될 것임이 분명합니다.
우리는 일반적으로 설명보다 제목 또는 제품 유형 필드에 더 많은 가중치를 첨부하여 특정 문서 필드를 향상 시켜이 문제를 해결합니다. 이런 종류의 효과가 있지만 논리는 잘못되었습니다. 우리는 본질적으로 쇼핑객에게 "우리가 판매하는 것에 기초하여, 이것이 우리가 당신에게 중요하다고 생각하는 것"이라고 말합니다.
인간은 쿼리 '포장 가능한 재킷'을 감안할 때 쇼핑객은 가장 먼저 재킷을 원한다는 것을 이해합니다. 우리는 '재킷'이 제품 유형이고 '포장 가능한'이 제품의 속성이라는 것을 이해하기 때문입니다. NLP (Natural Language Processing)를 통해 우리는이 동일한 추론을 프로그래밍 방식으로 적용 할 수 있습니다. 간단히 말해서 우리는 '재킷'과 일치 해야하며 'Packable'과 일치 해야하는 Elasticsearch Bool 쿼리를 수행 할 수 있습니다.
첫째, 가장 중요한 것은 생산 구현이 아닙니다. 이 예제에 사용 된 NLP 모델은 실제로 기본입니다. 생산 사용을 위해 우리는 역사적인 검색 데이터로 훈련 된 훨씬 더 강력한 것을 구축했습니다. 또한 텍스트의 문장과 조각을 더 잘 이해하기 위해 의존성 구문 분석과 함께 음성 태그의 일부를 사용했습니다.
둘째, Elasticsearch 코드는 매우 기본적입니다. 생산 사용을 위해 우리는 맞춤형 토큰 화제, 분석기 및 동의어를 사용하고 싶습니다. 물론, 우리는 더 많은 분야와 더 많은 문서를 가지고있을 것입니다.
마지막으로 오류 처리가 없습니다!.
그러니 이것을 만들어진 정신으로 취급하십시오 - 개념 증명!
파이썬 코드에는 3.9.7+ 환경이 필요합니다. venv 또는 pyenv/virtualenv를 사용하여 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.txtDocker-Compose.yml 파일을 제공 했으므로 간단한 엘라스틱 검색 인스턴스를 발사 할 수 있습니다.
$ docker-compose up -d elasticsearch-7파이썬 의존성과 경로는 까다로울 수 있으므로 모든 것이 예상대로 작동하는지 확인하는 간단한 유틸리티를 제공했습니다. 참고 : Elasticsearch는 온라인으로 몇 초가 걸릴 수 있습니다.
$ 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
...Uvicorn/Fastapi를 발사하기 위해 래퍼 쉘 스크립트를 만들었습니다.
$ bin/server.sh
uvicorn.error INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
...http : // localhost : 8000에 JSON 본체를 통과하는 데 요청하십시오.
{
"query" : " lightweight black jacket less than $100 "
}우체부는 아마도 이것에 가장 적합한 도구 일 것입니다. 그러나 나는 또한 간단한 클라이언트도 포함했습니다.
$ 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 "
]
}
]
}중요 : 이 스크립트를 사용하기로 선택한 경우 변수 확장을 피하기 위해 검색 쿼리를 단일 따옴표로 동봉해야합니다.
ctrl + c
asyncio.exceptions.CancelledError 에 대해 걱정하지 마십시오 - 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_defaultDocker 내부에서 모든 것을 실행하고 싶을 때 Dockerfile을 제공했습니다.
$ docker build -t nlp-search-poc .그런 다음 Elasticsearch 및 서버를 실행하십시오
$ docker-compose up -dDocker를 사용하여 테스트 데이터를 Elasticsearch에 수집하려면 다음을 수행 할 수 있습니다.
$ docker run -it --rm --network nlp-search-poc_default -e " ELASTIC_SEARCH_HOST=elasticsearch-7 " nlp-search-poc " python " " -m " " src.tools " " reset "참고 : 네트워크 이름은 Docker의 네트워킹 규칙에 따라 결정됩니다.
docker-compose.yml 서버의 포트 8000을 노출하므로 이전과 같이 쿼리 할 수 있습니다.
$ python -m src.client ' packable jacket '