[Frontmatter] (如果你只是想问这个问题,请跳过这个):
我目前正在研究使用Shannon-Weaver 互信息和标准化冗余来测量按特征组织的离散和连续特征值袋之间的信息屏蔽程度。使用这种方法,我的目标是构建一个看起来与ID3非常相似的算法,但不是使用香农熵,该算法将寻求(作为循环约束)最大化或最小化单个特征和基于完整输入特征空间的特征集合之间的共享信息,当(且仅当)新特征增加或分别减少互信息。实际上,这将 ID3 的决策算法移动到对空间中,将集成方法与这两种方法的所有预期时间和空间复杂性结合在一起。
[/前线]
关于这个问题:我正在尝试让一个使用SciPy在 Python 中工作的连续积分器。因为我正在比较离散变量和连续变量,所以我当前对特征-特征对的每次比较的策略如下:
对于后一种情况,我可以执行某种离散化,但由于我的输入数据集本质上不是线性的,这可能是不必要的复杂。
这是显着的代码:
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 的大小相互接近无穷大,这种影响变得可以忽略不计。
我目前的障碍是试图在 SciPy 中针对高斯核密度估计进行多重集成。我一直在尝试使用 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)
然而,舍入校正的问题仍然存在,对于更强大的实现的要求也是如此。任何一个领域的任何帮助都将不胜感激。