❄️

データエンジニア向け Snowflakeプライバシー保護機能まとめと実践⑤合成データ 25年4月一般提供版

に公開

はじめに

データ駆動型の意思決定がビジネスの重要な要素となる中、プライバシー保護とデータ活用の両立は多くの組織にとって重要な課題となっています。

2024年10月28日、Snowflakeは新たなプライバシー保護機能として合成データ生成機能をプレビューリリースしました。
その際に以下の合成データに関する記事を投稿させていただきました。
https://zenn.dev/dataheroes/articles/2aa501bd841128

それから約半年を経て、25年4月に合成データは一般提供され、複数の機能アップデートがありました。

https://docs.snowflake.com/en/release-notes/2025/9_10#synthetic-data-generation-general-availability

今回、それらの最新仕様を元に再度の検証を行いたいと思います。

1. 合成データの概要

1.1 技術的概要

合成データとは、実データの統計的特性を保持しながら、人工的に生成された新しいデータセットです。

Snowflakeの合成データ生成機能

snowlfakeでは、GENERATE_SYNTHETIC_DATA というストアドプロシージャにより、合成データを作成できます。
このストアドプロシージャは、コピュラをベースとした機械学習技術を用いて、元データの分布や関係性を学習して新たなデータを生成します。

コピュラにより、以下を実現することが期待できます

  • 個々のレコードは完全に人工的に生成
  • 統計的な特性は元データを維持
  • データ間の関連性も考慮した生成が可能

このコピュラなどの合成データに関する技術は、以前に投稿した記事を参考にしてください

https://zenn.dev/taro_cccmkhd/articles/526e83eff7dc1f

1.2 ビジネス上の意義

生成された合成データの活用により、以下のビジネス価値の提供が期待されます。

  1. 開発・テスト環境での活用

    • 本番データを使用せずに現実的なテストが可能
    • セキュリティリスクの軽減
    • 開発サイクルの効率化
  2. データ分析での活用

    • プライバシーを考慮した分析環境の提供
    • データサイエンティストの早期参画
    • 探索的なデータ分析の促進
  3. コンプライアンス対応

    • 規制要件への対応
    • データ共有における新たな選択肢
    • プライバシーリスクの低減

1は分かりやすいですね。精度よりも一定レベルのデータセットが欲しいケースは多々あります。
2や3はどうでしょう。プライバシーの保護と分析データとしての精度の両立は悩ましい課題です。

1.3 プライバシー保護機能との比較

上記を踏まえて、従来のプライバシー保護機能と合成データの特徴を比較してみました。

機能 保護レベル 実装の複雑さ 性能影響 主な使用シナリオ リスクや懸念事項
動的データマスキング 特定のユーザーや状況に応じたデータ保護 不適切な条件設定でデータ露出のリスク
行アクセスポリシー ロール別・ユーザー別のアクセス制御 ポリシーの複雑化による管理オーバーヘッド
ハッシュ化・暗号化 機密データの保存・転送時の保護 鍵管理の複雑さ、暗号化処理の遅延
セキュアビュー 必要最低限のデータアクセスの提供 設計ミスによる露出リスク、パフォーマンス低下
集計ポリシー 小規模グループに対する統計的保護 厳格すぎるポリシーによる分析の制約
投影ポリシー プライバシー項目の出力制御 設計ミスによる露出リスク
差分プライバシー 高度な匿名化と統計的有用性の両立 ノイズ追加でデータ精度が低下する可能性
合成データ 元データとの完全な分離
開発/テスト環境での利用
規制対応したデータ共有
モデルの品質管理の複雑さ
生成データの品質保証
統計的特性の検証必要性

従来のプライバシー保護機能に比べ、目的特化な機能であることが分かります。

2. 合成データ生成の仕様

生成工程に入るに辺り、snowflakeの公式ドキュメントを読み解き、その前提事項をまとめました。
プレビュー段階よりかなりの機能追加があり、非常に良いアップデートであったと判断しています。

https://docs.snowflake.com/en/sql-reference/stored-procedures/generate_synthetic_data

2.1 合成データ仕様比較表(2024年プレビュー vs 2025年GA)

