简介
将地理空间数据与语义数据相结合,可以释放构建强大应用的潜力。可以利用 Qdrant、Llama2 和 Streamlit 等尖端技术,以及 LlamaIndex 和 LangChain 等先进技术,创建视觉效果极佳的高效应用程序。
地理空间数据提供了物理位置信息,而语义数据则增加了意义和上下文,两者的融合开辟了一个充满可能性的世界。想象一下,轻松分析和可视化庞大的地理空间数据集,然后将其与语义洞察进行叠加,从而发现隐藏的模式和相关性。这正是高性能矢量数据库 Qdrant 发挥威力的地方。Qdrant 可以高效地存储和查询由 Hugging Face 的 LLM 生成的嵌入,从而能够快速检索相关信息。
通过将 Llama2 等自然语言处理(NLP)模型的洞察力与地理空间数据集相结合,开发人员可以创建同时理解数据的文本上下文和空间上下文的应用程序。这有助于实现更丰富、更智能的可视化,让用户获得更深入的洞察,做出更明智的决策。
在本文中,我将向你展示如何使用所有这些工具来制作出色的可视化效果。
为什么选择矢量搜索和 LLM?
为什么我们要使用矢量搜索和 LLM(大型语言模型)来创建强大的可视化工具,如 Llama2、Streamlit、Folium 和 Qdrant?
首先,矢量搜索是必不可少的,因为它能帮助我们快速高效地找到相似项目。想象一下,你有一大批数据点分布在地图上。通过矢量搜索,你可以找到在属性或特征方面与给定参考点相似的点。这种功能对于发现地理空间数据中的模式、趋势和关系至关重要。
LLM (如 Hugging Face 开发的 LLM)在这一过程中发挥着至关重要的作用。这些模型是在大量文本数据的基础上训练出来的,能够理解单词、短语和句子的上下文和含义。通过将文本输入转换为高维嵌入(表征),LLM 使我们能够将文本信息纳入可视化。
现在,让我们将这些点连接起来。像 Qdrant 这样的矢量数据库可以高效地存储和检索这些嵌入,从而实现快速准确的搜索。这意味着我们可以将矢量搜索的强大功能与 LLM 的功能无缝结合起来,创建不仅能表示地理空间数据,还能结合文本见解的可视化效果。
例如,想象一下在地图可视化中,每个点都代表新闻文章中提到的一个地点。通过使用矢量搜索和 LLM,我们可以将类似地点聚类在一起,并与相关新闻片段叠加在一起,让用户全面了解事件和话题的地理分布。
Qdrant: 矢量相似性搜索技术
让我们来谈谈 Qdrant DB,它是一款强大的工具,能让我们轻而易举地找到相似的物品。Qdrant DB是我们所说的 "矢量数据库",这意味着它善于处理数据,帮助我们找到彼此相似的事物。
那么,找到相似的东西有什么大不了的呢?这么想吧:假设你在地图上有一堆点,每个点代表一个不同的地方。有了 Qdrant DB,你就能在地图上快速找到与给定点相似的其他点。这对于寻找具有相似特征的地点或将属于同一类别的点分组等各种事情都非常有用。
Qdrant DB 最酷的一点是它能处理高维数据。这意味着它可以处理具有大量不同属性或特征的数据,使其成为自然语言处理(NLP)等任务的完美选择,在这些任务中,我们经常要处理复杂的数据结构。
不过,Qdrant DB 还有更好的地方: Qdrant DB 不仅擅长查找相似项目,而且速度非常快。这意味着,即使在处理海量数据时,你也能在眨眼之间从数据集中检索出相似项目。
使用 LlamaIndex 构建露营地搜索系统的分步指南
利用 LlamaIndex 建立露营地搜索系统为寻找完美的户外度假地点提供了令人兴奋的可能性。利用 Qdrant 和 LlamaIndex,你可以为露营者创建无缝、高效的搜索体验。
下载露营地数据
在使用 LlamaIndex 构建露营地搜索系统之前,我们先下载露营地数据。你可以通过以下链接找到该数据集: https://data.world/caroline/campgrounds
该数据集包含各种露营地的宝贵信息,包括它们的位置、设施和用户评级。下载完成后,我们将使用这些数据创建强大的可视化和搜索系统。
现在,让我们使用 LlamaIndex 和其他先进技术来构建露营地搜索系统。
安装所需库
在使用 Qdrant 实现 LlamaIndex 搜索之前,你需要安装几个库,以正确设置你的开发环境。请按照以下步骤安装必要的依赖库:
安装 Python 3.11
首先,确保你的系统已安装 Python 3.11 版本。你可以从官方网站下载 Python 3.11:https://www.python.org/downloads/release/python-3118/。
安装 Qdrant 客户端
接下来,使用 pip 安装 Qdrant 客户端库:
pip install qdrant-client
该库允许你的 Python 代码与 Qdrant 矢量数据库连接。
安装 LlamaIndex
pip install llama-index
LlamaIndex 提供用于处理和索引文本数据以进行搜索的功能。
为 Qdrant 安装 LlamaIndex 矢量存储
pip install llama-index-vector-stores-qdrant
该库可实现 LlamaIndex 和 Qdrant 之间的无缝集成,使你能够高效地索引和搜索矢量数据。
安装用于Hugging Face 的 LlamaIndex 嵌入
在本指南中,使用 Hugging Face 嵌入和 LlamaIndex,安装嵌入库:
pip install llama-index-embeddings-huggingface
该库支持使用预先训练的 Hugging Face 模型进行文本嵌入。
为 LLAMA CPP 安装 LlamaIndex LLMS
对于 LLAMA CPP 与 LlamaIndex 的集成,请安装 LLMS(大型语言模型)库:
pip install llama-cpp-python
pip install llama-index-llms-llama-cpp
LLMS 使你能够利用 LLAMA CPP 模型来执行 LlamaIndex 中的高级自然语言处理任务。
安装这些库后,你就可以在 Python 环境中使用 Qdrant 实现 LlamaIndex 的搜索功能。
将 Qdrant 连接到集群
设置 Qdrant Cloud
要开始使用 Qdrant Cloud,请按照以下步骤操作:
注册 Qdrant Cloud
访问Qdrant cloud,并注册一个帐户以访问 Qdrant Cloud 服务。
如果你是现有用户,可以登录;否则,请使用 Google 帐户或电子邮件注册。
登录后,仪表板如下图所示:
创建集群
按照给定的步骤创建集群:
输入你要添加的集群的名称。例如,我们将使用“MAPP”,然后单击“创建免费层集群”。
设置 API 密钥
要访问 Qdrant 集群,你需要设置 API 密钥。请按照以下步骤获取并使用你的 API 密钥:
如上图所示,只需点击“API Key”按钮即可生成API Key。然后,生成API Key(如下图所示)后,复制它以连接到Qdrant集群。
访问集群 URL
要访问集群 URL,请从仪表板中单击集群。你会发现显示了集群 URL,如下图所示:
使用下面提供的指南将 Qdrant 连接到你创建的集群。将占位符替换为你的实际集群 URL 和 API 密钥:
from qdrant_client import QdrantClient
# Connect Qdrant to your created cluster.
client = QdrantClient(
url="YOUR_CLUSTER_URL",
api_key="YOUR_API_KEY"
)
将“YOUR_CLUSTER_URL”替换为你的 Qdrant 集群的 URL,将“YOUR_API_KEY”替换为你的实际 API 密钥。此信息允许 Qdrant 进行身份验证并与你的集群建立连接。
加载外部数据
要将外部数据合并到你的应用程序中,你可以使用 LlamaIndex 中的 SimpleDirectoryReader 类。请按照以下步骤加载外部数据:
导入必要的模块
确保你已导入使用“SimpleDirectoryReader”类所需的模块:
from llama_index.core import SimpleDirectoryReader
该模块提供从外部源读取数据的功能。
加载外部数据
使用提供的代码从指定文件(本例中为 us_campsites.csv)加载外部数据:
# Load external data
documents = SimpleDirectoryReader(
input_files=["caroline-campgrounds/data/us_campsites.csv"]
).load_data()
print(documents)
将“caroline-campgrounds/data/us_campsites.csv”替换为外部数据文件的路径。此代码片段将指定文件中的数据加载到内存中以进行进一步处理。
输出显示从外部文件加载的数据,包括露营地详细信息,例如经度、纬度、名称、城市、代码等。
通过执行这些步骤,你可以使用 LlamaIndex 中的 SimpleDirectoryReader 类将外部数据无缝集成到你的应用程序中。
文本解析为节点
加载外部数据后,下一步是使用以下步骤将文本解析为节点:
导入必要的模块
确保你已导入使用“SentenceSplitter”和“TextNode”类所需的模块:
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.schema import TextNode
创建文本解析器
首先,使用 SentenceSplitter 类创建一个文本解析器对象:
# Parse a text in a list
text_parser = SentenceSplitter(
chunk_size=1024,
)
该文本解析器将文本分割成更小的块进行处理。
将文本分割成块
使用文本解析器将文本拆分为块:
text_chunks = []
doc_idxs = []
for doc_idx, doc in enumerate(documents):
current_text_chunks = text_parser.split_text(doc.text)
text_chunks.extend(current_text_chunks)
doc_idxs.extend([doc_idx] * len(current_text_chunks))
此代码迭代文档,将文本拆分为块,并将它们存储在列表中。
从块构造节点
从文本块构造节点:
# Construct node from the chunks
nodes = []
for idx, text_chunk in enumerate(text_chunks):
node = TextNode(
text=text_chunk,
)
src_doc = documents[doc_idxs[idx]]
node.metadata = src_doc.metadata
nodes.append(node)
此代码片段从文本块创建节点,将源文档中的元数据分配给每个节点。
通过执行这些步骤,你可以将文本解析为节点,以便在应用程序中进一步处理和分析。
嵌入节点
将文本解析为节点后,下一步是使用预先训练的语言模型和 LLAMA CPP 嵌入每个节点:
导入必要的模块
确保你已导入使用“HuggingFaceEmbedding”、“StorageContext”、“VectorStoreIndex”和“LlamaCPP”类所需的模块:
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.llama_cpp import LlamaCPP
from llama_index.core.storage.storage_context import StorageContext
from llama_index.core import VectorStoreIndex
嵌入文本节点
使用提供的代码嵌入文本节点:
# Embed the node
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en")
for node in nodes:
node_embedding = embed_model.get_text_embedding(
node.get_content(metadata_mode="all")
)
node.embedding = node_embedding
此代码迭代每个节点,提取文本内容,并使用指定的预训练语言模型将其嵌入。
初始化 LLAMA CPP
初始化 LLAMA CPP 以进行进一步处理:
# LLAMA CPP
model_url = "https://huggingface.co/TheBloke/Llama-2-13B-chat-GGUF/resolve/main/llama-2-13b-chat.Q4_0.gguf"
llm = LlamaCPP(
model_url=model_url,
model_path=None,
temperature=0.1,
max_new_tokens=256,
context_window=3900,
generate_kwargs={},
model_kwargs={"n_gpu_layers": 1},
verbose=True,
)
此代码使用指定的模型 URL 和用于生成嵌入的参数初始化 LLAMA CPP。
配置服务上下文
使用 LLAMA CPP 和嵌入模型配置服务上下文:
from llama_index.core import Settings
Settings.llm = llm
Settings.embed_model = embed_model
此步骤使用初始化的 LLAMA CPP 模型和嵌入模型设置服务上下文。
初始化向量存储和索引
使用提供的代码片段初始化向量存储、存储上下文和索引。
vector_store = QdrantVectorStore(client=client, collection_name="MAP")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents, storage_context=storage_context)
将节点添加到向量存储
将嵌入节点添加到向量存储中:
vector_store.add(nodes)
此代码将嵌入节点添加到向量存储中,以实现高效存储和检索。
通过执行这些步骤,你可以嵌入文本节点并设置必要的组件,以便在应用程序中进行进一步处理和分析。
查询检索
嵌入并存储节点后,你可以执行查询来检索相关信息:
导入必要的模块
确保你已导入使用“VectorStoreQuery”、“RetrieverQueryEngine”类所需的模块:
from llama_index.core.vector_stores import VectorStoreQuery
from llama_index.core.query_engine import RetrieverQueryEngine
设置查询模式
设置查询模式以确定要执行的搜索类型:
query_mode = "default"
这指定搜索的默认查询模式。
执行向量存储查询
对向量存储执行查询以检索相似的节点:
vector_store_query = VectorStoreQuery(
query_embedding=query_embedding, similarity_top_k=2
)
query_result = vector_store.query(vector_store_query)
print(query_result.nodes[0].get_content())
此代码使用指定的查询嵌入在向量存储上执行查询,并检索前 k 个相似节点。
检索带有分数的节点
检索节点及其相似度分数:
nodes_with_scores = []
for index, node in enumerate(query_result.nodes):
score: Optional[float] = None
if query_result.similarities is not None:
score = query_result.similarities[index]
nodes_with_scores.append(NodeWithScore(node=node, score=score))
该循环迭代查询结果节点及其相应的相似度分数,并将它们存储在列表中。
执行查询检索
定义一个函数来执行查询检索:
def _retrieve(self, query_bundle: QueryBundle) -> List[NodeWithScore]:
"""Retrieve."""
query_embedding = embed_model.get_query_embedding(
query_bundle.query_str
)
vector_store_query = VectorStoreQuery(
query_embedding=query_embedding,
similarity_top_k=self._similarity_top_k,
mode=self._query_mode,
)
query_result = vector_store.query(vector_store_query)
nodes_with_scores = []
for index, node in enumerate(query_result.nodes):
score: Optional[float] = None
if query_result.similarities is not None:
score = query_result.similarities[index]
nodes_with_scores.append(NodeWithScore(node=node, score=score))
return nodes_with_scores
该函数根据提供的查询检索节点并返回它们及其相似度分数。
初始化查询引擎并执行查询
初始化检索器查询引擎并执行查询:
retriever = _retrieve()
query_engine = RetrieverQueryEngine.from_args(
retriever, service_context=service_context
)
query_str = "Beeds Lake State Park"
response = query_engine.query(query_str)
print(str(response))
此代码使用检索器函数和服务上下文初始化查询引擎,然后使用指定的查询字符串执行查询。
通过执行这些步骤,你可以有效地从应用程序中的存储节点查询和检索相关信息。
使用 Streamlit 和 Folium 显示地图
为了在地图上可视化检索到的位置,我们利用 Streamlit 和 Folium 库。我们是这样做的:
安装必要的模块
pip install streamlit-folium
导入必要的模块
确保你已导入使用“streamlit_folium”和“streamlit”类所需的模块:
import folium
import streamlit as st
from streamlit_folium import st_folium
定义搜索和地图显示功能
# Function to perform semantic search and retrieve latitude and longitude
def search_city(place_name):
# Perform semantic search using Llama Index
response = query_engine.query(place_name)
if response:
return response.nodes[0].get_content()
# Function to display map with retrieved data
def show_map(latitude, longitude, place_name):
if latitude is not None and longitude is not None:
# Create a folium map centered around the retrieved location
m = folium.Map(location=[latitude, longitude], zoom_start=16)
# Add a marker for the retrieved location
folium.Marker([latitude, longitude], popup=place_name, tooltip=place_name).add_to(m)
# Display the map
st_data = st_folium(m, width=700)
用户输入和检索
# User input for city name
place_name = st.text_input("Enter the name of a place")
# Perform semantic search and retrieve latitude and longitude when the user submits the input
if place_name:
matched_city = search_city(place_name)
if matched_city:
latitude, longitude = matched_city["latitude"], matched_city["longitude"]
st.write(f"Retrieved location for {place_name}: Latitude - {latitude}, Longitude - {longitude}")
show_map(latitude, longitude, place_name)
else:
st.write("Place not found")
此设置允许用户输入地名、执行语义搜索并在交互式地图上可视化检索到的位置。
输出:
结论
在本文中,我们探索了 Llama2、Streamlit、Folium 和 Qdrant 的综合威力来创建露营地搜索系统。通过利用这些工具,我们能够利用地理空间数据集的功能并有效地执行高级矢量搜索。