0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Histgram関数の理解

Posted at

はじめに

Histgramは、numpyで計算してからplotする方法と、matplotlibで直接Plotする方法があります。(Matplotlibでも内部でnumpyを用いて計算している。)
matplotlibで直接Plotを行うには下記の1が参考になります。 ここでは、1の記事に従いnumpyで計算を行いその後Plotを行った覚えです。
ここでは、度数分布、相対度数分布、相対度数密度の計算とPlotを示します。

参考
  1. matplotlibでヒストグラムの縦軸を相対度数(柱の高さの合計=1)や相対度数密度(ヒストグラム全体の面積=1)にする

  2. NumPyでヒストグラムを作るnp.histogram関数の使い方

  3. pandasで度数分布表を自動で作る関数

ヒストグラムの用語

階級:度数を集計するための 1つ1つ区間
階級数 : 階級の数
階級幅 : 区間の大きさを階級の幅
階級値 : その階級を代表する値(階級の真ん中の値)

度数 (Frequency)

相対度数 (Relative Frequency)
-> 相対度数 = 度数 / 度数の合計値

相対度数密度 (Density = relative frequency density)
-> 相対度数密度 = 相対度数 / 階級幅

度数密度 (frequency density)
-> 度数密度 = 度数 / 階級幅

度数分布、相対度数分布、相対度数密度

import matplotlib.pyplot as plt
import numpy as np
# dataの作成
mu = 50
sg = 10
data = np.array([ np.random.normal(mu, sg) for i in range(10000) ])

print(f'Data length: {data.shape}, {len(data)}')
#>>>Data length: (10000,), 10000

plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.plot(data)
plt.grid()

plt.subplot(1,2,2)
plt.plot(data.cumsum())
plt.title("cumsum")
plt.grid()

output_2_1.png

度数分布

# Frequency example
print('Frequency example')

# Bins (階級数)
num_bins = 100

# Bins width (階級幅)
bin_width = (max(data) - min(data)) / num_bins
print(f"Bin width: {bin_width:.3f}")

hist, bins = np.histogram(data, bins=num_bins) 

print(f'Bins length:{len(bins)}')
# binsの長さに注意 帰ってくるbinsの長さは指定したnum_bins+1
print(f'Histgram length: {len(hist)}')
print(f'Max cumsum: {hist.cumsum().max():.2f}')
print(f'Area: {np.sum(bin_width*hist):.2f}')

plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.title("histgram")
plt.plot(bins[:-1],hist)
plt.grid()

plt.subplot(1,2,2)
plt.plot(bins[:-1],hist.cumsum())
plt.title("cumsum")
plt.grid()

Frequency example
Bin width: 0.766
Bins length:101
Histgram length: 100
Max cumsum: 10000.00
Area: 7662.08

output_3_1.png

相対度数分布

# Relative Frequency example
print('Relative Frequency example')

# Bins
num_bins = 100

# Bins width
bin_width = (max(data) - min(data)) / num_bins
print(f"Bin width: {bin_width:.3f}")

# weightsを指定することで各階級の重み付けを行う
weights = np.ones_like(data) / len(data)

print(f'weight length:{len(weights)}')

hist, bins = np.histogram(data, bins=num_bins, weights=weights) 

print(f'bins length:{len(bins)}')
print(f'histgram length: {len(hist)}')
print(f'Max cumsum: {hist.cumsum().max():.2f}')
print(f'Area: {np.sum(bin_width*hist):.2f}')
plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.title("histgram")
plt.plot(bins[:-1],hist)
plt.grid()

plt.subplot(1,2,2)
plt.plot(bins[:-1],hist.cumsum())
plt.title("cumsum")
plt.grid()

# Note:
# 度数分布を求めて、度数累積和の最大値で規格化しても同じ
# hist, bins = np.histogram(data, bins=num_bins) 

# plt.figure(figsize=(12, 6))
# plt.subplot(1,2,1)
# plt.title("histgram")
# plt.plot(bins[:-1],hist/(max(hist.cumsum())))
# plt.grid()

# plt.subplot(1,2,2)
# plt.plot(bins[:-1],hist.cumsum()/(max(hist.cumsum())))
# plt.title("cumsum")
# plt.grid()

Relative Frequency example
Bin width: 0.766
weight length:10000
bins length:101
histgram length: 100
Max cumsum: 1.00
Area: 0.77

累積和の最大値が1になっている。

output_5_1.png

# 累積和で50%の位置の階級値を求めたい場合

def getNearestValue(list, num):
    """
    リストからある値に最も近い値を返却する関数
    Args:
        list (list or ndarray): 探索対象データ
        num (float): 対象値

    Returns:
        float:  対象値に最も近い値
    """
    # リスト要素と対象値の差分を計算し最小値のインデックスを取得
    idx = np.abs(np.asarray(list) - num).argmin()
    
    return idx

ind = getNearestValue(hist.cumsum(), 0.5)

print(f'Index :{ind}')
print(f'Bin : {bins[ind]}')

Index :52
Bin : 48.92290015560406

相対度数密度

# Density example

# Density (relative frequency density)
# -> Relative frequency density ->  relative frequency / bin_width

print('Density (relative frequency density) example')

# Bins
num_bins = 100

# Bins width
bin_width = (max(data) - min(data)) / num_bins
print(f"Bin width : {bin_width:.3f}")

weights = np.ones_like(data) / len(data)
print(f'weight length : {len(weights)}')


hist, bins = np.histogram(data, bins=num_bins, weights=weights, density=True) 

# weightsを指定しなくて同じ結果になる
# hist, bins = np.histogram(data, bins=num_bins, density=True) 

print(f'bins length : {len(bins)}')
print(f'histgram length : {len(hist)}')
print(f'Max cumsum : {hist.cumsum().max():.2f}')

# density = True :ヒストグラム全体の面積が1になる。
print(f'Area: {np.sum(bin_width*hist):.2f}')
plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.title("histgram")
plt.plot(bins[:-1],hist)
plt.grid()

plt.subplot(1,2,2)
plt.plot(bins[:-1],hist.cumsum())
plt.title("cumsum")
plt.grid()

Density (relative frequency density) example
Bin width : 0.766
weight length : 10000
bins length : 101
histgram length : 100
Max cumsum : 1.31
Area: 1.00

output_7_1.png

相対度数分布で範囲を変えた場合

# Relative Frequency example. Range change

print('Range change  -Relative Frequency example- ')

# Bins
num_bins = 100

# Bins width
# bin_range =(min(data),max(data))
bin_range=(40,70)

bin_width = (max(bin_range) - min(bin_range)) / num_bins
print(f"Bin width: {bin_width:.3f}")

# weightsを指定することで各階級の重み付けを行う
weights = np.ones_like(data) / len(data)

print(f'weight length:{len(weights)}')

hist, bins = np.histogram(data, bins=num_bins, range=bin_range, weights=weights) 

print(f'bins length : {len(bins)}')
print(f'histgram length : {len(hist)}')
print(f'Max cumsum : {hist.cumsum().max():.2f}')
print(f'Area : {np.sum(bin_width*hist):.2f}')
plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.title("histgram")
plt.plot(bins[:-1],hist)
plt.grid()

plt.subplot(1,2,2)
plt.plot(bins[:-1],hist.cumsum())
plt.title("cumsum")
plt.grid()

Range change -Relative Frequency example-
Bin width: 0.300
weight length:10000
bins length:101
histgram length: 100
Max cumsum: 0.81
Area: 0.24

output_9_1.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?