跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

用 MGeo 和 Neo4j 搭建中文地址语义知识图谱

利用阿里开源的中文地址语义模型 MGeo 生成地址相似度结果,导入 Neo4j 构建知识图谱,实现地址去重、查询连通组件等功能,为位置服务提供可推理的数据基础。

暖阳发布于 2026/6/300 浏览

用 MGeo 和 Neo4j 搭建中文地址语义知识图谱

中文地址的表达方式千奇百怪,缩写、省略、别名到处都是。用 Levenshtein 距离或规则清洗去匹配它们,不仅累,准确率也上不去。阿里巴巴开源的 MGeo 模型专门解决这个问题,它基于 BERT 微调,输入一对地址就能给出 0~1 的语义相似度。像'上海徐汇漕溪路 123 号华鑫天地'和'上海市徐汇区漕溪路 123 号 B 栋'这种,得分能到 0.96。

有了这些匹配结果之后,怎么把它们变成可查询、可分析的知识库?我的选择是导入 Neo4j。节点存地址,边存相似关系,图算法的能力正好用来做地址聚类和归一化。下面把整个搭建过程记录下来。

MGeo 部署:镜像拉下来就能跑

阿里提供了 Docker 镜像,在单卡 GPU(比如 4090D)上直接启动就行:

docker run -itd --gpus all \
  -p 8888:8888 \
  -v /your/workspace:/root/workspace \
  registry.aliyuncs.com/mgeo-public/mgeo-inference:latest

容器里自带 Conda 和 Jupyter Notebook,浏览器打开 http://localhost:8888 就能用。不过,官方给的推理脚本放在 /root/推理.py,我习惯先把它拷到 workspace 目录再改,免得误操作:

docker exec -it <container_id> /bin/bash
cp /root/推理.py /root/workspace

然后激活环境运行推理:

conda activate py37testmaas
python /root/workspace/推理.py

你可以在这个脚本里加日志输出、批量处理逻辑,或者把结果导出成 JSON/CSV,方便后面导入图库。

用 MGeo 做地址匹配

模型输出的典型结果长这样:

{
  "addr1": "杭州市文三路 369 号",
  "addr2": "杭州西湖文三路 369 号智博大厦",
  "similarity": 0.93,
  "is_match": true
}

超过 0.85 我就认为是'同指'实体。实际处理几万条地址时,两两配对太多了,可以先按城市分区粗略分组,或者用 Elasticsearch 的模糊召回先筛一遍,减少无效比对。

导入 Neo4j:建模与写入

图模型很简单:

  • 节点标签 Address,属性:id(唯一ID)、raw_text(原始地址)、city、district、street 等。
  • 关系类型 SIMILAR_TO,属性:score(相似度)、source(来源)、timestamp。

用 Cypher 手动建两个节点试试:

CREATE (a1:Address { id: "addr_001", raw_text: "北京市朝阳区建国门外大街 1 号", city: "北京", district: "朝阳区" })
CREATE (a2:Address { id: "addr_002", raw_text: "北京朝阳建外大街 1 号国贸大厦", city: "北京", district: "朝阳区" })
CREATE (a1)-[:SIMILAR_TO { score: 0.95, source: "mgeo_v1", timestamp: datetime() }]->(a2)

实际批量导入,我直接写 Python 用 neo4j-driver 操作:

from neo4j import GraphDatabase

uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "your_password"))

def create_address_and_relations(tx, addr_data, relations):
    for addr in addr_data:
        tx.run("""
            MERGE (a:Address {id: $id})
            SET a.raw_text = $raw_text, a.province = $province,
                a.city = $city, a.district = $district, a.street = $street
        """, **addr)
    for rel in relations:
        tx.run("""
            MATCH (a1:Address {id: $from_id})
            MATCH (a2:Address {id: $to_id})
            MERGE (a1)-[r:SIMILAR_TO]->(a2)
            SET r.score = $score, r.source = $source, r.timestamp = datetime()
        """, **rel)

# 示例数据
addresses = [
    {"id": "addr_001", "raw_text": "上海市徐汇区漕溪路 123 号", "city": "上海", "district": "徐汇区", "street": "漕溪路 123 号"},
    {"id": "addr_002", "raw_text": "上海徐汇漕溪路 123 号华鑫天地", "city": "上海", "district": "徐汇区", "street": "漕溪路 123 号"}
]
similarities = [{"from_id": "addr_001", "to_id": "addr_002", "score": 0.94, "source": "mgeo_v1"}]

