概率密度函数的非参数估计方法

news2024/11/18 13:29:07

概率密度函数的非参数估计方法

  • 1. Parzen窗方法
  • 2. kn近邻估计

\qquad 直接由样本来估计概率密度 p ( x ) p(\boldsymbol{x}) p(x) 的方法,称为非参数方法 (non-parametric method) \text{(non-parametric method)} (non-parametric method)
\quad
\quad 概率密度估计问题

( 1 ) (1) (1) 取自于概率密度 p ( x ) p(\boldsymbol{x}) p(x) 的一个样本落在区域 R \mathcal{R} R 中的概率为

P = ∫ R p ( x ) d x \qquad\qquad\qquad P=\displaystyle\int_\mathcal{R}p(\boldsymbol{x})\mathrm{d}\boldsymbol{x} P=Rp(x)dx

概率 P i P_i Pi 对应于离散随机变量 X X X 取值为 x i x_i xi 的情形,即 P i = P ( X = x i ) P_i=P(X=x_i) Pi=P(X=xi)
连续随机变量用概率密度 p ( x ) p(\boldsymbol{x}) p(x) 描述,概率 P = ∫ R p ( x ) d x P=\int_\mathcal{R}p(\boldsymbol{x})\mathrm{d}\boldsymbol{x} P=Rp(x)dx 可看成是概率密度函数的 smoothed or averaged \text{smoothed or averaged} smoothed or averaged的版本。

( 2 ) (2) (2) 假设基于概率密度 p ( x ) p(\boldsymbol{x}) p(x) 独立同分布地抽取了 n n n 个样本 x 1 , x 2 , ⋯   , x n \boldsymbol{x}_1,\boldsymbol{x}_2,\cdots,\boldsymbol{x}_n x1,x2,,xn,当 k k k 个样本落在区域 R \mathcal{R} R 中,对概率 P P P 的一个较为合理的估计可表示为

k ≈ E [ Y ] = n P ⟹ P = k n \qquad\qquad\qquad k\approx E[Y]=nP\quad\Longrightarrow\quad \textcolor{crimson}{P=\dfrac{k}{n}} kE[Y]=nPP=nk

n n n 个样本中有 k k k 个落在区域 R \mathcal{R} R 中属于“ n n n 重伯努利试验”: 
(1) 样本落入区域 R \mathcal{R} R次数 Y Y Y 是一个随机变量,服从二项分布 Y ∼ B ( n , P ) Y\sim B(n,P) YB(n,P),其中 P P P单个样本落入区域 R \mathcal{R} R的概率
  概率 p ( Y = k ) = C n k P k ( 1 − P ) n − k p(Y=k)=C_n^kP^k(1-P)^{n-k} p(Y=k)=CnkPk(1P)nk 
(2) 求 Y Y Y 的数学期望可得到 E [ Y ] = n P E[Y]=nP E[Y]=nP
  此外,对于二项分布 Y ∼ B ( n , P ) Y\sim B(n,P) YB(n,P) 而言, [ ( n + 1 ) P ] [(n+1)P] [(n+1)P] 是最可能出现的次数,也就是众数 (mode) \text{(mode)} (mode),概率 p ( Y = k ) p(Y=k) p(Y=k) 的值在 [ ( n + 1 ) P ] [(n+1)P] [(n+1)P] 处达到最大(概率分布在此处出现波峰)
  因此,可以认为 k ≈ n P k\approx nP knP 是一个较为合理的估计。

\qquad 在这里插入图片描述

图1 左图取自《模式分类》图4.1
三条曲线分别表示抽样数为 n = 20 , 50 , 100 n=20,50,100 n=20,50,100 时,二项分布 p ( Y = k ) = C n k P k ( 1 − P ) n − k   ( k = 0.7 n ) p(Y=k)=C_n^kP^k(1-P)^{n-k}\ (k=0.7n) p(Y=k)=CnkPk(1P)nk (k=0.7n) 在不同的 P P P 处的值(纵轴都进行了尺度调整)
抽样点数 n n n 越大, p ( Y = k ) p(Y=k) p(Y=k) 的值越容易在真实概率 P = 0.7 P=0.7 P=0.7 处形成尖峰,当 n → ∞ n\to\infty n,曲线形状逼近 δ ( x − 0.7 ) \delta(x-0.7) δ(x0.7)

