每个人都想知道最佳的用餐地点,但是“最佳地点”本质上是主观的。当然,你可以阅读众多“镇上最佳餐厅”列表(这些列表通常都很不错!),但是我想使用数据来回答这个问题:“科罗拉多斯普林斯市的最佳餐厅是什么?”我一直在与大型语言模型(LLMs)进行很多有趣的实验,所以为什么不用它们来进行一些数据分析呢?
这个简单的问题变成了一个相当大的数据科学项目。我将其分解为几个部分。如果你只是来看结果的,那么请随意跳过。如果你对整个过程感兴趣,那么请继续阅读。
首先,我需要收集什么数据来获得一个不错的餐厅列表?
此外,我需要限制我的搜索范围。我想关注科罗拉多斯普林斯市的核心地区,所以我选择了市中心周围的15公里半径。如果一家餐厅在此范围之外,那么就不考虑了。我不想处理太多数据,只想找到好吃的食物。

我没有花太多时间思考从哪里收集数据:我想使用谷歌地图。谷歌地图已经存在很长时间了,它非常流行,拥有很多用户评论,我也熟悉可用的数据类型,而且我不想使用像Yelp(声誉不佳)或TripAdvisor(更注重度假)这样的单次平台。那么,我如何从谷歌地图获取数据呢?
我的第一想法是使用谷歌地图的API,但我不想冒着花钱的风险。我需要那笔钱来吃饭!我看到了一些第三方工具,它们可以抓取数据,但这违反了服务条款,我不想担心被谷歌生态系统封禁。
我知道谷歌地图应用程序允许您下载地图以供离线使用。那么,如果我能从手机中获取该文件并解析出餐厅信息怎么办?第一个问题是:该文件中的餐厅列表不完整,基于应用程序中的快速离线搜索。第二:我使用MacDroid扫描了手机的文件系统,但找不到该文件 ¯_(ツ)_/¯ 我没有看得太仔细,因为所有迹象都表明我应该使用API。
我首先查看了谷歌地图平台。为了使用它,我必须注册为谷歌开发者。注册后,我可以登录谷歌云控制台。登录后,我必须设置一个项目。设置项目后,我必须设置一个计费账户。设置计费账户后,我必须启用Places API(新版)。启用Places API(新版)后,我必须创建一个API密钥。然后,我就可以开始向谷歌地图API发送请求来获取餐厅数据。

如果我听起来像是在抱怨,我保证我只抱怨了一点点。在每个步骤之间,我尝试运行一些查询,API的错误响应做得很好,解释说:“等等,你需要先设置一个计费账户,前往这个链接”,“等等,你需要先启用计费账户,前往那个链接”等等。遗憾的是,我没有从一开始就遵循这个指南。
除了开发者友好度之外,我仍然担心意外花钱。显然,每个月每个人都可以获得200美元的积分来使用谷歌地图功能,从3月1日开始,每个人每月都可以获得3,250美元的积分。对于这一点,我没有什么负面的话要说!最终,我的担忧并非完全没有道理,因为我花了总共38.61美元(以积分形式)的费用来获取所有我需要的数据。
不幸的是,像许多云平台一样,我找不到一个可以在用完积分后关闭一切的杀死开关。这样,我就可以在这篇文章中嵌入地图等内容,让每个人都可以玩耍,但我不想冒着被收费的风险。所以,只能使用截图了!
距离结果又近了一步
一切就绪后,我终于可以开始使用“Places API(新版)”了,不要与旧的、破旧的“Places API”混淆。我同情那些重构旧API的人,而不是直接开始新的事物。这是一个漫长的过程,直到你可以停止将事物称为“新”的。例如,新API于2023年10月发布。
文档和演示场景正是我需要的东西,可以让我入门并获取所需的数据。我从运行使用Nearby Search(新版)文档中的示例的curl命令开始。使用X-Goog-FieldMask头部时,你会得到有关一个地方的很多数据。我最终将参数缩小到:
这会产生这样的结果:
{
"name": "Arnold's Donuts and Coffee",
"place_id": "ChIJxZ3YBa5HE4cRlucg9jTNos0",
"type": "Donut Shop",
"rating": 4.8,
"user_ratings_total": 428,
"location": {
"latitude": 38.8556089,
"longitude": -104.7184834
},
"address": "5883 Palmer Park Blvd site B, Colorado Springs",
"maps_url": "https://maps.google.com/?cid=14817631351353698198"
}
我开始感到兴奋,因为我只需要再进行一次API调用就可以获取所有结果了!我练习的curl命令看起来像这样:
curl -X POST -d '{
"maxResultCount": 10,
"locationRestriction": {
"circle": {
"center": {
"latitude": 38.878400,
"longitude": -104.767914
},
"radius": 1000.0
}
}
}'
现在我只需要设置一些更高的限制:
然后我们就可以开始了!哦等一下,怎么回事?
{
"error": {
"code": 400,
"message": "Max number of place results to return must be between 1 and 20 inclusively.",
"status": "INVALID_ARGUMENT"
}
}
好吧,这有点令人沮丧,但这并不是世界末日。如果我一次只能获取20个结果,那么我如何捕获城市中的每一家餐厅呢?我需要将15公里半径分成更小的块,然后先搜索这些块。只要确保它们之间有一点重叠,去除重复的结果,然后*我就可以开始了!*将这个策略可视化看起来像这样。

