情報量まとめ
弊PRMLラボのアドベントカレンダー → https://adventar.org/calendars/2186
5日目を担当します.M1のsumvoです.
研究のテーマがら情報量を扱うことがあり,何度も調べてはこれでいいのか?ってなっていたり忘れたりするので,備忘録的な意味も含め書いていきたいと思います.
基本的なことは↓でできるのですけども,ライブラリに無いものも多くスケール感を合わせたりするためにも全部自分でやっていこうみたいな感じです.
from scipy.stats import entropy# entropy, KLDの計算 from sklearn.metrics import mutual_info_score# MIの計算
まずは,シャノンエントロピーや平均情報量と一般的に言われている物です.エントロピーと言ったらこれみたいな感じです.
logの底が2の場合は単位がbitで在りJIS:ISO的にはこの単位がシャノンになる.eの時はnatで在り単位もnat.10の時はditであり,単位はハートレー.
import numpy as np print(np.histogram(data,bins=100)[0]) print(np.histogram(data,bins=100)[0]/data.shape[0]) pa = np.histogram(data,bins=100)[0]/data.shape[0] print(-np.sum(pa*np.log2(pa)))
array([210, 81, 90, 64, 57, 115, 95, 78, 103, 82, 88, 95, 72, 72, 169, 122, 129, 125, 90, 86, 58, 76, 85, 98, 98, 57, 75, 112, 130, 226, 139, 160, 162, 140, 129, 133, 163, 146, 122, 93, 88, 95, 133, 104, 101, 114, 96, 96, 107, 95, 100, 88, 88, 92, 160, 168, 137, 111, 101, 120, 132, 155, 372, 276, 276, 264, 220, 220, 239, 203, 193, 238, 261, 241, 307, 285, 357, 500, 198, 194, 189, 211, 129, 138, 133, 200, 222, 219, 224, 213, 217, 289, 351, 211, 229, 192, 194, 341, 346, 386], dtype=int64) array([ 0.01281738, 0.00494385, 0.00549316, 0.00390625, 0.003479 , 0.00701904, 0.00579834, 0.00476074, 0.00628662, 0.00500488, 0.00537109, 0.00579834, 0.00439453, 0.00439453, 0.01031494, 0.00744629, 0.00787354, 0.00762939, 0.00549316, 0.00524902, . . . 6.4636211511753165
続いて結合エントロピー,joint entropyと呼ばれているものです.
複数の場合
結合エントロピーは常に元のエントロピーよりも上になります.また,2つのエントロピーの総和よりは下になります.
例 : 2つの結合エントロピー
import numpy as np pab = np.histogram2d(data,data,bins=100)[0]/data.shape[0] print(pab.shape) print(-np.sum(pab*np.log2(pab+1e-15)))
(100, 100) 12.399404410313927
例 : 複数の結合エントロピー
import numpy as np prnit(x.shape, y.shape, z.shape) w = np.c_[x,y,z] print(w.shape) pabc = np.histogramdd(w, bins=100)[0] / w.shape[0] print(pabc.shape) print(-np.sum(pabc*np.log2(pabc+1e-15)))
((50, ), (50, ), (50, )) (50, 3) (100, 100, 100) 5.6438561897746533
そして相互情報量(Mutual Information : MI)
import numpy as np pa = np.histogram(data1,bins=100)[0]/data1.shape[0] pb = np.histogram(data2,bins=100)[0]/data2.shape[0] pab = np.histogram2d(data,data2,bins=100)[0]/data1.shape[0] print((-np.sum(pa*np.log2(pa))) , (-np.sum(pb*np.log2(pb))) , (-np.sum(pab*np.log2(pab+1e-15)))) print(-np.sum(pab*np.log2(pab+1e-15)) + (-np.sum(pa*np.log2(pa))) + (-np.sum(pb*np.log2(pb))))
(6.4636211511753165, 6.3849326697480082, 12.399404410313927) 0.44914941060939739
実際sklearnとかにもある.CMIは計算できない.
作っている確率分布が違ってくるので出力も違う
from sklearn.metrics import mutual_info_score mutual_info_score(data1, data2)
9.6793088338861271
そして条件付エントロピー(conditional entropy)
多分チェインルールにしたほうが楽
そして条件付相互情報量(Conditional Mutual Information : CMI)
基本的には条件付エントロピーを式に入れているが,結合エントロピー重視で展開してくとこんな感じになる.結果結合エントロピーとエントロピーだけの式になる.
番外
import numpy as np prob = np.array([ [0.1,0.8,0.1], [0.3,0.4,0.3], [0.7,0.2,0.1], [0.3,0.3,0.4]]) label = np.array([ [0,1,0], [1,0,0], [1,0,0], [0,0,1]]) print(-np.sum(label * np.log(prob)))
2.7000820314530332
カルバックライブラー情報量(カルバックライブラーダイバージェンス:KLD, 情報利得:Information gain)
import numpy as np from scipy import stats prob = np.array([ [0.1,0.8,0.1], [0.3,0.4,0.3], [0.7,0.2,0.1], [0.3,0.3,0.4]]) label = np.array([ [0,1,0], [1,0,0], [1,0,0], [0,0,1]]) print(stats.entropy(label,prob,2))#2つ入れるとKLD,1つだけだとエントロピー
array([ 0.61119621, 1.08746284, 1.169925 ])
とりあえず以上でまとめ終わりっ!!明日の人お願いします.