实现代码如下:

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import comb
Pk = lambda k,n,p: comb(n,k)*(p**k)*((1-p)**(n-k))
p0 = 0.7
k20 = np.floor(20*p0).astype('int')
p20 = np.zeros(100)
k50 = np.floor(50*p0).astype('int')
p50 = np.zeros(100)
k100 = np.floor(100*p0).astype('int')
p100 = np.zeros(100)    
i = np.arange(0,100)
p = i/100
P20 = Pk(k20,20,p)
P50 = Pk(k50,50,p)
P100 = Pk(k100,100,p)
y20m = max(P20)
y50m = max(P50)
y100m = max(P100)
plt.figure()
plt.plot(p[i],P20[i])
plt.plot(p[i],P50[i]*y20m/y50m)
plt.plot(p[i],P100[i]*y20m/y100m)
plt.legend(['n=20','n=50','n=100'],loc='upper left')
plt.show()

( 3 ) (3) (3) 当区域 R \mathcal{R} R 足够小,可近似认为区域 R \mathcal{R} R 中的概率密度是恒定的,若有一个样本 x ∈ R \boldsymbol{x}\in\mathcal{R} xR,那么该样本落在区域 R \mathcal{R} R 中的概率为

P = ∫ R p ( x ) d x ≈ p ( x ) V \qquad\qquad\qquad P=\displaystyle\int_\mathcal{R}p(\boldsymbol{x})\mathrm{d}\boldsymbol{x} \approx p(\boldsymbol{x})V P=Rp(x)dxp(x)V  此处, V V V 为区域 R \mathcal{R} R 的体积

\qquad 此时,位于 x ∈ R \boldsymbol{x}\in\mathcal{R} xR 处的概率密度值就可以表示为:

p ( x ) ≈ p ^ ( x ) = P V = k / n V \qquad\qquad\qquad \textcolor{crimson}{p(\boldsymbol{x})\approx}\hat{p}(\boldsymbol{x})=\dfrac{P}{V}=\textcolor{crimson}{\dfrac{k/n}{V}} p(x)p^(x)=VP=Vk/n

\qquad 因此, x \boldsymbol{x} x 处的概率密度估计 p ^ ( x ) \hat{p}(\boldsymbol{x}) p^(x) 与样本数 n n n、包含 x \boldsymbol{x} x 的区域 R \mathcal{R} R、以及落入区域 R \mathcal{R} R 中的样本数 k k k 有关。

\qquad
\quad 考虑概率密度函数的估计 p ^ ( x ) = k / n V \textcolor{crimson}{\hat{p}(\boldsymbol{x})=\dfrac{k/n}{V}} p^(x)=Vk/n

( 1 ) (1) (1) 如果体积 V V V 的值是固定的,且能够获得足够多的样本,那么 P = k n P=\frac{k}{n} P=nk 的值也可以足够精确(如图 1 1 1所示)。

\qquad 此时, p ^ ( x ) = P V = ∫ R p ( x ) d x ∫ R d x \hat{p}(\boldsymbol{x})=\dfrac{P}{V}=\dfrac{\displaystyle\int_\mathcal{R}p(\boldsymbol{x})\mathrm{d}\boldsymbol{x}}{\displaystyle\int_\mathcal{R}\mathrm{d}\boldsymbol{x}} p^(x)=VP=RdxRp(x)dx p ( x ) p(\boldsymbol{x}) p(x) 空间平均化的版本。

\qquad 如果希望得到更精确的 p ( x ) p(\boldsymbol{x}) p(x),而不是平滑后的版本,就必须要求体积 V → 0 V\to0 V0
\qquad
( 2 ) (2) (2) 另一方面,从取样的角度,能够获得的样本数总是有限的,体积 V V V 又不能任意小。

