我正在尝试为图像实现语义/向量搜索。
为此,我使用gpt-4-mini来分析图像并通过以下提示创建数据:
你的任务是从给定的图像生成JSON数据。
以以下格式返回你的输出:
{
description: "图像的描述。仅使用相关关键词。",
text: "如果图像包含文字,在这里包括,否则删除此字段",
keywords: "描述图像的关键词",
artstyle: "图像的艺术风格",
text_language: "图像中文字的语言,否则删除此字段",
design_theme : "如果图像有一个主题(爱好、兴趣、职业等),在这里包括,否则删除此字段",
}
我得到的数据在我的眼中是相当准确的。然后我使用“text-embedding-3-small”模型嵌入JSON数据。
问题是搜索结果非常差。
例如:我有两张仅包含文字的图像。一张写着“straight outta knee surgery”,另一张写着“straight outta valhalla”。
当我搜索“straight outta”时,我必须将相似度阈值调低到0.15才能得到这两个结果。
这是我的Postgres搜索函数:
CREATE OR REPLACE FUNCTION search_design_items (
query_embedding vector(1536),
match_threshold FLOAT,
match_count INT
) RETURNS TABLE (
id BIGINT
) AS $$
BEGIN
RETURN QUERY
SELECT id
FROM public.design_management_items
WHERE 1 - (design_management_items.description_vector <=> query_embedding) > match_threshold
ORDER BY (design_management_items.description_vector <=> query_embedding) asc
LIMIT match_count;
END;
$$ LANGUAGE plpgsql;
当我使用更高的数值(0.5)时,几乎没有结果。这似乎不对,因为在每个我看过的教程中,他们都使用了0.7+的阈值
我需要做些什么来提高搜索结果的准确性?
回答:
尝试执行混合搜索。所有向量数据库都提供混合搜索功能。
正如官方Weaviate博客中所述:
混合搜索是一种结合多种搜索算法以提高搜索结果准确性和相关性的技术。 它利用基于关键词的搜索算法和向量搜索技术的最佳功能。通过利用不同算法的优势,为用户提供更有效的搜索体验。
简单来说,执行混合搜索意味着你同时使用关键词和嵌入向量进行搜索,其中你可以设置alpha
参数作为这两种方法的权重。例如,设置alpha
为0
表示仅进行关键词搜索,而设置alpha
为1
表示仅进行嵌入向量搜索。
我之前创建了一个项目,其中包含了混合搜索,你可以搜索Lex Fridman的播客洞见,而无需观看完整的剧集。查看演示。
"use server";import weaviate from "weaviate-client";import { PodcastType } from "@/app/types/podcast";// 定义并导出queryPodcasts函数export async function queryPodcasts(searchTerm: string, alpha: number) { /** * 根据搜索词和alpha值查询播客集合。 * * @param {string} searchTerm - 要查询的搜索词。 * @param {number} alpha - 用于混合搜索的alpha值。 * @return {Promise<PodcastType[]>} - 表示搜索结果的PodcastType对象数组。 */ // 连接到本地Weaviate实例 const client = await weaviate.connectToLocal(); // 获取播客集合 const podcastCollection = await client.collections.get< Omit<PodcastType, "distance"> >("Podcast"); // 在播客集合上执行混合搜索 const { objects } = await podcastCollection.query.hybrid(searchTerm, { limit: 10, alpha: alpha, returnMetadata: ["score"], returnProperties: ["number", "guest", "title", "transcription"], }); // 处理结果 const podcasts: PodcastType[] = objects.map((podcast: any) => ({ ...podcast.properties, distance: podcast.metadata?.score!!, })); // 返回播客 return podcasts;}