項目 プレビュー(2024) 一般提供(GA 2025) 変更要約
エディション要件 Enterprise以上 Enterprise以上 変更なし
ウェアハウス要件 Snowpark(M)推奨 Snowpark(M)推奨 変更なし
最小行数要件 20行 20行 変更なし
サポート対象テーブル テーブル/ビュー 通常のテーブル、
一時テーブル、
動的テーブル、
および一時テーブル
通常のマテリアライズド ビュー、
セキュアなマテリアライズド ビュー
拡張
より詳細な記載というべきか
入力テーブル数上限 5テーブル 5テーブル 変更なし
列数上限(1テーブル) 100列 100列 変更なし
タイムスタンプ型対応 TIMESTAMP_TZ
以外のすべての日付・時刻型
TIMESTAMP_TZ
以外のすべての日付・時刻型
変更なし
レコード上限 2,300,000行/テーブル 14,000,000行/テーブル 拡張
プライバシーフィルター privacy_filter similarity_filterが推奨
privacy_filterは互換パラメータ
パラメータ変更
カテゴリ項目の識別 自動判定
(意図しないredact)
categoricalパラメータで明示指定可能 制御強化
機密項目の代替 自動判定
(意図しないredact)
replaceパラメータで明示指定可能 制御強化
結合キー整合性 なし
実行単位で整合性維持
consistency_secretにより複数実行での整合性維持 大規模対応

similarity_filterという新しいパラメータが増えており、またcategoricalreplaceconsistency_secretにいう新たな制御が追加されています。

privacy_filter/similarity_filter

公式ドキュメントでは以下の記載となっており、どちらも同じ制御を行うためのものと思われます。

privacy_filter(過去ドキュメントアーカイブより)

When you call the GENERATE_SYNTHETIC_DATA stored procedure, you can optionally set the 'privacy_filter': True configuration option to apply a privacy filter to the output table.
The privacy filter removes rows from the output table if the rows are too similar to the input data set. The privacy threshold uses the nearest neighbor distance ratio (NNDR) and distance to closest record (DCR) values to determine whether a row should be removed from the output table.

similarity_filter

When you call the GENERATE_SYNTHETIC_DATA stored procedure, you can optionally set the 'similarity_filter': True configuration option to apply a privacy filter to the output table.
The privacy filter removes rows from the output table if the rows are too similar to the input data set. The privacy threshold uses the nearest neighbor distance ratio (NNDR) and distance to closest record (DCR) values to determine whether a row should be removed from the output table.

実際の挙動としては本番データと類似性が高いデータを削除して出力するという仕様のため、
"privacy-filter"という個人情報マスキング的な意味合いではなく、"similarity-filter"という類似性の高いデータをフィルタするという意味に合わせた変更と思われます。

なお、下位互換対応としてprivacy_filterも継続して利用出来ます。

similarity_filter のフィルタ仕様

similarity_filterは、NNDRとDCRという2つの値を元に自動判定されます。

NNDR(Nearest Neighbor Distance Ratio):
最近傍データとの距離比を用いたプライバシー保護指標。0に近いほど匿名性が高い。
元データ同士で元々似ているデータがあり、それらと合成データとの比較

DCR(Distance to Closest Record):
最近傍データまでの絶対距離を用いたプライバシー保護指標。値が大きいほど匿名性が高くなります。
元データと同一のデータが出来ていないか(完全コピー)

要は、NNDRもDCRも「元データと“似すぎている”合成データを自動的に見つけて除外する、”保護すべきデータの安全性”を維持するための仕組みです。

3. 合成データの実装

それでは合成データの作成をハンズオン形式で実施しつつ、アップデート部分にも触れていきたいと思います。

3.1 基本的な構文

https://docs.snowflake.com/en/sql-reference/stored-procedures/generate_synthetic_data

GENERATE_SYNTHETIC_DATAストアドプロシージャを呼び出す事で合成データを作成できます。

CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
    'datasets': [{
        'input_table': 'PRIVACY_HO_DB.PRIVACY.TPC_STORE_SALES',
        'output_table': 'PRIVACY_HO_DB.PRIVACY.SYNTHETIC_TPC_STORE_SALES',
        'columns': {
            'ss_customer_sk': {'join_key': true}, --結合キーの指定
            'ss_store_sk': {'join_key': true} --結合キーの指定
        }
    },
    {
        'input_table': 'PRIVACY_HO_DB.PRIVACY.TPC_ACTIVE_CUSTOMERS',
        'output_table': 'PRIVACY_HO_DB.PRIVACY.SYNTHETIC_TPC_CUSTOMERS',
        'columns': {
            'c_customer_sk': {'join_key': true},
            'C_CUSTOMER_ID': {'categorical': true},--非機密情報として出力が可能(値は合成)
            'C_FIRST_NAME': {'replace': 'first_name'},
            'C_LAST_NAME': {'replace': 'last_name'},
            'C_EMAIL_ADDRESS': {'replace': 'email'}--出力時に特定の書式で出力する            
        }
    },
    {
        'input_table': 'PRIVACY_HO_DB.PRIVACY.TPC_STORE',
        'output_table': 'PRIVACY_HO_DB.PRIVACY.SYNTHETIC_TPC_STORE',
        'columns': {
            's_store_sk': {'join_key': true}
        }
    }],
    'similarity_filter': true, --プライバシー項目を除外する設定
    'consistency_secret': SYSTEM$REFERENCE('SECRET', 'SYNTHETIC_JOIN_SECRET', 'SESSION', 'READ')::STRING,--暗号化キーを設定する(複数実行時に結合キーの整合性維持)
    'replace_output_tables': true --同名テーブルを置き換える設定
});

この詳細については次の章より順に説明していきます。

3.2 合成データ ハンズオンの環境準備

TPC-Hデータより検証用のデータを切り出して作成します

-- 環境セットアップ
-- 1. ウェアハウスの作成
CREATE WAREHOUSE PRIVACY_HO_XS
WAREHOUSE_SIZE = 'X-SMALL' AUTO_SUSPEND = 60 AUTO_RESUME = TRUE INITIALLY_SUSPENDED = TRUE;
CREATE WAREHOUSE PRIVACY_HO_SNOWPARK_M
WAREHOUSE_TYPE = 'SNOWPARK-OPTIMIZED' WAREHOUSE_SIZE = 'MEDIUM'  AUTO_SUSPEND = 60 AUTO_RESUME = TRUE INITIALLY_SUSPENDED = TRUE;

-- 2. 環境、権限設定
CREATE DATABASE IF NOT EXISTS PRIVACY_HO_DB;
CREATE SCHEMA IF NOT EXISTS PRIVACY_HO_DB.PRIVACY;
CREATE ROLE IF NOT EXISTS PRIVACY_HO_ADMIN;
GRANT USAGE, OPERATE ON WAREHOUSE PRIVACY_HO_XS TO ROLE PRIVACY_HO_ADMIN;
GRANT USAGE, OPERATE ON WAREHOUSE PRIVACY_HO_SNOWPARK_M TO ROLE PRIVACY_HO_ADMIN;
GRANT OWNERSHIP ON DATABASE PRIVACY_HO_DB TO ROLE PRIVACY_HO_ADMIN;
GRANT ALL PRIVILEGES ON DATABASE PRIVACY_HO_DB TO ROLE PRIVACY_HO_ADMIN;
GRANT OWNERSHIP ON SCHEMA PRIVACY_HO_DB.PRIVACY TO ROLE PRIVACY_HO_ADMIN;
GRANT ALL PRIVILEGES ON SCHEMA PRIVACY_HO_DB.PRIVACY TO ROLE PRIVACY_HO_ADMIN;
GRANT ALL PRIVILEGES ON FUTURE TABLES IN SCHEMA PRIVACY_HO_DB.PRIVACY TO ROLE PRIVACY_HO_ADMIN;
-- GRANT ROLE PRIVACY_HO_ADMIN TO USER [username];

-- 3. サンプルテーブル作成(5,000件)
USE WAREHOUSE PRIVACY_HO_XS;
CREATE OR REPLACE TABLE PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN AS
SELECT 
  C_CUSTOMER_SK AS ID,
  C_CUSTOMER_ID,
  C_FIRST_NAME,
  C_LAST_NAME,
  C_EMAIL_ADDRESS,
  C_BIRTH_YEAR || '-' || LPAD(C_BIRTH_MONTH,2,'0') || '-' || LPAD(C_BIRTH_DAY,2,'0') AS BIRTH_DATE,
  C_PREFERRED_CUST_FLAG = 'Y' AS IS_PREMIUM
FROM SNOWFLAKE_SAMPLE_DATA.TPCDS_SF10TCL.CUSTOMER
LIMIT 5000;

3.3 合成データの作成(プレビュー機能の振り返り)

データ準備が出来たのでストアドプロシージャGENERATE_SYNTHETIC_DATAを実行します
プレビュー段階のパラメータでまずは実行してみましょう。

