[JAVA] Erstellen Sie eine Restaurant-Such-App mit der IBM Watson + Guru Navi-API (mit Quelle).

Einführung

Ich habe versucht, eine Webanwendung mit Watson Developer Cloud als Material für die interne Präsentation zu entwickeln. Daher handelt es sich um eine Zusammenfassung und ein Memorandum.

Über die App

Funktion (ohne zu sagen, dass dies möglich ist)

Wenn Sie einen Text eingeben oder sprechen und eine Frage stellen, stellt Watson Ihnen die empfohlenen Restaurants unter den Restaurants mit einem Radius von etwa 1 km von einem bestimmten Punkt vor. Sie können Fragen stellen wie "Ich möchte ein Karaage-Menü essen" oder "Eine Kneipe auf Fischbasis mit einem Budget von bis zu 4000 Yen".

search.png

Die Shops werden in einem Listenformat angezeigt. Je mehr ★, desto mehr empfohlene Restaurants. Sie können die Geschäfte, an denen Sie interessiert sind, in die Liste aufnehmen. Entscheiden Sie also, welches Geschäft Sie besuchen möchten, und überprüfen Sie die Informationen auf der Guru Navi-Website sowie die Entfernung und Wegbeschreibung von Ihrem aktuellen Standort.

map.png

Wenn Sie in den Laden gehen (ich war schon vor langer Zeit dort, aber das spielt keine Rolle), kommentieren Sie bitte Ihre Eindrücke. Die Suchergebnisse werden verbessert, indem der Inhalt von Kommentaren analysiert und gelernt wird, z. B. Geschäfte, die anderen Personen empfohlen werden können, wenn sie "sehr lecker" sind, und Geschäfte, die nicht empfohlen werden können, wenn "der Angestellte einen Streit hatte".

comment.png

classify.png

Diagramm

Zuerst dachte ich darüber nach, alles auf Bluemix aufzubauen, aber ich hatte keine kostenlose Stufe für ClearDB (5 MB) und es bedeutete auch, eine Entwicklungsumgebung für meinen persönlichen PC vorzubereiten. ..

Die auf Node-RED vorbereitete REST-API wird vom Client-JS entsprechend aufgerufen, um Suchergebnisse anzuzeigen und Benutzerkommentare auszuwerten. kousei.png

Stellen Sie sich die folgenden Operationen vor.

  1. Lokale R & R- und NLC-Datenerstellung / -eingabe
  2. Wenn der Benutzer das System verwendet, werden Protokolle in ClearDB gesammelt.
  3. Wenn das Protokoll erfasst wurde, exportieren Sie es lokal und erstellen / geben Sie erneut Daten ein.
  4. Verbesserte Suchergebnisse (ganz zu schweigen)

Impressionen

Retrieve and Rank

