近年来,随着诸如ChatGPT、Bard等生成式人工智能工具的发布,大型语言模型(LLM)在机器学习社区引起了全球热议。这些解决方案背后的核心思想之一是计算非结构化数据(如文本和图像)的数字表示,并找出这些表示之间的相似之处。
创新互联是一家专注于网站设计制作、成都网站制作与策划设计,鱼峰网站建设哪家好?创新互联做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:鱼峰等地区。鱼峰做网站价格咨询:13518219792
然而,将所有这些概念应用到生产环境中存在其自身的一系列机器学习工程挑战:
首先,我们需要找到一种将输入数据转换为向量的方法,我们称之为嵌入(如果你想深入了解嵌入概念,我推荐您阅读一下Boykis的文章《什么是嵌入?》,参考引文3:https://vickiboykis.com/what_are_embeddings/about.html)。
因此,首先让我们来看看我们可以使用NPR数据集处理什么样的数据:
import pandas as pd
df = pd.read_parquet("articles.parquet")
df.tail()
NPR数据集提供的样本数据(图片由作者本人生成)
NPR数据集提供了一些有趣的文本数据,如文章的标题和正文内容等。我们可以在嵌入生成过程中使用它们,如下图所示:
嵌入生成过程(作者本人提供的图片)
这样一来,一旦我们从输入数据中定义了文本特征,我们就需要建立一个嵌入模型来生成我们的数字表示。幸运的是,存在像HuggingFace这样的网站,你可以在那里寻找适合特定语言或任务的预训练模型。在我们的例子中,我们可以使用neuralmind/bert-base-portuguese-cased模型,该模型是用巴西葡萄牙语训练的,用于以下任务:
from sentence_transformers import SentenceTransformer
model_name = "neuralmind/bert-base-portuguese-cased"
encoder = SentenceTransformer(model_name_or_path=model_name)
title = """
Paraguaios vão às urnas neste domingo (30) para escolher novo presidente
"""
sentence = title
sentence_embedding = encoder.encode(sentence)
print (sentence_embedding)
# output: np.array([-0.2875876, 0.0356041, 0.31462672, 0.06252239, ...])
根据这里的代码逻辑,给定一个样本输入数据,我们就可以将标题和标签内容连接到单个文本中,并将其传递给编码器以生成文本嵌入。
我们可以对NPR数据集中的所有其他文章应用于上面相同的过程:
def generate_item_sentence(item: pd.Series, text_columns=["title"]) -> str:
return ' '.join([item[column] for column in text_columns])
df["sentence"] = df.apply(generate_item_sentence, axis=1)
df["sentence_embedding"] = df["sentence"].apply(encoder.encode)
请注意:上面这个过程可能需要耗费更长的时间,具体情况取决于您的机器的处理能力。
一旦我们有了所有新闻文章的嵌入;接下来,我们就可以定义一个存储它们的策略了。
由于生成嵌入可能是一个昂贵的过程;因此,我们可以使用向量数据库来存储这些嵌入并基于不同的策略执行有关查询。
目前,已经存在几个向量数据库软件可以实现这项任务,但我将在本文中选择使用Qdrant,这是一个开源解决方案,它提供了可用于python、Go和Typescript等多种流行编程语言的API支持。为了更好地比较这些向量数据库,请查看引文4来了解更多有关详情。
为了处理所有的Qdrant操作,我们需要创建一个指向向量数据库的客户端对象。Qdrant允许您创建一个免费的层服务来测试与数据库的远程连接,但为了简单起见,我选择在本地创建并保持数据库:
from qdrant_client import QdrantClient
client = QdrantClient(path="./qdrant_data")
一旦建立了这种连接,我们就可以在数据库中创建一个集合,用于存储新闻文章嵌入:
from qdrant_client import models
from qdrant_client.http.models import Distance, VectorParams
client.create_collection(
collection_name = "news-articles",
vectors_config = models.VectorParams(
size = encoder.get_sentence_embedding_dimension(),
distance = models.Distance.COSINE,
),
)
print (client.get_collections())
# output: CollectionsResponse(collectinotallow=[CollectionDescription(name='news-articles')])
请注意,代码中的向量配置参数是用于创建集合的。这些参数告诉Qdrant向量的一些属性,比如它们的大小和比较向量时要使用的距离指标(我会使用余弦相似性,不过你也可以使用例如内积或欧几里得距离等其他的计算策略)。
在最终存储到数据库之前,我们需要创建合适的上传对象。在Qdrant数据库中,向量可以使用PointStruct类存储,您可以使用该类定义以下属性:
from qdrant_client.http.models import PointStruct
metadata_columns = df.drop(["newsId", "sentence", "sentence_embedding"], axis=1).columns
def create_vector_point(item:pd.Series) -> PointStruct:
"""Turn vectors into PointStruct"""
return PointStruct(
id = item["newsId"],
vector = item["sentence_embedding"].tolist(),
payload = {
field: item[field]
for field in metadata_columns
if (str(item[field]) not in ['None', 'nan'])
}
)
points = df.apply(create_vector_point, axis=1).tolist()
最后,在将所有信息都转换成点结构后,我们就可以将它们分块上传到数据库中:
CHUNK_SIZE = 500
n_chunks = np.ceil(len(points)/CHUNK_SIZE)
for i, points_chunk in enumerate(np.array_split(points, n_chunks)):
client.upsert(
collection_name="news-articles",
wait=True,
points=points_chunk.tolist()
)
现在,既然我们已经用向量存储满集合,接下来,我们就可以开始查询数据库了。我们可以通过多种方式输入信息来查询数据库,但我认为这两种非常有用的输入可以使用:
假设我们已经成功构建了用于搜索引擎的上述向量数据库,我们希望用户的输入是一个输入文本,并且我们必须返回最相关的内容。
由于向量数据库中的所有操作都是使用向量来实现的,所以,我们首先需要将用户的输入文本转换为向量,这样我们就可以根据该输入找到类似的内容。回想一下,我们曾经使用句子转换器将文本数据编码到嵌入中;因此,我们也可以使用相同的编码器为用户的输入文本生成数字表示。
由于NPR包含了新闻文章,那么假设用户键入“Donald Trump”(唐纳德·特朗普)来了解美国大选信息:
query_text = "Donald Trump"
query_vector = encoder.encode(query_text).tolist()
print (query_vector)
# output: [-0.048, -0.120, 0.695, ...]
一旦计算出输入查询向量,我们就可以搜索集合中最接近的向量,并定义我们希望从这些向量中得到什么样的输出,比如它们的newsId、标题和主题:
from qdrant_client.models import Filter
from qdrant_client.http import models
client.search(
collection_name="news-articles",
query_vector=query_vector,
with_payload=["newsId", "title", "topics"],
query_filter=None
)
注意:默认情况下,Qdrant使用近似最近邻居算法来快速扫描嵌入,但是您也可以进行完全扫描,并带来准确的最近邻数据——请记住,这是一个更昂贵的操作。
运行上面的操作后,以下是生成的输出标题(为了更好地理解,翻译成了英语):
最后,我们可以要求向量数据库“推荐”更接近某些所需向量ID但远离不需要的向量ID的内容。期望的ID和不期望的ID分别被称为正样本和负样本,它们被认为是推荐的种子样本。
例如,假设我们有以下正样本ID:
seed_id = '8bc22460-532c-449b-ad71-28dd86790ca2'
# title (translated): 'Learn why Joe Biden launched his bid for re-election this Tuesday'
那么,我们就可以要求提供与此样本类似的内容:
client.recommend(
collection_name="news-articles",
positive=[seed_id],
negative=None,
with_payload=["newsId", "title", "topics"]
)
运行上面的操作后,以下是已翻译的输出标题:
本文向您展示了如何将LLM和向量数据库结合起来构建一个新闻推荐系统。特别提到了,使用句子转换器来实现从NPR数据集中的文本新闻文章中生成数字表示(嵌入)的方法。一旦计算出这些嵌入,就可以用这些嵌入来填充例如Qdrant这样的向量数据库,Qdrant的使用将非常有助于通过多种策略来实现向量查询。
最后,您可以基于本文提供的基础示例进行大量进一步的改进,例如:
换言之,您可以提出许多想法来改进基于LLM推荐技术的机器学习工程。所以,如果您想分享您对这些改进的想法,请毫不犹豫地给我发信息吧。
分享名称:基于大型语言模型和向量数据库开发新闻推荐系统
本文来源:http://www.mswzjz.cn/qtweb/news14/253664.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能