概览
标准位置信息数据可以告诉您附近有什么,但往往无法回答更重要的问题:“这个区域对我来说怎么样?”用户的需求各不相同。与养狗的年轻专业人士相比,有幼儿的家庭有不同的优先事项。为了帮助他们做出有把握的决策,您需要提供反映这些特定需求的分析洞见。自定义位置得分是一项强大的工具,可帮助您实现这一价值,并打造显著差异化的用户体验。
本文档介绍了如何使用 BigQuery 中的 Places Insights 数据集创建自定义的多方面位置得分。通过将 POI 数据转换为有意义的指标,您可以丰富房地产、零售或旅游应用,并为用户提供所需的相关信息。我们还提供了一个选项,可使用 BigQuery 中的生成式 AI 来计算位置得分,这是一种强大的方法。
通过量身定制的分数提升业务价值
以下示例说明了如何将原始位置数据转换为以用户为中心的强大指标,从而增强应用功能。
- 房地产开发商可以创建“家庭友好度得分”或“通勤者理想得分”,帮助买家和租客选择符合其生活方式的理想社区,从而提高用户互动度、获得更优质的潜在客户并加快转化速度。
- 旅游和酒店行业的工程师可以构建“夜生活指数”或“观光天堂指数”,帮助旅客选择符合其度假风格的酒店,从而提高预订率和客户满意度
- 零售分析师可以生成“健身与健康指数”,根据附近的互补型商家确定新健身房或健康食品店的最佳位置,从而最大限度地提高定位合适用户群体的潜力。
在本指南中,您将学习一种灵活的三部分方法,用于直接在 BigQuery 中使用 Places 数据构建任何类型的自定义位置得分。我们将通过构建两个不同的示例得分来演示此模式:家庭友好度得分和宠物主人天堂得分。借助这种方法,您可以摆脱地点数量的限制,充分利用 Places Insights 数据集中的丰富详细属性。您可以利用营业时间、地点是否适合儿童或是否允许携带狗狗等信息,为用户创建精细而有意义的指标。
解决方案工作流程

本教程使用单个强大的 SQL 查询来构建可适应任何应用场景的自定义得分。我们将通过为一组假设的公寓房源构建两个示例得分来演示此流程。
前提条件
在开始之前,请按照这些说明设置地点洞见。
1. 打好基础:您感兴趣的地点
在创建得分之前,您需要一份要分析的营业地点列表。第一步是确保此数据以表的形式存在于 BigQuery 中。关键在于为每个位置提供一个唯一标识符,并提供一个用于存储其坐标的 GEOGRAPHY 列。
您可以使用如下查询创建并填充要评分的位置表:
CREATE OR REPLACE TABLE `your_project.your_dataset.apartment_listings`
(
id INT64,
name STRING,
location GEOGRAPHY
);
INSERT INTO `your_project.your_dataset.apartment_listings` VALUES
(1, 'The Downtowner', ST_GEOGPOINT(-74.0077, 40.7093)),
(2, 'Suburban Oasis', ST_GEOGPOINT(-73.9825, 40.7507)),
(3, 'Riverside Lofts', ST_GEOGPOINT(-73.9470, 40.8079))
-- More rows can be added here
. . . ;
对位置数据执行 SELECT * 的效果如下所示。

