Crea un Chatbot personalizzato di FAQ con BERT

Crea un Chatbot con BERT

I chatbot sono diventati sempre più standard e preziosi come interfacce utilizzate da numerose organizzazioni per vari scopi. Trovano numerose applicazioni in diversi settori, come offrire raccomandazioni personalizzate sui prodotti ai clienti, offrire supporto clienti 24 ore su 24 per la risoluzione delle query, assistere con le prenotazioni dei clienti e molto altro ancora. Questo articolo esplora il processo di creazione di un chatbot FAQ specificamente progettato per l’interazione con i clienti. I chatbot FAQ affrontano domande all’interno di un dominio specifico, utilizzando un elenco predefinito di domande e relative risposte. Questo tipo di chatbot si basa su Semantic Question Matching come suo meccanismo sottostante.

Obiettivi di apprendimento

  • Comprendere i concetti di base del modello BERT
  • Comprendere Elasticsearch e la sua applicazione nel chatbot
  • Il meccanismo per la creazione dei chatbot
  • Indicizzazione e interrogazione in Elasticsearch

Questo articolo è stato pubblicato come parte del Data Science Blogathon.

Cos’è BERT?

BERT, acronimo di Bidirectional Encoder Representations from Transformers, è un grande modello di linguaggio sviluppato da Google nel 2018. A differenza dei modelli unidirezionali, BERT è un modello bidirezionale basato sull’architettura Transformer. Impara a comprendere il contesto di una parola considerando sia le parole che precedono che seguono in una frase, consentendo una comprensione più completa.

Un grande sfida con BERT era che non poteva raggiungere prestazioni all’avanguardia per compiti di NLP. Il problema principale era che le embedding a livello di token non potevano essere utilizzate in modo efficace per la similarità testuale, con conseguente scarsa prestazione nella generazione di embedding di frase.

Tuttavia, è stato sviluppato Sentence-BERT (SBERT) per affrontare questa sfida. SBERT si basa su una rete Siamese, che prende due frasi alla volta e le converte in embedding a livello di token utilizzando il modello BERT. Applica quindi uno strato di pooling a ciascun insieme di embedding per generare embedding di frase. In questo articolo, utilizzeremo SBERT per gli embedding di frase.

Elastic Search è un motore di ricerca e analisi open-source molto potente, altamente scalabile e progettato per gestire dati estesi in tempo reale. Sviluppato sulla libreria Apache Lucene, che fornisce funzionalità di ricerca full-text. Elasticsearch è altamente scalabile in quanto offre una rete altamente distribuita per scalare su nodi multipli, garantendo alta disponibilità e tolleranza ai guasti. Offre anche un’API RESTful flessibile e robusta, che consente l’interazione con il motore di ricerca tramite richieste HTTP. Supporta vari linguaggi di programmazione e fornisce librerie client per una facile integrazione nell’applicazione.

Questo articolo ci insegnerà a creare un chatbot FAQ con BERT pre-addestrato ed Elasticsearch.

Passaggio 1) Installa la libreria SBERT

#installa la libreria sentence transformers
pip install sentence-transformers

Passaggio 2) Genera gli embedding delle domande

Utilizzeremo la libreria SBERT per ottenere gli embedding per le domande predefinite. Per ogni domanda, verrà generato un array numpy di dimensione 768, che è equivalente alla dimensione degli embedding a livello di token di BERT:

from sentence_transformers import SentenceTransformer

sent_transformer = SentenceTransformer("bert-base-nli-mean-tokens")

domande = [

    "Come migliorare le tue abilità di conversazione? ",

    "Chi decide la nomina del Governatore in India? ",

    "Qual è il miglior modo per guadagnare denaro online?",

    "Chi è il capo del governo in India?",

    "Come posso migliorare le mie abilità di conversazione in inglese? "

]

embedd_domande = sent_transformer.encode(domande)

Passaggio 3) Installa la libreria Elasticsearch

pip install elasticsearch

Passaggio 4) Creazione dell’indice in Elasticsearch

from elasticsearch import Elasticsearch


# definizione del client Python per Elasticsearch
es_client = Elasticsearch("localhost:9200")

NOME_INDICE = "chat_bot_index"


# dimensioni dell'indice per l'array numpy, cioè 768
dim_embedding = 768