使用Claude,我给它提供了一个工作的curl请求,并要求它编写一个具有我描述的算法的Python脚本。经过几次迭代后,我将其放入VSCode中,使用GitHub Copilot解决了一些运行时错误,然后执行脚本以输出所有餐厅到一个.json文件中。
.json文件的美食表现
首先,必须检查数据并确保它是可用的。我投下了一个广泛的网,获得了1200多个结果和近半兆字节的.json文件。首先,我只是看了一些数据,想看看初步的结果。以下的清理部分非常特定于科罗拉多斯普林斯,所以您可以随意滚动到分析部分,或者继续阅读,看看香肠是如何制作的。
谷歌地图是社区维护的,所以它的数据本质上是不完美的。另外,它是短暂的,因为即使我写这篇文章,人们也在留下评分、评论,餐厅也在开业和关闭。我在2025年2月9日收集了这个列表,所以最好把它当作一个时间快照。也许有一天,另一个有进取心的人可以拿起这个概念,并为每个城市制作一个更通用、更及时的列表,但我只是想在我的城市找到最好的地方吃饭!
在前两个结果中,我看到了一个非餐厅地点,被列为犹太教堂。
{
"name": "Chabad of Colorado Springs Jewish Community",
"place_id": "ChIJi1_uDLpPE4cR8CvBDjJPCEA",
"type": "Synagogue",
"rating": 5,
"user_ratings_total": 181,
"location": {
"latitude": 38.920195,
"longitude": -104.787714
},
"address": "6062 Hollow Tree Ct, Colorado Springs",
"maps_url": "https://maps.google.com/?cid=4614024894655572976"
}
查看其网站后,我发现他们提供餐食,这解释了为什么它获得了“餐厅”标签,因为一个地方可以有多个types,但只有一个primary type。然后,我偶然发现了一个关于花园之神交易站的条目。是的,他们有食物,但它仍然主要是一个礼品店。
我决定将整个.json文件通过一个LLM来获取关于其他可以删除的内容的建议。.json文件大约有218k个标记(非常大),所以我使用了Gemini 2.0 Flash Experimental,它有1M个标记限制(且免费!)。它建议删除以下地方,列表足够小,以至于我可以对每一个做出判断。
我决定删除那些不是酒吧的酿酒厂(例如删除Mash Mechanix,但保留Voodoo Brewing)。我还允许冰淇淋店、面包店等,因为它们仍然主要提供食物,即使它们不是“正规”的餐厅。
我注意到一个问题,即很多餐厅没有评论。大多数看起来像是用户错误地创建的重复项(例如“Fargo's pizza”而不是“Fargo's Pizza Co.”)、错误的名称(例如“Third Watch”而不是“First Watch”)、虚构的地方、地址只是某人的房子,或者与此分析无关(例如“Bon Fire”在Maverick加油站内的食物柜台)。这些都没有评论,所以基本上是垃圾数据,我都删除了。唯一合法的似乎是Kissing Camels Grille and Bar。为什么它没有任何评论?如果你喜欢这个地方,请去留下评论!更新:有人评论了它。现在它在列表中了!
列表的其余部分包括暂时关闭的地点,但我核实过,它们没有任何永久关闭的地点,所以我将它们保留在数据集中。有时新闻变化的速度比社区更新地图的速度还快。例如,Wild Goose Meeting House被列为永久关闭,但它不在我的数据集中。然而,最近的新闻报道说新老板正在接管。
唯一能验证100%质量的方法是阅读每一行并评估每个项目,但我不会这样做。我有事情要做,也有餐厅要去!在某个时候,你只需要接受你收集到的数据是“足够好”的。不要让完美成为良好的敌人。最终的列表变成了1130 1378家餐厅。
这里需要一种不同的清理方式
收集所有餐厅数据的脚本也对所有餐厅进行了粗略排序。它将所有5星评论放在一起,按评论数量降序排列。然后,它将所有4.9星评论放在一起,按评论数量降序排列,依此类推。这是一种还不错的排序方式,但它并不能完全准确地捕捉到质量。例如:
观众并不傻
我们如何以适当的权重来排名它们?我曾经发现了一份科罗拉多斯普林斯所有啤酒厂的列表,排名方式与此类似,我认为一定有更好的方法!我发现了一种叫做贝叶斯平均值的方法,可以更好地对啤酒厂进行排名。
我制作这个列表以来,划掉的啤酒厂已经关闭了。这对它们来说很艰难
我喜欢这种排名方法,它考虑到了评论数量,但看起来它惩罚了评论最多的啤酒厂。Cerberus和Bristol,作为最受欢迎的啤酒厂,真的是最糟糕的吗?可能不是。有没有其他排名方法可以不那么惩罚它们?
我在使用LLM之前就了解了贝叶斯平均值,所以我向ChatGPT-4o描述了这种情况,其中一个建议是使用称为威尔逊评分间隔的排名。
[威尔逊评分间隔是] 最好的,如果你想要一个基于置信度的统计排名,可以防止小样本大小扭曲结果。它被广泛应用于Reddit和IMDB等排名系统中。
它真的被Reddit和IMDB使用吗?也许这是一个幻觉,但在这种情况下,谁在乎呢?这只需要两秒钟来尝试一下。在将这种方法应用于大型餐厅数据集之前,我将其应用于啤酒厂列表作为测试。

