carto-site-selection について
carto-site-selectionは、施設候補地の評価、既存地点と新設地点の商圏重複リスクの測定、好成績地点に似たエリアの探索に使うCARTO Workflowsの構築を案内します。小売や交通などの立地分析向けです。
主な機能
- 01需要指標で候補地を採点・順位付け
- 02既存地点と新設地点の商圏重複を測定
- 03好成績地点に似たエリアを探索
- 04H3またはQuadbinグリッドで分析
- 05人口、所得、POIデータを組み合わせ
活用シーン
- 01新店舗の候補地を絞り込む
- 02新店舗が既存店舗に与える影響を推定
- 03好調店舗に似た拡張エリアを探す
MCP 対応
CARTO MCPサーバーのワークフローツールでWorkflowを作成、検証、実行する方法を案内します。サーバーが接続されていない場合はCARTO CLIを利用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cartodb/ agent-skills --skill carto-site-selectionインストール後、Claude Code で/carto-site-selectionを入力して読み込まれたか確認します。
詳細
立地選定とカニバリゼーション分析
空間的な条件を組み合わせて新施設(店舗、駅、オフィス)の最適な立地を特定し、商圏の重複によるカニバリゼーションのリスクを定量化する CARTO Workflows を構築します。ツインエリアや類似立地の検索についても扱います。
前提条件:開発プロセス、JSON 構造、検証については carto-create-workflow を読み込んでください。MCP サーバーのワークフローツール(接続されている場合は create_workflow、validate_workflow、run_workflow)、それ以外の場合は carto workflows CLI を使う、両方のアクセス方法を扱っています。アクセス方法の判定シグナルについては carto-basics/references/access-paths.md を参照してください。ワークフローで等時間圏、バッファ、または商圏のエンリッチメントを扱う場合は、商圏パイプラインを詳しく説明する carto-trade-area-analysis を読み込んでください。
意思決定ツリー
| ユーザーの意図 | パターン |
|---|---|
| 「新しい店舗を出すなら、どこがよいですか?」 | 立地選定(スコアリング+ランキング) |
| 「新しい店舗によって既存店舗の売上が減りますか?」 | カニバリゼーション分析 |
| 「業績のよい店舗に似た立地を探してください」 | ツインエリア/類似立地 |
手順
パターン A:立地選定(スコアリング+ランキング)
Existing locations + Target area -> Spatial indexing -> Enrich with demographics/POIs -> Score/Rank -> Filter top candidates -> Save
ステップ 1:データを読み込む
native.gettablebyname を使って、次の 2 つのデータセットを読み込みます。
- 既存の立地(現在の店舗/施設)
- 対象エリア(例:都市の境界、地区のポリゴン、または調査対象エリアを覆うグリッド)
候補地と既存ネットワークが同じテーブルにある場合の分割。 ユーザーのデータソースが、数値のしきい値(例:revenue ≥ X、size ≥ Y)によって「候補地」が定義される単一のテーブルの場合は、その条件を使った native.where を 1 つ配置し、match 出力を候補地のパイプラインに、unmatch 出力を既存ネットワークのパイプラインに接続します。1 つのノードから 2 つのストリームを作るため、orderby + limit + customsql NOT IN より大幅にすっきりし、customsql も不要です。このしきい値は「上位 N 件」の近似です。ユーザーが「上位 25 件ちょうど」と明示した場合は、orderby + limit が引き続き適切ですが、ノードが増えることを承知のうえで選択してください。
成功条件:両方のテーブルが、ジオメトリ列と一意の識別子を含んだ状態で読み込まれていること。
ステップ 2:候補地のグリッドを作成する
native.h3polyfill または native.quadbinpolyfill を使って、対象エリアを H3 または Quadbin セルにポリフィルします。各セルが候補となるマイクロ立地です。
成功条件:調査対象エリアを覆う、連続したセルのグリッドが作成されていること。
ステップ 3:候補地をエンリッチする
native.h3enrich、native.joinv2、または Data Observatory を使って、人口、所得、人通り、POI 密度などの需要指標を各セルに付与します。
候補地がグリッドではなく連続したポリゴン(商圏/地区)の場合、native.enrichpolygons と native.spatialjoin + native.groupby のどちらを選ぶかが重要です。トレードオフ(AT への依存、ノード数、述語/結合の制御)については、carto-spatial-enrichment のステップ 4 を参照してください。
成功条件:各グリッドセルに、需要や適性の要因を表す数値列が含まれていること。
Step 4: 既存店舗からの近接性でフィルタリングする
native.h3distance を使用して、各候補セルから最寄りの既存店舗までのホップ距離を計算します。近すぎるセル(カニバリゼーションのリスク)や遠すぎるセル(物流コスト)を除外します。出力はホップ数であり、メートル単位の距離ではありません。解像度ごとのエッジ長を使って換算してください(「注意事項」を参照)。
距離の意味 — 候補地点からではなく、商圏ポリゴンからカニバリゼーションを測定します。 候補が生成済みの商圏(等値線/バッファー。carto-trade-area-analysis を参照)を持つポイントの場合、既存の競合ポイントまでの距離は、候補ポイントからではなく、候補の商圏ポリゴンから native.distance で計算します。理由:競合店舗が商圏内にある場合、ST_DISTANCE(polygon, point) = 0 となり、まさに検出したいカニバリゼーションの兆候が示されます。ポイント間距離では「最寄りの競合店舗までの距離」しか分からず、重複が隠れてしまいます。商圏の大きさに合った radius を選んでください(例:徒歩10分の商圏なら約5 km)。半径が大きすぎると、兆候が薄まります。このポリゴンからポイントへのパターンは、Pattern A の H3 ホップフィルターと Pattern B の完全なグリッド重複分析の中間に位置します。候補に連続的な商圏ジオメトリがすでにある場合は、このパターンを使用してください。
成功条件:候補セルが既存店舗から適切な距離の範囲内にあり、商圏ポリゴンが存在する場合は、そこからカニバリゼーションの兆候が測定されていること。
Step 5: スコアを付けて順位付けする
trade-area-analysis のスコアリングパターンを使用します。
- 正規化:
native.normalizeを使って各変数を [0,1] の範囲に正規化します - 合成スコア:ユーザー定義の重みを使い、
native.selectexpressionで計算します - 順位付け:
native.orderby(降順)とnative.limit(上位 N 件)を使います
成功条件:合成スコアとその要因となる変数を含む、候補セルの順位付きショートリストが得られていること。
Step 6: 保存する
native.saveastable を使用します。H3/Quadbin 列は CARTO Builder で直接可視化できます。
成功条件:アップロード可能な、検証済みのワークフローが完成していること。
Pattern B: カニバリゼーション分析
Existing + Proposed locations -> Trade areas (isoline/buffer) -> Polyfill to grid -> Intersect/Join -> Measure overlap -> Save
Step 1: データを読み込む
既存店舗と出店候補を読み込みます(または、両者を区別するフラグ列を含む単一のテーブルを読み込みます)。両方の集合が単一のテーブルにあり、数値しきい値(例:revenue ≥ X)で分割する場合は、Pattern A の Step 1 にある native.where の一致/不一致による分割を参照してください。1 つのノードから両方のストリームを生成でき、customsql を使わずに済みます。
成功条件:ジオメトリと一意の識別子を含む両方のデータが読み込まれていること。
Step 2: 商圏を生成する
native.isolines(現実に即した方法)または native.buffer(簡易的な方法)を使い、既存店舗と出店候補の両方の周囲に商圏を作成します。比較可能性を確保するため、両方の集合に同じパラメーターを使用します。
成功条件:すべての店舗に、統一されたパラメーターで作成された商圏ポリゴンがあること。
Step 3: 空間インデックスにポリフィルする
native.h3polyfill を使い、すべての商圏ポリゴンを H3 または Quadbin セルに変換します。店舗識別子と is_proposed フラグを保持します。
成功条件:店舗 ID と種別フラグを含む、セルごと、店舗ごとの行が生成されていること。
Step 4: 重複を検出する
空間インデックス列をキーにして、native.joinv2 で既存店舗のセルと出店候補のセルを内部結合します。その結果には、少なくとも 1 つの既存店舗と 1 つの出店候補の両方に共有されるセルが含まれます。
成功条件:既存店舗と出店候補の両方の商圏に含まれるセルだけが出力されていること。
Step 5: 影響を測定する
native.groupby を使って重複を集計します。
- 既存店舗ごと:重複セル数/その店舗の商圏内の総セル数 = 重複率
- 重複セルをエンリッチし、人口や売上を付加して共有需要を定量化します
native.selectexpression を使って重複率を計算します。
成功条件:各既存店舗について、出店候補と共有される商圏の割合を示す重複指標が得られていること。
Step 6: 保存する
native.saveastable を使用します。
成功条件:店舗ごとのカニバリゼーション指標を含む、検証済みのワークフローが完成していること。
パターン C:類似エリア/類似ロケーション
Top-performing locations -> Trade areas -> Enrich -> Build similarity model -> Score all candidate areas -> Rank -> Save
ステップ 1:参照ロケーションを特定する
ロケーションデータセット全体を読み込みます。native.wheresimplified または native.orderby と native.limit を使用して、上位の実績を持つロケーション(例:売上上位 4 分の 1)に絞り込みます。
成功条件:実績の高いロケーションのサブセットが参照セットとして抽出されていること。
ステップ 2:商圏を生成してエンリッチする
参照ロケーションの周囲に等時間圏またはバッファー商圏を作成します。H3/Quadbin にポリフィルします。人口統計、POI、その他関連する変数でエンリッチします。
成功条件:各参照ロケーションに豊富な人口統計プロファイルがあること。
ステップ 3:ツインエリアモデルを構築する
native.buildtwinareasmodel(BUILD_TWIN_AREAS_MODEL)を使用して、エンリッチした参照ロケーションから PCA ベースの類似性モデルを作成します。
- 入力:数値特徴量の列を持つ、エンリッチ済みの参照ロケーション
- モデルは、実績の高いロケーションの多変量「シグネチャ」を捉えます
成功条件:実績上位ロケーションの人口統計プロファイルを符号化したモデル成果物があること。
ステップ 4:類似ロケーションを見つける
native.findsimilarlocations(FIND_SIMILAR_LOCATIONS)を使用して、すべての候補エリアをツインエリアモデルに照らしてスコアリングします。
- 入力:モデル構築に使用したものと同じ変数でエンリッチした候補エリア
- 出力:候補ごとの類似度スコア
成功条件:すべての候補エリアに、参照セットに対する類似度スコアがあること。
ステップ 5:順位付けして保存する
類似度スコアの降順で順位付けします。上位候補を保存します。
成功条件:実績上位のロケーションに最も類似したエリアの順位付きリストがあること。
商業ホットスポットのバリエーション
需要主導の出店場所選定(例:「未充足需要が最も高いのはどこか?」)では、native.commercialhotspots を使用します。
- 対象エリア全体に H3 グリッドを構築します
- 対象となる需要変数(例:15~34 歳の人口)でエンリッチします
variablecolumnsとweightsを指定してnative.commercialhotspotsを実行します- 有意性(
p_value < 0.05)で結果を絞り込みます - 必要に応じて、既存ロケーションからの
native.h3distanceで絞り込み、サービスが行き届いていないエリアに焦点を当てます
注:variablecolumns には Python 形式のリスト構文(['col1', 'col2'])を使用し、weights はカンマ区切りです。詳細は trade-area-analysis の注意事項を参照してください。
注意事項
- プロバイダーの大文字・小文字表記と SQL 方言。 このスキルでは小文字の列名(
h3、is_proposed、populationなど)を使用します。これは BigQuery/Databricks/Postgres/Redshift の慣例です。Snowflake では、引用符で囲まれていない識別子は大文字で表示されるため、H3、IS_PROPOSED、POPULATIONとして参照してください。大文字・小文字の規則と SQL 方言の対応については、carto-create-workflow/references/providers/<provider>.mdを参照してください。 native.commercialhotspotsを使用するには、Analytics Toolbox の Retail モジュールが必要です。--connectionで利用可能か確認してください。- Twin Areas と Similar Locations は内部で PCA を使用するため、結果は変数の選択とスケーリングに左右されます。関連性があり、重複しない変数のみを含めてください。スケールが大きく異なる場合は、入力を正規化してください。
- カニバリゼーションの重複は、商圏の定義(バッファー半径、等時線の所要時間)に大きく左右されます。パラメーターを少し変更するだけで結果が逆転する場合があります。選択したパラメーターとその根拠を記録してください。
native.h3distanceが返すのはホップ数であり、物理的な距離ではありません。おおよその距離を求めるには、解像度に応じたセルの辺の長さを掛けてください(例:解像度 8 では約 460 m、解像度 9 ではホップあたり約 174 m)。- サイズの異なる地域を比較する場合は、規模による偏りを避けるため、人口統計データを人口あたりまたは面積あたりの値に正規化してください(例:総人口ではなく人口密度)。
- 「最適な」ロケーションは、選択した基準と重みに完全に依存します。客観的に正しい答えはありません。必ず前提を記録し、ユーザーが重みを調整できるようにしてください。
- ツインエリアモデルでは、参照ロケーションと候補の両方に同じエンリッチメント変数セットを使用してください。変数が一致しないと、モデルが失敗したり、意味のないスコアが生成されたりします。
参照テンプレート
Academy のチュートリアル
| チュートリアル | プロバイダー | URL |
|---|---|---|
| Pizza Hut Honolulu — 商業ホットスポットを活用した出店場所の選定 | BigQuery | リンク |
| Pizza Hut Honolulu — 商業ホットスポットを活用した出店場所の選定 | Snowflake | リンク |
| 店舗間のカニバリゼーション — 新店舗の影響を定量化 | BigQuery | リンク |
| Starbucks のカニバリゼーション — H3 グリッドの重複分析 | BigQuery | リンク |
| 店舗間のカニバリゼーション — Quadkey グリッドの重複 | Snowflake | リンク |
| 業績上位店舗の類似エリアを見つける | BigQuery | リンク |
| 商圏に基づいて類似する場所を見つける | BigQuery | リンク |
| EV 充電ステーションの設置場所の選定 | Workflows | リンク |
よくあるバリエーション
| バリエーション | 方法 |
|---|---|
| 小売店舗の拡大 | 等時間圏 -> 人口統計 + 競合密度のデータを付加 -> 複合スコアを算出 -> 上位 N 件 |
| フランチャイズのテリトリー計画 | テリトリーを割り当てる前に、商圏が重ならないようカニバリゼーションのパターンを確認 |
| EV 充電/公共サービス | グリッドベースの需要(人口、交通量)+ 既存施設からの距離によるフィルター -> サービスが行き届いていないセルを順位付け |
| 看板/OOH の設置 | バッファー -> オーディエンスのデータを付加 -> 正規化 + 重み付け -> 上位 N 件(trade-area-analysis を参照) |
| 銀行支店の最適化 | 業績上位の支店周辺にある類似エリアを特定 -> 類似するサービス未提供エリアを見つける -> 新規支店を提案 |
| 競合施設との近接分析 | 競合施設までの H3 距離を算出 -> 需要が近く、競合施設から遠いセルを絞り込む |