[Frontmatter] (如果您只是想要问题,请跳过此步骤):
我目前正在考虑使用Shannon-Weaver Mutual Information和normalized redundancy来衡量按功能组织的离散和连续特征值之间的信息屏蔽程度。使用此方法,我的目标是构建一个看起来与ID3非常相似的算法,但算法将寻找(作为循环约束)以最大化或最小化之间的共享信息,而不是使用Shannon entropy。基于完整输入要素空间的单个要素和一组要素,如果(并且仅当)它们分别增加或减少相互信息,则向后一个集合添加新要素。实际上,这会将ID3的决策算法移动到成对空间中,并使用两种方法的所有预期时间和空间复杂性来装订集合方法。
[/ Frontmatter]
关于问题:我正在尝试使用integrator在Python中使用连续SciPy。因为我正在使用离散变量和连续变量的比较,我对特征 - 特征对的每个比较的当前策略如下:
离散特征与离散特征:使用离散形式的互信息。这导致概率的双重总和,我的代码处理没有问题。
所有其他情况(离散与连续,反向,连续与连续):使用连续形式,使用Gaussian estimator平滑probability density functions。
< / LI>对于后一种情况,我可以进行某种离散化,但由于我的输入数据集本身并不是线性的,因此这可能是不必要的复杂。
这是重要的代码:
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来执行集成,但在后一种情况下,我收到了以下消息的令人震惊的消息。
当我设置numpy.seterr ( all='ignore' )
时:
警告:检测到舍入错误的发生,这会阻止 要求的容忍度。错误可能是 低估。
当我使用错误处理程序将其设置为'call'
时:
浮点错误(下溢),标志4
浮点错误(无效值),标志为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)
然而,舍入修正的问题仍然存在,对更强大的实施的要求也是如此。任何领域的任何帮助将不胜感激。
答案 0 :(得分:3)
在尝试更复杂的解决方案(如重构问题或使用不同的集成工具)之前,请先看看这是否有帮助。将INF=float('INF')
替换为INF=1E12
或其他一些大号 - 可能会消除对输入变量进行简单算术运算所产生的 NaN 结果。
对此没有任何承诺,但在进行重要的算法重写或替换替代工具之前尝试快速修复有时会很有帮助。