🌏

個人で地図にAIをマッピングしてみた #1 設計編

に公開

1. はじめに

地図や位置情報といえば、GoogleやAppleといったビッグテックの領域です。
高精度な地図データ、高速な検索エンジンとAI -- これらは莫大なインフラとチームで開発されているもの、というのが一般的な認識でしょう。

ふと思いました。
この何でも作れる時代、これを個人でも作れるんじゃないか?

もちろん、同じスケールは無理でも、「考え方」や「仕組み」の一部は再現できるかもしれない。
そう思い立ち、地図上で位置情報を扱うAIを個人R&D(研究開発)してみました。

このシリーズでは、何回かに分けてその開発記録をまとめていきます。
現在も開発中で、アジャイル形式で進めているため、記事の内容も随時アップデートしていく予定です。

この試みが役に立てば幸いです。


2. 開発目的と設計思想

地図データや位置データを活用するには、高速な検索処理や集計処理が不可欠です。
これらの地理データはもともと膨大な情報量を持ち、処理には空間的な演算に伴う高い計算コストが発生します。

たとえば、SQLのようなリレーショナル検索で空間計算を行うと、多くの場合、データ量 n に対してO(n^2) の計算量がかかります。
このため、大規模な地理データでは、高速な検索やコストの最適化が難しくなります。

こうした課題を解決するために、以下の3つの技術的チャレンジに取り組んでいます。


(1) 計算量のオーダーを削減する

空間検索の計算コストを抑えるために、次の2種類のデータ構造を活用しています。

  • グラフ構造(空間インデックス)
    検索:O(\log n)
    構築:O(n \log n)
    適した場面:限定範囲内の検索や近傍検索
    kd-tree などのオープンソースの空間インデックスを活用することで、無駄な比較を避け、高速な探索を実現しています。

  • ハッシュ構造(ジオハッシュなど)
    検索:平均 O(1)(定数時間)
    構築:O(n)
    適した場面:特定の領域(マス目)への高速アクセス
    緯度経度の座標をハッシュ化して、地理空間をグリッド状に分割して管理し、特定エリアへのアクセスをハッシュで高速に行うことが可能になります。

さらに、各グリッド内の詳細な位置情報はグラフ構造で管理することで、ピンポイントな検索に対しても、高精度かつ高速な応答を実現しています。
まずはハッシュで空間を粗く分割し、対象エリアを効率的に特定します。
その後、必要に応じて各グリッド内でグラフ構造を使った詳細検索を行うことで、処理負荷を抑えながら高精度な探索を可能にしています。


(2) 並列・分散処理でバッチ処理を高速化する

大量の地理データを処理するバッチ処理では、逐次実行では処理時間が現実的ではありません。
とはいえ、高性能なサーバーを何台も常時稼働させるのは、個人開発としてはコストが高すぎます。

そこで、AWSのサーバーレスサービスを活用し、オンデマンドで分散・並列処理を実行しながら、高速化と自動化を実現する構成にしました。

  • 処理エンジン:Lambda + EMR(PySpark)
  • 処理監視:EventBridge + Lambda

これにより、個人による大規模なデータ処理でも、スケーラブルで現実的な運用基盤を構築できることを目指しています。


(3) 軽量・安価なAPIでデータを提供する

処理済みの地理データは、サーバーレスAPIを通じて取得可能な構成としています。

APIのレスポンス速度を向上させるために、以下のような設計上の工夫を取り入れています:

  • 分散・軽量化されたデータを S3 に配置
  • APIが必要な範囲のみを効率的に読み取る構成
  • 分割の粒度(データの大きさ)を調整し、バッチ処理の性能とAPI応答速度のバランスを最適化

こうすることで、API利用者にとっても、速くて安く使いやすい位置情報APIの提供が可能になります。


まとめ

このようにして、地図AIを支える「検索・処理・提供」の技術基盤を、個人でも構築・運用できるようにすることが、今回のR&Dプロジェクトの目的です。


3. データ

今回は、Wikipediaのアーカイブデータから、地理情報を抽出・加工し、記事本文と位置情報との紐付けを行います。
対象としているのは、日本全国の位置情報が付加された日本語のWikipediaページです。
また、その豊富で多様な記述から、一般的なAIの学習データとしても広く活用されています。

Wikipediaの位置情報

Wikipediaには、都市・建築物・自然地形など、世界中の場所に関するページが数多く存在します。
これらのページの一部には、緯度・経度の位置情報が埋め込まれています。


アーカイブデータの取得元と形式

Wikipediaの日本語アーカイブデータは、Wikimedia Downloads から取得しています。
今回使用したデータは、jawiki-latest-pages-articles.xml.bz2 です。

このアーカイブデータは、およそ週1回のペースで定期的に生成・公開されており、常に最新の状態を取得することができます。
このファイルをそのまま AWS S3 にアップロードし、クラウド上で並列処理を行う前提でシステム設計しています。


4. システム全体の処理フロー

本システムは、大きく分けて以下の3つの処理ステージで構成されています。

  1. Wikipediaアーカイブの並列分散処理バッチ
  2. 検索用APIの構築とパブリック化
  3. 地図アプリケーションからの呼び出し

ステージ1:Wikipediaアーカイブのバッチ処理(概要)について

Wikipediaの .bz2 形式のアーカイブデータを、AWS上で並列分散処理し、位置情報を含むページを抽出・整形しています。

処理の大まかな流れは以下の通りです。

  1. S3にアップロードされたWikipediaアーカイブ(bz2ファイル)を、EMR + PySparkでストリーム処理
  2. 各ページから、緯度・経度・タイトル・本文などを抽出
  3. 緯度経度をもとにジオハッシュを計算し、空間グリッド単位にデータを分割
  4. 各データを、AI処理に適した形式でベクトル化(Embedding)
  5. 緯度経度とEmbedding(どちらも座標情報)をノード化し、近傍関係をエッジで結ぶグラフ構造に変換
  6. Wikipediaの分割データとグラフ構造データを、ハッシュアクセス可能な形式でS3に保存

次回予告

今回は、Wikipediaの地理データをクラウド上で処理する全体像と、バッチ処理の仕組みの概要を紹介しました。
次回は、バッチ処理の仕組みとAWSで処理する方法について解説する予定です。

本シリーズでは今後、API構築や地図アプリ連携、地理情報を活用したAI応用まで順に公開予定です。
ご興味ある方は、ぜひ次回もご覧ください!

Discussion