Press "Enter" to skip to content

用BERT构建自定义FAQ聊天机器人

用BERT构建自定义FAQ聊天机器人 四海 第1张

聊天机器人已成为许多组织用于各种目的的越来越标准和有价值的界面。它们在不同行业中有许多应用,例如为客户提供个性化的产品推荐,提供全天候的客户支持来解决查询问题,协助客户预订等等。本文探讨了创建专门用于客户互动的FAQ聊天机器人的过程。FAQ聊天机器人解答特定领域内的问题,利用预定义的问题列表和相应的答案。这种类型的聊天机器人依赖于语义问题匹配作为其基本机制。

学习目标

  • 了解BERT模型的基础知识
  • 了解Elasticsearch及其在聊天机器人中的应用
  • 创建聊天机器人的机制
  • 在Elasticsearch中进行索引和查询

本文是作为Data Science Blogathon的一部分发布的。

BERT是什么?

用BERT构建自定义FAQ聊天机器人 四海 第2张

BERT(Bidirectional Encoder Representations from Transformers)是谷歌于2018年发布的一个大型语言模型。与单向模型不同,BERT是基于Transformer架构的双向模型。它通过考虑句子中在它之前和之后出现的单词来学习理解单词的上下文,实现更全面的理解。

BERT面临的一个主要挑战是无法在自然语言处理任务中达到最先进的性能。主要问题是标记级别的嵌入在文本相似性方面无法有效使用,导致在生成句子嵌入时性能较差。

然而,为了解决这个挑战,开发了Sentence-BERT(SBERT)。SBERT基于一个Siamese网络,它每次接收两个句子,并使用BERT模型将它们转换为标记级别的嵌入。然后,它对每组嵌入应用汇聚层以生成句子嵌入。在本文中,我们将使用SBERT进行句子嵌入。

用BERT构建自定义FAQ聊天机器人 四海 第3张

Elasticsearch是一个开源的搜索和分析引擎,具有强大的实时处理能力、高度可扩展性,并专为处理大规模数据而设计。它基于Apache Lucene库开发,提供全文搜索功能。Elasticsearch具有高度可扩展性,因为它提供了一个高度分布式的网络,可以跨多个节点进行扩展,提供高可用性和容错性。它还提供了一个灵活而强大的RESTful API,允许使用HTTP请求与搜索引擎进行交互。它支持各种编程语言,并提供客户端库以便于应用程序集成。

本文将教我们如何使用预训练的BERT和Elasticsearch创建FAQ聊天机器人。

步骤1)安装SBERT库

#安装sentence transformers库
pip install sentence-transformers

步骤2)生成问题嵌入

我们将使用SBERT库为预定义的问题获取嵌入。对于每个问题,它将生成一个维度为768的numpy数组,该维度等于通用BERT标记级别嵌入的大小:

from sentence_transformers import SentenceTransformer

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

questions = [

    "如何提高你的对话技巧? ",

    "谁决定印度的总督任命? ",

    "赚钱的最佳方式是什么?",

    "印度政府的负责人是谁?",

    "如何提高我的英语口语能力? "

]

ques_embedd = sent_transformer.encode(questions)

步骤3)安装Elasticsearch库

pip install elasticsearch

第四步)创建Elasticsearch索引

from elasticsearch import Elasticsearch


# 定义Elasticsearch的Python客户端
es_client = Elasticsearch("localhost:9200")

INDEX_NAME = "chat_bot_index"


# numpy数组的索引维度,即768
dim_embedding = 768

def create_index() -> None:

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

    es_client.indices.create(

        index=INDEX_NAME,

        ignore=400,

        body={

            "mappings": {

                "properties": {

                    "embedding": {

                        "type": "dense_vector",

                        "dims": dim_embedding,

                    },

                    "question": {

                        "type": "text",

                    },

                    "answer": {

                        "type": "text",

                    }

                }

            }

        }

    )



create_index()

在Elasticsearch中创建索引的过程与在任何数据库中定义模式的过程非常相似。在上面的代码中,我们创建了一个名为“chat_bot_index”的索引,定义了三个字段,即“embedding”,“question”和“answer”,以及它们的类型,即对于“embeddings”是“dense_vector”,对于其他两个是“text”。

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=INDEX_NAME,
  
              body=data
  
          )
  
 

qa_pairs = [{

    "question": "如何提高对话技巧? ",

    "answer": "多说话",

},{

    "question": "谁决定印度的总统任命? ",

    "answer": "印度总统",

},{

    "question": "如何提高英语口语能力? ",

    "answer": "多练习",

}]

indexing_q(qa_pairs)

在上述代码中,我们使用问题的嵌入将问题-答案对索引到Elasticsearch数据库中。

第六步)从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=INDEX_NAME,
          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("如何使我的英语流利?")#import csv

我们可以通过在ES查询中包含一个“script”字段来修改ES查询,从而创建一个计算嵌入余弦相似度得分的评分函数。将此得分与整体ES BM25匹配得分相结合。要调整嵌入余弦相似度的权重,可以修改名为“ENCODER_BOOST”的超参数。

结论

在本文中,我们探讨了在创建聊天机器人中应用SBERT和Elasticsearch的方法。我们讨论了创建一个能够根据预定义的问题-答案对回答查询的聊天机器人,考虑到查询的意图。

以下是我们探索的关键要点:

  1. 了解SBERT和Elasticsearch在聊天机器人开发领域的重要性,利用它们的功能来增强对话体验。
  2. 利用SBERT生成问题的嵌入,实现对其语义和上下文的深入理解。
  3. 利用Elasticsearch建立一个索引,高效地存储和组织问题-答案对,优化搜索和检索操作。
  4. 演示了在Elasticsearch中查询的过程,展示了聊天机器人根据用户的问题有效地检索最相关的答案。

常见问题

本文中显示的媒体不归Analytics Vidhya所有,仅由作者自行选择使用。

Leave a Reply

Your email address will not be published. Required fields are marked *