[Frontmatter] (質問が必要な場合はこれをスキップしてください):
私は現在、シャノンウィーバー相互情報量と正規化された冗長性を使用して、特徴ごとに整理された、離散的および連続的な特徴値のバッグ間の情報マスキングの程度を測定することを検討しています。この方法を使用して、 ID3に非常によく似たアルゴリズムを構築することが私の目標ですが、シャノンエントロピーを使用する代わりに、アルゴリズムは、完全な入力特徴空間に基づいて、単一の特徴と特徴のコレクションの間で共有される情報を最大化または最小化することを(ループ制約として)求め、後者のコレクションに新しい特徴が増加した場合、または増加した場合にのみ追加します。それぞれ相互情報量を減らします。これにより、事実上、ID3の決定アルゴリズムがペアスペースに移動し、両方の方法で予想される時間とスペースの複雑さのすべてを備えたアンサンブルアプローチが妨げられます。
[/フロントの問題]
質問に移ります:私はSciPyを使用してPythonで継続的なインテグレーターを動作させようとしています。離散変数と連続変数の比較を行っているため、特徴と特徴のペアの各比較に対する現在の戦略は次のとおりです。
離散機能と離散機能:相互情報量の離散形式を使用します。これにより、確率が2倍になり、コードで問題なく処理されます。
他のすべての場合(離散対連続、逆、および連続対連続):ガウス推定量を使用して確率密度関数を平滑化する連続形式を使用します。
後者の場合、ある種の離散化を実行することは可能ですが、入力データセットは本質的に線形ではないため、これは潜在的に不必要に複雑です。
顕著なコードは次のとおりです。
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クラスの特異性を防ぐために、正確に1つのポイントを過大評価することが意図的に行われていることに注意してください。xとyのサイズが相互に無限大に近づくと、この影響は無視できるようになります。
私の現在の問題は、SciPyのガウスカーネル密度推定に対して多重積分を機能させようとしていることです。私はSciPyのdblquadを使用して統合を実行しようとしていますが、後者の場合、次のメッセージの驚異的な噴出を受け取ります。
私が設定したときnumpy.seterr ( all='ignore' )
:
警告:丸め誤差の発生が検出されたため、要求された許容値を達成できません。エラーは過小評価されている可能性があります。
そして'call'
、エラーハンドラを使用するように設定すると:
浮動小数点エラー(アンダーフロー)、フラグ4
浮動小数点エラー(無効な値)、フラグ8
何が起こっているのかを理解するのはとても簡単ですよね?まあ、ほとんど:IEEE 754-2008とSciPyは、ここで何が起こっているのかを教えてくれるだけで、その理由や回避方法は教えてくれません。
結果:一般的には;minfo_xy
に解決されます。nan
Float64演算を実行するときに情報が失われたり無効になったりするのを防ぐには、そのサンプリングが不十分です。
SciPyを使用する場合、この問題の一般的な回避策はありますか?
さらに良いことに、浮動小数点値の2つのコレクションまたはペアのマージされたコレクションを取得するインターフェイスを備えた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)
ただし、より堅牢な実装の要求と同様に、丸め修正の問題が残っています。どちらのドメインでも助けていただければ幸いです。