-- 3. 合成データの生成(プレビュー仕様)
USE ROLE PRIVACY_HO_ADMIN;
USE WAREHOUSE PRIVACY_HO_SNOWPARK_M;--Snowpark M推奨
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW',
    'columns': {'ID': {'join_key': true}}
  }],
  'privacy_filter': true,--旧パラメータ(元データと類似性の高いデータを除去)
  'replace_output_tables': true
});
-- データ量にもよりますが、数分程度で完了しました

処理後に処理結果が返却されます。

CREATED_ON TABLE_NAME TABLE_SCHEMA TABLE_DATABASE COLUMNS SOURCE_TABLE_NAME SOURCE_TABLE_SCHEMA SOURCE_TABLE_DATABASE SOURCE_COLUMNS METRIC_TYPE METRIC_VALUE
2025-05-10 17:27:55.969 CUSTOMER_SYN_OUT_PREVIEW PRIVACY PRIVACY_HO_DB ["C_FIRST_NAME", "C_LAST_NAME"] CUSTOMER_SYN PRIVACY PRIVACY_HO_DB ["C_FIRST_NAME", "C_LAST_NAME"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0351770811
2025-05-10 17:27:55.969 CUSTOMER_SYN_OUT_PREVIEW PRIVACY PRIVACY_HO_DB ["C_FIRST_NAME", "IS_PREMIUM"] CUSTOMER_SYN PRIVACY PRIVACY_HO_DB ["C_FIRST_NAME", "IS_PREMIUM"] CORRELATION_COEFFICIENT_DIFFERENCE 0.1413756622
2025-05-10 17:27:55.969 CUSTOMER_SYN_OUT_PREVIEW PRIVACY PRIVACY_HO_DB ["C_LAST_NAME", "IS_PREMIUM"] CUSTOMER_SYN PRIVACY PRIVACY_HO_DB ["C_LAST_NAME", "IS_PREMIUM"] CORRELATION_COEFFICIENT_DIFFERENCE 0.04233789739

この情報は項目ごとの相関係数の絶対値の差を表しており、"0"に近いほど高品質な(関係性の差が少ない)合成データを作成出来ているという事になります。
今回の場合、以下のような見解になります。

  • C_FIRST_NAMEC_LAST_NAMEの相関性は97%維持出来ている
  • C_FIRST_NAME, IS_PREMIUMの相関性は85%維持出来ている(ちょっと偏りがある)
  • C_LAST_NAME, IS_PREMIUMの相関性は95%維持出来ている(ちょっと偏りがある)

ここで疑問となるのがインプットしたテーブルについては他にも項目があるため、この3の組み合わせのみを評価している事に違和感があります。
そこで実際の出力結果や件数を確認してみましょう。

-- 元データと出力件数を比較
USE WAREHOUSE PRIVACY_HO_XS;
SELECT * FROM 
(SELECT '0.original' as "Type",COUNT(*) as "CNT" from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN )
union
(SELECT '1.preview',COUNT(*) from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW )

Type	CNT
0.original	5000
1.preview	154

--大きく件数が減少していますね。これはどういう事でしょうか?

-- 元データと出力件数を5件ずつサンプル比較
SELECT * FROM 
(SELECT '0.original' as "Type",* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN limit 5)
union
(SELECT '1.preview',* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW limit 5)
Type ID C_CUSTOMER_ID C_FIRST_NAME C_LAST_NAME C_EMAIL_ADDRESS BIRTH_DATE IS_PREMIUM
0.original 13823036 AAAAAAAAMDMOCNAA Evonne King Evonne.King@lIEvtT3fHSV1GH.com 1954-12-07 FALSE
0.original 13823037 AAAAAAAANDMOCNAA Byron Kelly Byron.Kelly@ni.com 1962-11-09 TRUE
0.original 13823039 AAAAAAAAPDMOCNAA Ruth Terry Ruth.Terry@jdJTPT42m.org 1965-12-27 FALSE
0.original 13823040 AAAAAAAAAEMOCNAA Chester Woods Chester.Woods@e6vM592vQfl.com 1946-04-06 TRUE
0.original 13823038 AAAAAAAAODMOCNAA Paula Rose Paula.Rose@EskCx2PrOuGA7T7.edu 1987-08-11 FALSE
1.preview 0 redacted Kareem Huntington redacted redacted TRUE
1.preview 1 redacted Maurice Wynn redacted redacted FALSE
1.preview 4 redacted Marcos Santana redacted redacted TRUE
1.preview 2 redacted Brain Thayer redacted redacted TRUE
1.preview 3 redacted Terrie Savage redacted redacted TRUE

オリジナルに対し、プレビュー版のデータはC_CUSTOMER_ID,C_EMAIL_ADDRESS,BIRTH_DATEがredactedされていることが分かります。
一意性の傾向があり、機密性の高いデータと判定された項目は自動的にredactedされており、その結果、それ以外の項目での相関性を図る事になります。
つまり、join_key以外の値のある項目C_FIRST_NAME,C_LAST_NAME,IS_PREMIUM項目での評価となり、この3つの項目で類似性が高い場合、privacy_filterを制御により、元データの近似性が高いデータは出力行から削除されます。

つまり、redactedされた項目を除く残りの項目のみでは、元データと合成データの類似性が高い状態となってしまい、出力行から大幅に除外されたものと思われます。

この問題は以前より傾向として存在しており、新しく追加されたパラメータにより、改善されるのでないかと推測されます。

3.4 合成データのプレビュー/GA パターンごとの出力

主な観点として、redactedされないためのcategorical,replaceの制御を行いつつ、新旧のプライバシー制御である、similarity_filter,privacy_filterをオリジナルデータとの比較を通じて実施していきたいと思います。


-- 0.複数実行用の結合キー整合性用の consistency_secret の作成
USE ROLE PRIVACY_HO_ADMIN;
USE WAREHOUSE PRIVACY_HO_XS;
CREATE SECRET PRIVACY_HO_DB.PRIVACY.SYNTHETIC_JOIN_SECRET
  TYPE = SYMMETRIC_KEY
  ALGORITHM = GENERIC;

GRANT USAGE ON SECRET PRIVACY_HO_DB.PRIVACY.SYNTHETIC_JOIN_SECRET TO ROLE PRIVACY_HO_ADMIN;

-- 1.プレビュー版の合成データ(privacy_filterあり)
USE WAREHOUSE PRIVACY_HO_SNOWPARK_M;
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW',
    'columns': {'ID': {'join_key': true}}
  }],
  'privacy_filter': true,
  'replace_output_tables': true
});
-- 2.プレビュー版の合成データ(privacy_filterなし)
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW_NP',
    'columns': {'ID': {'join_key': true}}
  }],
  'privacy_filter': false,
  'replace_output_tables': true
});

