*说明1:本文中的算法均来自
作者:DPer
链接:https://zhuanlan.zhihu.com/p/67761743
来源:知乎
GitHub:https://github.com/forestneo/sunDP
在此仅为学习记录
说明2:在python 中:
- 不写过长的语句,需要时用“\”续航符,或圆括号将更多代码行括起来表示为一条语句
- 使用“#”或者三引号"""注释,前者用于单行注释,后者用于大段说明文本的注释*
文章目录
基本函数介绍
- epsilon2probability(epsilon, n=2)
- discretization(value, lower, upper)
- perturbation(value, perturbed_value, epsilon)
- random_response(value, epsilon)
- random_response_adjust(sum, N, epsilon)
1.epsilon2probability
p = e x e x + 1 p=\frac{e^x}{e^x+1} p=ex+1ex
根据 ε 计算概率p,代码如下:
def epsilon2probability(epsilon, n=2):
return np.e ** epsilon / (np.e ** epsilon + n - 1)
说明:
numpy.exp()函数
exp:高等数学里以自然常数e为底的指数函数
numpy.exp():返回e的幂次方,即
e
x
e^x
ex,e是一个常数为2.71828。
np.exp(1) 为
e
e
e
np.exp(2) 为
e
2
e^2
e2
例如:
import numpy as np
print(np.exp(0))
print(np.exp(1))
print(np.exp(2))
原文链接:https://blog.csdn.net/duanlianvip/article/details/100102797
2. discretization
假如数据分布是0-100,现在有个数据是20,那么我们就以20%的概率输出0,以80%的概率输出1,这样可以保证期望不变。所以,假如我们想要将一个值value离散化到lower和upper,公式如下:
p [ u p p e r ] = v a l u e − l o w e r u p p e r − l o w e r p[upper]=\frac{value -lower}{upper-lower} p[upper]=upper−lowervalue−lower
为了知道返回lower还是upper,我们产生一个[0,1]的随机数r,如果r<p那么我们就返回lower即可。离散化的代码如下所示:
def discretization(value, lower, upper):
"""
discretiza values
:value:参数值:需要离散化的值
:lower:参数下界,离散值的下界
:upper:参数上界:离散值的上界
:return:离散值
"""
if value > upper or value < lower:
raise Exception("the range of value is not valid in Function @Func: discretization")
#抛出异常(“值的范围在函数@Func:discretization中无效”)
p = (value - lower) / (upper - lower)
rnd = np.random.random()
return upper if rnd < p else lower
3.perturbation
输入值A,值B和 ε ,以较大概率返回值A,以较小概率返回B,概率由 ε 控制,实际上,这就是最基本的random response了。所以先根据 ε 计算概率,然后再由概率控制输出哪个值。算法如下:
def perturbation(value, perturbed_value, epsilon):
"""
扰动,(随机响应是扰动的一种)
:param value: 原始值
:param perturbed_value: 扰动参数(注:在random_response函数(异常处理函数)定义中perturbed_value=1-value)
:param epsilon:隐私预算
:return: dp version of perturbation
"""
p = epsilon2probability(epsilon)
rnd = np.random.random()
#生成一个0到1的随机浮点数rnd: 0 <= rnd < 1.0
return value if rnd < p else perturbed_value
#如果rnd < p,则返回value,否则返回perturbed_value
np.random.random()函数
np.random.random((100, 20))
上面这个就代表生成100行 20列的浮点数,浮点数范围 : (0,1)。
参考博客:https://blog.csdn.net/kancy110/article/details/69665164/
额外说明:random.random() 和random.Random() 的区别
random.random()生成0和1之间的随机浮点数float,它其实是一个隐藏的random.Random类的实例的random方法。
random.Random() 生成random模块里得Random类的一个实例,这个实例不会和其他Random实例共享状态,一般是在多线程的情况下使用。
就是说直接用random.random()的时候,其实有一个隐藏生成的random.Random类的实例,也就是random.Random()。你自己可以试一下,random.random()和random.Random().random()作用是一样的。
原文链接:https://blog.csdn.net/u011318077/article/details/87868240
额外说明2
random.uniform(a, b) 生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成的随机数n: a <= n <= b。如果 a <b, 则 b <= n <= a。
random.randint(a, b):生成一个指定范围内的整数。其中参数a是下限,参数b是上限,
生成的随机数n: a <= n <= b,注意:此处要求 a<=b
random.randrange(start, stop, step):从指定范围内,按指定基数递增的集合中获取一个随机数。如:
#产生一个0-10的随机数,其步长为2,即[0,2,4,6,8],然后在随机取出一个随机数
print(random.randrange(0, 10, 2))
import numpy as np
#产生随机数组
#产生一个(0,1)之间的10维的随机数组
c = np.random.random(10)
print(c)
#产生一个(0,1)之间的 3*4 的数组矩阵
#方法三;
d = np.random.random(size = (3,4))
print(d)
if-else 多种用法
a, b, c = 1, 2, 3
# 常规
def test1():
if a>b:
c = a
else:
c =b
print c
# 表达式
def test2():
c = a if a>b else b
print c
# 二维列表
def test3():
c = [b,a][a>b]
print c
# 黑客用法
def test4():
c = (a>b and [a] or [b])[0]
print c
if __name__ == "__main__":
test1()
test2()
test3()
test4()
#以上四种输出结果都是一样的,都是2
参考文章:https://blog.csdn.net/ithomer/article/details/6065772
4.random_response
random response针对的是01变量,而不是特殊的值,所以可以有perturbation再封装一个函数。为了防止错误使用,加了一个筛选条件,如果不是01变量,那么会抛出一个异常。
def random_response(value, epsilon):
if value not in [0, 1]:
raise Exception("The input value is not in [0, 1] @Func: random_response")
return perturbation(value=value, perturbed_value=1-value, epsilon=epsilon)
'''perturbed_value=1-value :因为针对的是01变量,value不是1就是0,所以perturbed_value就是与value相反,简单的1-value即可'''
5.random_response_adjust
该函数是用来对Random Response结果的反推,假如一共有N条数据,其中x个1,N-x个0,那么数据收集者应该收到多少个1呢?我们有这么个公式:
M = x • p + ( N − x ) ( 1 − p ) M=x•p + (N-x)(1-p) M=x•p+(N−x)(1−p)
所以对于收到的求和M我们可以根据这个公式估计出原来有多少个x,所以我把这个函数的名字取做Random response adjust,代码如下:
def random_response_adjust(sum, N, epsilon):
"""
对random response的结果进行校正
:param sum: 收到数据中1的个数
:param N: 总的数据个数
:return: 实际中1的个数
"""
p = epsilon2probability(epsilon)
#epsilon2probability函数是根据 ε 计算概率p,p是维持原有数据的概率
return (sum + p*N - N) / (2*p - 1)
参考文章:
https://blog.csdn.net/ithomer/article/details/6065772
https://blog.csdn.net/mmh19891113/article/details/82114815
https://blog.csdn.net/huanhuan_Coder/article/details/80762208