城市之旅:使用 LLM 和 Elasticsearch 简化地理空间搜索(一)

news2024/12/30 1:25:53

作者:来自 Elastic Philipp Kahr, Valentin Crettaz

这篇博文的本地部署实践 Jupyter notebook 请详细阅读文章 “城市之旅:使用 LLM 和 Elasticsearch 简化地理空间搜索(二)”。

探索如何从自然语言提问创建地理空间搜索。在下面的示例中,我们将演示一个请求在地铁站或兴趣点周围一定半径内的 Airbnb 房源列表的问题。你可以将这一日常用例扩展到其他地理空间搜索,例如在指定区域内寻找餐馆、景点、学校和其他地方。

我们将使用以下纽约市的数据集:

  • Airbnb 房源列表
  • 兴趣点 (point of interests - POIs)
  • MTA 地铁站

我们提供了一本 Jupyter Notebook,它将引导你完成设置数据集、将它们导入 Elasticsearch 以及设置生成式 AI 和 LLM 部分的过程。我们还会展示如何使用 Elasticsearch 进行地理空间搜索以及如何结合这两者。

我们首先需要做的事情是获取正确的数据集并准备好它们以供导入。Jupyter Notebook 中对此有更详细的描述。我们决定对 Airbnb 数据集运行 ELSER 以进行语义搜索。这意味着我们需要使用一个运行 inference 处理器并将 ELSER 作为目标的导入管道,并确保我们将字段映射为 sparse_vector。下面是一个 Airbnb 房源的 JSON 表示,仅保留了 name、 descriptions 和 amenities 重要字段。

{
    "name": "Lovely 1 bedroom rental in New York",
    "name_embedding": {
      "bed": 0.4812702,
      "studio": 0.3967694,...
    },
    "description": "My guests will enjoy easy access to everything from this centrally located place.",
    "description_embedding": {
      "parking": 0.5157142,
      "studio": 0.2493607,...
    },
    "amenities": ["Mosquito net", "Dishes and silverware", "N/A gas stove", "Refrigerator", "Babysitter recommendations", "Children's books and toys", "N/A  oven", "Air conditioning", "Toaster", "Wifi", "TV", "Security cameras on property", "Long term stays allowed", "Kitchen", "Wine glasses", "Hot water", "Rice maker", "Carbon monoxide alarm", "Bathtub", "Laundromat nearby", "Essentials", "Baking sheet", "Extra pillows and blankets", "Clothing storage", "Free parking on premises", "Smoke alarm", "Paid parking garage off premises", "Hangers", "N/A  conditioner", "Fire extinguisher", "Private hot tub", "Cleaning products", "Dining table", "Dedicated workspace", "Blender", "Safe", "Cooking basics", "Freezer", "Bed linens", "Hair dryer", "Iron", "Window guards", "Fireplace guards", "Coffee", "Heating", "N/A shampoo", "Microwave", "Free street parking"],
    "amenities_embedding": {
      "2000": 0.1171638,
      "tub": 0.8834068,...
    },
    "location": {
      "lon": -73.93711,
      "lat": 40.8015
    }
}

利用 ELSER,我们为便利 amenities、names 和 descriptions 生成了向量嵌入。嵌入帮助我们找到明确且相关的匹配项,从而帮助我们构建更好的搜索体验。用户可能会搜索靠近花园,即任何公园、花园或休闲区。因此,此查询的答案可以包含 Central Park、Botanical Garden、Convent Garden 和更多绿地。下面是用户正在搜索 Next to Central Park and Empire State Building。

{
  "text_expansion": {
      "description_embedding": {
          "model_id": ".elser_model_2_linux-x86_64",
          "model_text": "Next to Central Park and Empire State Building",
      }
  }
}

现在,它将搜索 description 字段的嵌入。对于标有 “Close to Empire State Building” 或提及 “Central Park” 的 Airbnb 房源,这当然会更准确。但它也会找到靠近这些位置但未在描述中提及的房源,具体取决于语义搜索功能。ELSER 可能知道 Bow Bridge 是位于中央公园内的一座风景优美的桥梁,因此结果中也可能出现 “Only a short walk to the iconic Bow Bridge” 的描述。

从 Python 代码示例来看,所需的整个代码如下所示:

response = client.search(
    index="airbnb-*",
    size=10,
    query={
        "text_expansion": {
            "description_embedding": {
                "model_id": ".elser_model_2_linux-x86_64",
                "model_text": "Next to Central Park and Empire State Building",
            }
        }
    },
)