\qquad 假设固定样本个数为 n n n,若体积 V V V 过小,在某处可能会:
\qquad ① 体积 V V V 中不包含任何样本,导致此处的概率密度估计 p ^ ( x ) → 0 \hat{p}(\boldsymbol{x})\to0 p^(x)0
\qquad ② 体积 V V V 中只包含几个样本,导致此处的概率密度估计 p ^ ( x ) → ∞ \hat{p}(\boldsymbol{x})\to\infty p^(x)
\qquad
\qquad 因此,如果采用 p ^ ( x ) = k / n V \textcolor{crimson}{\hat{p}(\boldsymbol{x})=\dfrac{k/n}{V}} p^(x)=Vk/n 的方法来估计概率密度,那么 k n \dfrac{k}{n} nk 的值总会有一定程度的变动,而概率密度估计 p ^ ( x ) \hat{p}(\boldsymbol{x}) p^(x) 总包含了一定程度的空间平滑。

\qquad
( 3 ) (3) (3) 为了估计点 x \boldsymbol{x} x 处的概率密度函数,采用如下方法:

\qquad ① 构造一系列包含点 x \boldsymbol{x} x 的区域: R 1 , R 2 , ⋯ \mathcal{R}_1,\mathcal{R}_2,\cdots R1,R2,,其中 R 1 \mathcal{R}_1 R1 中包含了 1 1 1 个样本, R 2 \mathcal{R}_2 R2 中包含了 2 2 2 个样本 ⋯ \cdots
\qquad ② 记 V n V_n Vn 为区域 R n \mathcal{R}_n Rn 的体积, k n k_n kn 为落在区域 R n \mathcal{R}_n Rn 中的样本个数,用 p ^ n ( x ) \hat{p}_n(\boldsymbol{x}) p^n(x) 表示对概率密度 p ( x ) p(\boldsymbol{x}) p(x) 的第 n n n 次估计。

\qquad 那么  p ^ n ( x ) = k n / n V n \textcolor{crimson}{\hat{p}_n(\boldsymbol{x})=\dfrac{k_n/n}{V_n}} p^n(x)=Vnkn/n