def create_index() -> None:

    es_client.indices.delete(index=NOME_INDICE, ignore=404)

    es_client.indices.create(

        index=NOME_INDICE,

        ignore=400,

        body={

            "mappings": {

                "properties": {

                    "embedding": {

                        "type": "dense_vector",

                        "dims": dim_embedding,

                    },

                    "question": {

                        "type": "text",

                    },

                    "answer": {

                        "type": "text",

                    }

                }

            }

        }

    )



create_index()

Il processo di creazione di un indice in Elasticsearch è molto simile al processo di definizione dello schema in qualsiasi database. Nel codice precedente, abbiamo creato un indice chiamato “chat_bot_index”, che definisce tre campi, ovvero ’embedding’, ‘question’ e ‘answer’, e i loro tipi, ovvero “dense_vector” per “embeddings” e “text” per gli altri due.

def indexing_q(qa_pairs: List[Dict[str, str]]) -> None:

  for pair in qa_pairs:
  
      ques = pair["question"]
  
      ans = pair["answer"]
  
      embedding = sent_transformer.encode(ques)[0].tolist()
  
          data = {
  
              "question": questi,
  
              "embedding": embedding,
  
              "answer": ans,
  
          }
  
          es_client.index(
  
              index=NOME_INDICE,
  
              body=data
  
          )
  
 

qa_pairs = [{

    "question": "Come migliorare le tue abilità di conversazione? ",

    "answer": "Parla di più",

},{

    "question": "Chi decide la nomina del Governatore in India? ",

    "answer": "Il Presidente dell'India",

},{

    "question": "Come posso migliorare le mie abilità di conversazione in inglese? ",

    "answer": "Pratica di più",

}]

indexing_q(qa_pairs)

Nel codice precedente, abbiamo indicizzato le coppie domanda-risposta nel database Elasticsearch con gli embeddings delle domande.

Passaggio 6) Query da Elasticsearch

ENCODER_BOOST = 10

def query_question(question: str, top_n: int=10) -> List[dict]:
  embedding = sentence_transformer.encode(question)[0].tolist()
      es_result = es_client.search(
          index=NOME_INDICE,
          body={
              "from": 0,
              "size": top_n,
              "_source": ["question", "answer"],
              "query": {
                  "script_score": {
                      "query": {
                          "match": {
                              "question": question
                          }
                      },
                      "script": {
                          "source": """
                              (cosineSimilarity(params.query_vector, "embedding") + 1)
                              * params.encoder_boost + _score
                          """,
                          "params": {
                              "query_vector": embedding,
                              "encoder_boost": ENCODER_BOOST,
                          },
                      },
                  }
              }
          }
      )
      hits = es_result["hits"]["hits"]
      clean_result = []
      for hit in hits:
          clean_result.append({
              "question": item["_source"]["question"],
              "answer": item["_source"]["answer"],
              "score": item["_score"],
          })
  return clean_result

query_question("Come rendere il mio inglese fluente?")#import csv

Possiamo modificare la query di ES includendo un campo “script”, che ci consente di creare una funzione di punteggio che calcola il punteggio di similarità cosinale su embeddings. Combiniamo questo punteggio con il punteggio di corrispondenza ES BM25 complessivo. Per regolare il peso della similarità cosinale dell’embedding, possiamo modificare l’iperparametro chiamato “ENCODER_BOOST”.

Conclusione

In questo articolo, abbiamo esplorato l’applicazione di SBERT ed Elasticsearch nella creazione del chatbot. Abbiamo discusso la creazione di un chatbot che rispondesse alle domande basate su coppie di domande-risposte predefinite considerando l’intento della domanda.

Ecco i punti chiave della nostra esplorazione:

  1. Capire l’importanza di SBERT ed Elasticsearch nel campo dello sviluppo di chatbot, sfruttando le loro capacità per migliorare le esperienze conversazionali.
  2. Utilizzare SBERT per generare embeddings per le domande consente una comprensione più profonda della loro semantica e contesto.
  3. Sfruttare Elasticsearch per stabilire un indice che memorizzi ed organizzi efficientemente le coppie domanda-risposta, ottimizzando le operazioni di ricerca e recupero.
  4. Illustrare il processo di interrogazione in Elasticsearch, mostrando come il chatbot recuperi efficacemente le risposte più pertinenti in base alla domanda dell’utente.

Domande frequenti

Il materiale mostrato in questo articolo non è di proprietà di Analytics Vidhya ed è utilizzato a discrezione dell’autore.