使用嵌入比较文本#
在本教程中,您将学习如何创建一个 Python 应用程序,该应用程序使用语义嵌入和 Levenshtein 相似性来比较两个输入文本。应用程序与 API 服务器通信以生成嵌入,并以编程方式计算相似性指标。
嵌入是文本字符串含义的数字表示形式。相似的文本字符串将具有相似的数字,并且数字越接近,主题就越密切相关,即使单词不同。例如,单词 “vision” 和 “sight” 可能由于含义相似而具有数字上接近的嵌入。
- 先决条件
在开始之前,请确保您的计算机上安装了 conda 包管理器。您可以安装
conda
使用 Anaconda Distribution 或 Miniconda。您必须具有
sentence-similarity
键入 model downloaded onto your local machine。
设置环境#
在处理新的 conda 项目时,建议您创建一个新的开发环境。按照以下步骤为嵌入应用程序设置环境:
打开 Anaconda Prompt(macOS/Linux 上的终端)。
提示
如果愿意,可以从 IDE(JupyterLab、PyCharm、VSCode、Spyder)中打开此终端。
通过运行以下命令创建 conda 环境以开发嵌入应用程序并安装所需的包:
conda create --name content-compare python numpy scikit-learn python-Levenshtein requests
通过运行以下命令激活新创建的 conda 环境:
conda activate content-compare
有关管理环境的更多信息和最佳实践,请参阅运行环境。
构建文本比较器#
下面,您将找到构建文本比较器所需的代码片段,以及每个步骤的解释,以帮助您了解应用程序的工作原理。文本比较器结合了两种比较文本的方法:使用嵌入的语义相似性和使用 Levenshtein 距离的结构相似性。
语义相似性告诉我们两个文本的含义有多接近,而 Levenshtein 距离通过计算将一个字符串转换为另一个字符串所需的编辑来查看实际字符的相似程度。总之,这些方法可以帮助我们了解两个文本字符串的相似程度 - 无论它们看起来相似、含义相同,还是两者兼而有之。
使用首选 IDE,创建一个新文件并为其命名similarian.py
.
导入库#
我们正在构建的应用程序需要库来处理 HTTP 请求、数值运算和字符串相似性计算。
将以下代码行添加到similarian.py
文件:
import requests import numpy as np from sklearn.metrics.pairwise import cosine_similarity import Levenshtein
设置base_url
#
为了让应用程序以编程方式处理文本输入以运行服务器健康检查、生成嵌入和执行其他作,正确构建应用程序以与 API 服务器及其端点交互至关重要。
这些 API 端点的 URL 是通过组合base_url
使用特定的/endpoint
对于每个函数。这base_URL
可以通过组合 Anaconda AI Navigator 中指定的服务器地址和服务器端口来构造,如下所示:http://<SERVER_ADDRESS>:<SERVER_PORT>
.
将base_url
通过将以下行添加到您的文件来指向默认服务器地址。
base_url = 'http://localhost:8080'提示
localhost
和127.0.0.1
在语义上相同。
添加 API 调用#
AI Navigator 利用 llama.cpp 的规范与 API 服务器的/embedding
端点。
提示
API 服务器还与 OpenAI 的
/embeddings
API 规范。
要使您的应用程序能够与 API 服务器通信,您必须实现以服务器可以理解的方式进行 API 调用的函数。
GET /health#
在向服务器发送任何请求之前,最好验证服务器是否正常运行。此函数将 GET 请求发送到/health
endpoint 并返回一个 JSON 响应,告诉您服务器的状态。
将以下行添加到similarian.py
文件:
def get_server_health(): response = requests.get(f'{base_url}/health') return response.json()
POST /嵌入#
要与sentence-similarity
model 中,您必须有一个函数来命中服务器的/embedding
端点。此函数处理输入文本并返回其向量表示形式(嵌入)。
将以下行添加到similarian.py
文件:
def get_embedding(input_text):
data = {"content": input_text}
headers = {"Content-Type": "application/json"}
response = requests.post(f"{base_url}/embedding", json=data, headers=headers)
if response.status_code == 200:
return response.json()["embedding"]
else:
raise Exception(f"Error: {response.status_code}, {response.text}")
构造函数#
现在我们已经添加了 API 调用来与 API 服务器通信,我们需要构建应用程序的核心功能:比较两个文本字符串。这涉及测量它们的语义 (基于意义) 和结构 (基于字符) 的相似性。
compare_texts
#
此函数从main
函数并计算语义和结构相似性分数。
将以下行添加到similarian.py
文件:
def compare_texts(text1, text2):
# Get embeddings and calculate semantic similarity
emb1 = get_embedding(text1)
emb2 = get_embedding(text2)
semantic_sim = cosine_similarity(
np.array(emb1).reshape(1, -1),
np.array(emb2).reshape(1, -1)
)[0][0]
# Calculate Levenshtein similarity
distance = Levenshtein.distance(text1.lower(), text2.lower())
max_length = max(len(text1), len(text2))
levenshtein_sim = 1 - (distance / max_length)
return semantic_sim, levenshtein_sim
main
#
这main
function 将其余函数绑定在一起并处理用户输入。它从用户那里获取两个输入,并显示相似度计算的结果。
将以下行添加到similarian.py
文件:
def main():
print("Enter two sentences to compare:")
text1 = input("Sentence 1: ")
text2 = input("Sentence 2: ")
print("\nCalculating similarities...")
try:
semantic_sim, levenshtein_sim = compare_texts(text1, text2)
print("\nResults:")
print(f"Semantic (embedding) similarity: {semantic_sim:.2%}")
print(f"Levenshtein (string) similarity: {levenshtein_sim:.2%}")
except requests.exceptions.ConnectionError:
print("\nError: Could not connect to embedding server at localhost:8080")
print("Make sure your local embedding server is running")
if __name__ == "__main__":
main()
与 API 服务器交互#
构建好文本比较器后,是时候比较一些文本了!
打开 Anaconda AI Navigator 并将模型加载到 API 服务器中。
注意
这必须是
sentence-similarity
type model!将 Server Address 和 Server Port 保留为默认值,然后单击 开始。
打开终端并导航到您存储
similarian.py
文件。提示
确保您仍在
content-compare
conda 环境。通过运行以下命令启动文本比较器:
python similarian.py
注意
每次要运行文本比较器时,您都需要运行此命令。
输入文本字符串,然后按 Enter 键 (Windows)/Return 键 (Mac)。
输入要与上一个字符串进行比较的文本字符串,然后再次按 Enter 键 (Windows)/Return 键 (Mac)。
查看 Anaconda AI Navigator API 服务器日志。如果一切都设置正确,服务器日志将填充来自应用程序的流量,从运行状况检查开始。
下面是一个与文本比较器交互的示例,假设您之前已经导航到包含similarian.py
文件:
(content-compare) ➜ python similarian.py
Sentence 1: That book was amazing! I did not see that twist coming!
Sentence 2: That tome was naught but wondrous! The twist therein didst elude mine keenest foresight.
Calculating similarities...
Results:
Semantic (embedding) similarity: 72.61%
Levenshtein (string) similarity: 31.82%
比较句子#
以下是一些示例,您可以使用这些示例来更好地了解和感受文本比较的工作原理:
同义词和改写
尝试以两种不同的方式编写相同的短语,以查看语义含义相似性如何保持高水平,即使结构相似性差异很大。
The quick brown fox jumped over the lazy dog.The swift auburn fox leaped above the sluggish canine.
错别字的影响
尝试使用细微的拼写错误来观察语义相似性如何保持一致,而结构相似性如何由于编辑距离的增加而下降。
The quick brown fox jumps over the lazy dog.The quikc brn fox jumpd ovr the lazy dog.
相反的含义
比较结构相似但含义相反的句子。这突出了即使 Levenshtein 相似度仍然很高,语义相似度也会下降。
I love dogs; they are the best.
I hate dogs; they are the worst.
后续步骤#
您可以继续开发和扩展此文本比较器以处理更高级的使用案例,例如实施数据库来存储嵌入以进行大规模高效比较,从而允许您构建重复内容检测器、推荐系统或文档聚类应用程序等工具。
或者,如果您已完成此项目,则可以通过运行以下命令删除该文件并清理 conda 环境:
conda deactivate conda remove --name content-compare --all