聊天机器人已经逐渐成为许多组织用于各种目的的常见且有价值的工具。它们在不同行业中有着众多应用,例如为客户提供个性化的产品推荐,为客户提供全天候的客户支持以解决查询问题,协助客户预订等等。
本文探讨了创建专门用于客户互动的常见问题解答(FAQ)聊天机器人的过程。FAQ聊天机器人处理特定领域内的问题,利用预定义的问题和相应的答案列表。这种类型的聊天机器人依赖于语义问题匹配作为其基本机制。
BERT,全称为“Bidirectional Encoder Representations from Transformers”,是谷歌于2018年推出的大型语言模型。与单向模型不同,BERT是基于Transformer架构的双向模型。它通过考虑在句子中出现在它之前和之后的词语,从而学习理解一个词语的上下文,实现了更全面的理解。
BERT面临的一个主要挑战是,它无法在自然语言处理任务中达到最先进的性能。主要问题是令牌级别的嵌入无法有效地用于文本相似性,从而在生成句子嵌入时表现不佳。
然而,为了解决这个挑战,出现了Sentence-BERT(SBERT)。SBERT基于Siamese网络,一次性接受两个句子,并使用BERT模型将它们转换为令牌级别的嵌入。然后,它对每组嵌入应用汇聚层以生成句子嵌入。在本文中,我们将使用SBERT进行句子嵌入。
Elasticsearch是一个开源的搜索和分析引擎,非常强大且高度可扩展,专门设计用于实时处理大量数据。它构建在Apache Lucene库的基础上,提供全文搜索功能。
Elasticsearch高度可扩展,因为它提供了一个高度分布式的网络,可以跨多个节点进行扩展,从而提供高可用性和容错性。它还提供了一个灵活且强大的RESTful API,允许通过HTTP请求与搜索引擎进行交互。它支持多种编程语言,并提供客户端库以便于应用集成。
本文将教我们使用预训练的 BERT 和 Elasticsearch 创建一个 FAQ 聊天机器人。
#install sentence transformers library
pip install sentence-transformers
我们将使用 SBERT 库来获取预定义问题的嵌入。对于每个问题,它将生成一个维度为 768 的 numpy 数组,这相当于一般 BERT 令牌级别嵌入的大小:
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)
pip install elasticsearch
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”。
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数据库中索引了问答对。
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的方法。我们讨论了如何创建一个根据预定义的问题-答案对来回答查询的聊天机器人,考虑查询的意图。
以下是我们探索的主要要点:
Q1. SBERT 与 BERT 有何不同?
答:SBERT扩展了BERT以对句子级语义进行编码,而BERT专注于单词级表示。SBERT将整个句子视为单个输入序列,生成捕捉整个句子含义的嵌入。
Q2。SBERT 可以用来做什么?
答. 在各种自然语言处理任务中使用SBERT,例如语义搜索、句子相似性、聚类、信息检索和文本分类。它使得可以比较和分析句子之间的语义相似性。
Q3。SBERT 可以处理长文档吗?
答:SBERT主要设计用于句子级别的嵌入。然而,它也可以处理短段落或文本片段。对于较长的文档,常见的方法是提取句子级别的表示,并使用平均或池化等技术进行聚合。
Q4。Elasticsearch 是如何工作的?
答:Elasticsearch作为一个分布式系统运行,数据被分成多个分片,可以分布在集群中的不同节点上。每个分片包含数据的一个子集,并且具备完全功能,允许高效的并行处理和高可用性。当执行搜索查询时,Elasticsearch使用分布式搜索协调机制将查询路由到相关的分片,同时执行并行搜索操作,并在将结果返回给用户之前将结果合并。
✄-----------------------------------------------