这将返回靠近中央公园和帝国大厦的前 10 个 Airbnb 房源。结果将按相关性排序,而不是按任何地理测量排序。

地理空间搜索快速入门

下一步是强调进行正确的地理空间搜索。我们在 Jupyter Notebook 中提供了所有详细信息。在深入讨论细节之前,我们需要讨论几种搜索类型。在所有可用的地理搜索中,我们可以找到 geo_bounding_box 和 geo_distance,这是我们今天要关注的。

geo_distance 查询非常简单。给定一个特定的地理点(也可以使用地理形状,但这是另一篇博文的内容),你可以搜索该点周围一定半径内的所有文档。

GET /airbnb-listings/_search
{
  "query": {
    "geo_distance": {
      // The maximum radius around the location
      "distance": "1km",
      // The location of the `Empire State Building` from where you want to calculate the 1km radius.
      "location": {
        "lat": 40.74,
        "lon": -73.98
      } 
    }
  }
}

geo_bounding_box 查询稍微复杂一些。你需要提供至少两个代表矩形边界框的点,这有助于我们回答诸如 “Find me all Airbnb between Empire State Building and Central Park Bow Bridge” 之类的问题。这将确保 Bow Bridge 上方的任何 Airbnb 都被排除在搜索结果之外。当可视化时,此类搜索看起来就是这样的。

GET /airbnb-listings/_search
{
  "query": {
    "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.77,   // lat of Bow bridge
              "lon": -73.98   // lon of Empire State
            },
            "bottom_right": {
              "lat": 40.74,   // lat of Empire State
              "lon": -73.97   // lon of Bow Bridge
            }
          }
        }
  }
}

这是一个非常简单的示例,说明如何使用 Elasticsearch 进行地理空间搜索。你还可以做更多的事情,例如添加 sort 参数以按距离排序,或添加过滤器以过滤掉某些不符合你要求的 Airbnb 房产,例如太贵的房产或缺少便利设施的房产。

由于我们在 Elasticsearch 中将兴趣点索引为文档,因此我们不需要像上面那样手动指定纬度和经度。相反,我们可以使用 terms 查询来搜索兴趣点的名称。下面是如何通过 geo_bounding_box 查询搜索 Empire State Building 和 Central Park Bow Bridge 的示例。

# We first grab the location of the Empire State Building and Central Park Bow Bridge
response = client.search(
    index="points-of-interest",
    size=2,
    query={
        "terms": {
            "name": ["central park bow bridge", "empire state building"]
        }
    },
)

# for easier access we store the locations in two variables
central = {}
empire = {}
for hit in response["hits"]["hits"]:
    hit = hit["_source"]
    if "central park bow bridge" in hit["name"]:
        central = hit["location"]
    elif "empire state building" in hit["name"]:
        empire = hit["location"]

# Now we can run the geo_bounding_box query and sort it by the 
# distance first to Central Park Bow Bridge
# and then to the Empire State Building.
response = client.search(
    index="airbnb-*",
    size=50,
    query={
        "geo_bounding_box": {
          "location": {
              "top_left": {
                  "lat": central["lat"],
                  "lon": empire["lon"]
              },
              "bottom_right": {
                  "lat": empire["lat"],
                  "lon": central["lon"]
              }
          }
        }
    },
    sort=[
        {
            "_geo_distance": {
                "location": {
                  "lat": central["lat"],
                  "lon": central["lon"]
                },
                "unit": "km",
                "distance_type": "plane",
                "order": "asc"
            }
        },
                {
            "_geo_distance": {
                "location": {
                  "lat": empire["lat"],
                  "lon": empire["lon"]
                },
                "unit": "km",
                "distance_type": "plane",
                "order": "asc"
            }
        }
    ]
)

要求 LLM 提取实体

现在我们了解了地理空间搜索的工作原理,我们可以将 GenAI 和 LLM 部分添加到我们的情形中。这个想法是有一个搜索框、聊天机器人或你喜欢的任何其他东西,你可以在其中用自然语言询问在某个位置或位置附近找到你的 Airbnb 房产。在 Jupyter Notebook中,我们依靠 ChatGPT3.5 Turbo 从自然语言中提取信息并将其转换为 JSON,然后进行解析和处理。

问题

