引数normed = 1でヒストグラムを作成しようとしています
例えば:
import pylab
data = ([1,1,2,3,3,3,3,3,4,5.1])
pylab.hist(data, normed=1)
pylab.show()
ビンの合計は1になると予想しましたが、代わりに、ビンの1つが1より大きくなります。この正規化は何をしましたか。そして、ヒストグラムの積分が1になるような正規化でヒストグラムを作成する方法は?
ヒストグラム内のすべてのビンの合計を1に等しくする方法については、他の投稿を参照してください: https://stackoverflow.com/a/16399202/1542814
コピーペースト:
weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)
myarrayにはデータが含まれます
documentationnormed:Trueの場合、結果はビンでの確率密度関数の値であり、範囲全体の積分が1になるように正規化されます。ユニティ幅のビンが選択されない限り、ヒストグラム値の合計は1に等しくなりません。これは確率質量関数ではありません。これはnumpy docからのものですが、pylabでも同じです。
In []: data= array([1,1,2,3,3,3,3,3,4,5.1])
In []: counts, bins= histogram(data, normed= True)
In []: counts
Out[]: array([ 0.488, 0., 0.244, 0., 1.22, 0., 0., 0.244, 0., 0.244])
In []: sum(counts* diff(bins))
Out[]: 0.99999999999999989
したがって、次のようなドキュメントに従って、単純に正規化が行われます。
In []: counts, bins= histogram(data, normed= False)
In []: counts
Out[]: array([2, 0, 1, 0, 5, 0, 0, 1, 0, 1])
In []: counts_n= counts/ sum(counts* diff(bins))
In []: counts_n
Out[]: array([ 0.488, 0., 0.244, 0., 1.22 , 0., 0., 0.244, 0., 0.244])
ビンの高さとビンの内容を混同していると思います。各ビンの内容、つまりすべてのビンの高さ*幅を追加する必要があります。これは1でなければなりません。
この正規化は何をしましたか?
シーケンスを正規化するには、ビンのサイズを考慮する必要があります。 documentation によると、デフォルトのビンの数は10です。したがって、ビンのサイズは(data.max() - data.min() )/10
、つまり0.41です。 normed=1
の場合、バーの高さは合計に0.41を掛けた値が1になるようになります。これが統合時に発生することです。
そして、ヒストグラムの積分が1になるような正規化でヒストグラムを作成する方法は?
積分ではなく、ヒストグラムの合計を1にしたいと思います。この場合、最も簡単な方法は次のように思われます。
h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)
私は同じ問題を抱えていましたが、解決中に別の問題が発生しました。正規化されたビンの頻度を、四捨五入値の目盛り付きのパーセンテージとしてプロットする方法です。誰にとっても役に立つ場合に備えて、ここに投稿しています。私の例では、y軸の最大値として10%(0.1)、10ステップ(0%から1%、1%から2%など)を選択しました。トリックは、n
クラスを使用して次にパーセンテージに変換されるdataカウント(plt.hist
の出力リストFuncFormatter
)にティックを設定することです。私がやったことは次のとおりです。
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
fig, ax = plt.subplots()
# The required parameters
num_steps = 10
max_percentage = 0.1
num_bins = 40
# Calculating the maximum value on the y axis and the yticks
max_val = max_percentage * len(data)
step_size = max_val / num_steps
yticks = [ x * step_size for x in range(0, num_steps+1) ]
ax.set_yticks( yticks )
plt.ylim(0, max_val)
# Running the histogram method
n, bins, patches = plt.hist(data, num_bins)
# To plot correct percentages in the y axis
to_percentage = lambda y, pos: str(round( ( y / float(len(data)) ) * 100.0, 2)) + '%'
plt.gca().yaxis.set_major_formatter(FuncFormatter(to_percentage))
plt.show()
正規化前:y軸の単位は、x軸のビン間隔内のサンプル数です。
正規化後:y軸の単位は、すべてのサンプルに対する割合としてのビン値の頻度です
Numpyにもアナログがあります-numpy.historgram
: http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html パラメーターの1つは「密度」です。density=True
、出力は正規化されます。
normed:bool、optionalこのキーワードは、混乱/バグのある動作のためにNumpy 1.6で非推奨になりました。 Numpy 2.0では削除されます。代わりにdensityキーワードを使用してください。 Falseの場合、結果には各ビンのサンプル数が含まれます。 Trueの場合、結果は範囲の積分が1になるように正規化されたビンでの確率密度関数の値です。この後者の動作は、ビンの幅が等しくない場合にバグがあることがわかっています。代わりに密度を使用してください。
density:bool、オプションFalseの場合、結果には各ビンのサンプル数が含まれます。 Trueの場合、結果はビンでの確率密度関数の値であり、範囲全体の積分が1になるように正規化されます。1の幅のビンが選択されない限り、ヒストグラム値の合計は1になりません。確率質量関数ではありません。指定されている場合、normedキーワードをオーバーライドします。
あなたの期待は間違っています
ビンの高さの合計その幅は1に等しい。または、あなたが正しく言ったように、integralは1でなければなりません関数ではなく統合します。
probability(「20歳から40歳までの確率は...%」のように)は整数です( 「20〜40歳」))確率密度ビンの高さは確率密度を示し、幅と高さの積は、このビンにある特定のポイントの確率(ビンの始めからビンの終わりまで一定の仮定関数、ビンの高さを積分します)を示します。高さ自体は密度であり、確率ではありません。それは、幅ごとの確率であり、もちろん1よりも高くなる可能性があります。
簡単な例:0から0.9の値0を持つ0から1の確率密度関数を想像してください。関数はおそらく0.9から1の間にあるでしょうか?統合する場合は、試してみてください。 1よりも高くなります。
ところで、大まかな推測から、histのheightとwidthの合計はおよそ1になりますね。