它绝对通过了我的直觉测试;Cerberus和Bristol不再处于底部,排名靠前的啤酒厂仍然靠近顶部。
小测试完成后,我使用Claude创建了一个脚本,接受餐厅列表作为输入,并以正确的顺序输出列表。该算法需要一个置信度作为输入,我选择了99%的置信度。这个值更保守,这意味着它倾向于偏爱更成熟的场所,而较低的置信度(例如90%)将为新场所提供更大的提升。由于我们处理的是餐厅,我觉得更成熟的机构应该占优势,因为它们必须做对了什么(即制作美味的食物)才能开业这么久并积累评论。
话虽如此,列表仍然以一些新的5星级餐厅靠近顶部。数学就是这样。
| 1 | Arelita Authentic Cuban Food | 11 | Taste of Ethiopia restaurant and coffee shop |
|---|---|---|---|
| 2 | Starving | 12 | Por Favor Tacos & Tragos |
| 3 | Manitou Baked | 13 | PETES Jamaican restaurant |
| 4 | Crepe Amour CO | 14 | Po' Brothers |
| 5 | ArkCleoRich African Kitchen | 15 | Roots Cafe |
| 6 | B&B's Bunzy's and Booze | 16 | Otis's BBQ |
| 7 | Shah Kabob House | 17 | The Chuckwagon |
| 8 | Turmeric Indian Cuisine at Power Center Point | 18 | HAPPY EATS PASTA |
| 9 | Momo Korean Restaurant | 19 | Native Grill |
| 10 | Mountain View Cafe and Catering | 20 | Somjai Thai Cuisine |
更新:列表的早期版本由于我的搜索算法漏掉了一些地方。列表已更新!这并没有太大影响地图的见解。
结果是我所期望的吗?并非完全如此!我只认识其中几家餐厅,它们都很棒,这让我很兴奋去尝试列表上的其他地方。它与人类策划的列表不同,因为除了“数学就是这样”的主题之外,它没有任何主题。
如果您想对自己的城市做同样的事情,请随意使用我的代码。
列表很有趣,但我们还有位置数据,所以让我们来绘制一些东西。谷歌地图支持热力图,感谢他们不错的代码示例,很容易显示所有餐厅的位置。
很酷
看到所有餐厅的位置很有趣,但最佳餐厅在哪里?我从尝试使用加权数据点开始,但结果几乎与上面的地图相同。有这么多数据点,很难在颜色有限的热力图中区分它们。我考虑过调整不透明度/强度/颜色,但我有一个更简单的想法:只要切掉列表的下75%就行了。这产生了一个更好的比较。
所有餐厅与前25%的餐厅
好多了!以下是前25%的静态图像,以便您在寻找城镇周围最热门的美食地点时不会出现癫痫。
我再次为只能使用图像而不是交互式地图而道歉。交互式地图更有趣!
热点不仅仅对应于人口,但很多热点对于任何在科罗拉多斯普林斯居住过一段时间的人来说都不令人惊讶。话虽如此,也有一些隐藏的宝藏,我很高兴发现了它们。
不出所料的市中心
老科罗拉多城
马尼图
流行但不太出名的花园之神路西部I-25
大学村(向Ambli Kitchen and Bar致敬!)
询问和航海家
学院大道沿线
这可能是数据分析的最大好处。以下是一些值得探索的偏僻地点,包括:
有了一个想法并能够快速执行它是非常有趣的,多亏了LLM的帮助。以前,我没有时间或耐心来编写快速脚本来解析数据、格式化数据、转换和分析前面提到的解析和格式化数据... 但现在做这些事情很快就像拥有超能力一样。我通常有足够的技术知识来完成事情,LLM帮助我快速填补空白。现在,我对谷歌API的工作原理有了更广泛的了解,我在使用VSCode和GitHub Copilot时更加敏捷,我也很渴望学习更多。
但是我更渴望尝试我所在城市的新美食!虽然,最终,没有一个地方能与我美味的自家烧烤相比,但这可能是所有错误的,根本不值得听。

但绝对不要去Trailer Birds吃饭。