Python中的连续互信息
[Frontmatter](如果您只想提问,请跳过此项): 我目前正在研究使用和测量离散特征值和连续特征值包之间的信息掩蔽程度,按特征组织。使用此方法,我的目标是构造一个算法,该算法看起来非常类似,但不是使用,而是根据完整的输入特征空间,寻求(作为循环约束)最大化或最小化单个特征和特征集合之间的共享信息,在后一个集合中添加新特征(如果需要)(且仅当)它们分别增加或减少互信息。这实际上将ID3的决策算法移动到了成对空间,将一个集成方法与这两种方法的所有预期时间和空间复杂性绑定在一起 [/Frontmatter]Python中的连续互信息,python,math,floating-point,scipy,information-theory,Python,Math,Floating Point,Scipy,Information Theory,[Frontmatter](如果您只想提问,请跳过此项): 我目前正在研究使用和测量离散特征值和连续特征值包之间的信息掩蔽程度,按特征组织。使用此方法,我的目标是构造一个算法,该算法看起来非常类似,但不是使用,而是根据完整的输入特征空间,寻求(作为循环约束)最大化或最小化单个特征和特征集合之间的共享信息,在后一个集合中添加新特征(如果需要)(且仅当)它们分别增加或减少互信息。这实际上将ID3的决策算法移动到了成对空间,将一个集成方法与这两种方法的所有预期时间和空间复杂性绑定在一起 [/Front
关于这个问题:我正在尝试使用Python获得一个连续的工作。因为我正在处理离散变量和连续变量的比较,所以我当前对每个特性对的比较策略如下:
- 离散特征与离散特征:使用互信息的离散形式。这会导致概率的双重总和,我的代码可以毫无问题地处理
- 所有其他情况(离散与连续、反向、连续与连续):使用连续形式,使用a平滑
以下是突出的代码:
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类中出现奇点而故意做的。当x和y的大小相互接近无穷大时,这种影响变得可以忽略不计
我目前的障碍是试图在SciPy中使用一个新的工具。我一直在尝试使用SciPy来执行集成,但在后一种情况下,我收到了以下令人震惊的消息 当我设定: 警告:检测到舍入错误,这会阻止 无法达到要求的公差。错误可能为 被低估了 当我使用错误处理程序将其设置为
'call'
时:
浮点错误(下溢),带标志4
浮点错误(无效值),带标志8
很容易弄清楚到底发生了什么,对吧?嗯,差不多了:SciPy只告诉我这里发生了什么,而不是为什么或者如何解决它
结果是:
minfo_xy
通常解析为nan
;它的采样不足以防止执行浮点运算时信息丢失或无效
使用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)
然而,舍入修正的问题仍然存在,对更健壮的实现的要求也是如此。我们非常感谢在这两个领域中的任何帮助。在尝试更激进的解决方案(如重新定义问题或使用不同的集成工具)之前,看看这是否有帮助。替换
INF=float('INF'))
带有INF=1E12
或其他一些大数字,这可能会消除对输入变量进行简单算术运算产生的NaN结果
在这方面没有承诺,但有时在进行重要的算法重写或替换替代工具之前尝试快速修复是有帮助的。好建议,尽管我已经尝试过。在实现当前实现时,我还尝试了非超限边界,以查看QUADPACK()中是否有不同的代码路径就足够了,SciPy与之接口。没有这样的运气。--但是,我已经修改了常数的定义,看看这是否有效,我仍然在结果集中收到
nan
。这意味着nan值可能在概率为零的区域传播,这让我很担心。*测试*是的;我已经修复了nan至少是代码>传播。原始问题已经更新。不接受它是故意的,因为它回答了一个警告,但不是整个问题(我希望有更多的答案)。因此,我将设法填补缺失的细节。--解决方法确实是使用更多正确的积分器。如果这些积分器不可用,大部分问题可以通过使用绝对和相对ε值来解决。这里有一个难点:dblquad
来自SciPy,它有一个错误,这些值被丢弃到内部集成的地板。因此,他们的团队已经收到了通知,并提供了一个补丁。--现在将此标记为已接受。令人惊讶的是,python中还没有持续的互信息实现。您得到了更多信息吗?另外,为什么您的gfun=0而不是-INF在DBLQUARD调用中?不幸的是,我放弃了此查询ce最初是我写的,我怀疑我的代码示例可以改进。如果我回想起来(两年前),我是在寻找互信息w.r.t.绝对值,所以(-INF,0)没有意义。但是,如果我错了,我尝试链接的原始Shannon和Weaver文件应该能够澄清这一点。:)Minepy似乎有一个连续互信息的实现:我想在这种情况下,始终存在着高斯KDE是否比简单直方图更好的问题