使用高斯内核估计向量的 pdf

Estimate pdf of a vector using Gaussian Kernel

我正在使用高斯核来估计基于等式的数据的 pdf 其中 K(.) 是高斯核,数据是给定的向量。 z 是从 1 到 256 的 bin。bin 的大小是 1。

我是用matlab代码实现的。然而,结果显示我的 pdf 估计(蓝色)的幅度与真实数据的 pdf 不相似。你能看看我的代码并给我一些关于我的代码的评论吗?

MATLAB 代码

function pdf_est=KDE()
close all;
%%Random values of 20 pixels, range=[1 256]
data=randi([1 256],1,20);

%% Estimate histogram%%%%% 
pdf_est=zeros(1,256);
z=256;

for i=1:z
    for j=1:length(data)
        pdf_est(i)=pdf_est(i)+Gaussian(i-data(j));
    end
end
%% Plot real histogram 1 to 256; binsize=1;
hold on
plot(imhist(uint8(data))./length(data),'r');
%% Plot histogram estimation
plot(pdf_est./length(data),'b');
hold off
function K=Gaussian(x)
   sigma=1;
   K=1./(sqrt(2*pi)*sigma)*exp(-x^2./(2*sigma^2));

RESULT 蓝色是我的结果,红色是真实的 pdf

您有两个问题:

  1. 蓝色和红色图之间的 1 个单位位移。
  2. 蓝色的尖刺比红色的尖刺更宽,高度也更低。

如何解决每个问题:

  1. 这是由于 数据范围 0,...,255 和 索引区间 [=57 之间可能存在混淆造成的=] 1,...,256。由于您的数据表示 8 位图像,因此值应为 0,...,255(而不是 1,...,256)。您绘制的水平轴应为 0,...,255。 for 行中的 i 变量也是如此。然后,由于 Matlab 索引从 1 开始,因此在索引 pdf_est.

    时应使用 i+1
  2. 这是正常现象。您在内核中假设 单位方差 。要查看更高的蓝色尖峰,您可以减少 sigma 以使内核更窄更高。但是你永远不会得到与你的数据完全相同的高度(必要的 sigma 将取决于你的数据)。

    实际上,您在高度和宽度之间有一个权衡,由sigma控制。但重要的是 区域 对任何 sigma 保持不变。所以我建议绘制 CDF(面积)而不是 pdf(面积密度)。为此,绘制 accumulated 直方图和 pdf(使用 cumsum)。

代码根据1修改:

function pdf_est=KDE()
close all;
%%Random values of 20 pixels, range=[1 256]
data=randi([1 256],1,20)-1; %// changed: "-1"

%% Estimate histogram%%%%% 
pdf_est=zeros(1,256);
z=256;

for i=0:z-1 %// changed_ subtracted 1 
    for j=1:length(data)
        pdf_est(i+1)=pdf_est(i+1)+Gaussian(i-data(j)); %// changed: "+1" (twice)
    end
end
%% Plot real histogram 1 to 256; binsize=1;
hold on
plot(0:255, imhist(uint8(data))./length(data),'r'); %// changed: explicit x axis
%% Plot histogram estimation
plot(0:255, pdf_est./length(data),'b'); %// changed: explicit x axis
hold off
function K=Gaussian(x)
   sigma=1; %// change? Set as desired
   K=1./(sqrt(2*pi)*sigma)*exp(-x^2./(2*sigma^2));

代码根据1和2修改:

function pdf_est=KDE()
close all;
%%Random values of 20 pixels, range=[1 256]
data=randi([1 256],1,20)-1; %// changed: "-1"

%% Estimate histogram%%%%% 
pdf_est=zeros(1,256);
z=256;

for i=0:z-1 %// changed: subtracted 1 
    for j=1:length(data)
        pdf_est(i+1)=pdf_est(i+1)+Gaussian(i-data(j)); %// changed: "+1" (twice)
    end
end
%% Plot real histogram 1 to 256; binsize=1;
hold on
plot(0:255, cumsum(imhist(uint8(data))./length(data)),'r'); %// changed: explicit x axis
                                                            %// changed: cumsum
%% Plot histogram estimation
plot(0:255, cumsum(pdf_est./length(data)),'b'); %// changed: explicit x axis
                                                %// changed: cumsum
hold off
function K=Gaussian(x)
   sigma=1; %// change? Set as desired
   K=1./(sqrt(2*pi)*sigma)*exp(-x^2./(2*sigma^2));