-- 3.一般提供版の合成データ(similarity_filterあり)
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA',
    'columns': {
      'ID': {'join_key': true},
      'C_EMAIL_ADDRESS': {'replace': 'email'},--メールアドレス形式の合成データ化
      'BIRTH_DATE': {'categorical': true}--一意性があるが出力を可とする
    }
  }],
  'similarity_filter': true,
  'consistency_secret': SYSTEM$REFERENCE('SECRET', 'SYNTHETIC_JOIN_SECRET', 'SESSION', 'READ')::STRING,--セッション内のキーの指定
  'replace_output_tables': true
});

-- 4.一般提供版の合成データ(similarity_filterなし)
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA_NS',
    'columns': {
      'ID': {'join_key': true},
      'C_EMAIL_ADDRESS': {'replace': 'email'},
      'BIRTH_DATE': {'categorical': true}
    }
  }],
  'similarity_filter': false,--フィルターをオフ
  'consistency_secret': SYSTEM$REFERENCE('SECRET', 'SYNTHETIC_JOIN_SECRET', 'SESSION', 'READ')::STRING,--セッション内のキーの指定
  'replace_output_tables': true
});

3.5 元データとの比較

元データと生成した合成データを比較しましょう。

-- 全体の件数チェック
USE WAREHOUSE PRIVACY_HO_XS;
SELECT * FROM 
(SELECT '0.original' as "Type",COUNT(*) as "CNT" from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN )
union
(SELECT '1.preview',COUNT(*) from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW )
union
(SELECT '2.preview_np',COUNT(*) from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW_NP )
union
(SELECT '3.ga',COUNT(*) from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA )
union
(SELECT '4.ga_ns',COUNT(*) from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA_NS )
ORDER BY 1

-- アルゴリズムで生成するため、ストアド実行ごとに結果が微妙に変わります。

Type	CNT_1	CNT_2	CNT_3
0.original	5000	5000	5000
1.preview	123	123	121
2.preview_np	4842	4842	4842
3.ga	3638	3105	4764
4.ga_ns	4842	4842	4842

similarity_filterprivacy_filterも)を設定した際は、出力結果にばらつきがあるため、減少率が高い時は、categorical``replaceを見なおしたり、生成を再実行すると良いと思います。