2. 开发核心逻辑:评分查询
确定位置后,下一步是查找、过滤和统计与您的自定义得分相关的附近地点。所有这些操作都在单个 SELECT 语句中完成。
使用地理空间搜索功能查找附近地点
首先,您需要找到“地点概览”数据集中距离每个营业地点一定距离内的所有地点。BigQuery 函数 ST_DWITHIN 非常适合此用途。我们将对 apartment_listings 表和 places_insights 表执行 JOIN,以查找半径 800 米内的所有地点。LEFT JOIN 可确保搜索结果中包含您的所有原始位置,即使附近没有找到匹配的地点也是如此。
使用高级属性过滤相关性
您可以在此处将得分的抽象概念转化为具体的数据过滤条件。对于我们的两个示例得分,相应标准有所不同:
- 对于“亲子友好度得分”,我们关注的是明确适合儿童的公园、博物馆和餐厅。
- 对于“宠物主人天堂指数”,我们会考虑公园、兽医诊所、宠物店以及允许携带狗狗进入的任何餐厅或咖啡馆。
您可以在查询的 WHERE 子句中直接过滤这些特定属性。
汇总每个位置的数据洞见
最后,您需要统计每个公寓附近有多少个相关场所。GROUP BY 子句用于汇总结果,而 COUNTIF 函数用于统计符合每项得分的特定条件的地点数量。
以下查询将这三个步骤结合在一起,只需一次计算即可得出两个得分的原始计数:
-- This Common Table Expression (CTE) will hold the raw counts for each score component.
WITH insight_counts AS (
SELECT WITH AGGREGATION_THRESHOLD -- Correctly includes the mandatory aggregation threshold
apartments.id,
apartments.name,
COUNTIF(places.primary_type = 'park') AS park_count,
COUNTIF(places.primary_type = 'museum') AS museum_count,
COUNTIF(places.primary_type = 'restaurant' AND places.good_for_children = TRUE) AS family_restaurant_count,
COUNTIF(places.primary_type IN ('veterinary_care', 'pet_store')) AS pet_service_count,
COUNTIF(places.allows_dogs = TRUE) AS dog_friendly_place_count
FROM
`your_project.your_dataset.apartment_listings` AS apartments
LEFT JOIN
`your-project.places_insights___us.places` AS places -- Corrected table name for the US dataset
ON ST_DWITHIN(apartments.location, places.point, 800) -- Find places within 800 meters
GROUP BY
apartments.id, apartments.name
)
SELECT * FROM insight_counts;
此查询的结果将类似于以下内容。

我们将在下一部分中基于这些结果进行构建。
3. 创建得分
现在,您已经获得了每个位置的地点数量和每个地点类型的权重,接下来就可以生成自定义位置得分了。本部分将讨论两种方案:在 BigQuery 中使用您自己的自定义计算,或使用 BigQuery 中的生成式人工智能 (AI) 函数。
方法 1:在 BigQuery 中使用您自己的自定义计算
上一步中的原始计数很有参考价值,但我们的目标是获得一个简单易懂的分数。最后一步是使用权重组合这些数量,然后将结果归一化到 0-10 的范围内。
应用自定义权重:选择权重既是艺术,也是科学。 它们需要反映您的业务优先级或您认为对用户最重要的内容。对于“适合家庭”得分,您可能会认为公园的重要性是博物馆的两倍。先从最佳假设入手,然后根据用户反馈进行迭代。
对得分进行归一化处理 下面的查询使用了两个通用表表达式 (CTE):第一个 CTE 用于计算原始计数(与之前一样),第二个 CTE 用于计算加权得分。最终的 SELECT 语句随后对加权得分执行最小-最大归一化。输出示例 apartment_listings 表的 location 列,以在地图上实现数据可视化。
WITH
-- CTE 1: Count nearby amenities of interest for each apartment listing.
insight_counts AS (
SELECT WITH AGGREGATION_THRESHOLD
apartments.id,
apartments.name,
COUNTIF(places.primary_type = 'park') AS park_count,
COUNTIF(places.primary_type = 'museum') AS museum_count,
COUNTIF(places.primary_type = 'restaurant' AND places.good_for_children = TRUE) AS family_restaurant_count,
COUNTIF(places.primary_type IN ('veterinary_care', 'pet_store')) AS pet_service_count,
COUNTIF(places.allows_dogs = TRUE) AS dog_friendly_place_count
FROM
`your_project.your_dataset.apartment_listings` AS apartments
LEFT JOIN
`your-project.places_insights___us.places` AS places
ON ST_DWITHIN(apartments.location, places.point, 800)
GROUP BY
apartments.id,
apartments.name
),
-- CTE 2: Apply custom weighting to the amenity counts to generate raw scores.
raw_scores AS (
SELECT
id,
name,
(park_count * 3.0) + (museum_count * 1.5) + (family_restaurant_count * 2.5) AS family_friendliness_score,
(park_count * 2.0) + (pet_service_count * 3.5) + (dog_friendly_place_count * 2.5) AS pet_paradise_score
FROM
insight_counts
)
-- Final Step: Normalize scores to a 0-10 scale and rejoin to retrieve the location geometry.
SELECT
raw_scores.id,
raw_scores.name,
apartments.location,
raw_scores.family_friendliness_score,
raw_scores.pet_paradise_score,
-- Normalize Family Score using a MIN/MAX window function.
ROUND(
COALESCE(
SAFE_DIVIDE(
(raw_scores.family_friendliness_score - MIN(raw_scores.family_friendliness_score) OVER ()),
(MAX(raw_scores.family_friendliness_score) OVER () - MIN(raw_scores.family_friendliness_score) OVER ())
) * 10,
0
),
2
) AS normalized_family_score,
-- Normalize Pet Score using a MIN/MAX window function.
ROUND(
COALESCE(
SAFE_DIVIDE(
(raw_scores.pet_paradise_score - MIN(raw_scores.pet_paradise_score) OVER ()),
(MAX(raw_scores.pet_paradise_score) OVER () - MIN(raw_scores.pet_paradise_score) OVER ())
) * 10,
0
),
2
) AS normalized_pet_score
FROM
raw_scores
JOIN
`your_project.your_dataset.apartment_listings` AS apartments
ON raw_scores.id = apartments.id;
查询结果将类似于以下内容。最后两列是归一化得分。

