非参数估计——Parzen窗与k近邻估计
在做分类问题时,有时候需要使用样本的概率密度函数来求其后验概率。但是很多情况下并不知道其概率密度函数的形式(即样本的分布未知),此时就需要对样本进行非参数估计,来求解其概率密度函数。
求解未知分布样本的概率密度函数的一种方法是:\(n\)个样本点中,在某点周围取一个区间\(R_{n}\),计算区间\(R_{n}\)的体积\(V_{n}\)以及落在\(R_{n}\)中的样本的个数\(k_{n}\),然后就可以求出该点处的概率密度:
Parzen窗方法就是一种非参数估计的方法,它的主要思想是选取一个窗函数\(\varphi(\boldsymbol{u})\),通过该窗函数来统计落在所取区间中的样本个数\(k_{n}\),然后通过公式(1)得到某个点的概率密度。一种窗函数\(\varphi(\boldsymbol{u})\)定义如下:
其中\(d\)表示空间的维度。若取区间\(R_{n}\)为一个超立方体,它的边长为\(h_{n}\),则可以通过如下表达式计算\(k_{n}\):
因此样本中某点\(\boldsymbol{x}\)处的概率密度为:
Parzen窗方法的代码实现如下,其中参数\(Data\)为样本总体,\(X\)为需要求概率密度的点坐标,\(h\)为参数,\(d\)为样本空间的维度,\(f\)为窗函数\(\varphi(\boldsymbol{u})\)。
def Parzen(Data, X, h, d, f) :
Prob = []
n = len(Data)
for x in X :
p = 0.0
for s in Data :
p += f((s-x)/h)
Prob.append(p / (n * (h**d)))
return np.array(Prob)
如下代码是上述\(\varphi(\boldsymbol{u})\)函数的实现,即判断当前样本点是否落在了所取的超立方体空间中:
def cube(u) :
T = abs(u)
if all(t <= 0.5 for t in T) :
return 1
else :
return 0
窗函数\(\varphi(\boldsymbol{u})\)的形式可以有很多方式,但必须满足如下的性质,以此保证最终求解的概率密度函数是合理的。
例如当样本空间为一维时,我们可以也定义窗函数是一个高斯函数:
Parzen窗方法是给定区间的范围\(h_{n}\),求落在区间的样本点个数\(k_{n}\),以此估计概率密度。除了Parzen窗方法外,k近邻估计也可以实现对概率密度函数的估计,与Parzen窗方法不同的是,k近邻估计是先给定要取的样本点的个数\(k_{n}\),然后求点\(\boldsymbol{x}\)附近包含\(k_{n}\)个样本的区间的范围\(h_{n}\),最后通过公式(1)求解概率密度。如下是k近邻估计的实现代码,其中参数\(f\)为求解两个点直接距离的函数。
def knn(Data, X, kn, d, f) :
t = kn / len(Data)
Prob = []
for x in X :
dis = []
for s in Data :
dis.append(f(x,s))
dis.sort()
v = (dis[kn] * 2) ** d
Prob.append(t/v)
return np.array(Prob)
下图是通过Parzen窗方法和k近邻估计对某个样本(二维正态分布样本随机采样获得)概率密度函数的估计结果。
以上两种非参数估计的Python实现可以在我的GitHub中获取到。
1.参考文档:
[1]. 模式分类 Richard O.Duda 等著 李宏东 等译