\qquad 如果要求 p ^ n ( x ) → p ( x ) \hat{p}_n(\boldsymbol{x})\to p(\boldsymbol{x}) p^n(x)p(x),那么必须满足 { lim ⁡ n → ∞ V n = 0 lim ⁡ n → ∞ k n = ∞ lim ⁡ n → ∞ k n n = 0 \begin{cases}\displaystyle\lim_{n\to\infty}V_n=0\\\displaystyle\lim_{n\to\infty}k_n=\infty\\\displaystyle\lim_{n\to\infty}\textstyle \frac{k_n}{n}=0\end{cases} nlimVn=0nlimkn=nlimnkn=0

lim ⁡ n → ∞ V n = 0 \quad\displaystyle\lim_{n\to\infty}V_n=0 nlimVn=0 保证体积 V V V 能够尽可能小,从而减轻空间平滑的程度,使得 p ^ n ( x ) → p ( x ) \hat{p}_n(\boldsymbol{x})\to p(\boldsymbol{x}) p^n(x)p(x)
lim ⁡ n → ∞ k n = ∞ \quad\displaystyle\lim_{n\to\infty}k_n=\infty nlimkn= 保证在 V V V 尽可能小的情形下仍包含了大量样本,如果在点 x \boldsymbol{x} x 处的 p ^ ( x ) ≠ 0 \hat{p}(\boldsymbol{x})\neq0 p^(x)=0,那么 k n n → P \frac{k_n}{n}\to P nknP(如图 1 1 1所示);
lim ⁡ n → ∞ k n n = 0 \quad\displaystyle\lim_{n\to\infty}\textstyle\frac{k_n}{n}=0 nlimnkn=0 保证在 V V V 尽可能小的情形下,尽管包含了大量的样本 k n   ( k n → ∞ ) k_n\ (k_n\to\infty) kn (kn),但相对于样本总数 n   ( n → ∞ ) n\ (n\to\infty) n (n) 来说,还是可以忽略的 ( k n n → 0 ) (\dfrac{k_n}{n}\to0) (nkn0),进而保证了 lim ⁡ n → ∞ k n / n V n \displaystyle\lim_{n\to\infty}\dfrac{k_n/n}{V_n} nlimVnkn/n 的收敛性。

1. Parzen窗方法

\qquad 根据某一个确定的体积函数来逐渐收缩到一个给定的区间,就是 Parzen \text{Parzen} Parzen窗方法。

Parzen \quad\text{Parzen} Parzen窗方法估计概率密度函数的基本思路

( 1 ) \qquad(1) (1) 考虑 d d d 维空间,令 h n h_n hn 表示超立方体的边长,该超立方体的体积为 h n d h_n^d hnd

( 2 ) \qquad(2) (2) 定义窗函数 φ ( u ) = { 1 , ∣ u j ∣ ≤ 1 2 0 , ∣ u j ∣ > 1 2 , j = 1 , 2 , ⋯   , d \varphi(\boldsymbol{u})=\begin{cases}1&,\vert u_j\vert\le\frac{1}{2} \\ 0&,\vert u_j\vert>\frac{1}{2}\end{cases},\quad j=1,2,\cdots,d φ(u)={10,uj21,uj>21,j=1,2,,d

\qquad   显然, φ ( u ) \varphi(\boldsymbol{u}) φ(u) 表示一个中心在原点、边长为 1 1 1 的立方体

\qquad   如果点 x i \boldsymbol{x}_i xi 包含在以点 x \boldsymbol{x} x 为中心单位超立方体中,必然有 φ ( x − x i h n ) = 1 \varphi\left(\dfrac{\boldsymbol{x}-\boldsymbol{x}_i}{h_n}\right)=1 φ(hnxxi)=1

( 3 ) \qquad(3) (3) 因此,以点 x \boldsymbol{x} x 为中心的超立方体中包含的样本点数为:

k n = ∑ i = 1 n φ ( x − x i h n ) \qquad\qquad\qquad k_n=\displaystyle\sum_{i=1}^n\varphi\left(\dfrac{\boldsymbol{x}-\boldsymbol{x}_i}{h_n}\right) kn=i=1nφ(hnxxi)

\qquad 那么由 p ^ n ( x ) = k n / n V n \textcolor{mediumblue}{\hat{p}_n(\boldsymbol{x})=\dfrac{k_n/n}{V_n}} p^n(x)=Vnkn/n,可得到 Parzen \text{Parzen} Parzen 窗法的概率密度估计为:

p ^ n ( x ) = 1 n ∑ i = 1 n 1 V n φ ( x − x i h n )   , V n = h n d \qquad\qquad\qquad\textcolor{crimson}{\hat{p}_n(\boldsymbol{x})=\dfrac{1}{n}\displaystyle\sum_{i=1}^n\dfrac{1}{V_n}\varphi\left(\dfrac{\boldsymbol{x}-\boldsymbol{x}_i}{h_n}\right)}\ ,\quad V_n=h_n^d p^n(x)=n1i=1nVn1φ(hnxxi) ,Vn=hnd

\qquad p ^ n ( x ) \hat{p}_n(\boldsymbol{x}) p^n(x) 的形式上可以看出,其本质上是一个基于核函数的内插公式。同时,也说明了概率密度函数估计可以采用更一般的方式,而不必规定窗函数必须是超立方体。
\quad
\quad 窗宽 h n h_n hn p ^ n ( x ) \hat{p}_n(\boldsymbol{x}) p^n(x) 的影响

\qquad 定义函数 ϕ n ( x ) = 1 V n φ ( x h n ) \textcolor{blue}{\phi_n(\boldsymbol{x})=\dfrac{1}{V_n}\varphi\left(\dfrac{\boldsymbol{x}}{h_n}\right)} ϕn(x)=Vn1φ(hnx),那么 Parzen \text{Parzen} Parzen 窗法的概率密度估计为:

p ^ n ( x ) = 1 n ∑ i = 1 n ϕ n ( x − x i ) \qquad\qquad\qquad\textcolor{crimson}{\hat{p}_n(\boldsymbol{x})=\dfrac{1}{n}\displaystyle\sum_{i=1}^n\phi_n(\boldsymbol{x}-\boldsymbol{x}_i)} p^n(x)=n1i=1nϕn(xxi)

( 1 ) \qquad(1) (1) 如果 h n h_n hn 很大,则 ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) 的强度非常低,即使 x i \boldsymbol{x}_i xi 远离 x \boldsymbol{x} x ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) ϕ n ( 0 ) \phi_n(0) ϕn(0) 相差不太大。

( 2 ) \qquad(2) (2) 如果 h n h_n hn 很小,则 ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) 的强度非常高,只有离 x \boldsymbol{x} x 非常近的 x i \boldsymbol{x}_i xi 才对计算 ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) 有贡献,即: h n h_n hn 越小, ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) 越尖。

