差分プライバシー入門¶
概要¶
このチュートリアルでは、差分プライバシーポリシーを使用して機密データを保護し、アナリストと安全に共有する方法を説明します。
学習内容¶
このチュートリアルでは、以下の方法を学びます。
差分プライバシーポリシーを作成します。
そのプライバシーポリシーをテーブルに適用し、差分プライバシーで保護します。
テーブルのプライバシードメインを定義します。
差分プライバシーで保護されたテーブルに対してクエリを実行します。
クエリ結果に含まれるノイズの量を判断します。
このチュートリアルでは、 ノイズ、 プライバシーバジェット、 プライバシードメイン など、差分プライバシーのキーコンセプトについて完全には説明していません。このチュートリアルでは、データに差分プライバシーを適用する方法に焦点を当てます。
管理者とアナリストについて¶
このチュートリアルでは、2人のペルソナを想定しています。
生データへの権限を持ち、テーブルの差分プライバシーポリシーを管理する管理者。
アナリストは、この保護されたデータに対してクエリを実行します。
実際の大文字と小文字の使用例では、異なる2人またはグループであったり、保護された結果を分析し、他の人と安全に共有したい1人であったりします。
このチュートリアルでは、保護されたデータに対してクエリを実行する方法を示しますが、これは主に、差分プライバシーの利用方法よりも、差分プライバシーの実装方法を示すことを目的としています。
前提条件¶
Enterprise Editionもしくはそれ以上 のアカウントである必要があります。
ACCOUNTADMIN ロールが** 使用できなければなりません。
重要
このチュートリアルでは、 ACCOUNTADMIN ロールを使用して、管理者ペルソナのすべての手順を実行します。しかし、一般的には、実行するアクションに対して特別に定義された権限を持つロールを使用すべきです。プライバシーポリシーの作成と適用に必要な権限は、 ここに記載 されています。
ロール、ウェアハウス、データの作成¶
このセクションでは、以下のセットアップ手順を実行します。
アナリストのロールを作成します。
保護されたデータに対するクエリの実行に使用するウェアハウスを作成します。
プライバシーポリシーによって保護される、模擬的な機密データを作成します。
これらのセットアップ手順はいずれも、差分プライバシーポリシーに特化したものではありません。適切なロール、ウェアハウス、データセットが既に存在する場合は、それらを代わりに使用することができます。
アナリストロールの作成¶
自分のSnowflakeアカウントでSnowflake SQL を実行するために接続されているSnowsightワークシートまたはその他の環境で、以下のコマンドを実行してアナリストロールを作成し、自分に割り当てます。
USE ROLE ACCOUNTADMIN;
CREATE ROLE dp_tutorial_analyst;
-- You can find your own user name by running "SELECT CURRENT_USER();"
GRANT ROLE dp_tutorial_analyst TO USER <user_name>;
データウェアハウスの構築¶
CREATE OR REPLACE WAREHOUSE dp_tutorial_wh;
GRANT USAGE ON WAREHOUSE dp_tutorial_wh TO ROLE dp_tutorial_analyst;
模擬機密データの作成¶
以下のコマンドは、データベース、スキーマ、テーブルを作成し、データを入れます。このデータは、患者のIDを保護したい単純な糖尿病研究をシミュレートしたものです。チュートリアルの後半では、差分プライバシーを使用して、研究に参加する個人のIDを保護します。
-- Create the table
CREATE OR REPLACE DATABASE dp_db;
CREATE OR REPLACE SCHEMA dp_db.dp_schema;
USE SCHEMA dp_db.dp_schema;
CREATE OR REPLACE TABLE dp_tutorial_diabetes_survey (
patient_id TEXT,
is_smoker BOOLEAN,
has_difficulty_walking BOOLEAN,
gender TEXT,
age INT,
has_diabetes BOOLEAN,
income_code INT);
-- Populate the table
INSERT INTO dp_db.dp_schema.dp_tutorial_diabetes_survey
VALUES
('ID-23493', TRUE, FALSE, 'male', 39, TRUE, 2),
('ID-00923', FALSE, FALSE, 'female', 82, TRUE, 5),
('ID-24020', FALSE, FALSE, 'male', 69, FALSE, 8),
('ID-92848', TRUE, TRUE, 'other', 75, FALSE, 3),
('ID-62937', FALSE, FALSE, 'male', 46, TRUE, 5);
注意:
差分プライバシーを使用するよりも、患者 ID をマスキングする方が良いように思われるかもしれませんが、その列に対する結合を妨げることになります。さらに、投薬テーブルや面会テーブルなど、各患者が複数の行を持つテーブルを追加した場合、単純なマスキングによって、患者ごとに結果をグループ化することができなくなります。これは、差分プライバシーが単純なマスキングや行の非表示よりもはるかに強力になる大文字と小文字のケースです。エンティティのプライバシーを保護しながら、分析者がより多くのデータを利用できるようにし、より有用なクエリを可能にすることができます。
プライバシーポリシーの定義¶
プライバシーポリシー をテーブルまたはビューに適用することで、差分プライバシーで保護し、 プライバシーバジェット をグループまたはユーザーに割り当てることで、Snowflake が複数のクエリで機密情報が過度に公開されるのを防ぐことができます。
独自のデータベースにプライバシーポリシーを作成します。これは、Snowflakeのすべてのタイプのポリシーのベストプラクティスです。同じデータベースにポリシーを作成する場合、データベースのクローニングを行うと、ポリシーの同期されていないコピーが作成されます。すべてのポリシーを単一の独立したデータベースに格納し、複数のテーブルに適用することで、各ポリシーの単一のコピーを管理および更新できます。
この新しいポリシーには patients_policy
という名前を付けます。
-- Define a privacy policy. Use default budget, budget window, max budget per aggregate.
CREATE OR REPLACE DATABASE policy_db;
CREATE OR REPLACE SCHEMA policy_db.diff_priv_policies;
CREATE OR REPLACE PRIVACY POLICY policy_db.diff_priv_policies.patients_policy AS () RETURNS privacy_budget ->
CASE
WHEN CURRENT_ROLE() = 'ACCOUNTADMIN' THEN no_privacy_policy()
WHEN CURRENT_ROLE() IN ('DP_TUTORIAL_ANALYST')
THEN privacy_budget(budget_name => 'clinical_analysts')
ELSE privacy_budget(budget_name => 'default')
END;
注意:
適用されるプライバシーポリシーは、 CASE ステートメントで指定されているように、ユーザーのロールによって異なります。CURRENT_ROLE() は大文字の値を返すので、ロール名はここでは大文字で指定します。
ロールごとに別々のプライバシー予算を作成することで、アナリストとその他のユーザーに使用する予算を分けることができ、また各グループの使用状況を監視することができます。
評価時にプライバシーポリシーが有効なプライバシーバジェットに解決された場合、ユーザーは非集約 SELECT クエリを実行できず、クエリ結果にノイズが追加され、クエリ数はそのポリシーのプライバシーバジェットによって制限されます。
アカウント管理ロールにはプライバシーポリシーが適用されていません。これは、そのロールとして実行されるクエリには差分プライバシーが適用されないことを意味します。プライバシーポリシーがないことを示すには、 NULL を返すのではなく、
no_privacy_policy()
を返す必要があります。DP_TUTORIAL_ANALYST ロールは "clinical_analysts "という名前のプライバシーポリシーを使用し、プライバシー予算、予算ウィンドウ、および集約ごとの最大予算はデフォルト値です。
SELECT アクセスを持つ他のユーザーは、「default」という名前のプライバシーバジェットを取得し、デフォルトのプライバシーポリシー値も取得します。他のユーザーがこのテーブルでクエリを実行できないようにするには、テーブルの SELECT 権限を制限する必要があります。テーブルレベルのポリシーは ELSE 句を必要とし、 NULL を返すことはできません。
プライバシーポリシーの割り当て¶
次に、先ほど作成したプライバシーポリシーをテーブルに割り当て、差分プライバシーで保護します。
-- Assign the privacy policy to the table.
ALTER TABLE dp_db.dp_schema.dp_tutorial_diabetes_survey
ADD PRIVACY POLICY policy_db.diff_priv_policies.patients_policy ENTITY KEY (patient_id);
注意:
ENTITY KEY 句は、差分プライバシーで保護されるべきエンティティを一意に識別する列を指定します。このチュートリアルでは、各エンティティが1つの行に1つだけリストされる単一のテーブルを使用するため、エンティティ・キーの定義はそれほど重要ではありません。しかし、各患者が複数の行に表示される可能性がある場合(例えば、患者の来院や患者の投薬状況を把握する場合)、キーの定義が重要になります。後で2つ目のテーブルがデータベースに追加された場合に備えて、ここでキーを定義しておくのは良い習慣です。 エンティティレベルのプライバシー の詳細については、こちらをご覧ください。
プライバシードメインの定義¶
次に、 プライバシードメイン をテーブルの選択列にセットします。
プライバシードメイン は、その列の結果に表示できる値の範囲をシステムに伝えます。システムはこの情報を2つの方法で使用します。
この範囲外の値は、列が文字列であるか数値/日付値であるかに応じて、省略されるか境界に固定されます。
システムは、各測定値に適用されるノイズを決定するために、結果の範囲を決定する方法として、この「有効範囲」を使用します。
分析者は、例えば WHERE 句を使用することで、ドメインをさらに制限することができ、差分プライバシーによって生成されるノイズの量を潜在的に減らすことができます(ドメインが小さいほど、ノイズは少なくなります)。列にプライバシー・ドメインを設定しない場合、アナリストがその列の値を表示するには、 WHERE 句でプライバシー・ドメインを追加する必要があります (プライバシー・ドメインのない列は表示できませんし、クエリで使用できません)。
糖尿病の調査データについては、 gender
、 age
、 income_code
の3列にプライバシードメインをセットします。また、 patient_id
列にプライバシードメインを設定すべきではありません。なぜなら、プライバシードメインに設定した値をユーザーが見ることができ、どの患者 IDs がデータに含まれているかがわかってしまうからです。ZIP コードなど、限られた文字列値に対してプライバシー・ドメインを指定する必要がある場合、 ドメイン定義 に、存在しない値を追加して、可能性のある値をわかりにくくする必要があります。
-- Define privacy domains.
ALTER TABLE dp_db.dp_schema.dp_tutorial_diabetes_survey ALTER (
COLUMN gender SET PRIVACY DOMAIN IN ('female', 'male', 'other'),
COLUMN age SET PRIVACY DOMAIN BETWEEN (0, 90),
COLUMN income_code SET PRIVACY DOMAIN BETWEEN (1, 8)
);
アナリストにテーブルへのアクセスを付与する¶
データにプライバシーポリシーを割り当てた後でのみ、テーブルへのアクセスを許可します。そうしないと、プライバシーポリシーを適用する前にユーザーにデータを見られる可能性があります。
GRANT USAGE ON DATABASE dp_db TO ROLE dp_tutorial_analyst;
GRANT USAGE ON SCHEMA dp_schema TO ROLE dp_tutorial_analyst;
GRANT SELECT
ON TABLE dp_db.dp_schema.dp_tutorial_diabetes_survey
TO ROLE dp_tutorial_analyst;
クエリの実行¶
最後に、データに対してクエリを実行することができます!
管理者とアナリストのロールを切り替えて、それぞれのロールの動作と出力を比較します。
差分プライバシーが機能しているかチェックする¶
個々の行を返すクエリを実行するには、管理者ロールを使用してください。このクエリは、 ACCOUNTADMIN ロールのプライバシー・ポリシーが no_privacy_policy() に解決されるので成功します。
USE ROLE ACCOUNTADMIN;
SELECT * FROM dp_db.dp_schema.dp_tutorial_diabetes_survey;
次に、同じクエリをアナリスト・ロールを使用して実行します。ディファレンシャル・プライバシーは SELECT * クエリを許可しないため、クエリは失敗します。
USE ROLE dp_tutorial_analyst;
SELECT * FROM dp_db.dp_schema.dp_tutorial_diabetes_survey;
既定の結果が同じであることを確認するために、3つ目のロールで試してみてください。(テーブル上の SELECT を、その人やロールに付与することをお忘れなく!)
ノイズとはどのようなものか¶
まず、管理者として単純なクエリを実行します。正確なテーブル値が表示されます。
-- Run a basic query without DP.
USE ROLE ACCOUNTADMIN;
SELECT COUNT(DISTINCT patient_id)
FROM dp_db.dp_schema.dp_tutorial_diabetes_survey
WHERE income_code = 5;
同じクエリをアナリストとして実行すると、結果にノイズがかかっていることがわかります。差分プライバシーが適用されているため、クエリに少し時間がかかることに注意してください。
USE ROLE dp_tutorial_analyst;
SELECT COUNT(DISTINCT patient_id)
FROM dp_db.dp_schema.dp_tutorial_diabetes_survey
WHERE income_code = 5;
差分プライバシーは、データセット内の個人の存在を不明瞭にするために、結果にノイズを導入しているため、結果は通常、管理者の結果とは異なります。しかし、どのクエリでもランダムに発生したノイズが0に切り捨てられるほど小容量であったため、クエリ結果が同じになることがあります。しかし、アナリストは与えられたクエリにノイズがかかっているかどうかを知ることはできません。このクエリを再度実行して、異なる結果が得られるかどうかを確認してください。
ノイズの量を分析する¶
分析者はノイズのない結果を見ることはできませんが、データが用途に対して使用可能かどうか判断するために、一般的にどの程度ノイズのある結果なのかを理解する方法は必要です。この情報を提供するために、各クエリパラメーターのノイズ間隔をアナリストに公開します。ノイズ区間は関数 DP_INTERVAL_LOW と DP_INTERVAL_HIGH を使って取得します。
-- Retrieve noise interval for the previous query.
USE ROLE dp_tutorial_analyst;
SELECT COUNT(DISTINCT patient_id) as c,
DP_INTERVAL_LOW(c) as LOW,
DP_INTERVAL_HIGH(c) as HIGH
FROM dp_db.dp_schema.dp_tutorial_diabetes_survey
WHERE income_code = 5;
集計の真の値が LOW から HIGH の間であることは、最低95%の信頼性があります。
このデータに対するこのクエリの区間は、人為的にデータセットを小さくしているため、結果の大きさに比べて広いことに注意してください。このようにノイズの間隔が広いということは、Snowflakeが患者のプライバシーを守りながら正確な答えを出すには、患者の数が少なすぎるということです。
ご予算と残りクエリの目安をご確認ください。¶
差分プライバシー保護されたテーブルでクエリを実行しているユーザーは、 ESTIMATE_REMAINING_DP_AGGREGATES テーブル関数を呼び出すことで、使用した差分プライバシーバジェット、および残りのクエリ数の見積もりを確認することができます。予算を確認したいロールを想定し、次のように関数を呼び出してください。
USE ROLE <role_name>;
SELECT * FROM TABLE(SNOWFLAKE.DATA_PRIVACY.ESTIMATE_REMAINING_DP_AGGREGATES(dp_db.dp_schema.dp_tutorial_diabetes_survey));
クリーンアップする¶
リソースをクリーンアップして、後でチュートリアルを実行できるようにしてください。
USE ROLE ACCOUNTADMIN;
DROP ROLE dp_tutorial_analyst;
DROP WAREHOUSE dp_tutorial_wh;
ALTER TABLE dp_tutorial_diabetes_survey
DROP PRIVACY POLICY policy_db.diff_priv_policies.patients_policy;
DROP DATABASE dp_db;
DROP DATABASE policies_db;