[前沿内容](如果你只是想问这个问题,就跳过这个):
我目前正在研究使用Shannon-Weaver Mutual Information和normalized redundancy来测量按特征组织的离散和连续特征值包之间的信息掩蔽程度。使用这种方法,我的目标是构造一个看起来非常类似于ID3的算法,但该算法将寻求(作为循环约束)最大化或最小化单个特征和基于完整输入特征空间的特征集合之间的共享信息,而不是使用Shannon entropy,如果(且仅当)后一个集合中的新功能分别增加或减少了相互信息,则将其添加到后一个集合中。实际上,这将ID3的决策算法移动到pairspace中,将集成方法与这两种方法的所有预期时间和空间复杂性结合起来。
[/Frontmatter]
关于这个问题:我正在尝试使用SciPy在Python中使用连续的integrator。因为我正在处理离散变量和连续变量的比较,所以我目前针对每个特征对的比较策略如下:离散特征与离散特征:使用相互信息的离散形式。这将导致概率的双重求和,我的代码可以毫无问题地处理这些概率。
对于后一种情况,我可以执行某种离散化,但由于我的输入数据集不是固有的线性,这可能是不必要的复杂。
下面是最重要的代码:import math
import numpy
import scipy
from scipy.stats import gaussian_kde
from scipy.integrate import dblquad
# Constants
MIN_DOUBLE = 4.9406564584124654e-324
# The minimum size of a Float64; used here to prevent the
# logarithmic function from hitting its undefined region
# at its asymptote of 0.
INF = float('inf') # The floating-point representation for "infinity"
# x and y are previously defined as collections of
# floating point values with the same length
# Kernel estimation
gkde_x = gaussian_kde(x)
gkde_y = gaussian_kde(y)
if len(binned_x) != len(binned_y) and len(binned_x) != len(x):
x.append(x[0])
y.append(y[0])
gkde_xy = gaussian_kde([x,y])
mutual_info = lambda a,b: gkde_xy([a,b]) * \
math.log((gkde_xy([a,b]) / (gkde_x(a) * gkde_y(b))) + MIN_DOUBLE)
# Compute MI(X,Y)
(minfo_xy, err_xy) = \
dblquad(mutual_info, -INF, INF, lambda a: 0, lambda a: INF)
print 'minfo_xy = ', minfo_xy
请注意,为了防止SciPy的gaussian_kde类中出现奇点,特意对一个点进行了过度计数。当x和y的大小相互接近无穷大时,这种影响可以忽略不计。
我目前的障碍是试图让multiple integration与SciPy中的Gaussian kernel density estimate进行协作。我一直在尝试使用SciPy的dblquad来执行集成,但在后一种情况下,我收到了以下令人震惊的消息。
当我设置^{}时:Warning: The ocurrence of roundoff error is detected, which prevents
the requested tolerance from being achieved. The error may be
underestimated.
当我使用错误处理程序将其设置为'call'时:Floating point error (underflow), with flag 4
Floating point error (invalid value), with flag 8
很容易搞清楚是怎么回事,对吧?好吧,差不多:IEEE 754-2008和SciPy只告诉我这里发生了什么,而不是为什么或如何解决它。
结果:minfo_xy通常解析为nan;其采样不足以防止执行Float64数学运算时信息丢失或无效。
使用SciPy时,是否有解决此问题的通用方法?
更好的方法是:如果Python有一个健壮的、固定的、连续互信息的实现,它有一个接受两个浮点值集合或合并的对集合的接口,那么它将解决这个完整的问题。如果你知道其中一个存在,请链接它。
提前谢谢你。
编辑:这解决了上面示例中的nan传播问题:mutual_info = lambda a,b: gkde_xy([a,b]) * \
math.log((gkde_xy([a,b]) / ((gkde_x(a) * gkde_y(b)) + MIN_DOUBLE)) \
+ MIN_DOUBLE)
然而,取整校正的问题仍然存在,要求更稳健的实现也是如此。在这两个领域的任何帮助都将不胜感激。