h n → 0 h_n\to0 hn0 ϕ n ( x − x i ) \phi_n(\boldsymbol{x}-\boldsymbol{x}_i) ϕn(xxi) 逼近狄拉克函数 δ ( x − x i ) \delta(\boldsymbol{x}-\boldsymbol{x}_i) δ(xxi) ,此时的概率密度估计为 p ^ n ( x ) = 1 n ∑ i = 1 n δ ( x − x i ) \textcolor{crimson}{\hat{p}_n(\boldsymbol{x})=\dfrac{1}{n}\displaystyle\sum_{i=1}^n\delta(\boldsymbol{x}-\boldsymbol{x}_i)} p^n(x)=n1i=1nδ(xxi)

\qquad 对于任意窗宽 h n h_n hn,其概率分布满足归一性:

∫ ϕ n ( x − x i ) d x = ∫ 1 V n φ ( x − x i h n ) d x = ∫ φ ( u ) d u = 1 \qquad\qquad\qquad\displaystyle\int\phi_n(\boldsymbol{x}-\boldsymbol{x}_i)\mathrm{d}\boldsymbol{x}=\int\dfrac{1}{V_n}\varphi\left(\dfrac{\boldsymbol{x}-\boldsymbol{x}_i}{h_n}\right)\mathrm{d}\boldsymbol{x}=\int\varphi\left(\boldsymbol{u}\right)\mathrm{d}\boldsymbol{u}=1 ϕn(xxi)dx=Vn1φ(hnxxi)dx=φ(u)du=1

\qquad 因此,窗宽的选择对概率密度估计 p ^ n ( x ) \hat{p}_n(\boldsymbol{x}) p^n(x) 的影响非常大,如下例所示。

\qquad
《模式分类》图4.5实现代码(假设真实概率密度为标准正态分布)
高斯窗函数: φ ( u ) = 1 2 π e − u 2 2 \varphi(u)=\dfrac{1}{2\pi}e^{-\frac{u^2}{2}} φ(u)=2π1e2u2
概率密度估计: p ^ n ( x ) = 1 n ∑ i = 1 n 1 h n φ ( x − x i h n ) \hat{p}_n(x)=\dfrac{1}{n}\displaystyle\sum_{i=1}^n\dfrac{1}{h_n}\varphi\left(\dfrac{x-x_i}{h_n}\right) p^n(x)=n1i=1nhn1φ(hnxxi)

import numpy as np
import matplotlib.pyplot as plt
def parzen1d(sample, x, h):
    kernel = lambda u: np.exp(-u**2/2)/np.sqrt(2*np.pi)
    pdf = np.zeros(len(x))
    for i in range(len(sample)):
        pdf += kernel((x-sample[i])/h)/h        
    return pdf/len(sample)
def parzen1d_show(num):
    x = np.linspace(-3, 3, 100)  
    rx = np.random.randn(num)
    ry = np.zeros_like(rx)    
    pdf1 = parzen1d(rx, x, 1.0)
    pdf2 = parzen1d(rx, x, 0.5)
    pdf3 = parzen1d(rx, x, 0.1)    
    plt.figure(figsize=(12,2))
    plt.subplot(131),plt.plot(rx, ry, 'r.', markersize='3'),plt.plot(x,pdf1),plt.title('h=1')
    plt.xticks([-3,-2,-1,0,1,2,3])
    plt.subplot(132),plt.plot(rx, ry, 'r.', markersize='3'),plt.plot(x,pdf2),plt.title('h=0.5')
    plt.xticks([-3,-2,-1,0,1,2,3])
    plt.subplot(133),plt.plot(rx, ry, 'r.', markersize='3'),plt.plot(x,pdf3),plt.title('h=0.1')
    plt.xticks([-3,-2,-1,0,1,2,3])  
    plt.show()      
parzen1d_show(1)   
parzen1d_show(10)
parzen1d_show(100)
parzen1d_show(10000)

采用高斯窗函数时的结果

\qquad 在这里插入图片描述

采用矩形窗时的结果

\qquad 在这里插入图片描述
二维 Parzen \text{Parzen} Parzen窗概率密度估计:

\qquad 在这里插入图片描述