with driver.session() as session:
    session.execute_write(create_address_and_relations, addresses, similarities)

用 MERGE 而不用 CREATE 是因为重复跑脚本时不至于抛异常。大数据量时,可以加上 UNWIND 分批写入。

图上的查询与分析

数据进去后,最常用的就是找'连通组件'——把那些通过高相似度关系连在一起的地址归为一簇。前提是你的 Neo4j 装了 GDS 插件:

MATCH path = (a:Address)-[:SIMILAR_TO {score: 0.85}]-(b)
WITH collect(path) AS subgraph
CALL gds.alpha.connectedComponents.stream({
  nodeProjection: 'Address',
  relationshipProjection: {
    SIMILAR_TO: {
      type: 'SIMILAR_TO',
      properties: 'score',
      orientation: 'UNDIRECTED'
    }
  },
  relationshipWeightProperty: 'score'
})
YIELD nodeId, componentId
RETURN gds.util.asNode(nodeId).raw_text AS address, componentId
ORDER BY componentId

每个 componentId 对应一组语义一致的地址,选代表地址时就方便了。

人工复核那些模棱两可的匹配也容易,查得分在 0.7~0.85 之间的关系:

MATCH (a)-[r:SIMILAR_TO]->(b)
WHERE r.score >= 0.7 AND r.score < 0.85
RETURN a.raw_text, b.raw_text, r.score
LIMIT 10

在 Neo4j Browser 里跑个可视化查询,也能直观看到关联网络:

MATCH (a:Address)-[r:SIMILAR_TO]->(b)
WHERE r.score > 0.9
RETURN a, r, b
LIMIT 50

维护小事

  • 索引要建,否则节点多了查询慢:CREATE INDEX FOR (a:Address) ON (a.id);
  • 定期用 neo4j-admin dump 备份。
  • 生产环境别用默认密码。

结尾

这套方案跑了几个月,在地址去重和归一化上省了不少人工,但 MGeo 的阈值设定仍得根据业务微调——0.8 可能太松,0.9 又太严。临界值附近的 case 最让人头疼,偶尔还得肉眼扫一遍。后面打算把 GPS 坐标也塞进图里,结合空间关系可能还能搞点别的好玩查询。如果你也在做地址库的治理,这种'语义模型 + 图数据库'的路子值得一试。

目录

  1. 用 MGeo 和 Neo4j 搭建中文地址语义知识图谱
  2. MGeo 部署:镜像拉下来就能跑
  3. 用 MGeo 做地址匹配
  4. 导入 Neo4j:建模与写入
  5. 示例数据
  6. 图上的查询与分析
  7. 维护小事
  8. 结尾
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 2026 年 AI Agent 框架对比:OpenClaw 及 8 款衍生版怎么选
  • Linux 进程控制实战:微型 Shell 命令行解释器实现
  • 从后端到前端:AI Agent 跨语言全栈项目实战记录(Java + Python + Vue3)
  • 上手 Llama 3:推理与 LoRA 微调实践
  • 给 Wan2.2 装个风格插件:LoRA 微调实战指南
  • 2026毕业季:多校公布论文AI率红线与应对指南
  • 2026低代码选型:AI融合下,三个核心维度
  • PyCharm 断点排查 GLM-4.6V-Flash-WEB 脚本错误
  • 2023年网络安全趋势观察:十个绕不开的方向
  • 无人机植物病害检测数据集:1500张标注航拍图像
  • iOS 18.2 上 Flutter WebView 点击失效的来龙去脉
  • 三台 Win11 笔记本跑 VMware Ubuntu 24:网络配置实录
  • 上手 YOLO12 WebUI:浏览器里跑目标检测,不用装环境
  • 花10美元买的“GPT-5”,结果只是个套壳免费模型
  • 10 个 Python 脚本让日常重复活自动跑起来
  • 字节跳动前端面试回顾:一面到三面常见考点与高频题
  • 给 OpenCode 接上 Kimi K2.5:三种方式与一些选择
  • 用 Claude 在 Android Studio 里 10 分钟搭好 WebView 模块
  • 7款国内AI助手横评:豆包、元宝、千问、Kimi、DeepSeek、MiniMax、GLM
  • 2026 大模型落地观察:国产反超、百万上下文与 Agent 工程化实践

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online