全体の傾向は把握出来たので具体的なデータ内容を確認していきましょう。

-- 各パターンの5件ずつの比較
SELECT * FROM 
(SELECT '0.original' as "Type",* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN limit 5)
union
(SELECT '1.preview',* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW limit 5)
union
(SELECT '2.preview_np',* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_PREVIEW_NP limit 5)
union
(SELECT '3.ga',* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA limit 5)
union
(SELECT '4.ga_ns',* from PRIVACY_HO_DB.PRIVACY.CUSTOMER_SYN_OUT_GA_NS limit 5)
ORDER BY 1
Type ID C_CUSTOMER_ID C_FIRST_NAME C_LAST_NAME C_EMAIL_ADDRESS BIRTH_DATE IS_PREMIUM
0.original 13823037 AAAAAAAANDMOCNAA Byron Kelly Byron.Kelly@ni.com 1962-11-09 TRUE
0.original 13823039 AAAAAAAAPDMOCNAA Ruth Terry Ruth.Terry@jdJTPT42m.org 1965-12-27 FALSE
0.original 13823040 AAAAAAAAAEMOCNAA Chester Woods Chester.Woods@e6vM592vQfl.com 1946-04-06 TRUE
0.original 13823038 AAAAAAAAODMOCNAA Paula Rose Paula.Rose@EskCx2PrOuGA7T7.edu 1987-08-11 FALSE
0.original 13823036 AAAAAAAAMDMOCNAA Evonne King Evonne.King@lIEvtT3fHSV1GH.com 1954-12-07 FALSE
1.preview 0 redacted Cristi Burchfield redacted redacted TRUE
1.preview 1 redacted Doreen Rawlins redacted redacted TRUE
1.preview 2 redacted Terrance Poland redacted redacted FALSE
1.preview 3 redacted Saul Lear redacted redacted TRUE
1.preview 4 redacted Lynnette Wooten redacted redacted TRUE
2.preview_np 2 redacted Brett Crooks redacted redacted FALSE
2.preview_np 4 redacted Jerald Phillips redacted redacted TRUE
2.preview_np 3 redacted Linda Moore redacted redacted TRUE
2.preview_np 1 redacted Donnie Hoffman redacted redacted FALSE
2.preview_np 0 redacted Ronald Sills redacted redacted FALSE
3.ga 1 redacted Claude Watson UYMakc7nUfWJ52vNnqc5XA@yahoo.com 1952-11-03 TRUE
3.ga 2 redacted Celia Daly qwbyzZmkXYuGu9XLZI5zAQ@yahoo.com 1978-04-24 TRUE
3.ga 3 redacted John Ellison EZ.147ZMUy.z9RRvDEOtvw@example.com 1969-09-09 TRUE
3.ga 4 redacted John Joseph Q1L4TDqLW_yVqFTQ9kv6jA@example.org 1936-04-15 TRUE
3.ga 0 redacted Donald Maddox ceUKc3nhUk6LQj7MPDqTng@example.org 1934-04-08 FALSE
4.ga_ns 0 redacted Gerald Rodriguez qSRVnfl8WJioxP7s1v.skg@example.com 1964-11-27 FALSE
4.ga_ns 1 redacted Shelley Ayala YdByWDYQWAS1RaVin45pfQ@duck.com 1947-07-23 TRUE
4.ga_ns 3 redacted Antoine Callaghan 8KmbXG1AXBSCDf6CCIerPw@example.com 1957-10-13 TRUE
4.ga_ns 4 redacted Bertha Childs 6vivfwbjVJ24V71lC1w.uA@outlook.com 1969-04-20 TRUE
4.ga_ns 2 redacted Lyda Pruitt S5zQAmp9WNGXevli2aCqVw@protonmail.com 1989-05-09 TRUE

ID:0からの採番で出力
C_CUSTOMER_ID:redacted※出力するための設定は未実施
C_FIRST_NAME:類似した合成名で出力
C_LAST_NAME:類似した合成名で出力
C_EMAIL_ADDRESS:redactedされていたが、replaceにより出力
BIRTH_DATE:redactedされていたが、categoricalにより出力
IS_PREMIUM:boolean型に従って出力

メアドや生年月日を出力されるように設定したため、パターン3,4については合成データとして利用可能な項目が増えました。
それぞれ機密情報に近しいものではあるものの分析や販促用途で使うケースが考えられ、これらの出力可否を明示的に指示出来るようになったのは大きなバージョンアップと言えます。

