Pythonの継続的な相互情報
-
27-10-2019 - |
質問
フロントの問題 (質問が必要な場合はこれをスキップします):
現在、使用を検討しています シャノンウィーバー相互情報 と 正規化された冗長性 機能ごとに整理された、個別の機能値と連続的な機能値のバッグ間の情報マスキングの程度を測定する。この方法を使用すると、非常に似ているアルゴリズムを構築することが私の目標です id3, 、しかし、使用する代わりに シャノンエントロピー, 、アルゴリズムは(ループの制約として)(ループの制約として)を求めて、単一の機能と完全な入力機能空間に基づいて共有情報と機能のコレクションを最大化または最小化し、後者のコレクションに新しい機能を追加する(およびのみ)増加または増加するかどうかを追加します。それぞれ相互情報を減らします。これにより、実際には、ID3の決定アルゴリズムがペアスペースに移動し、両方の方法の予想される時間と空間の複雑さのすべてを使用してアンサンブルアプローチを登録します。
/フロントの問題
質問について:私は連続して得ようとしています インテグレーター Pythonを使用して作業します scipy. 。私は離散変数と連続変数の比較に取り組んでいるため、機能フィーチャーペアの各比較に関する私の現在の戦略は次のとおりです。
離散機能と離散機能:相互情報の離散形式を使用します。これにより、確率が二重に合計され、コードが問題なく処理します。
他のすべてのケース(離散対連続、逆、および連続と連続):連続フォームを使用して、 ガウス推定器 滑らかにするために 確率密度関数.
後者のケースに対して何らかの離散化を実行することは可能ですが、入力データセットは本質的に線形ではないため、これは不必要に複雑です。
これが顕著なコードです:
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'sの特異性を防ぐために、正確に1つのポイントを1つのポイントをオーバーカウントすることは意図的に行われていることに注意してください gaussian_kde クラス。 xとyのサイズが相互にInfinityに近づくと、この効果は無視できます。
私の現在のひっかかったのは、得ようとしています 複数の統合 Aに対して作業 ガウスカーネル密度推定 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)
ただし、ラウンドオフ修正の問題は残っており、より堅牢な実装の要求も同様です。どちらのドメインでも、どんな助けも大歓迎です。
解決
問題を再構築したり、異なる統合ツールを使用したりするなど、より根本的なソリューションを試す前に、これが役立つかどうかを確認してください。交換 INF=float('INF')
と INF=1E12
または他のいくつかの数 - それは排除される可能性があります ナン 入力変数の単純な算術操作によって作成された結果。
これについては約束はありませんが、重要なアルゴリズムの書き直しまたは代替ツールの置換に従事する前に、簡単な修正を試みることが役立つ場合があります。