Get me the closest Airbnb within 1 mile of the Empire State Building
question="""
As an expert in named entity recognition machine learning models, I will give you a sentence from which I would like you to extract what needs to be found (location, apartment, airbnb, sight, etc) near which location and the distance between them. The distance needs to be a number expressed in kilometers. I would like the result to be expressed in JSON with the following fields: "what", "near", "distance_in_km". Only return the JSON.
Here is the sentence: "Get me the closest Airbnb between 1 miles distance from the Empire State Building"
"""

answer = oai_client.completions.create(prompt=question, model=model, max_tokens=100)
print(answer.choices[0].text)
# Output below
{
    "what": "Airbnb",
    "near": "Empire State Building",
    "distance_in_km": 1610
}

解析兴趣点

我们首先针对兴趣点索引进行搜索,并提取 Empire State Building 的地理位置。接下来,我们针对 airbnb-listings 索引进行搜索,并使用 geo_distance 查询查找距离帝国大厦 1 英里以内的所有 Airbnb 房源。然后,我们按距离对结果进行排序,并返回最接近的结果,如下所示:

Distance to Empire State Building: 0.004002111094864837 km
Title: Comfort and Convenience! 2 Units Near Bryant Park!

Distance to Empire State Building: 0.011231615140053008 km
Title: Relax and Recharge! 3 Relaxing Units, Pets Allowed

寻找无障碍地铁站

我们现在有一个由 GenAI 和 Elasticsearch 提供支持的地理空间搜索功能,但我们可以更进一步!一开始,我们还提取了地铁站列表,其中包含一个名为 ADA 的字段,这是《Americans with Disabilities Act - 美国残疾人法案》的缩写,其值可以是:

  • 0:无法访问
  • 1:完全可访问
  • 2:部分可访问

结合不同的数据集,我们可以搜索完全可访问、提供电梯通道、残疾人专用卫生间和更多便利设施的 Airbnb 房源,并确保 Airbnb 尽可能靠近完全可访问的地铁站。

用户的问题可能是,Find me all Airbnb properties within 250m in Manhatten near the Empire State Building that are fully accessible and close to a subway station that is fully accessible。GenAI 将提取信息,我们可以针对 airbnb-listings 和 mta-stations 索引进行搜索,为用户找到最佳的 Airbnb。

{
    "what": "Airbnb",
    "near": "Empire State Building",
    "accessibility": "fully accessible",
    "distance_in_km": 0.250
}

我们可以构建以下查询,搜索帝国大厦附近完全无障碍的地铁站。如果我们没有找到任何地铁站,我们可以通知用户,告诉他们帝国大厦附近没有完全无障碍的地铁站,我们应该选择另一个景点。

GET mta-stations/_search
{
  "query": {
    "bool": {
      "filter": [
        // Subway stations have `fully accessible` as `ADA` 1 value.
        {
          "term": {
            "ADA": 1
          }
        }
      ],
      "must": [
          {
            "geo_distance": {
              // The distance, 250m as in the prompt.
              "distance": "250m",
              // The location of the `Empire State Building` from where you want to calculate the 250m radius.
              "location": {
                "lon": -73.985322454067,
                "lat": 40.74842927376084
              }
            }
          }
        ]
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lon": -73.985322454067,
          "lat": 40.74842927376084
        },
        "unit": "km",
        "distance_type": "plane",
        "order": "asc"
      }
    }
  ]
}

这将返回所有可完全到达且距离帝国大厦 250 米以内的地铁站。结果按距离排序,因此最近的地铁站是结果中的第一个。这是我们使用地理空间搜索时可能遇到的问题的一个很好的例子。我们可能在 250 米范围内找不到任何东西,但可能有一个车站距离只有一米,我们仍然可以考虑它。这就是为什么我们可以运行后续查询将距离延长到 300 米。使用调整后的距离第二次运行查询将返回名为 “34 St-Herald Sq” 的站点,距离帝国大厦 254 米。

综合起来

现在我们在帝国大厦附近有一个完全无障碍的地铁站,我们可以针对 airbnb-listings 索引运行以下查询,以查找距离帝国大厦 250 米范围内所有完全无障碍的 Airbnb 房源。然后我们按距离对结果进行排序,首先按与帝国大厦的距离排序,然后按与地铁站的距离排序。