また上記の制御をいれる事でデータパターンが増えたことで、パターン1のような高近似性による大幅な減少も解消されています。

3.6 トラン系での合成データ(最大行数1,400万件)

さてここまでは顧客マスタに対して実施してきましたが、最後にトランザクションデータとして、1,400万件の注文データに対してGENERATE_SYNTHETIC_DATAで実行してみましょう。

USE WAREHOUSE PRIVACY_HO_XS;
-- TPC-Hデータより1400万件の注文データを作成
CREATE TABLE PRIVACY_HO_DB.PRIVACY.ORDERS_14M as
select * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF10.ORDERS
limit 14000000

USE WAREHOUSE PRIVACY_HO_SNOWPARK_M;

CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
  'datasets': [{
    'input_table': 'PRIVACY_HO_DB.PRIVACY.ORDERS_14M',
    'output_table': 'PRIVACY_HO_DB.PRIVACY.ORDERS_14M_SYN'
  }],
  'similarity_filter': false,--フィルターをオフ
  'replace_output_tables': true
});

処理時間は約7分でした。
SnowparkのMサイズは1時間当たり6クレジットなので、7分で0.7クレジットぐらいですね。

出力結果

CREATED_ON TABLE_NAME TABLE_SCHEMA TABLE_DATABASE COLUMNS SOURCE_TABLE_NAME SOURCE_TABLE_SCHEMA SOURCE_TABLE_DATABASE SOURCE_COLUMNS METRIC_TYPE METRIC_VALUE
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_CUSTKEY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_CUSTKEY"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0002091584203
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERSTATUS"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERSTATUS"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0002062337205
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_TOTALPRICE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_TOTALPRICE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0002435110197
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERDATE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERDATE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0006057645466
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERPRIORITY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_ORDERPRIORITY"] CORRELATION_COEFFICIENT_DIFFERENCE 3.691570796e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERKEY", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0004168086192
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERSTATUS"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERSTATUS"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0003700285148
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_TOTALPRICE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_TOTALPRICE"] CORRELATION_COEFFICIENT_DIFFERENCE 1.568617092e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERDATE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERDATE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0001830211924
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERPRIORITY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_ORDERPRIORITY"] CORRELATION_COEFFICIENT_DIFFERENCE 9.957017011e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_CUSTKEY", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 0.000365676654
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_TOTALPRICE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_TOTALPRICE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0001421590071
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_ORDERDATE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_ORDERDATE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.8760759033
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_ORDERPRIORITY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_ORDERPRIORITY"] CORRELATION_COEFFICIENT_DIFFERENCE 1.025114405e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERSTATUS", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 0.000127519367
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_ORDERDATE"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_ORDERDATE"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0003041761783
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_ORDERPRIORITY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_ORDERPRIORITY"] CORRELATION_COEFFICIENT_DIFFERENCE 4.033736648e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_TOTALPRICE", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 8.034025813e-05
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERDATE", "O_ORDERPRIORITY"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERDATE", "O_ORDERPRIORITY"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0001365820082
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERDATE", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERDATE", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 0.0001977346515
2025-05-11 15:37:39.791 ORDERS_14M_SYN PRIVACY PRIVACY_HO_DB ["O_ORDERPRIORITY", "O_CLERK"] ORDERS_14M PRIVACY PRIVACY_HO_DB ["O_ORDERPRIORITY", "O_CLERK"] CORRELATION_COEFFICIENT_DIFFERENCE 7.617043486e-06

3.7 トラン系データの結果分析

1. 主要指標の概要

項目間の相関性評価を元にサマリした結果がこちらです。

指標 解釈
処理行数 14,000,000行 Snowflakeの最大処理能力をフル活用
平均相関差異 0.0021 全体的に極めて高い再現性
最大相関差異 0.876 O_ORDERSTATUS-O_ORDERDATE間で発生

この中で特に相関性の乖離が大きい、O_ORDERSTATUS-O_ORDERDATEについて比較してみましょう。

2. 異常値の詳細分析

O_ORDERSTATUS(注文状態)とO_ORDERDATE(注文日)の関係性崩壊

