Beispiel -App, mit der veranschaulicht werden soll, wie natürliche Sprachverarbeitung (NLP) , insbesondere die Entitätserkennung (NER), verwendet werden kann, um die Genauigkeit von Elasticsearch -Abfragen und die allgemeine Benutzererfahrung zu verbessern. Die Verwendung von NLP neben Elasticsearch (oder einer anderen Volltexten -Suchmaschine) hat zwei wichtige Vorteile:
Angesichts der Abfrage "Schwarze Jacke kostet weniger als 200 US -Dollar" können wir die Farbe und den maximalen Preis schließen und diese Suchfilter für den Benutzer anwenden. Dieses Konzept kann auf andere Felder (z. B. Marke) ausgedehnt werden und auch Konjugationen unterstützen, z .
Stellen Sie sich vor, Sie arbeiten für ein Kleidungs- und Ausrüstungsgeschäft im Freien. Sie bauen eine Katalog -Suchfunktion. Wie sollte die Datenbank angesichts der Abfrage "Packbare Jacke" zwischen einem "packbaren Mückennetz" und einer "leichten Jacke" wählen. Beide Produkte stimmen teilweise überein. TF- IDF wird höchstwahrscheinlich das Moskitonetz auswählen, da es im Korpus weniger als "Jacke" als "Jacke" vorhanden ist. Wenn Sie jedoch die Frage betrachten, ist klar, dass die leichte Jacke besser passt.
Wir lösen dieses Problem normalerweise, indem wir bestimmte Dokumentenfelder z. B. durch Anbringen von mehr Gewicht an den Titels- oder Produkttypfeldern als die Beschreibung anbringen. Diese Art von funktioniert, aber die Logik ist falsch. Wir sagen dem Käufer im Wesentlichen, "basierend auf dem, was wir verkaufen, ist das, was wir für Sie für wichtig halten".
Der Mensch versteht, dass der Käufer angesichts der Abfrage "Packbare Jacke" in erster Linie eine Jacke will. Das liegt daran, dass wir verstehen, dass 'Jacke' ein Produkttyp ist und 'packbares' ein Attribut des Produkts ist. Die natürliche Sprachverarbeitung (NLP) ermöglicht es uns, dieselbe Argumentation programmatisch anzuwenden. In einfachen Worten können wir eine Elasticsearch -Bool -Abfrage ausführen, in der wir ein Match für 'Jacke' haben müssen und ein Match für 'Packbar' haben sollten .
Erstens, und vor allem ist dies keine Produktionsimplementierung. Das für dieses Beispiel verwendete NLP -Modell ist wirklich einfach. Für den Produktionsgebrauch würden wir etwas weitaus robusteres erstellen, das mit historischen Suchdaten geschult wurde. Wir würden auch einen Teil des Sprachmarkierens zusammen mit der Analyse der Abhängigkeit einsetzen, um ein besseres Verständnis der Sätze und Fragmente des Textes zu erhalten.
Zweitens ist der Elasticsearch -Code sehr einfach. Für den Produktionsgebrauch möchten wir benutzerdefinierte Tokenisierer, Analysatoren und Synonyme verwenden. Natürlich hätten wir noch viele weitere Felder und viele weitere Dokumente.
Schließlich gibt es keine Fehlerbehandlung!.
Gehen Sie dies also in dem Geist, in dem es geschaffen wurde - ein Beweis für das Konzept!
Der Python -Code benötigt eine Umgebung 3.9.7+. Ich empfehle, dies in einem Virtualenv mit Venv oder Pyenv/Virtualenv auszuführen
$ 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.txtIch habe eine Docker-compose.yml-Datei zur Verfügung gestellt, damit Sie eine einfache Elasticsarch-Instanz abbauen können
$ docker-compose up -d elasticsearch-7Python -Abhängigkeiten und -Pade können schwierig sein. Daher habe ich ein einfaches Dienstprogramm zur Überprüfung von allem gegeben, was wie erwartet funktioniert. Hinweis: Elasticsearch kann einige Sekunden dauern, bis er online kommt.
$ 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
...Ich habe ein Wrapper -Shell -Skript erstellt, um Uvicorn/Fastapi abzunehmen
$ bin/server.sh
uvicorn.error INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
...Machen Sie eine Anfrage an http: // localhost: 8000 eine json -Körperschaft übergeben:
{
"query" : " lightweight black jacket less than $100 "
}Postman ist wahrscheinlich das beste Werkzeug dafür, aber ich habe auch einen einfachen Kunden aufgenommen:
$ 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 "
]
}
]
}Wichtig: Wenn Sie dieses Skript verwenden, sollten Sie Ihre Suchabfrage in einzelnen Zitate einschließen, um eine variable Erweiterung zu vermeiden.
Treffer Strg + C.
Machen Sie sich keine Sorgen um die asyncio.exceptions.CancelledError - Es wird durch die Hot Reload -Funktion des Uvicorn -Servers verursacht.
$ 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_defaultIch habe eine Dockerfile zur Verfügung gestellt, falls Sie alles in Docker ausführen möchten
$ docker build -t nlp-search-poc .Führen Sie dann Elasticsearch und den Server aus
$ docker-compose up -dWenn Sie auch Docker verwenden möchten, um die Testdaten in Elasticsearch aufzunehmen, können Sie dies tun:
$ docker run -it --rm --network nlp-search-poc_default -e " ELASTIC_SEARCH_HOST=elasticsearch-7 " nlp-search-poc " python " " -m " " src.tools " " reset "Hinweis : Der Netzwerkname wird durch Dockers Netzwerkregeln bestimmt
Docker-compose.yml enthält den Port 8000 des Servers, sodass Sie wie zuvor abfragen können:
$ python -m src.client ' packable jacket '