GET airbnb-listings/_search
{
  "query": {
    "bool": {
      "filter": [
        // Airbnb listings that are `fully accessible`
        {
          "text_expansion": {
            "amenities_embedding": {
                "model_id": ".elser_model_2_linux-x86_64",
                "model_text": "fully accessible"
            }
          }
        }
        ],
        "must": [
          {
            "geo_distance": {
              // The distance, 250m as in the prompt.
              "distance": "250m",
              // The location of the `Empire State Building` from where you want to calculate the 250m radius.
              "location": {
                "lon": -73.985322454067,
                "lat": 40.74842927376084
              }
            }
          }
          ]
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lon": -73.985322454067,
          "lat": 40.74842927376084
        },
        "unit": "km",
        "distance_type": "plane",
        "order": "asc"
      }
    },
    {
      "_geo_distance": {
        "location": {
          "lon": -73.985322454067,
          "lat": 40.74842927376084
        },
        "unit": "km",
        "distance_type": "plane",
        "order": "asc"
      }
    }
  ]
}

此查询现在列出了符合我们基于 ELSER 的 fully accessible 设施搜索的所有 Airbnb 房源。在答案中,sort 对象包含两个值:0.004 和 0.254,以公里为单位。因此,Airbnb 距离帝国大厦 4 米,距离地铁站 254 米。这是一个很棒的结果,我们现在可以将其返回给用户并让他们做出决定。

结论

我们在这篇博文中向你介绍了许多不同的任务和想法。我们从地理空间搜索的基础知识开始,然后添加了 GenAI 和 LLM 部分,最后将两者结合起来,创造了强大的搜索体验。我们希望你喜欢这篇博文,并学到了一些新东西。

准备好自己尝试一下了吗?开始免费试用。
想要获得 Elastic 认证吗?了解下一期 Elasticsearch 工程师培训何时举行!

原文:Geospatial search made simple with LLMs and Elasticsearch — Elastic Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1794752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15- Redis 中的 整数集合 数据结构

整数集合是 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。 1. 整数集合结构设计 整数集合本质上是一块连续内存空间,它的结构定义如下: typedef s…

​在 The Sandbox 元宇宙的 CU 超商中寻找Milk币!

CU(韩国领先的便利店)和 MiL.k(基于区块链的忠诚度整合平台)合作在 The Sandbox 推出了首款元宇宙游戏,通过独家活动在 Web2 和 Web3 之间建立联系。 在元宇宙中玩转 “Play CU X MiL.k” 体验 通过引人入胜的游戏内容…

uniapp小程序多线程 Worker 实战【2024】

需求 最近遇到个小程序异步解码的需求,采用了WebAssembly,涉及大量的计算。由于小程序的双线程模型只有一个线程处理数据,因此智能寻求其它的解决方案。查看小程序的文档,发现小程序还提供一个异步线程的Worker方案,可…

暗黑系短视频:成都鼎茂宏升文化传媒公司

暗黑系短视频:探索未知的视觉艺术 在短视频盛行的今天,各种风格和主题的作品层出不穷,其中,暗黑系短视频以其独特的魅力和深度,成都鼎茂宏升文化传媒公司吸引了众多观众的关注。这类视频往往带有一种神秘、压抑的氛围…

李良济中医课堂,助力市民健康,传播中医药文化,坚守初心扬国粹!

为了更好地传承并发扬中医文化,传播健康理念,提高民众预防疾病的意识,让广大市民感受到中医药就在我身边。 李良济中医课堂,积极走进老年大学,青年夜校,同时主动加入萌趣中草药的活动等,为市民群…

小程序集arcgis地图显示自定义坐标的功能实现记录!(学习笔记)

最近再做一个新能源回收项目,项目中有个根据回收点坐标数据显示区域内回收点位置,点击图标直接导航到该位置,及分布的需求,研究了一下,实现效果如下,实现起来很简单,代码及效果 回收点位置及分…

在编程Python的时候发生ModuleNotFoundError: No module named distutils报错怎么办

1.先查看Python版本 首先我们先去打开终端就是先widr再输入cmd 然后进去在输入Python -V要注意大小写 我的版本是3.9.7版本但是我使用的PyCharm 是 2021.1.1 x64版本没有办法主动去识别因为这个版太低了你的Python版本很高所以无法识别 2.解决方法 只需要把你的Python现版…

使用手机小程序给证件照换底色

临时遇到一个需求,需要给证件照换底色。原始图像如下 最终需要换成红底的。 本次使用一款小程序"泰世茂证件照",打开该小程序,如下图所示 单击开始制作,然后选择二寸红底,如下图所示 然后单击相…

