グラウンド トゥルース データを準備する
人口動態エンベディングを使用するには、グラウンド トゥルース データをサポートされている地理的境界に集約する必要があります。行政境界の種類は世界中で異なるため、ユニバーサル数学グリッド システム(S2 セルなど)またはローカルの行政地域(特定の国のデータセットに応じて郡や地区など)を使用してデータを調整できます。
オプション 1: 既存のモデルにエンベディングを組み込む
- 既存のモデルベースのグラウンド トゥルースを準備する: エンベディングを地理空間共変量として使用して、既存のモデルを強化します。
- エラー修正モデルをトレーニングする: エンベディングを、元のモデル出力、期待値またはグラウンド トゥルース、エンベディングを入力として受け取り、新しいエラー修正モデルを学習するモデルに統合して、既存のモデルを改善します。
オプション 2: 特定のユースケースに合わせて調整する
- 予測モデルを選択します。GBDT、MLP、線形などの任意のモデルを予測に使用できます。
- 予測にエンベディングを使用する: 人口動態エンベディングを入力特徴として他のコンテキスト データとともに使用して、予測精度を向上させます。
カスタム境界集計
グラウンド トゥルース データで郵便番号、運転時間等時線、商圏などのカスタム ポリゴンを使用している場合は、境界集計を実行できます。このプロセスでは、複数の S2 セルベクトルを結合して、ターゲット ポリゴンの単一の表現を作成します。適切な重み付け方法を選択することで、集約されたエンベディングがダウンストリーム モデリングの目標を正確に反映します。
1. 人口加重平均(PDI の推奨デフォルト)
人口重み付け集計は、小売店のパフォーマンスや消費者行動のモデリングなど、人間中心のユースケースで使用します。
人口統計データに面積加重空間集計を使用すると、ML の特徴が歪む可能性があります。これは、公園、工業地帯、水域などの人口の少ない地域が、実際の居住者のプロフィールを歪めている場合に発生します。
この問題を解決するには、BigQuery で人口加重平均を計算します。このアプローチでは、Earth Engine データカタログの WorldPop などの高解像度の人口統計データセットを使用して、交差する各 S2 セル セグメントの正確な密度を計算します。
人口重み付けワークフローの完全な実装例については、インタラクティブ ノートブックを実行してください。
2. 面積加重平均
環境または物理的なユースケースでは、代わりに面積加重集計を使用します。これは、人口分布に関係なく地域を評価する必要がある土地利用分析、建築環境調査、インフラストラクチャ計画に役立ちます。
このようなシナリオでは、人口密度よりも物理的な土地面積の方が重要になります。これにより、ポリゴンの境界内のすべての平方キロメートルが、集計されたベクトルに均等に寄与します。
この方法では、各構成要素の S2 セルのエンベディング ベクトルは、ターゲット ポリゴン内でカバーする地理的表面積によって重み付けされます。
地理空間オペレーションと S2 セルの変換
人口動態の分析情報では、S2 セル レベル 12 のトークン(geo_id 列に 7 文字の 16 進数文字列として保存)が主な空間単位として使用されます。BigQuery の組み込みの地理関数を使用して、ポイント座標またはカスタム空間境界を一致する S2 セル トークンに変換できます。S2 セル トークンを可視化用のポリゴン ジオメトリに変換するには、クライアントサイド ライブラリを使用します。詳細については、S2 レベル 12 の 16 進数トークンから S2 セルのジオメトリを取得するをご覧ください。
ポイントの座標を S2 レベル 12 の 16 進数トークンに変換する
緯度/経度ポイントの座標を人口動態分析の geo_id 列と照合するには、BigQuery の S2_CELLIDFROMPOINT 関数と ST_GEOGPOINT を組み合わせて使用します。
BigQuery は S2 セル ID を符号付き INT64 値として保存するため、特定のリージョンのセル ID が負の整数として評価されます。次の例では、整数を標準の 16 進数トークンに変換し、S2 ジオメトリ仕様に従って末尾のゼロを削除する TO_S2_HEX というヘルパー関数を定義します。
次のクエリは、ニューヨークのタイムズ スクエアのポイント座標(緯度 40.75796、経度 -73.98554)を対応する S2 レベル 12 の 16 進数トークンに変換します。
CREATE TEMP FUNCTION TO_S2_HEX(s2_int INT64) RETURNS STRING AS ( RTRIM(FORMAT('%x%015x', (s2_int >> 60) & 0xF, s2_int & 0x0FFFFFFFFFFFFFFF), '0') ); SELECT 'Times Square, NYC' AS location_name, TO_S2_HEX(S2_CELLIDFROMPOINT(ST_GEOGPOINT(-73.98554, 40.75796), level => 12)) AS geo_id;
latitude 列と longitude 列を含む既存のポイント テーブルを結合可能な S2 トークンに変換するには:
CREATE TEMP FUNCTION TO_S2_HEX(s2_int INT64) RETURNS STRING AS ( RTRIM(FORMAT('%x%015x', (s2_int >> 60) & 0xF, s2_int & 0x0FFFFFFFFFFFFFFF), '0') ); SELECT store_id, TO_S2_HEX(S2_CELLIDFROMPOINT(ST_GEOGPOINT(longitude, latitude), level => 12)) AS geo_id FROM `your-project.internal_data.store_locations`;
ポリゴンの S2 レベル 12 セル トークンを生成する
データでカスタム エリア境界(商圏、配達ゾーン、郵便番号など。WKT 形式または GeoJSON 形式)を使用している場合は、ST_GEOGFROM を使用してテキスト表現を GEOGRAPHY に変換し、S2_COVERINGCELLIDS を使用して交差するすべての S2 レベル 12 セルを抽出します。
次のクエリは、ミッドタウン マンハッタンのカスタム ポリゴンをカバーするすべての S2 レベル 12 の 16 進数トークンを抽出します。
CREATE TEMP FUNCTION TO_S2_HEX(s2_int INT64) RETURNS STRING AS ( RTRIM(FORMAT('%x%015x', (s2_int >> 60) & 0xF, s2_int & 0x0FFFFFFFFFFFFFFF), '0') ); WITH CustomBoundary AS ( SELECT ST_GEOGFROM('POLYGON((-73.99 40.75, -73.97 40.75, -73.97 40.76, -73.99 40.76, -73.99 40.75))') AS geom ) SELECT TO_S2_HEX(s2_id) AS geo_id FROM CustomBoundary, UNNEST(S2_COVERINGCELLIDS(geom, min_level => 12, max_level => 12)) AS s2_id;
S2 レベル 12 の 16 進数トークンから S2 セルのジオメトリを取得する
BigQuery GIS 関数は一方向のコンバータ(Geometry → S2 セル ID)であり、S2 セルトークンをポリゴン GEOGRAPHY に変換する関数は含まれていません。可視化や空間分析のために S2 セル トークンのポリゴン ジオメトリを取得するには、s2sphere などの Python のクライアントサイド ライブラリを使用して、7 文字の S2 セル トークンを境界座標にデコードし、shapely を使用して Folium などのマッピング ツール用のポリゴンを構築します。
import s2sphere from shapely.geometry import Polygon def s2_token_to_polygon(s2_token: str) -> Polygon: """Converts a 7-character S2 cell token into a Shapely Polygon.""" cell_id = s2sphere.CellId.from_token(s2_token) cell = s2sphere.Cell(cell_id) # Extract the 4 corner vertices of the S2 cell vertices = [] for i in range(4): vertex = cell.get_vertex(i) lat_lng = s2sphere.LatLng.from_point(vertex) vertices.append((lat_lng.lng().degrees, lat_lng.lat().degrees)) # Close the polygon loop vertices.append(vertices[0]) return Polygon(vertices) # Example: Get boundary for S2 token '549056f' cell_polygon = s2_token_to_polygon('549056f') print(cell_polygon.wkt)
クエリの例
your-project.your_dataset.embeddings_table は、実際のプロジェクト、データセット、ターゲット テーブルの名前に置き換えます。
SQL: エンベディングを取得する
このクエリは、プロビジョニングされたデータセット内の S2 セルのエンベディング ベクトルと管理メタデータを取得します。
SELECT geo_id, administrative_area_level_1_name AS state, administrative_area_level_2_name AS county, features -- The 330-dim vector FROM `your-project.your_dataset.embeddings_table` LIMIT 10;
SQL: 類似した場所を検索する
このクエリは、外部データを必要とせずに、行動が類似している場所を特定します。
ML.DISTANCE 関数を使用してコサイン類似度を計算し、ターゲット S2 セルの上位一致を返します。このアプローチは、既存の成功した店舗のプロファイルに基づいて新しい店舗を開設する場所を決定するなど、拡大計画のシナリオをサポートします。
地図上に S2 セルを可視化するには、S2 セル ID を対応するポリゴン ジオメトリに変換するか、結合する必要があります。このデータセットでは、緯度と経度のポイントではなく、S2 セルトークンが使用されているためです。
WITH TargetLocation AS ( SELECT features AS target_vector FROM `your-project.your_dataset.embeddings_table` -- Replace with your target S2 hex token (e.g., '80ead45') WHERE geo_id = 'YOUR_TARGET_S2_TOKEN' ) SELECT t.geo_id, t.administrative_area_level_1_name AS state, t.administrative_area_level_2_name AS county, -- Calculate Similarity (1.0 is identical, 0.0 is dissimilar) (1 - ML.DISTANCE(t.features, p.target_vector, 'COSINE')) AS similarity_score FROM `your-project.your_dataset.embeddings_table` t, TargetLocation p WHERE t.geo_id != 'YOUR_TARGET_S2_TOKEN' -- Exclude the target itself ORDER BY similarity_score DESC LIMIT 20;
SQL: 顧客データを結合する
この例では、行動エンベディングを使用して独自の内部データ(店舗のパフォーマンス テーブルなど)を拡充する方法を示します。内部データに一致する S2 セル トークン(16 進文字列)が含まれていることを確認します。
SELECT store.store_id, store.s2_token, store.total_revenue, embeddings.features AS pdfm_vector FROM `your-project.internal_data.store_performance` AS store JOIN `your-project.your_dataset.embeddings_table` AS embeddings ON -- Join based on the S2 hex token string store.s2_token = embeddings.geo_id
Python: ML 用データを読み込む
エンベディングは BigQuery 配列として保存されます。ML ライブラリで使用するには、列を NumPy 行列に変換する必要があります。
from google.cloud import bigquery import numpy as np import pandas as pd client = bigquery.Client() query = """ SELECT geo_id, features -- Returns as a list of floats FROM `your-project.your_dataset.embeddings_table` LIMIT 1000 """ # 1. Load data into DataFrame df = client.query(query).to_dataframe() # 2. Convert the 'features' column (Series of Lists) into a Matrix (2D Array) X_matrix = np.stack(df['features'].values) print(f"Data Loaded. Matrix Shape: {X_matrix.shape}") # Output: Data Loaded. Matrix Shape: (1000, 330)
Google Colab で実行
GitHub 上のソースを見る