了解标准化得分
请务必了解此最终归一化步骤为何如此重要。原始加权得分的范围为 0 到一个可能非常大的数字,具体取决于您位置的城市密度。对于没有上下文的用户来说,500 的得分毫无意义。
归一化会将这些抽象数字转换为相对排名。通过将结果缩放到 0 到 10 之间,该得分可清晰地传达每个位置与特定数据集中的其他位置相比如何:
- 原始得分最高的地点会被分配 10 分,表示它是当前组中的最佳选项。
- 原始得分最低的位置会被分配 0 分,作为比较基准。这并不意味着该位置没有任何便利设施,而是相对于正在评估的其他选项而言,该位置最不适合。
- 所有其他得分都按比例介于两者之间,让用户能够以清晰直观的方式一目了然地比较各种选项。
选项 2:使用 AI.GENERATE 函数 (Gemini)
除了使用固定的数学公式外,您还可以使用 BigQuery AI.GENERATE 函数直接在 SQL 工作流中计算自定义位置得分。
虽然方法 1 非常适合根据设施数量进行纯粹的定量评分,但它无法轻松纳入定性数据。借助 AI.GENERATE 函数,您可以将“地点概览”查询中的数字与非结构化数据(例如公寓房源的文字说明)相结合,“此位置适合家庭入住,夜间安静”)或特定用户资料偏好设置(例如,“此用户为家人预订,偏好位于中心位置的安静区域”)。这样一来,您就可以生成更细致的分数,从而检测到严格的计数可能遗漏的细微差别,例如某个地点虽然设施密度很高,但也被描述为“对儿童来说太吵”。
构建提示
如需使用此函数,请将聚合结果(来自第 2 步)格式化为自然语言提示。您可以在 SQL 中动态执行此操作,方法是将数据列与模型指令串联起来。
在以下查询中,insight_counts 与公寓的文字说明相结合,为每一行创建提示。此外,还定义了目标用户个人资料来指导评分。
使用 SQL 生成得分
以下查询会在 BigQuery 中执行整个操作。其中包括:
- 汇总地点数量(如第 2 步中所述)。
- 为每个位置构建提示。
- 调用
AI.GENERATE函数,以使用 Gemini 模型分析提示。 - 将结果解析为结构化格式,以便在您的应用中使用。
WITH
-- CTE 1: Aggregate Place counts (Same as Step 2)
insight_counts AS (
SELECT WITH AGGREGATION_THRESHOLD
apartments.id,
apartments.name,
apartments.description, -- Assuming your table has a description column
COUNTIF(places.primary_type = 'park') AS park_count,
COUNTIF(places.primary_type = 'museum') AS museum_count,
COUNTIF(places.primary_type = 'restaurant' AND places.good_for_children = TRUE) AS family_restaurant_count
FROM
`your-project.your_dataset.apartment_listings` AS apartments
LEFT JOIN
`your-project.places_insights___us.places` AS places
ON ST_DWITHIN(apartments.location, places.point, 800)
GROUP BY
apartments.id, apartments.name, apartments.description
),
-- CTE 2: Construct the Prompt
prepared_prompts AS (
SELECT
id,
name,
FORMAT("""
You are an expert real estate analyst. Generate a 'Family-Friendliness Score' (0-10) for this location.
Target User: Young family with a toddler, looking for a balance of activity and quiet.
Location Data:
- Name: %s
- Description: %s
- Parks nearby: %d
- Museums nearby: %d
- Family-friendly restaurants nearby: %d
Scoring Rules:
- High importance: Proximity to parks and high restaurant count.
- Negative modifiers: Descriptions indicating excessive noise or nightlife focus.
- Positive modifiers: Descriptions indicating quiet streets or backyards.
""", name, description, park_count, museum_count, family_restaurant_count) AS prompt_text
FROM insight_counts
)
-- Final Step: Call AI.GENERATE
SELECT
id,
name,
-- Access the structured fields returned by the model
generated.family_friendliness_score,
generated.reasoning
FROM
prepared_prompts,
AI.GENERATE(
prompt_text,
endpoint => 'gemini-flash-latest',
output_schema => 'family_friendliness_score FLOAT64, reasoning STRING'
) AS generated;
了解配置
- 费用感知:此函数会将您的输入传递给 Gemini 模型,并且每次调用时都会在 Vertex AI 中产生费用。如果要分析大量位置(例如数千个公寓房源),建议先将数据集过滤为最相关的候选位置。如需详细了解如何最大限度地降低费用,请参阅最佳实践。
endpoint:在此示例中,我们指定了gemini-flash-latest,以优先考虑速度和成本效益。不过,您可以选择最符合您需求的型号。如需尝试使用不同的版本(例如Gemini Pro,可用于处理更复杂的推理任务),找到最适合您使用场景的模型。output_schema:强制执行架构(FLOAT64表示得分,STRING表示推理),而不是解析原始文本。这样可确保输出结果无需进行后处理,即可立即在应用或可视化工具中使用。
输出示例
该查询会返回一个标准 BigQuery 表,其中包含自定义得分和模型的推理结果。
| id | name | family_friendliness_score | 推理 |
|---|---|---|---|
| 1 | The Downtowner | 5.5 | 设施数量(公园、餐厅)非常多,满足了定量指标。不过,定性数据显示,周末噪音过大,夜生活氛围浓厚,这与目标用户对安静环境的需求直接冲突。 |
| 2 | 郊区绿洲 | 9.8 | 出色的定量数据,以及与目标家庭资料完全一致的说明(“安静的绿树成荫的街道”)。较高的正调节系数会产生接近满分的得分。 |
此过程可让您在单个 SQL 查询中提供高度个性化的评分,让每位用户都能感受到评分的合理性和量身定制性。
4. 在地图上直观呈现您的得分
对于包含 GEOGRAPHY 列的任何查询结果,BigQuery Studio 都包含集成式地图可视化图表。由于我们的查询会输出 location 列,因此您可以立即直观呈现得分。
点击 Visualization 标签页会显示地图,而 Data Column 下拉菜单用于控制要直观呈现的地理位置得分。在此示例中,normalized_pet_score 是从示例 1 中直观呈现的。请注意,在此示例中,apartment_listings 表中添加了更多位置。

