如何估算密度函数并计算其峰值?

时间:2015-07-06 14:48:28

标签: python python-2.7 numpy pandas

我已经开始使用python进行分析了。我想做以下事情:

  1. 获取数据集的分发
  2. 获取此分布中的高峰
  3. 我使用scipy.stats中的gaussian_kde来估算核密度函数。 guassian_kde是否对数据做出任何假设?我正在使用随时间变化的数据。因此,如果数据具有一个分布(例如高斯分布),则稍后可能有另一个分布。 gaussian_kde在这种情况下有任何缺点吗?在question中建议尝试在每个分布中拟合数据以获得数据分布。那么使用gaussian_kde与question中提供的答案之间的区别是什么?我使用下面的代码,我还想知道如果数据会随着时间的推移而改变,那么gaussian_kde是估算pdf的好方法吗?我知道gaussian_kde的一个优点是它可以通过here中的经验法则自动计算带宽。另外,我怎样才能达到峰值呢?

    import pandas as pd
    import numpy as np
    import pylab as pl
    import scipy.stats
    df = pd.read_csv('D:\dataset.csv')
    pdf = scipy.stats.kde.gaussian_kde(df)
    x = np.linspace((df.min()-1),(df.max()+1), len(df)) 
    y = pdf(x)                          
    
    pl.plot(x, y, color = 'r') 
    pl.hist(data_column, normed= True)
    pl.show(block=True)       
    

1 个答案:

答案 0 :(得分:10)

我认为您需要区分非参数密度(scipy.stats.kde中实现的密度)与参数密度(您提到的StackOverflow question中的密度)。为了说明这两者之间的区别,请尝试以下代码。

import pandas as pd
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

np.random.seed(0)
gaussian1 = -6 + 3 * np.random.randn(1700)
gaussian2 = 4 + 1.5 * np.random.randn(300)
gaussian_mixture = np.hstack([gaussian1, gaussian2])

df = pd.DataFrame(gaussian_mixture, columns=['data'])

# non-parametric pdf
nparam_density = stats.kde.gaussian_kde(df.values.ravel())
x = np.linspace(-20, 10, 200)
nparam_density = nparam_density(x)

# parametric fit: assume normal distribution
loc_param, scale_param = stats.norm.fit(df)
param_density = stats.norm.pdf(x, loc=loc_param, scale=scale_param)

fig, ax = plt.subplots(figsize=(10, 6))
ax.hist(df.values, bins=30, normed=True)
ax.plot(x, nparam_density, 'r-', label='non-parametric density (smoothed by Gaussian kernel)')
ax.plot(x, param_density, 'k--', label='parametric density')
ax.set_ylim([0, 0.15])
ax.legend(loc='best')

enter image description here

从图中可以看出,非参数密度只不过是直方图的平滑版本。在直方图中,对于特定的观察x=x0,我们使用条形来表示它(将所有概率质量放在该单个点x=x0上,在其他地方放零)而在非参数密度估计中,我们使用钟形形状曲线(高斯核)表示该点(在其邻域上展开)。结果是平滑的密度曲线。这个内部高斯内核与您对基础数据x的分布式假设无关。它的唯一目的是平滑。

要获得非参数密度模式,我们需要进行详尽的搜索,因为密度不能保证具有单模式。如上例所示,如果准牛顿优化算法在[5,10]之间开始,则很可能最终得到局部最优点而不是全局点。

# get mode: exhastive search
x[np.argsort(nparam_density)[-1]]