-- 元データと合成データの月別注文数比較
WITH original AS (
  SELECT 
    O_ORDERSTATUS,
    DATE_TRUNC('MONTH', O_ORDERDATE) AS MONTH,
    COUNT(*) AS CNT
  FROM ORDERS_14M
  GROUP BY 1,2
),
synthetic AS (
  SELECT 
    O_ORDERSTATUS,
    DATE_TRUNC('MONTH', O_ORDERDATE) AS MONTH,
    COUNT(*) AS CNT
  FROM ORDERS_14M_SYN
  GROUP BY 1,2
)
SELECT 
  o.O_ORDERSTATUS,
  o.MONTH,
  o.CNT AS ORIGINAL_CNT,
  s.CNT AS SYNTHETIC_CNT,
  ABS(o.CNT - s.CNT) AS DIFF,
  ROUND(ABS(o.CNT - s.CNT) / o.CNT * 100, 2) AS DIFF_PERCENT
FROM original o
LEFT JOIN synthetic s
  ON o.O_ORDERSTATUS = s.O_ORDERSTATUS
  AND o.MONTH = s.MONTH
ORDER BY DIFF_PERCENT DESC
LIMIT 10;
O_ORDERSTATUS MONTH ORIGINAL_CNT SYNTHETIC_CNT DIFF DIFF_PERCENT
O 1995-02-01 537 65461 64924 12090.13
F 1995-06-01 1062 78077 77015 7251.88
F 1995-05-01 9722 86466 76744 789.38
O 1995-03-01 8051 69465 61414 762.81
O 1995-04-01 24155 91658 67503 279.46
F 1995-04-01 27200 91157 63957 235.14
P 1995-03-01 97248 3165 94083 96.75
P 1995-04-01 123074 4117 118957 96.65
P 1995-05-01 104255 4084 100171 96.08
P 1995-06-01 20816 3580 17236 82.80

原因推定:

  • 注文日時と注文ステータスの間には一定の相関性があるが、アルゴリズムではその判断が出来ない
  • 結果として時間依存性の強いデータ特性をモデルが捕捉できていない

影響範囲:

  • 時系列分析の精度低下
  • 需要予測モデルの信頼性低下

データを確認すると相関性を読み解けないことで、全体的に日ごとに平均化されている傾向があります。時系列の補足としては相関性がない状態となりますが、逆に言えば、満遍なくデータを散布して欲しいケースでは一定の効能もあるように思いますので、合成データの特徴を理解しつつ、どの用途に使えるかを見極める力が必要です。

総合考察

それらを踏まえた合成データの活用シーンは以下と考えます。

4.1 推奨される活用シーン

テーマ 活用用途 活用のポイント
開発・
テスト
基本分布の高精度な再現
プライバシー保護の確保
テストデータへ即活用可能
本番相当の検証環境構築
基礎分析 単一変数の特性維持
カテゴリ分布の再現
顧客属性分析
セグメント分析
機械学習 特徴量エンジニアリング用データ生成 モデル検証時のデータ漏洩防止
データ共有 プライバシーリスクの低減
データ活用の促進
部門間での安全な共有
外部連携での活用

また上記のような活用やさらに活用範囲を広げるためには以下のような改善や進化を続けて欲しいと考えています。

4.2 相関性の課題

  • 変数間の関係性表現の強化
  • より複雑なパターンの学習
  • 新しいデータタイプへの対応

合成データのまとめ

Snowflakeの合成データ機能は、プレビュー段階より大幅な機能アップデートがされており、より本番に近しい合成データをより安全に作成出来るようになりました。
また性能面や複数のテーブルでの段階的な作成にも対応出来るようになったことで、開発環境や複雑な分析への活用もよりしやすくなったと考えています。
一方でより深い活用をする上で、項目間相関性の再現性の向上が求められます。また現在利用しているコピュラでは限界もあると考えており、近い将来、ディープラーニングや生成AIベースの合成データ作成アルゴリズムがこれらの問題を解消してくれるのではないかと考えています。

それらを考慮するとプライバシーを考慮したデータ活用の新しい選択肢として、その発展が楽しみな機能と言えそうです。

本記事のまとめ

Snowflakeは、プライバシー保護を実現するためにさまざまな機能を提供しており、それらは強力で柔軟なプライバシー保護を実現できるものです。 ただし、自社のデータが複雑化し、詳細化していく中で、プライバシー保護の取り組みもさらに高度化していく必要があります。

プライバシー保護機能の紹介についても、第5章まで増えており、これらの機能の今後のアップデートも引き続き期待をしていきたいと思います。

毎度長文で読みづらくて申し訳ない気もしますが、自分で振り返る時に、1記事で情報がまとまっているので、便利に使っている事もあり、お付き合いいただければと思います!

Snowflake Data Heroes

Discussion