matplotlib에서 히스토그램의 종축을 상대 도수(기둥 높이의 합계=1)나 상대 도수 밀도(히스토그램 전체의 면적=1)로 한다

이 기사에서 할 일



matplotlib에서 히스토그램의 세로축
  • 빈도 (matplotlib의 기본값)
  • 상대 빈도
  • 상대 빈도 밀도

  • 으로 그립니다.

    참고 페이지(감사합니다)



    matplotlib.hist의 normed가 이상합니다.
    matplotlib : histgram normed의 거동
    통계학 ② python을 사용하여 확률 밀도 함수(정규 분포, 표준 정규 분포)를 기억해 버린다!

    용어 정리



    계산식은
  • 빈도 밀도 = 빈도/계급 폭
  • 상대 빈도 밀도 = 상대 빈도/계급 폭

  • 같다.
    아래의 Python 코드로 실험한 결과, hist 함수로 "density=True"를 지정하면 세로축이 상대 도수 밀도가 되는 것 같습니다.
    hist 함수에는 normed 옵션(비추천)도 있습니다만, 이것의 버그를 제거한 것이 density 옵션이라고 합니다.

    소스 코드 (Jupyter Notebook) 및 그리기 결과



    세 개의 히스토그램을 그립니다.
    데이터 건수는 10000건으로 평균값 50, 표준 편차 10의 정규 난수로 했습니다.
    
    #%% md
    
    #%%
    
    import numpy as np
    from scipy.stats import norm
    import matplotlib.pyplot as plt
    
    
    #%%
    
    # データ作成
    μ = 50
    σ = 10
    data = [ np.random.normal(μ, σ) for i in range(10000) ]
    
    
    #%%
    
    # 階級数
    num_bins = 20
    
    # 階級幅
    bin_width = (max(data) - min(data)) / num_bins
    print(f"階級幅 = 約{bin_width}")
    
    # グラフ描画
    fig = plt.figure(figsize=(8, 24))
    
    # (1) 縦軸を度数にしたヒストグラム
    ax1 = fig.add_subplot(311)
    ax1.title.set_text("(1) frequency")
    ax1.grid(True)
    ax1.hist(data, bins=num_bins)
    
    # (2) 縦軸を相対度数にしたヒストグラム
    ax2 = fig.add_subplot(312)
    ax2.title.set_text("(2) relative frequency")
    ax2.grid(True)
    ax2.set_xlim(ax1.get_xlim())
    weights = np.ones_like(data) / len(data)
    ax2.hist(data, bins=num_bins, weights=weights)
    
    # (3) 縦軸を相対度数密度にしたヒストグラム(青) & 正規分布の確率密度関数(赤)
    ax3 = fig.add_subplot(313)
    ax3.title.set_text("(3) density")
    ax3.grid(True)
    ax3.set_xlim(ax1.get_xlim())
    ax3.hist(data, bins=num_bins, density=True, color="blue", alpha=0.5)
    
    x = np.arange(0, 100, 1)
    y = norm.pdf(x, μ, σ)
    ax3.fill_between(x, y, color="red", alpha=0.5)
    ax3.plot(x, y, 'k', linewidth=3, color="red", alpha=0.5)
    
    

    코드를 실행하면 "계급 너비 = 약 3.718313197105561"이 표시되고 다음 히스토그램이 그려졌습니다.
    세 개의 히스토그램은 각각 (1) 세로축 = 도수, (2) 세로축 = 상대 도수, (3)은 세로축 = 상대 도수 밀도의 히스토그램 (파란색)에 정규 분포의 확률 밀도 함수 (적색)를 겹친다. 보고 있습니다.
    「density=True」의 히스토그램과 확률 밀도 함수가 겹치고 있기 때문에, 「density=True」로 하면 히스토그램 전체의 면적이 1이 되는 것 같습니다.



    「density=True」로 세로축이 상대 도수 밀도가 되어 있는지, 계산식으로부터 대략 검증



    검증에 히스토그램의 가장 높은 기둥을 사용합니다.

    상대 빈도



    (2)의 가장 높은 기둥은 0.14와 0.15 사이의 값입니다.

    계급 폭



    코드를 실행했을 때 약 3.7로 표시되었습니다.

    상대 도수 밀도



    상대도수/계급폭 = 0.145/3.7 ≒ 0.039
    (3)의 가장 높은 기둥과 맞는 것처럼 보입니다.
    (검증 끝)

    상대 빈도의 히스토그램에서 기둥 높이의 합이 1.0인지 확인



    위의 히스토그램을 읽고 합산하는 것도 어렵기 때문에 파이썬 코드의 계급 수 (num_bins 변수)를 1로 설정하여 다시 실행해 보겠습니다.



    (2)의 유일한 기둥 높이가 1.0이 되었습니다.
    또, 10000건의 데이터를 사용했으므로, (1)의 유일한 기둥의 높이도 10000이 되고 있습니다.
    (3)의 「density=True」의 히스토그램(파랑)도 확률 밀도 함수(적색)의 면적과 동일하게 보입니다(면적=1).
    (검증 끝)

    좋은 웹페이지 즐겨찾기