2. kn近邻估计

k n \qquad k_n kn 近邻估计,是另一种非参数的概率密度函数估计方法,其基本思路是让体积成为训练样本数 n n n 的函数。

\qquad 为了估计点 x \boldsymbol{x} x 处的概率密度,以点 x \boldsymbol{x} x 为中心不断扩张体积,直到体积 V n V_n Vn 内包含了 k n k_n kn 个相邻的样本点(其中, k n k_n kn 是训练样本数 n n n 的函数),则点 x \boldsymbol{x} x 处的概率密度估计为:

p ^ n ( x ) = k n / n V n \qquad\qquad\qquad\hat{p}_n(\boldsymbol{x})=\dfrac{k_n/n}{V_n} p^n(x)=Vnkn/n

( 1 ) \qquad(1) (1) 如果点 x \boldsymbol{x} x 处的概率密度比较小,包含 k n k_n kn 个相邻点的体积就相对比较大;
( 2 ) \qquad(2) (2) 如果点 x \boldsymbol{x} x 处的概率密度比较大,包含 k n k_n kn 个相邻点的体积就相对比较小;如果点 x \boldsymbol{x} x 处的概率密度非常高,随着 V n → 0 V_n\to0 Vn0,体积的生长就会停止。

Parzen \text{Parzen} Parzen 窗方法中,体积是训练样本数 n n n 某个固定的形式
k n k_n kn- 最近邻方法中,体积必须能够包含 k n k_n kn 个相邻样本点

\qquad

《模式分类》图4.12实现代码:(假设真实概率密度为标准正态分布)
k n = n ,   V n = 2 ∗ sort ( d i s t ) [ k n ] k_n=\sqrt{n},\ V_n=2*\text{sort}(dist)[k_n] kn=n , Vn=2sort(dist)[kn]

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
def knn_pdf(sample, x):
    num = len(sample)
    pdf = np.zeros(len(x))
    kn = num**(0.5)
    for i in range(len(x)):
        dist = np.abs(x[i] - sample)
        sortedDist = np.sort(dist)       
        vol = sortedDist[int(kn)-1]*2
        pdf[i] = kn/num/vol
    return pdf
def knn1d(num):
    mean = 0
    std = 1
    x = np.linspace(-4, 4, 1000)  
    y = norm.pdf(x, mean, std)
    rx = mean + std * np.random.randn(num)
    ry = np.zeros_like(rx)    
    pdf = knn_pdf(rx, x)
    plt.figure(figsize=(5,4))
    plt.plot(x,y,'r')
    plt.plot(rx, ry, 'r.', markersize='3')
    plt.plot(x,pdf,'g');plt.title('n={}'.format(num))
    plt.xticks([-4,-3,-2,-1,0,1,2,3,4]),plt.yticks([])   
knn1d(1)
knn1d(16)
knn1d(256)
knn1d(4096)   
plt.show()

运行结果:
\qquad 在这里插入图片描述

\qquad n → ∞ n\to\infty n 时的概率密度估计接近真实概率密度,此时 k n k_n kn 近邻估计需采用 k d kd kd 树这样的快速搜索算法。在样本数有限的情况下,可以考虑用核回归方法对 k n k_n kn 近邻估计的结果进行平滑,似乎此时核回归的窗宽相对容易选择一些。

经过核回归平滑后的结果

\qquad 在这里插入图片描述

二维 k n k_n kn近邻概率密度估计