直观呈现数据后,您便可一目了然地了解所创建得分最适合的位置,其中深绿色圆圈表示 normalized_pet_score 较高的位置(在本例中)。如需了解更多地点数据分析数据可视化选项,请参阅直观呈现查询结果。
总结
现在,您已经掌握了一种强大且可重复使用的方法,可以创建细致的地理位置得分。您从自己的位置信息入手,在 BigQuery 中构建了一个 SQL 查询,用于查找附近有 ST_DWITHIN 的地点,按 good_for_children 和 allows_dogs 等高级属性过滤这些地点,并使用 COUNTIF 汇总结果。通过应用自定义权重并对结果进行归一化处理,您生成了一个简单易懂的分数,可提供深入且可据以采取行动的分析洞见。您可以直接应用此模式,将原始位置数据转化为显著的竞争优势。
后续操作
现在,轮到您大显身手了。本教程提供了一个模板。您可以使用 Places Insights 架构中提供的丰富数据来创建最符合您的使用情形的分数。您可以考虑构建以下其他得分:
- “夜生活指数”:结合
primary_type(bar、night_club)、price_level和深夜营业时间过滤条件,找到夜幕降临后最热闹的区域。 - “健康与健身得分”:统计附近的
gyms、parks和health_food_stores,并过滤出提供serves_vegetarian_food的餐厅,以便为注重健康的用户提供位置得分。 - “通勤族理想之地”得分:查找附近有大量
transit_station和parking地点的位置,以帮助重视交通便利性的用户。
贡献者
Henrik Valve | DevX 工程师