差分隐私保护及应用简略了解
本人数学一直超差,差分隐私保护又是基于概率统计数学知识的,看的真是头大。。。但还是把所看的东西串起来记录一下吧。如有看到不正确的地方,还望指正!!
一:差分隐私基本概念
这是差分隐私保护的最基本概念了,首先得理解数据集D和,成为兄弟数据集。两个数据集中的记录最多相差一一条记录,例如:数据集1=(1,2,3,4),数据集2=(1,2,3),数据集3=(2,3,4,5);数据集1和数据集2求差值=(4),只有一条记录,因此为兄弟数据集。数据集1和数据集3求差值=(1,5),有两条记录,因此不是兄弟数据集。
应用例子:
数据如表1所示,其中的每个记录表示某个人是否患有癌症(1表示是,0表示否)。
我们把表1中前4条记录当做数据集D1,前5条当做数据集D2。隐私算法A=count(i)+噪音,其中i=1,2,3.....。
正常情况下:count(4)=2;(前四条记录,即数据集D1)
count(5)=3;(前五条记录,即数据集D2)
这样我们就可以推断第5条记录的值一定是1,会发生隐私泄露。
差分隐私保护情况下:count(4)+噪音与count(5)+噪音其结果均以几乎完全相同的概率输出{2,2,3,4}(这个结果只是假设)中的任意一个。其中几乎完全相同的概率:两者的概率差为。
差分隐私的基本概念已经了解了,那么怎么实现差分隐私呢?通过例子我们可以知道这是通过添加噪音来实现的,那么怎么产生符合需要的噪音呢?
现有研究常用的两种噪音机制
Laplace机制:这是适用于连续数据的噪音机制。给定数据集D,上述差分隐私保护基本概念中的随机算法A(D)=f(D)+Y,其算法A提供e-差分隐私保护,Y服从制度参数为 敏感度/e 的Laplace分布,即Lap(敏感度/e)。
Laplace分布:位置参数为0、尺度参数为b的Laplace分布为Lap(b),其概率密度函数为:
通过上述Laplace概念的了解,从而得知两个变量,一个是敏感度,一个是e隐私保护系数。这两个系数如何确定?这里只简单提一下。
敏感度:这主要与随机算法A(D)=f(D)+噪音中的f(D)有关。f(D)是作用在数据集上的查询函数,例如查询中位数,数据集D(x1,x2,x3,x4,...xm=a,xm+1,xm+2....xn=b)数据集前半截的值全等于a,后半截全等于b。
全局敏感度为函数f作用在所有兄弟数据集上,两者的函数结果最大差值。
这里f=查询中位数,最大的差值为b-a。
局部敏感为函数f作用在相邻兄弟数据集上,两者的函数结果最大差值。
那么这的局部敏感度其局部敏感度为max(xm-xm-1,xm+1-xm)。
局部敏感度与全局敏感度的关系:
这里e隐私保护系数暂时不做描述。
Laplace机制的实现代码:
import org.apache.commons.math3.distribution.LaplaceDistribution;
//epsilon为隐私保护参数,1 / epsilon中的1为敏感度。
static double laplaceMechanismCount(long realCountResult, double epsilon) {
LaplaceDistribution ld = new LaplaceDistribution(0, 1 / epsilon);
double noise = ld.sample();
return realCountResult + noise;
}
pom.xml
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies>
指数机制:适合用于离散型数据。
实现代码:上述定义提的可用性函数就是代码中的score
import java.util.Random;
/*
expMechanismImplement函数:
1-->根据指数的定义算出每个选项的概率
2-->把每项概率归一(这里的取值时0-0.9999)
3-->按概率取值
*/
public class expMechanism {
static int expMechanismImplement(int[] score,int m,double epslion,int sensitivity,double ratio){
double[] exponents_list=new double[m];
double sum=0;
double sum_exp=0;
int flag=-1;
//1-->根据指数的定义算出每个选项的概率
for(int i=0;i<m;i++){
double expo=ratio*0.5*(double)((score[i]*epslion)/sensitivity);
exponents_list[i]=Math.exp(expo);
}
//2-->把每项概率归一(这里的取值时0-0.9999)
for(int i=0;i<exponents_list.length;i++){
sum=sum+exponents_list[i];
}
for(int i=0;i<exponents_list.length;i++){
exponents_list[i]=exponents_list[i]/sum;
}
//3-->按概率取值,r.nextDouble()为该区间内部的每个数字生成的机率是相同的
Random r=new Random();
double temp=r.nextDouble();
for(int i=0;i<exponents_list.length;i++){
sum_exp=sum_exp+exponents_list[i];
if(sum_exp>=temp){
flag=i;
break;
}
}
return flag;
}
public static void main(String args[]){
int[] score={5,8,10,10,10};
double epsilon=1.0;
int sensitivity=1;
int m=score.length;
double ratio=1.0;
expMechanismImplement(score,m,epsilon,sensitivity,ratio);
}
}