聊天机器人已经逐渐成为许多组织用于各种目的的常见且有价值的工具。它们在不同行业中有着众多应用,例如为客户提供个性化的产品推荐,为客户提供全天候的客户支持以解决查询问题,协助客户预订等等。
本文探讨了创建专门用于客户互动的常见问题解答(FAQ)聊天机器人的过程。FAQ聊天机器人处理特定领域内的问题,利用预定义的问题和相应的答案列表。这种类型的聊天机器人依赖于语义问题匹配作为其基本机制。
学习目标
- 了解 BERT 模型的基础知识
- 了解 Elasticsearch 及其在聊天机器人中的应用
- 创建聊天机器人的机制
- Elasticsearch 中的索引和查询
目录
- 什么是 BERT?
- 什么是Elasticsearch?
- 如何使用 BERT 和 Elastic Search 创建聊天机器人?
- 结论
- 常见问题
什么是 BERT?
BERT,全称为“Bidirectional Encoder Representations from Transformers”,是谷歌于2018年推出的大型语言模型。与单向模型不同,BERT是基于Transformer架构的双向模型。它通过考虑在句子中出现在它之前和之后的词语,从而学习理解一个词语的上下文,实现了更全面的理解。
BERT面临的一个主要挑战是,它无法在自然语言处理任务中达到最先进的性能。主要问题是令牌级别的嵌入无法有效地用于文本相似性,从而在生成句子嵌入时表现不佳。
然而,为了解决这个挑战,出现了Sentence-BERT(SBERT)。SBERT基于Siamese网络,一次性接受两个句子,并使用BERT模型将它们转换为令牌级别的嵌入。然后,它对每组嵌入应用汇聚层以生成句子嵌入。在本文中,我们将使用SBERT进行句子嵌入。
什么是 Elasticsearch ?
Elasticsearch是一个开源的搜索和分析引擎,非常强大且高度可扩展,专门设计用于实时处理大量数据。它构建在Apache Lucene库的基础上,提供全文搜索功能。
Elasticsearch高度可扩展,因为它提供了一个高度分布式的网络,可以跨多个节点进行扩展,从而提供高可用性和容错性。它还提供了一个灵活且强大的RESTful API,允许通过HTTP请求与搜索引擎进行交互。它支持多种编程语言,并提供客户端库以便于应用集成。
如何使用 BERT 和 Elastic Search 创建聊天机器人?
本文将教我们使用预训练的 BERT 和 Elasticsearch 创建一个 FAQ 聊天机器人。
步骤1)安装SBERT库
代码语言:javascript复制#install sentence transformers library
pip install sentence-transformers
步骤 2) 生成问题嵌入
我们将使用 SBERT 库来获取预定义问题的嵌入。对于每个问题,它将生成一个维度为 768 的 numpy 数组,这相当于一般 BERT 令牌级别嵌入的大小:
代码语言:javascript复制from sentence_transformers import SentenceTransformer
sent_transformer = SentenceTransformer("bert-base-nli-mean-tokens")
questions = [
"How to improve your conversation skills? ",
"Who decides the appointment of Governor in India? ",
"What is the best way to earn money online?",
"Who is the head of the Government in India?",
"How do I improve my English speaking skills? "
]
ques_embedd = sent_transformer.encode(questions)
步骤 3)安装Elasticsearch库
代码语言:javascript复制pip install elasticsearch
步骤 4)在Elasticsearch中创建索引
代码语言:javascript复制from elasticsearch import Elasticsearch
# defingin python client for elastic search
es_client = Elasticsearch("localhost:9200")
INDEX_NAME = "chat_bot_index"
#index dimensions for numpy array i.e. 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”。
步骤 5) 在 Elastic Search 中索引问题答案
代码语言:javascript复制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": "How to improve your conversation skills? ",
"answer": "Speak more",
},{
"question": "Who decides the appointment of Governor in India? ",
"answer": "President of India",
},{
"question": "How can I improve my English speaking skills? ",
"answer": "More practice",
}]
indexing_q(qa_pairs)
在上面的代码中,我们使用问题的嵌入在Elastic Search数据库中索引了问答对。
步骤6)从Elasticsearch查询
代码语言:javascript复制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("How to make my English fluent?")#import csv
我们可以通过包含一个“script”字段来修改ES查询,从而创建一个评分函数,该函数计算嵌入的余弦相似性分数。将此分数与整体的ES BM25匹配分数结合起来。为了调整嵌入余弦相似性的权重,我们可以修改名为“ENCODER_BOOST”的超参数。
结论
在本文中,我们探讨了在创建聊天机器人方面应用SBERT和Elasticsearch的方法。我们讨论了如何创建一个根据预定义的问题-答案对来回答查询的聊天机器人,考虑查询的意图。
以下是我们探索的主要要点:
- 理解SBERT和Elasticsearch在聊天机器人开发领域的重要性,利用它们的能力来增强会话体验。
- 利用SBERT为问题生成嵌入,可以更深入地理解其语义和上下文。
- 利用Elasticsearch建立索引,有效存储和组织问题-答案对,优化搜索和检索操作。
- 演示Elasticsearch中的查询过程,展示聊天机器人如何根据用户的问题有效地检索最相关的答案。
常见问题
Q1. SBERT 与 BERT 有何不同?
答:SBERT扩展了BERT以对句子级语义进行编码,而BERT专注于单词级表示。SBERT将整个句子视为单个输入序列,生成捕捉整个句子含义的嵌入。
Q2。SBERT 可以用来做什么?
答. 在各种自然语言处理任务中使用SBERT,例如语义搜索、句子相似性、聚类、信息检索和文本分类。它使得可以比较和分析句子之间的语义相似性。
Q3。SBERT 可以处理长文档吗?
答:SBERT主要设计用于句子级别的嵌入。然而,它也可以处理短段落或文本片段。对于较长的文档,常见的方法是提取句子级别的表示,并使用平均或池化等技术进行聚合。
Q4。Elasticsearch 是如何工作的?
答:Elasticsearch作为一个分布式系统运行,数据被分成多个分片,可以分布在集群中的不同节点上。每个分片包含数据的一个子集,并且具备完全功能,允许高效的并行处理和高可用性。当执行搜索查询时,Elasticsearch使用分布式搜索协调机制将查询路由到相关的分片,同时执行并行搜索操作,并在将结果返回给用户之前将结果合并。
✄-----------------------------------------------