curl -k -X POST -u "**username:**password**" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters" -d "{\"cluster_size\":\"\",\"cluster_name\":\"WatsonRestaurantCluster\"}"

schema.xml


   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 

   <field name="shop_id" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="vote_id" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="shop_name" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="shop_name_kana" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="menu_name" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="menu_name_kana" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="latitude" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="longitude" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="shop_url" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="image_url" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 
   <field name="pr_text" type="string" indexed="false" stored="true" required="true" multiValued="false" /> 

   <field name="shop_text" type="watson_text_ja" indexed="false" stored="true" required="true" multiValued="false" /> 

   <field name="budget" type="int" indexed="true" stored="true" required="true" multiValued="false" />

schema.xml


  <fieldType name="watson_text_ja" indexed="true" stored="true" class="com.ibm.watson.hector.plugins.fieldtype.WatsonTextField">
      <analyzer type="index">
          <tokenizer class="solr.JapaneseTokenizerFactory" mode="search" userDictionary="lang/userdict_ja.txt" />
          <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" tokenizerFactory="solr.JapaneseTokenizerFactory" userDictionary="lang/userdict_ja.txt"/>
          <filter class="solr.JapaneseBaseFormFilterFactory"/>
          <filter class="solr.CJKWidthFilterFactory"/>
          <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
          <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
          <tokenizer class="solr.JapaneseTokenizerFactory" mode="search" userDictionary="lang/userdict_ja.txt" />
          <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" tokenizerFactory="solr.JapaneseTokenizerFactory" userDictionary="lang/userdict_ja.txt"/>
          <filter class="solr.JapaneseBaseFormFilterFactory"/>
          <filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt"/>
          <filter class="solr.CJKWidthFilterFactory"/>
          <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ja.txt"/>
          <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
          <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
  </fieldType>

Wie die Dokumentdaten generiert wurden (Abrufen)

  1. Dokumentenerstellung aus PR-Text des Guru Navi-Shops
  1. Dokumentenerstellung aus Guru Navis Mundpropaganda
  1. Dokumentgenerierung aus Systembenutzerkommentaren

rar_documents.json


{
  "id" : "5497472",
  "shop_id" : "5497472",
  "vote_id" : "",
  "shop_name" : "Tenka Ippin Gotanda Laden",
  "shop_name_kana" : "Tenkai Pingo Tandaten",
  "menu_name" : "",
  "menu_name_kana" : "",
  "latitude" : "35.624377",
  "longitude" : "139.723394",
  "shop_url" : "http://r.gnavi.co.jp/b5tzzw2g0000/",
  "image_url" : "",
  "pr_text" : "Es ist eine Suppe, die durch Kochen von Hühnchen und verschiedenen Zutaten im Laufe der Zeit hergestellt wird. Es ist voller Kollagen, das gut für Schönheit und Gesundheit ist.",
  "shop_text" : "Tenka Ippin Gotanda Laden. Tenkai Pingotandaten. Ramen Nudelgerichte und andere. Es ist eine Suppe, die reich an Kollagen ist, gut für Schönheit und Gesundheit ist und nirgendwo anders probiert werden kann. Darüber hinaus ein Menü, das halb gebratenen Reis und chinesisches Soba enthält. Gyoza-Menü mit Gyoza, halbem Reis und chinesischem Soba. Wir haben auch eine große Auswahl an Menüs, wie zum Beispiel ein Service-Set-Menü, das halb gebratenen Reis, Gyoza und chinesisches Soba umfasst.",
  "budget" : -1
}

Wie die Trainingsdaten generiert wurden (Rang)

--Erstellen Sie in der ersten Migrationsphase etwa 750 Elemente (keine Lerndaten werden generiert, wenn der Benutzer das System verwendet).

  1. Generieren Sie eine Frage aus der Kategorie und fügen Sie dem Dokument Punkte hinzu
  1. Generieren Sie eine Frage aus dem Menünamen und fügen Sie dem Dokument Punkte hinzu
  1. Fügen Sie dem Dokument Punkte hinzu, für die detaillierte Informationen angezeigt wurden
  1. Additionen und Subtraktionen zum kommentierten Dokument
  1. Fügen Sie Dokumente mit hohen Benutzerbewertungen Punkte hinzu ――Unter den Suchergebnissen aller vom Benutzer gesuchten Abfragen werden den Shops Punkte mit vielen erfreulichen Bewertungen in Guru Navi hinzugefügt.

rar_training.csv


"%E3%83%AF%E3%83%83%E3%83%91%E3%83%BC","6364602.681550","2"
"%E3%82%BF%E3%82%A4%E3%82%AC%E3%83%91%E3%82%AA","7255599","1","7255599.4618610","3"
"%E5%A1%A9%E3%83%AC%E3%83%A2%E3%83%B3%E3%82%AC%E3%83%91%E3%82%AA","e584801.1192601","2","6408790.4601796","2","geyc200.4614278","4","g044108.4609358","4","6085706.1451291","1"

Wörterbuchdaten (Solr-Funktion)

  1. Generieren Sie ein Benutzerwörterbuch aus dem Geschäftsnamen, dem Menünamen und dem Kategorienamen ――Ich möchte, dass Tenichi oben in der Suche mit dem Wort "Rich Ramen" erscheint.
  2. Generieren Sie ein Synonim-Wörterbuch, damit die enthaltenen Nebenkategorien der Kategorie durchsucht werden, wenn die Hauptkategorie der Kategorie durchsucht wird
  1. Bearbeiten Sie das Stoppwortwörterbuch entsprechend ――Ich denke, es ist besser, Wörter wie "lecker" und "einkaufen" zu entfernen.

userdict_ja.txt


Ein Gegenstand auf der Welt,Ein Gegenstand auf der Welt,Ein Gegenstand auf der Welt,Benutzerdefinierte Nomenklatur
Hühnchengeschmack Vogel,Hühnchengeschmack Vogel,Toridori Midori,Benutzerdefinierte Nomenklatur
Fisch Takumi Gotanda Laden,Fisch Takumi Gotanda Laden,Wosho Gotandaten,Benutzerdefinierte Nomenklatur
»Saba,»Saba,»Saba,Benutzerdefinierte Nomenklatur
Rafute,Rafute,Rafute,Benutzerdefinierte Nomenklatur

synonyms.txt


organisch=>Medizinische Gerichte Bio-Gerichte Gemüsegerichte Bio
Kreative kreative Küche=>Kreatives japanisches Essen Kreatives Essen Ausländisches Essen
Italienisch=>  Italienischイタリア料理 パスタ ピザ
Französisch=> Französischフランス料理 ビストロ

Natural Language Classifier

――Es war viel einfacher zu bedienen als R & R. (Ich sage nicht, dass es richtig beurteilt wird)

So erstellen Sie Trainingsdaten für eine positive / negative Beurteilung

  1. Positiv (lecker)
  1. Negativ (yacky) ――Es wurde erwartet, dass es durch das Gegenteil von positiv (niedrige Bewertung von Jubelbewertungen) erzeugt werden könnte, aber negative Bewertungen werden kaum in Bewertungen registriert und es ist verwirrend ... Ist es Zensur? ―― Immerhin habe ich mich per Handkopie aus dem Bewertungsblog von 2 Channel und Restaurants registriert.

nlc_training.csv


"Zufrieden mit dem Magen","yummy"
"Der Favorit meines Sohnes","yummy"
"Angenehm ist auch die Würde der frischen Handwerker","yummy"
"Dicker Bauch","yummy"
"Nostalgischer Geschmack","yummy"
"Es war ein schrecklicher Laden","yacky"
"Die Frische des Sashimi war schlecht","yacky"
"Die Qualität ist schlecht. subtil","yacky"
"Auf halbem Weg und es gibt keinen guten Punkt","yacky"
"Nicht lecker. Käsig","yacky"

Um den Kunden herum

――Das Organisieren von Schriftarten und Symbolen als R & R und NLC sowie das Verständnis der mit Interesse eingeführten Bootstrap- und Google Maps-API dauerte länger. ――Die Suche wurde nach Budget eingegrenzt, indem der Betrag aus dem Suchtext abgerufen und die Filterfunktion von Solr verwendet wurde.

Haushaltsurteil


function getBudgets(query) {
    var B_MIN = 0;
    var B_MAX = 100000;
    var B_RANGE = 500;
    var budgets = null;
    query = query.replace(/0-9/g, function(s) {
        return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
    });
    var matches = query.match(/\d+(?=Kreis)|(Von|das ist alles)|(Bis|Innerhalb|Weniger als|Weniger als|Nicht genug)/g);
    if (matches) {
        var yens = matches.filter(function(y) {
            if (isFinite(y)) {
                return y > B_MIN && y < B_MAX
            } else {
                return false;
            }
        });
        if (yens.length == 1) {
            var condition;
            try {
                condition = matches[matches.indexOf(yens[0]) + 1];
            } catch (e) {
                condition = null;
            }
            yens = yens.map(function(y) {
                return Number(y.replace(/^0+/g, ""));
            });

            if (condition) {
                if (/Von|das ist alles/g.test(condition)) {
                    budgets = {
                        budget_min: yens[0],
                        budget_max: B_MAX
                    };
                } else {
                    budgets = {
                        budget_min: B_MIN,
                        budget_max: yens[0]
                    };
                }
            } else {
                budgets = {
                    budget_min: yens[0] - B_RANGE,
                    budget_max: yens[0] + B_RANGE
                };
            }
        } else if (yens.length >= 2) {
            budgets = {
                budget_min: Math.min(yens[0], yens[1]),
                budget_max: Math.max(yens[0], yens[1])
            };
        }
    }
    if (budgets) {
        budgets.budget_min = Math.max(B_MIN, budgets.budget_min);
        budgets.budget_max = Math.min(B_MAX, budgets.budget_max);

        return budgets;
    } else {
        return null;
    }
}

Rund um den Server Entwicklungsumgebung

--Node-RED sieht wie folgt aus. ―― ~~ R & R funktionierte nur dann ordnungsgemäß, wenn es sich um einen HTTP-Knoten und NLC um einen dedizierten Knoten handelte ... ~~ Ich habe die Anmeldeinformationen zuerst in das Knotenformular geschrieben, aber wenn ich sie jetzt überprüft habe, funktioniert die Dienstverbindung auf der Bluemix-Seite so, wie sie auf dem dedizierten Knoten ist?

nodered.png

――Java wurde bei der Arbeit nicht sehr berührt, aber es hat Spaß gemacht, verschiedene Dinge wie REST-Aufrufe, JSON → DB, DB → JSON oder CSV ausführen zu können. ――Jedes Mal, wenn Maven of Eclipse eine Referenz hinzufügt oder löscht, tritt ein Fehler auf, und wenn ich darüber nachdenke, heilt er plötzlich und ich bin mir nicht sicher. ――Ich habe das Gefühl, dass etwa 3/5 des während der Arbeit erzeugten Stresses von Maven verursacht wird ...

Verschiedene Notizen

――Die Jahres- und Neujahrsferien dauern ca. 4 bis 5 Manntage. ――Wenn Sie das kostenlose Kontingent nicht berücksichtigen, beträgt die Wartungsgebühr etwa 5.000 Yen / Monat? (Ranker1-Instanz 1000 Yen + NLC1-Instanz 2000 Yen + Node-RED ~ 1500 Yen + Lern-API)

Quellcode

Ich habe es auf [Github] veröffentlicht (https://github.com/yktakaha4/WatsonRestaurant).

Recommended Posts

Erstellen Sie eine Restaurant-Such-App mit der IBM Watson + Guru Navi-API (mit Quelle).
[Rails6] Erstelle eine neue App mit Rails [Anfänger]
[Rails 5] Erstelle eine neue App mit Rails [Anfänger]
[Java] Erstellen Sie so etwas wie eine Produktsuch-API
Erstellen Sie einen Web-API-Server mit Spring Boot
Erstellen Sie eine Chat-App mit WebSocket (Tyrus) + libGDX + Kotlin
[Rails] Ich habe versucht, eine Mini-App mit FullCalendar zu erstellen
Erstellen Sie einen SlackBot mit AWS Lambda & API Gateway in Java
Erstellen Sie eine XML-RPC-API mit Wicket
Erstellen Sie einen Spielplatz mit Xcode 12
Erstellen Sie eine Memo-App mit Tomcat + JSP + Servlet + MySQL mit Eclipse
Erstellen Sie eine JVM für die App-Verteilung mit JDK 9-Modulen und jlink
Ich habe ein einfaches Suchformular mit Spring Boot + GitHub Search API erstellt.
Erstellen Sie mit Docker eine Vue3-Umgebung!
Erstellen Sie eine App mit Spring Boot 2
Erstellen einer Timer-App mit Schlamm
Erstellen Sie eine neue App mit Rails
Erstellen Sie eine App mit Spring Boot
Versuchen Sie, eine Server-Client-App zu erstellen
Erstellen Sie Ausnahmen mit einer Fluid-Schnittstelle
Erstellen Sie ein Maven-Projekt mit Befehlen
Erstellen Sie eine dynamische SQL-Anweisung mit MyBatis [Suche nach mehreren Wörtern zulassen]
Erstellen Sie mit dem Befehl cURL + tar ein Spring Boot-App-Entwicklungsprojekt
Erstellen Sie mit Rails x LineBot eine App für die Zusammenfassung von technischen Nachrichten im LINEnews-Stil! [Teil 1]
Los geht's mit Watson Assistant (ehemals Conversation) ⑤ Erstellen Sie einen Chatbot mit Watson + Java + Slack