ノイズ付き集計関数

概要

ノイズ付き集計関数は、sum()count()approx_distinct()などの一般的な集計や、approx_set()などのスケッチの、ランダムでノイズの多い近似値を提供する関数です。結果にランダムなノイズを注入することで、ノイズ付き集計関数は集計された正確なデータを特定または確認することをより困難にします。

これらの関数の多くは、差分プライバシーメカニズムに似ていますが、これらの関数によって返される値も、これらの関数を組み込んだクエリ結果も、一般的に差分プライベートではありません。詳細については、以下の制限事項を参照してください。強力なプライバシー保証をサポートしたいユーザーは、まず適切な技術専門家と相談する必要があります。

カウント、合計、平均

noisy_count_gaussian(col, noise_scale[, random_seed]) -> bigint()

col内のNULL以外の値をカウントし、真のカウントに、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。ノイズ付きカウントは、非負になるように後処理され、bigintに丸められます。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

SELECT noisy_count_gaussian(orderkey, 20.0) FROM tpch.tiny.lineitem; -- 60179 (1 row)
SELECT noisy_count_gaussian(orderkey, 20.0) FROM tpch.tiny.lineitem WHERE false; -- NULL (1 row)

count()とは異なり、この関数はcolの(真の)カウントが0の場合、NULLを返します。

個別カウントは、noisy_count_gaussian(DISTINCT col, ...)、またはnoisy_approx_distinct_sfm()を使用して実行できます。一般的に、noisy_count_gaussian()はより正確な結果を返しますが、計算コストは大きくなります。

noisy_count_if_gaussian(col, noise_scale[, random_seed]) -> bigint()

col内のTRUE値をカウントし、真のカウントに、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。ノイズ付きカウントは、非負になるように後処理され、bigintに丸められます。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

SELECT noisy_count_if_gaussian(orderkey > 10000, 20.0) FROM tpch.tiny.lineitem; -- 50180 (1 row)
SELECT noisy_count_if_gaussian(orderkey > 10000, 20.0) FROM tpch.tiny.lineitem WHERE false; -- NULL (1 row)

count_if()とは異なり、この関数は(真の)カウントが0の場合、NULLを返します。

noisy_sum_gaussian(col, noise_scale, lower, upper[, random_seed]) -> double()

colの入力値に対する合計を計算し、次に、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。各値は、合計に追加する前に、[lowerupper]の範囲にクリップされます。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

noisy_sum_gaussian(col, noise_scale[, random_seed]) -> double()

colの入力値に対する合計を計算し、次に、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

noisy_avg_gaussian(col, noise_scale, lower, upper[, random_seed]) -> double()

colのすべての入力値の平均(算術平均)を計算し、次に、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。各値は、平均化する前に、[lowerupper]の範囲にクリップされます。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

noisy_avg_gaussian(col, noise_scale[, random_seed]) -> double()

colのすべての入力値の平均(算術平均)を計算し、次に、平均0、標準偏差noise_scaleの正規分布するランダムなdouble値を追加します。

提供された場合、random_seedは乱数ジェネレータのシードに使用されます。それ以外の場合、ノイズはセキュアなランダムから取得されます。

近似個別カウント/スケッチ

ノイズ付きの近似個別カウントとスケッチ(決定論的なHyperLogLog関数に類似)は、スケッチフリップマージ(SFM)データスケッチ[Hehir2023]を介してサポートされます。

noisy_approx_set_sfm(col, epsilon[, buckets[, precision]]) -> SfmSketch()

colの入力値のSFMスケッチを返します。これは、(決定論的な)HyperLogLogスケッチを返すapprox_set()関数に類似しています。

  • colは、HyperLogLogと同様に、多くの型をサポートします。

  • epsilon(double)は、[Hehir2023]で説明されているように、スケッチのノイズレベルを制御する正の数です。epsilonの値が小さいほど、ノイズの多いスケッチに対応します。

  • buckets(int)は、デフォルトで4096です。

  • precision(int)は、デフォルトで24です。

approx_set()とは異なり、この関数はcolが空の場合、NULLを返します。この動作が望ましくない場合は、coalesce()noisy_empty_approx_set_sfm()と組み合わせて使用してください。

noisy_approx_set_sfm_from_index_and_zeros(col_index, col_zeros, epsilon, buckets[, precision]) -> SfmSketch()

col_indexcol_zerosの入力値のSFMスケッチを返します。