def knn2d(num):
    mu = [1,1]
    cov = [[3,1],[1,2]]
    sample1 = np.random.multivariate_normal(mu,cov,num//2)
    mu = [8,8]
    cov = [[3,-1],[-1,2]]
    sample2 = np.random.multivariate_normal(mu,cov,num//2)
    sample = np.concatenate((sample1, sample2))
    plt.figure(figsize=(5,5))
    plt.plot(sample[:,0], sample[:,1],'b.',markersize='4')
    plt.xlabel('x'), plt.ylabel('y')    
    fig = plt.figure(figsize=(8,6))
    ax = fig.add_subplot(projection='3d')
    X = np.arange(-7, 15, 0.1)
    Y = np.arange(-7, 15, 0.1)
    x, y = np.meshgrid(X, Y)
    pos = np.empty(x.shape + (2,))
    pos[:, :, 0] = x
    pos[:, :, 1] = y
    x1 = x.reshape(-1,1)
    y1 = y.reshape(-1,1)
    xy = np.concatenate((x1, y1), axis=1)
    pdf = np.zeros(x.shape)
    h,w = x.shape
    kn = int(num**(0.5))
    for i in range(len(xy)):
        dist = np.sqrt(np.sum((sample - xy[i,:])**2,axis=1))
        sortedDist = np.sort(dist)       
        vol = sortedDist[kn-1]**2
        i0 = i//h
        j0 = i % w
        pdf[i0,j0] = kn/num/vol
    surf = ax.plot_surface(x, y, pdf, cmap=cm.Blues, linewidth=1, antialiased=False)
    ax.view_init(elev=30., azim=300)
    ax.set_zlim(0, 0.3)
    plt.title('n = {}'.format(num))

运行结果:

\qquad 在这里插入图片描述
\qquad 在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/441489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数学建模第三天:数学建模算法篇之线性规划及matlab的实现

目录 一、前言 二、线性规划简介 1、线性规划模型介绍与特征 2、线性规划模型的一般形式 三、单纯形法 1、标准化 2、单纯形法解题 四、matlab解决问题1、matlab线性规划函数 2、解题代码 一、前言 数学建模,本意就是用来解决生活中的问题,我们今…

二叉树的前中后序遍历写法归纳

如题,对应力扣题目如下: 144.二叉树的前序遍历145.二叉树的后序遍历94.二叉树的中序遍历 1.递归 1.1 先序遍历 根 -> 左 -> 右 所以,这个递归函数先打印根节点的值,然后递归地遍历左子树,最后递归地遍历右子树。如果传入的根节点是空,则直接返回…

Linux学习记录—— 이십일 进程间通信(3)信号量和消息队列

文章目录 1、消息队列2、信号量1、了解概念2、信号量理解 3、接口4、理解IPC 1、消息队列 两个进程ab之间系统维护一个队列结构,a进程往队列里放信息,信息编号为1,b进程往队列里放信息,信息编号为2;之后开始读取数据的…

HADOOP伪分布式安装步骤

HADOOP安装步骤 一.创建Hadoop用户 二.更新apt和安装vim编辑器 更新apt: sudo apt-get install update安装VIM编辑器: apt install vim在弹出的提示中输入yes(y) 三、安装SSH和配置SSH无密码登录 apt install openssh-serverssh登录: ssh localh…

Vue2组件通信专题

组件通信专题 一、vue2中常用的6中组件通信方式 1. props 适用于的场景:父子组件通信 注意事项: 如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据。 如果父组件给子组件传递数据&#xff08…

【致敬未来的攻城狮计划】— 连续打卡第七天:(电脑重装系统)学习RA产品家族选型手册

系列文章目录 1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下 2.开发环境的选择和调试(从零开始,加油) 3.欲速则不达,今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

大数据hadoop课程实验总结

1一.安装hadoop 本门课程使用的是centos7.2 64位操作系统,原生hadoop2.7.7,java1.7版本。 安装centos7.2系统: 创建系统的同时创建一个名为hadoop的账户。这一步不难,此处就不再详说。 没有hadoop用户可以创建一个Hadoop用户: …

ChatBox安装--ChatGPT的桌面客户端

ChatBox 是什么 是开源的 ChatGPT API (OpenAI API) 桌面客户端,Prompt 的调试与管理工具,支持 Windows、Mac 和 Linux。 > github地址 下载链接 支持的平台: Windows : 请下载.msi安装包 Mac:请下载.dmg(推荐…

【微服务笔记13】微服务组件之Config配置中心基础环境搭建

这篇文章,主要介绍微服务组件之Config配置中心基础环境搭建。 目录 一、Config配置中心 1.1、什么是配置中心 1.2、Config配置中心特点 二、搭建Config配置中心 2.1、配置Git仓库 2.2、创建ConfigServer服务端 (1)引入依赖 &#xff…

性能测试,监控磁盘读写iostat

性能测试,监控磁盘读写iostat iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出 CPU使用情况。同vmstat一样,ios…

【iOS-#import <> ““, @class和C- #include<> ““, 】

前言 寒假分享会的遗漏问题总结 引入 在C/CPP语言里&#xff0c;引入某个头文件的操作 #include<iostream> #include<string>也有 #include "string"同样在OC里面 引入某个类会用到 #import关键字 #import "LoginViewController.h" #im…

web开发HTML生成PDF的三种解决方案(服务器端mpdf、html2canvas.js、浏览器打印、PDF虚拟打印机)

系列文章目录 python数据可视化开发(4)&#xff1a;爬取对应地址的pdf文档并分类保存到本地文件夹&#xff08;爬虫&#xff09;php使用mPDF实战案例分析字符串太长时文本变小无法自动分页的解决方案web开发HTML生成PDF的三种解决方案&#xff08;服务器端mdf、h2pdf.js、浏览…

Nuxt.js - 超详细实现路由 “伪静态“,将浏览器网页路径 URL 链接后面加上 .html 后缀名称(可以自定义任何结尾后缀名称)详细示例教程

前言 正常的项目,路由都是 /index | /user/add 这种,但有一个办法可以让其后面带上 .html,比如:/index.html。 本文 在 Nuxt.js 项目中,描述了如何实现伪静态详细教程,让页面路由后面都跟上一段自定义后缀名,比如 .html / .asp, 你可以按照本文的教程,最终得到伪静态…

阿赵的MaxScript学习笔记分享十四《Struct结构体的使用和面向对象的思考》

MaxScript学习笔记目录 大家好&#xff0c;我是阿赵 之前写了一些MaxScript的学习笔记&#xff0c;里面实现的功能不算很复杂&#xff0c;所以都是使用了偏向于面向过程的方式去编写的。 我本人其实是比较习惯用面向对象的方式去编写代码。关于面向过程和面向对象之间的优缺点…

3.5 方程组的状态与解的迭代改善

学习目标&#xff1a; 如果我要学习方程组的状态与解的迭代改善&#xff0c;我会采取以下步骤&#xff1a; 学习迭代方法的基本理论&#xff1a;首先&#xff0c;我会学习迭代方法的基本概念、原理和公式&#xff0c;包括雅可比迭代法、高斯-赛德尔迭代法和逐次超松弛迭代法等…

融合CDN行为分析动态加速解决方案

网络延迟对电商企业产生了巨大的负面影响&#xff0c;延迟是电子商务的杀手&#xff0c;网站访客等待的时间越长&#xff0c;最终实现转化的可能性就越小&#xff0c;同时他们对你的网站品牌的认可度也就越低&#xff0c;快速的网站内容交付是具有全球意识的电商企业不可或缺的…

Qt优秀开源项目之十八:QtService

QtService是一个用于实现Windows服务或unix守护进程的开源项目 github地址&#xff1a;https://github.com/qtproject/qt-solutions/tree/master/qtservice 源码可以编译成动态库&#xff0c;也可以直接在项目中引用源码 源码目录qtservice/examples中包含了三个例子&#xff0…

【Linux】system V 消息队列 | system V 信号量(简单赘述)

文章目录 1 . system V 消息队列(了解)接口查看消息队列 2.system V 信号量 (了解)1.进程互斥等概念的理解2.认识信号量3. 接口 这两部分主要是了解即可&#xff0c;为后面学习做铺垫 1 . system V 消息队列(了解) 为了让两个进程间通信 创建一个队列queue 进程A可以通过消息队…

Python——第2章 数据类型、运算符与内置函数

目录 1 赋值语句 2 数据类型 2.1 常用内置数据类型 2.1.1 整数、实数、复数 2.1.2 列表、元组、字典、集合 2.1.3 字符串 2.2 运算符与表达式 2.2.1 算术运算符 2.2.2 关系运算符 2.2.3 成员测试运算符 2.2.4 集合运算符 2.2.5 逻辑运算符 2.3 常用内置…

Kubernetes 笔记(15)— 应用保障、容器资源配额、容器状态探针概念及使用

作为 Kubernetes 里的核心概念和原子调度单位&#xff0c;Pod 的主要职责是管理容器&#xff0c;以逻辑主机、容器集合、进程组的形式来代表应用&#xff0c;它的重要性是不言而喻的。 在上层 API 对象的基础上&#xff0c;一起来看看在 Kubernetes 里配置 Pod 的两种方法&…