UI 自动化中的分层设计

以前的设计 在过去 UI 自动化测试领域有一个规范的设计模式是 page object 模式。 意思是测试用例不会直接定位页面元素, 而是把每一个页面封装成一个类。 在这个类中封装页面元素。 然后测试用例调用 page 类来操作页面元素完成测试用例。如下图: 以前…

前端面试题(二)答案版

面试形式:线上面试(不露脸):时长40分钟 面试评价:由易到难,由细到全,比较不错 面试官:项目经理 面试官提问(面试题): 1、聊聊最近写的这个项目…

【Meetup】探索Apache SeaTunnel的二次开发与实战案例

在数据科技快速演进的今天,业务场景的复杂化和数据量的激增,推动了大数据技术的迅速发展,在众多开源大数据处理工具中,Apache SeaTunnel以其强大的数据集成能力,成为众多企业的首选。 但随着应用深入,企业面…

32个小众搜索网站,相信一定有你想要的

首先问你一个问题,你平时都会用什么搜索引擎来进行搜索? 下面我将推荐32个小众搜索网站,相信一定会有你想要的。 1、多吉搜索 首先对因为拒绝商业化黑客攻击、不可抗力而停止服务的多吉搜索表示哀悼,这款由个人开发的小众搜索引…

Flutter基础 -- Flutter布局练习(小项目)

目录 1. Splash 布局(第一页) 1.1 目标 1.2 当前效果图 1.3 创建 Splash 界面 1.4 设置 MaterialApp 1.5 设置 Splash 背景色 1.6 布局 Splash 界面 1.7 总结 2. Splash 圆角图片 2.1 目标 2.2 当前效果图 2.3 蓝湖下载图片 2.4 图片导入项…

QT 信号和槽 一对多关联示例,一个信号,多个槽函数响应,一个信号源如何绑定多个槽函数

在窗体里放置一个单行文本编辑控件(QLineEdit)、一个标签控件(QLabel)和一个文本浏览控件(QTextBrowser),在单行文 本编辑控件里的文本被编辑时,标签控件和文本浏览控件都会同步显示…

OpenMV学习笔记4——二维码识别

一、示例程序 按照下图顺序点击,即可打开官方在IDE中准备好的二维码实例程序: # QRCode Example # # This example shows the power of the OpenMV Cam to detect QR Codes # using lens correction (see the qrcodes_with_lens_corr.py script for hig…

【Vue】项目目录介绍和运行流程

文章目录 一、项目目录介绍二、public/index.html三、src/main.js四、运行流程 一、项目目录介绍 虽然脚手架中的文件有很多,目前咱们只需认识三个文件即可,这三个文件就决定了我们项目的运行 main.js 入口文件App.vue App根组件index.html 模板文件 我…

如何实现vue项目不同屏幕适配(2024最新)

文章目录 1.下载插件,修改px单位为rem单位2.配置vue.config.js(如下图位置所示)3.屏幕自适应4.项目实际使用 1.下载插件,修改px单位为rem单位 npm i postcss-plugin-px2rem2.配置vue.config.js(如下图位置所示) 注意在根目录下,如果没有该文…

【记录贴:分布式系列文章】

分布式系列文章目录 文章目录 分布式系列文章目录前言一、Redisq1.怎么判断是否命中缓存1. MySQL数据库如何检查询查缓存是否命中链接2.如何判断redis是否命中缓存链接 q2.Redis缓存穿透、雪崩、击穿以及分布式锁和本地锁 二、分布式q1.分布式订单号生成策略q2.接口幂等性,防止…

Crosslink-NX器件应用连载(9): USB3.0相机

作者:Hello,Panda 大家晚上好,很久没有分享设计案例了,实在是太忙了,精力十分有限,今天分享一个CrosslinkNX系列器件用作USB3.0相机的案例。其实就是分享一下使用CrosslinkNX器件设计USB3.0相机主要有两种…

腾讯云 TDMQ for Apache Pulsar 多地区高可用容灾实践

作者介绍 林宇强 腾讯云高级工程师 专注于消息队列、API网关、微服务、数据同步等 PaaS 领域。有多年的开发和维护经验,目前在腾讯云从事 TDMQ Pulsar 商业化产品方向的研发工作。 导语 本文将从四个维度,深入剖析 Pulsar 在多可用区高可用领域的容…