使用 AI [特殊字符][特殊字符][特殊字符]开发一个支持 50 多种语言的表情符号语义搜索引擎

张开发
2026/4/17 14:42:05 15 分钟阅读

分享文章

使用 AI [特殊字符][特殊字符][特殊字符]开发一个支持 50 多种语言的表情符号语义搜索引擎
原文towardsdatascience.com/semantic-search-for-emojis-in-50-languages-using-ai-f85a36a86f21?sourcecollection_archive---------7-----------------------#2024-07-17使用 Python 和开源 NLP 库开发一个 AI 驱动的表情符号语义搜索引擎https://medium.com/badr.alabsi?sourcepost_page---byline--f85a36a86f21--------------------------------https://towardsdatascience.com/?sourcepost_page---byline--f85a36a86f21-------------------------------- Badr Alabsi, 博士·发表于Towards Data Science ·阅读时长 12 分钟·2024 年 7 月 17 日–https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4e4b22aa4d5eedea4c9699b59de728b5.png如果你常用社交媒体如 Twitter 或 LinkedIn你可能注意到表情符号在非正式和正式的文本交流中被创造性地使用。例如火箭 表情符号常在 LinkedIn 上表示高远的抱负和雄心壮志而靶心 表情符号则用于表示目标达成。尽管表情符号的创造性使用日益增长但大多数社交媒体平台缺乏帮助用户选择合适表情符号以有效传达信息的工具。因此我决定投入时间开发一个名为 Emojeez 的项目它是一个 AI 驱动的表情符号搜索和检索引擎。你可以通过这个有趣的互动演示体验 Emojeez 。在这篇文章中我将讨论我的经验并解释我如何运用先进的自然语言处理NLP技术开发一个语义搜索引擎用于表情符号。具体来说我将展示一个基于嵌入的语义搜索案例并按以下步骤进行讲解如何使用大语言模型生成语义丰富的表情符号描述如何使用 Hugging Face Transformers进行多语言嵌入如何集成Qdrant‍向量数据库以执行高效的语义搜索我已将该项目的完整代码上传至GitHub。灵感每一个新想法通常都始于一闪而过的灵感。对我来说这个灵感来自 Luciano Ramalho 的书《流畅的 Python》。这是一本非常棒的书强烈推荐给所有喜欢编写真正 Pythonic 代码的人。在书的第四章Luciano 展示了如何通过查询 Unicode 标准中的字符名称来搜索 Unicode 字符。他创建了一个 Python 工具它能够处理像“cat smiling”这样的查询检索所有名称中同时包含“cat”和“smiling”的 Unicode 字符。对于“cat smiling”这个查询该工具可以检索到三个表情符号、 和 。很酷对吧从那里开始我开始思考如何利用现代人工智能技术来构建一个更好的表情符号搜索工具。所谓的“更好”我设想的是一个不仅覆盖更多表情符号还能支持多语言用户查询的搜索引擎超越英语。关键词搜索的局限性 如果你是表情符号爱好者你一定知道、 和 不是唯一的笑脸猫表情符号。确实有些猫咪表情符号是缺失的特别是 和 。这是关键词搜索算法的一个已知限制关键词搜索依赖于字符串匹配来检索相关项目。关键词搜索或词汇搜索算法在信息检索领域被认为精确度高但召回率低。高精度意味着检索到的项目通常与用户查询匹配得很好。另一方面低召回率意味着算法可能不会检索到所有相关项目。在许多情况下较低的召回率是由于字符串匹配造成的。例如表情符号 的名字中没有“smiling”微笑——带着喜悦的泪水的猫。因此如果我们搜索“猫”和“微笑”这两个词它就无法被检索到。词汇搜索的另一个问题是它通常是语言特定的。在 Luciano 的《流畅的 Python》例子中你无法使用其他语言的查询来查找表情符号因为所有 Unicode 字符包括表情符号都是用英语命名的。为了支持其他语言我们需要先通过机器翻译将每个查询转换成英语。这会增加更多的复杂性并且可能并不适用于所有语言。不过嘿已经是 2024 年了人工智能取得了长足的进步。现在我们已经有了应对这些限制的解决方案。在本文的其余部分我将向你展示如何实现。基于嵌入的语义搜索 ✨近年来随着深度神经网络在自然语言处理NLP领域的普及出现了一种新的搜索范式。在这种范式中搜索算法不再关注构成搜索数据库或查询的字符串。相反它基于文本的数值表示进行操作这些表示被称为向量嵌入。在基于嵌入的搜索算法中无论是文本文档还是视觉图像搜索项首先会被转换为向量空间中的数据点以便语义相关的项彼此接近。嵌入技术使我们能够基于表情符号描述的意义而非名称中的关键词执行相似性搜索。由于它们基于语义相似性而非关键词相似性来检索项基于嵌入的搜索算法被称为语义搜索。使用语义搜索进行表情符号检索解决了两个问题我们可以超越关键词匹配利用表情符号描述与用户查询之间的语义相似性。这提高了检索到的表情符号的覆盖率从而提高了召回率。如果我们将表情符号表示为多语言嵌入空间中的数据点我们就可以支持用英语以外的语言编写的用户查询而无需翻译成英语。这是不是很酷让我们来看看 第一步使用 LLM 生成丰富的表情符号描述 如果你使用社交媒体你可能知道很多表情符号几乎从未按字面意思使用。例如和很少表示茄子和桃子。社交媒体用户在给表情符号赋予超越字面意义的含义时非常有创意。这种创意限制了 Unicode 标准中表情符号名称的表达性。一个显著的例子是表情符号它在 Unicode 名称中简单地被描述为彩虹然而它通常在与多样性、和平和 LGBTQ社区相关的语境中使用。为了构建一个有用的搜索引擎我们需要为每个表情符号生成一个丰富的语义描述定义该表情符号代表什么以及它象征什么。鉴于当前 Unicode 标准中有超过 5000 个表情符号手动完成这一任务是不可行的。幸运的是我们可以利用大型语言模型LLM来帮助我们为每个表情符号生成元数据。由于 LLM 是基于整个互联网进行训练的它们很可能已经见识过每个表情符号在不同语境中的使用方式。对于这项任务我使用了Llama 3大型语言模型LLM为每个表情符号生成元数据。我编写了一个提示定义了任务和 LLM 需要执行的操作。如下面的图所示LLM 为靶心表情符号生成了丰富的语义描述。这些描述相比于 Unicode 名称更适合进行语义搜索。我将 LLM 生成的描述发布为 Hugging Face 数据集。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ceeef194babbfb0bcd16d0b4f158e06c.png使用 Llama 3 LLM 生成表情符号的丰富语义描述。第 2 步使用句子变换器将表情符号表示为嵌入 现在我们拥有了每个表情符号在 Unicode 标准中的丰富语义描述下一步是将每个表情符号表示为一个向量嵌入位于一个多维空间中该空间捕捉了表情符号描述的含义。为此任务我使用了基于BERT架构的多语言变换器并针对 50 种语言的句子相似性进行了微调。您可以在 Hugging Face 库中的模型卡片上查看支持的语言。到目前为止我只讨论了由 LLM 生成的表情符号描述的嵌入这些描述是英文的。但是我们如何支持英文以外的语言呢好的接下来就是多语言变换器的魔力所在。通过嵌入空间本身启用了多语言支持。这意味着我们可以用任何 50 种支持的语言输入用户查询并根据它们的英文描述将查询与表情符号匹配。多语言句子编码器或嵌入模型将语义相似的文本短语映射到其嵌入空间中的相邻点。让我通过以下插图来展示我的意思。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c4f1cb844d59ebb3ee7160335f3365e3.png这是一个多语言嵌入空间的视觉示意图其中句子和短语根据其语义相似性在几何上组织无论文本语言如何。图中的阿拉伯语和中文文本是“Cat smiling”短语的字面翻译。在上面的图中我们看到语义相似的短语最终成为嵌入空间中相邻的数据点即使它们是用不同的语言表达的。多语言句子变换器使跨语言搜索应用成为可能因此用户查询和索引的搜索项不必使用相同的语言。第 3 步集成 Qdrant 的向量数据库 ‍一旦我们将表情符号表示为向量嵌入下一步就是在这些嵌入上构建索引以便进行高效的搜索操作。为此我选择了使用Qdrant这是一个开源的向量相似性搜索引擎提供高性能的搜索功能。为此任务设置 Qdrant 非常简单下面是代码片段您还可以查看这个 Jupyter Notebook。# Load the emoji dictionary from a pickle filewithopen(file_path,rb)asfile:emoji_dict:Dict[str,Dict[str,Any]]pickle.load(file)# Setup the Qdrant client and populate the databasevector_DB_clientQdrantClient(:memory:)embedding_dict{emoji:np.array(metadata[embedding])foremoji,metadatainemoji_dict.items()}# Remove the embeddings from the dictionary so it can be used# as payload in Qdrantforemojiinlist(emoji_dict):delemoji_dict[emoji][embedding]embedding_dim:intnext(iter(embedding_dict.values())).shape[0]# Create a new collection in Qdrantvector_DB_client.create_collection(collection_nameEMOJIS,vectors_configmodels.VectorParams(sizeembedding_dim,distancemodels.Distance.COSINE),)# Upload vectors to the collectionvector_DB_client.upload_points(collection_nameEMOJIS,points[models.PointStruct(ididx,vectorembedding_dict[emoji].tolist(),payloademoji_dict[emoji])foridx,emojiinenumerate(emoji_dict)],)现在搜索索引vector_DB_client已准备好接受查询。我们需要做的就是将用户查询转换为向量嵌入使用与我们嵌入表情符号描述时相同的嵌入模型。这个过程可以通过下面的函数完成。defretrieve_relevant_emojis(embedding_model:SentenceTransformer,vector_DB_client:QdrantClient,query:str,num_to_retrieve:int)-List[str]: Return emojis relevant to the query using sentence encoder and Qdrant. # Embed the queryquery_vectorembedding_model.encode(query).tolist()hitsvector_DB_client.search(collection_nameEMOJIS,query_vectorquery_vector,limitnum_to_retrieve,)returnhits为了进一步展示检索到的表情符号、它们与查询的相似度分数以及它们的 Unicode 名称我编写了以下辅助函数。defshow_top_10(query:str)-None: Show emojis that are most relevant to the query. emojisretrieve_relevant_emojis(sentence_encoder,vector_DB_clinet,query,num_to_retrieve10)fori,hitinenumerate(emojis,start1):emoji_charhit.payload[Emoji]scorehit.score spacelen(emoji_char)3unicode_desc .join(em.demojize(emoji_char).split(_)).upper()print(f{i:3}{emoji_char:{space}},end)print(f{score:7.3f},end)print(f{unicode_desc[1:-1]:55})现在一切都准备好了我们可以看几个例子。还记得 Luciano 书中的“猫咪微笑”查询吗让我们看看语义搜索与关键词搜索有何不同。show_top_10(cat smiling)10.651CAT WITH WRY SMILE20.643GRINNING CAT WITH SMILING EYES30.611CAT WITH TEARS OF JOY40.603SMILING CAT WITH HEART-EYES50.596GRINNING CAT60.522CAT FACE70.513CAT8‍⬛0.495BLACK CAT90.468KISSING CAT100.452LEOPARD太棒了不仅仅是像 、 和 这样的猫咪表情符号被关键词搜索检索到语义搜索还检索出了微笑的猫咪表情符号 、、 和 。这展示了我之前提到的更高召回率或更广泛的检索覆盖面。的确更多的猫咪总是更好语义搜索的真正力量 前面的“猫咪微笑”示例展示了基于嵌入的语义搜索如何能够检索到更广泛、更有意义的项目从而改善整体的搜索体验。然而我认为这个例子并没有真正展示语义搜索的强大功能。想象一下你在寻找某样东西但你不知道它的名字。例如拿 这个物品来说。你知道它在英语中叫什么吗我当时是完全不知道。但我对它还是有些了解。在中东和中亚文化中 被认为能够保护人们免受“恶眼”的伤害。所以我知道它的作用但不知道它的名字。让我们通过描述“防止恶眼”来尝试用搜索引擎找到 这个表情符号。show_top_10(protect from evil eye)10.409NAZAR AMULET20.405GLASSES30.387GOGGLES40.383EYE50.382SUPERVILLAIN LIGHT SKIN TONE60.374EYES70.370SUPERVILLAIN DARK SKIN TONE8️0.369SHIELD90.366SUPERVILLAIN MEDIUM-LIGHT SKIN TONE10‍♂0.364MAN SUPERVILLAIN LIGHT SKIN TONE结果出来了原来 其实叫做Nazar Amulet纳扎护符。我学到了一些新知识 超越英语 我特别希望这个搜索引擎有一个功能那就是它能够支持尽可能多的语言除了英语之外。到目前为止我们还没有测试过这个功能。让我们通过将“防止恶眼”的短语翻译成其他语言并逐一作为查询来测试其多语言能力。以下是一些语言的结果。阿拉伯语show_top_10(يحمي من العين الشريرة)# Arabic10.442NAZAR AMULET20.430GLASSES30.414EYE40.403GOGGLES50.403EYES60.398SUPERVILLAIN LIGHT SKIN TONE70.394SEE-NO-EVIL MONKEY80.387FACE WITH PEEKING EYE90.385VAMPIRE LIGHT SKIN TONE100.383SUPERVILLAIN MEDIUM-LIGHT SKIN TONE德语show_top_10(Vor dem bösen Blick schützen)# Deutsch10.369FACE WITH MEDICAL MASK20.364FACE WITH PEEKING EYE3️0.360SHIELD40.359SEE-NO-EVIL MONKEY50.353EYES60.350HEAR-NO-EVIL MONKEY70.346EYE80.345NAZAR AMULET9‍♀️0.345WOMAN GUARD DARK SKIN TONE10‍♀0.345WOMAN GUARD DARK SKIN TONE希腊语show_top_10(Προστατέψτε από το κακό μάτι)#Greek10.497GLASSES20.484GOGGLES30.452EYE4️0.430SUNGLASSES50.430SUNGLASSES60.429EYES7️0.415EYE80.411NAZAR AMULET90.404FACE WITH PEEKING EYE100.391FACE WITH MEDICAL MASK保加利亚语show_top_10(Защитете от лошото око)# Bulgarian10.475GLASSES20.452GOGGLES30.448EYE40.418EYES5️0.412EYE60.397FACE WITH PEEKING EYE7️0.387SUNGLASSES80.387SUNGLASSES90.375SQUINTING FACE WITH TONGUE100.373NAZAR AMULET中文show_top_10(防止邪眼)# Chinese10.425GLASSES20.397GOGGLES30.392EYE40.383NAZAR AMULET50.380EYES60.370SEE-NO-EVIL MONKEY70.369FACE WITH MEDICAL MASK8️0.363SUNGLASSES90.363SUNGLASSES100.360FACE WITH PEEKING EYE日语show_top_10(邪眼から守る)# Japanese10.379SEE-NO-EVIL MONKEY20.379NAZAR AMULET30.370HEAR-NO-EVIL MONKEY40.363FACE WITH MEDICAL MASK50.363SPEAK-NO-EVIL MONKEY60.355FACE WITH PEEKING EYE7️0.355SHIELD80.351EYE90.350SUPERVILLAIN MEDIUM-LIGHT SKIN TONE100.350GLASSES对于阿拉伯语、德语、希腊语、保加利亚语、中文和日语等如此多样的语言 表情符号总是出现在前十名中这真是太吸引人了因为这些语言拥有不同的语言特征和书写系统这要归功于我们强大的多语言 句子变换器。人工智能的局限性 最后我要提到的是任何技术无论多么先进都不完美。语义搜索对于提高信息检索系统的召回率非常有帮助。这意味着即使查询和搜索索引中的项目之间没有关键词重叠我们也能检索到更多相关的项目。然而这也以牺牲精确度为代价。记住在表情符号示例中的情况在某些语言中我们想要找到的表情符号没有出现在前五个结果中。对于这个应用来说这并不是一个大问题因为即使它排在第 50 位我们快速浏览表情符号找到所需的一个也不需要太多认知负担。但在其他情况中比如搜索长文档用户可能没有耐心也没有资源浏览数十篇文档。在构建搜索引擎时开发人员需要考虑用户的认知能力以及资源限制。我为 Emojeez 搜索引擎做出的某些设计选择可能在其他应用中效果并不理想。还有一点需要提到的是已知 AI 模型会从训练数据中学习到社会文化偏见。大量文献研究表明现代语言技术如何能够放大性别刻板印象并对少数群体不公。因此我们需要意识到这些问题并在将 AI 应用于现实世界时尽力解决它们。如果你在 Emojeez 中发现了此类不良偏见和不公行为请告诉我我会尽力处理。结论在 Emojeez 项目的开发过程中我经历了一段迷人的旅程学到了很多关于如何利用现代 AI 和自然语言处理技术来解决传统关键词搜索的局限性。通过利用大语言模型来丰富表情符号的元数据、多语言转换模型来创建语义嵌入以及使用 Qdrant 进行高效的向量搜索我成功创建了一个使表情符号搜索更加有趣且在 50 多种语言中可访问的搜索引擎。虽然这个项目主要聚焦于表情符号搜索但其底层技术在多模态搜索和推荐系统中也有潜在应用。对于精通英语以外语言的读者我特别希望听到你们的反馈。Emojeez 在英语和你的母语中表现是否同样出色你是否注意到在质量或准确性上的差异请试试看告诉我你的想法。你的见解对我来说非常宝贵。感谢阅读我希望你能像我在构建 Emojeez 时一样享受探索它的乐趣。祝你愉快地搜索表情符号注意除非另有说明所有图片均由作者创作。

更多文章