これは、noisy_approx_set_sfm()と似ていますが、この関数はcolMurmur3Hash128.hash64()を計算し、[FlajoletMartin1985]で説明されているように、SFM PCSAバケットインデックスと末尾のゼロの数を計算します。この関数では、呼び出し元がハッシュバケットインデックスとゼロを明示的に計算し、引数col_indexcol_zerosとして渡す必要があります。

  • col_index (bigint) は、0..buckets-1の範囲である必要があります。

  • col_zeros (bigint) は、0..64の範囲である必要があります。 precisionを超えた場合は、precision-1に切り捨てられます。

  • epsilon (double) は、[Hehir2023]で説明されているように、スケッチのノイズレベルを制御する正の数です。epsilonの値が小さいほど、ノイズの多いスケッチになります。

  • buckets (int) は、[Hehir2023]で説明されているように、SFM PCSAスケッチのバケット数です。

  • precision(int)は、デフォルトで24です。

noisy_approx_set_sfm()と同様に、この関数はcol_indexまたはcol_zerosNULLの場合、NULLを返します。この動作が望ましくない場合は、coalesce()noisy_empty_approx_set_sfm()と組み合わせて使用してください。

noisy_approx_distinct_sfm(col, epsilon[, buckets[, precision]]) -> bigint()

cardinality(noisy_approx_set_sfm(col, epsilon, buckets, precision))と同等であり、列colの概算カーディナリティ(重複を除いたカウント)を返します。これは、(決定論的な)approx_distinct()関数に類似しています。

approx_distinct()とは異なり、この関数はcolが空の場合、NULLを返します。

noisy_empty_approx_set_sfm(epsilon[, buckets[, precision]]) -> SfmSketch()

アイテムが含まれていないSFMスケッチを返します。これは、空の(決定論的な)HyperLogLogスケッチを返すempty_approx_set()関数に類似しています。

  • epsilon (double) は、[Hehir2023]で説明されているように、スケッチのノイズレベルを制御する正の数です。epsilonの値が小さいほど、ノイズの多いスケッチになります。

  • buckets(int)は、デフォルトで4096です。

  • precision(int)は、デフォルトで24です。

cardinality(SfmSketch) -> bigint()

SfmSketchオブジェクトの推定カーディナリティ(重複を除いたカウント)を返します。

merge(SfmSketch) -> SfmSketch()

個々のSfmSketchオブジェクトの和集合の結合されたSfmSketchを返すアグリゲーター関数です。merge(HyperLogLog)に似ています。

SELECT year, cardinality(merge(sketch)) AS annual_distinct_count
FROM monthly_sketches
GROUP BY 1
merge_sfm(ARRAY[SfmSketch, ...]) -> SfmSketch()

SfmSketchオブジェクトの配列の和集合の結合されたSfmSketchを返すスカラー関数です。merge_hll()に似ています。

SELECT cardinality(merge_sfm(ARRAY[
    noisy_approx_set_sfm(col_1, 5.0),
    noisy_approx_set_sfm(col_2, 5.0),
    noisy_approx_set_sfm(col_3, 5.0)
])) AS distinct_count_over_3_cols
FROM my_table

制限事項

これらの関数は差分プライバシーメカニズムに似ていますが、これらの関数によって返される値は、一般に差分プライベートではありません。プライバシー保護の目的でこれらの関数を使用する場合は、次のようないくつかの重要な制限事項に留意する必要があります。

  • すべてのノイズ付き集計関数は、空のセットを集計する場合、NULLを返します。これは、NULLの戻り値が、ノイズなしでデータの欠落を示していることを意味します。

  • ノイズ付き集計関数と組み合わせて使用されるGROUP BY句は、ノイズのない情報を明らかにします。グループの有無は、ノイズなしでデータの有無を示します。たとえば、[Wilkins2024]を参照してください。

  • 浮動小数点ノイズに依存する関数は、[Mironov2012][Casacuberta2022]で特定されたような推論攻撃の影響を受けやすい可能性があります。


[Casacuberta2022]

Casacuberta, S., Shoemate, M., Vadhan, S., & Wagaman, C. (2022). 差分プライベートライブラリにおける感度の広範な過小評価とその修正方法 In Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security (pp. 471-484).

[Hehir2023] (1,2,3,4,5)

Hehir, J., Ting, D., & Cormode, G. (2023). Sketch-Flip-Merge: プライベートな重複排除カウントのためのマージ可能なスケッチ In Proceedings of the 40th International Conference on Machine Learning (Vol. 202).

[Mironov2012]

Mironov, I. (2012). 差分プライバシーにおける最下位ビットの重要性について In Proceedings of the 2012 ACM Conference on Computer and Communications Security (pp. 650-661).

[Wilkins2024]

Wilkins, A., Kifer, D., Zhang, D., & Karrer, B. (2024). ガウス疎ヒストグラムメカニズムの正確なプライバシー分析 Journal of Privacy and Confidentiality, 14 (1).

[FlajoletMartin1985]

Flajolet, P, Martin, G. N. (1985). データベースアプリケーションのための確率的カウントアルゴリズム In Journal of Computer and System Sciences, 31:182–209, 1985