◾️はじめに
https://dk521123.hatenablog.com/entry/2025/12/21/000330
の続き。
https://dk521123.hatenablog.com/entry/2025/12/24/001900
を書いている時に気がついたのだが、外部キーがあるようなデータって SDV (Synthetic Data Vault)はサポートしているのかって気になった。 AIに聞いたら、 『SDVの最大の強みは「外部キー(リレーションシップ)」を持った 複数テーブルのサポートにあります』って言ってたので、折角なのでメモ。
目次
【1】外部キーを考慮する合成データを作るには 【2】HMA (Hierarchical Modeling Algorithm) 1)他モデルとの対比 2)メリット・デメリット 【3】サンプル 例1:Hello world 【4】Tips 1)メタデータをJSONで保存する 2)学習済みモデルを保存する
【1】外部キーを考慮する合成データを作るには
Metadata クラスで「テーブル同士の親子関係」を定義し、 専用の HMASynthesizer を使用
【2】HMA (Hierarchical Modeling Algorithm)
HMAは、リレーショナルデータベースのように 「親テーブル(例:ユーザー)」と「子テーブル(例:注文履歴)」 があるデータを扱うための専用モデル => 特徴:テーブルをまたいだ相関(関係性)を壊さないこと
1)他モデルとの対比
| 特徴 | Single Table系 (CTGAN/GaussianCopula) | HMA (HMASynthesizer) | PAR (PARSynthesizer) |
|---|---|---|---|
| 対象構造 | 1枚の表(CSV) | 複数の表(親子関係) | 1枚の表(時系列) |
| データの繋がり | なし(1行が独立) | 1対多のリレーション | 前後の時間的つながり |
| 整合性 | 行内の整合性のみ | テーブル間の参照整合性 | 時間軸の連続性 |
| 典型的な例 | 顧客リスト(名簿) | DB(顧客+注文+配送) | センサーログ、株価 |
2)メリット・デメリット
メリット
* 外部キーの不一致(親にいないIDが子にいる)が理論上発生しない * 「都会のユーザーは注文回数が多い」といった、テーブルをまたぐルールを再現可能 * 統計モデルをベースにしているため、深層学習(GAN)系よりも比較的計算が速く、 中規模なDBであれば現実的な時間で学習が終わる
デメリット
* 階層が3段階、4段階(親→子→孫→ひ孫...)と深くなると、 末端の「孫」や「ひ孫」のデータの再現性が落ちる傾向がある * 「AとBが互いに参照し合っている(循環参照)」ような複雑なリレーションは扱えない
【3】サンプル
例1:Hello world
import pandas as pd from sdv.metadata import MultiTableMetadata from sdv.multi_table import HMASynthesizer # 1. Sample data creation users_data = pd.DataFrame({ 'user_id': [1, 2, 3], 'country': ['JP', 'US', 'US'] }) orders_data = pd.DataFrame({ 'order_id': [101, 102, 103, 104, 105], 'user_id': [1, 1, 2, 3, 3], # Outer key to users table 'amount': [1000, 2000, 1500, 3000, 500] }) # 2. To create metadata for multi-table data metadata = MultiTableMetadata() # Important: "detect_table_from_dataframe" must be called before updating columns or setting keys metadata.detect_table_from_dataframe(table_name='users', data=users_data) metadata.detect_table_from_dataframe(table_name='orders', data=orders_data) # 3. Adjust primary keys and types # After the tables are registered, update_column will work metadata.update_column(table_name='users', column_name='user_id', sdtype='id') metadata.set_primary_key(table_name='users', column_name='user_id') metadata.update_column(table_name='orders', column_name='order_id', sdtype='id') metadata.set_primary_key(table_name='orders', column_name='order_id') # Set foreign key relationship ★注目★ metadata.add_relationship( parent_table_name='users', child_table_name='orders', parent_primary_key='user_id', child_foreign_key='user_id' ) # 4. Learning and synthesis data = { 'users': users_data, 'orders': orders_data } synthesizer = HMASynthesizer(metadata) synthesizer.fit(data) # Generate synthetic data synthetic_data = synthesizer.sample(scale=1) print("--- Synthesis successful! ---") print("\n[Users Table]") print(synthetic_data['users']) print("\n[Orders Table]") print(synthetic_data['orders'])
【4】Tips
1)メタデータをJSONで保存する
# 保存 metadata.save_to_json('my_metadata.json') # 次回からの読み込み # from sdv.metadata import MultiTableMetadata # metadata = MultiTableMetadata.load_from_json('my_metadata.json')
2)学習済みモデルを保存する
# 保存 synthesizer.save('my_synthesizer.pkl') # 次回からの読み込み # from sdv.multi_table import HMASynthesizer # synthesizer = HMASynthesizer.load('my_synthesizer.pkl')
関連記事
Python SDV 〜 入門編 〜
https://dk521123.hatenablog.com/entry/2025/12/21/000330