ヒストグラムの用途とわかること|分布の形の読み方と機械学習・データ分析での使い方
ヒストグラムの用途は、数値データが「どのあたりに、どれくらい集まっているか」という分布の形を一目で見ることです。1枚のヒストグラムから、データの中心、ばらつきの大きさ、左右の偏り、山が1つか2つか、外れ値や入力ミスの有無がわかります。
この記事では、ヒストグラムの基本と、形ごとに「何がわかるか」の読み方を、Pythonで作った架空のデータの実行結果で確認します。後半では、機械学習やデータ分析の前処理でヒストグラムをどう使うか、階級(ビン)の数の決め方もまとめます。コードは Python 3.12.15・NumPy 2.5.4・matplotlib 3.11.2(2026年10月15日確認時点のPyPI最新版)で実行しました。
ヒストグラムとは
ヒストグラムは、量的データ(身長、点数、金額など数値で測るデータ)をいくつかの区間に分け、各区間に入るデータの個数を棒の高さで表したグラフです。総務省統計局の「なるほど統計学園」では、ヒストグラムは量的データの分布の様子を見るのに用いられ、データを階級に分けて度数分布表を作ってからグラフにする、と説明しています(なるほど統計学園「ヒストグラム」)。
| 用語 | 意味 |
|---|---|
| 階級(ビン) | データを分ける区間。「60点以上70点未満」など |
| 階級幅 | 1つの区間の幅。上の例なら10点 |
| 度数 | その区間に入るデータの個数 |
| 度数分布表 | 階級と度数を並べた表。ヒストグラムの元になる |
棒グラフとの違い
見た目は棒グラフに似ていますが、役割が違います。
| ヒストグラム | 棒グラフ | |
|---|---|---|
| 横軸 | 数値の区間(連続している) | カテゴリ(支店名、商品名など) |
| 棒の並び順 | 数値の順で固定。入れ替えられない | 自由に並べ替えてよい |
| 棒のすき間 | 区間がつながっているので基本的に空けない | 空ける |
| 表すもの | 1つの変数の分布 | カテゴリごとの量の比較 |
なるほど統計学園は、ヒストグラムでは面積が度数を表すので、階級幅が異なる区間を混ぜるときは高さに注意するよう書いています。たとえば2つの区間をまとめて幅を2倍にしたなら、高さは半分にして描かないと、まとめた区間だけが多く見えてしまいます。
ヒストグラムの用途
ヒストグラムがよく使われる場面を整理すると、次のようになります。
| 用途 | 例 |
|---|---|
| 全体の傾向をつかむ | テストの点数がどこに集まっているか、どれくらい散らばっているか |
| 平均値だけでは見えない形を確かめる | 売上や購入金額のように一部の大きな値で平均が引っ張られていないか |
| 異なる集団が混ざっていないか調べる | 山が2つあれば、性別・地域・機種など別の集団が混ざっている可能性 |
| 外れ値・入力ミスを見つける | 体温に365.0のような桁の打ち間違いがないか |
| 品質管理で規格に収まっているか見る | 製品の寸法や重さが、規格の範囲内にどれだけ収まっているか |
| 機械学習の前処理を決める | 特徴量や目的変数の偏りを見て、対数変換や外れ値処理が要るか判断する |
平均値・中央値・標準偏差のような数字(要約統計量)でも傾向はわかりますが、数字だけでは「山が2つある」「1件だけ桁違いの値がある」といった形の情報は落ちてしまいます。ヒストグラムは、要約統計量を計算する前後に、その数字をそのまま信じてよいかを確かめるために使うと考えるとわかりやすいでしょう。要約統計量そのものは「統計量とは?記述統計量の種類と求め方」で説明しています。
ヒストグラムからわかること:形ごとの読み方
ここからは、乱数で作った架空のデータをヒストグラムにして、形ごとに何が読み取れるかを見ていきます。結果がそのまま読めるように、棒の長さを # の数で表示しています(# 1つが何件かは例ごとに変えています)。
1. 山が1つで左右対称:中心とばらつきがわかる
import numpy as np
rng = np.random.default_rng(0)
scores = rng.normal(loc=60, scale=12, size=200).clip(0, 100).round()
counts, edges = np.histogram(scores, bins=range(30, 101, 10))
for c, lo, hi in zip(counts, edges[:-1], edges[1:]):
print(f"{lo:3.0f}〜{hi:3.0f} {c:3d} {'#' * (c // 2)}")
print("平均", scores.mean().round(1), "中央値", np.median(scores))
30〜 40 8 ####
40〜 50 27 #############
50〜 60 60 ##############################
60〜 70 61 ##############################
70〜 80 35 #################
80〜 90 9 ####
90〜100 0
平均 60.2 中央値 61.0
200人分の架空の点数です。50〜70点に集まり、そこから左右にほぼ同じように減っていきます。このように山が1つで左右対称に近いときは、平均値(60.2)と中央値(61.0)がほぼ一致し、「だいたい60点前後の人が多い」と平均値で代表させても大きく外れません。山の幅が広いほどばらつきが大きいことを表します。
なお、np.histogram の区間は「左端を含み右端を含まない」ですが、最後の区間だけは右端も含みます(numpy.histogram)。上の例では最後の区間が「90以上100以下」です。
2. 右に裾が長い:平均値が実感より大きくなる
ここから先は、同じ形式で表示するための関数 show() を用意して使います。以降のコードは1つのファイルに上から順に書いて実行した結果です。
def show(data, bins=10, per=10, fmt="6.0f"):
"""度数を # で表示する(# 1つ = per 件)"""
counts, edges = np.histogram(data, bins=bins)
for i, (c, lo, hi) in enumerate(zip(counts, edges[:-1], edges[1:])):
end = "以下" if i == len(counts) - 1 else "未満"
print(f"{lo:{fmt}}〜{hi:{fmt}}{end} {c:4d} {'#' * int(c / per)}")
rng = np.random.default_rng(1)
amount = rng.lognormal(mean=8, sigma=0.6, size=1000).round() # 架空の購入金額
show(amount)
print("平均", round(amount.mean()), "中央値", round(float(np.median(amount))))
355〜 3150未満 559 #######################################################
3150〜 5946未満 341 ##################################
5946〜 8742未満 67 ######
8742〜 11537未満 25 ##
11537〜 14332未満 4
14332〜 17128未満 2
17128〜 19924未満 1
19924〜 22719未満 0
22719〜 25514未満 0
25514〜 28310以下 1
平均 3442 中央値 2923
購入金額、年収、Webページの滞在時間などは、小さい値に多くが集まり、一部の大きな値が右に長く伸びる形になりがちです。この形では、少数の大きな値に引っ張られて平均値(3,442)が中央値(2,923)より大きくなります。「平均的な客」を語るなら中央値も並べて示す、という判断ができるのはヒストグラムで形を見ているからです。
3. 山が2つ:別の集団が混ざっている
mix = np.concatenate([rng.normal(155, 5, 300), rng.normal(175, 5, 300)])
show(mix, bins=range(140, 196, 5), per=5)
print("平均", mix.mean().round(1), "中央値", np.median(mix).round(1))
140〜 145未満 6 #
145〜 150未満 45 #########
150〜 155未満 98 ###################
155〜 160未満 109 #####################
160〜 165未満 41 ########
165〜 170未満 57 ###########
170〜 175未満 98 ###################
175〜 180未満 90 ##################
180〜 185未満 45 #########
185〜 190未満 10 ##
190〜 195以下 1
平均 165.0 中央値 165.2
平均が155と175の2つの集団を混ぜた架空のデータです。平均値は165.0ですが、その周辺(160〜170未満)はむしろ谷になっていて、平均値の近くの人は、両側の山より少ないという状態です。山が2つあるときは、性別や年齢層、店舗、機械の種類など、データを分けるべき要因が隠れていないかを疑います。分けてから集計し直すと、それぞれの集団の傾向がはっきりします。
4. 離れた所にぽつんと棒がある:外れ値・入力ミス
temp = np.append(rng.normal(36.5, 0.3, 300).round(1), [365.0, 3.6]) # 架空の体温
show(temp, fmt="6.1f")
3.6〜 39.7未満 301 ##############################
39.7〜 75.9未満 0
75.9〜 112.0未満 0
112.0〜 148.2未満 0
148.2〜 184.3未満 0
184.3〜 220.4未満 0
220.4〜 256.6未満 0
256.6〜 292.7未満 0
292.7〜 328.9未満 0
328.9〜 365.0以下 1
体温のデータに「36.5」を「365.0」と打ち間違えた値が1件混ざっているだけで、区間の幅が36℃以上に広がり、ほとんどのデータが最初の1本に押し込まれました。このように「端にぽつんと棒がある」「1本だけ極端に高い」形は、外れ値や入力ミスのサインです。3.6℃も同じ1本目に入って見えなくなっている点にも注意してください。外れ値を見つけたら、最小値・最大値を確認し、元の記録を見て直すか除くかを決めます。
形ごとのまとめ
| 形 | わかること | 次にすること |
|---|---|---|
| 山が1つ・左右対称 | 中心とばらつき。平均値で代表させやすい | 平均値と標準偏差で要約してよい |
| 右に裾が長い | 一部の大きな値が平均を押し上げている | 中央値も示す。分析では対数変換を検討 |
| 左に裾が長い | 満点近くに集まるなど上限がある | 上限・下限の制約を確認する |
| 山が2つ以上 | 性質の違う集団が混ざっている | 分ける要因を探して層別に見る |
| 離れた棒・1本だけ突出 | 外れ値、入力ミス、特定の値への偏り(0や未入力の代わりの値など) | 元データを確認し、修正・除外・別扱いを決める |
| ほぼ平ら | どの値も同じくらい出る(くじ、IDの末尾など) | そもそも分析に意味がある変数か確認する |
機械学習・データ分析での使い方
探索的データ分析(EDA)の最初に全列を見る
データを受け取ったら、モデルを作る前に数値の列を1つずつヒストグラムにして、上の表のどの形かを確認します。pandas なら df.hist() で全列をまとめて描けます。ここで入力ミスや、未入力を 0 や 999 で埋めた値(1本だけ突出した棒として見えます)を見つけておくと、後でモデルの精度がおかしいときに原因を探し回らずに済みます。
偏った変数を変換するか決める
右に裾が長い変数は、対数をとると左右対称に近づくことがよくあります。先ほどの購入金額を log10 で変換すると、次のようになりました。
show(np.log10(amount), fmt="5.2f")
2.55〜 2.74未満 2
2.74〜 2.93未満 22 ##
2.93〜 3.12未満 70 #######
3.12〜 3.31未満 185 ##################
3.31〜 3.50未満 285 ############################
3.50〜 3.69未満 248 ########################
3.69〜 3.88未満 136 #############
3.88〜 4.07未満 45 ####
4.07〜 4.26未満 5
4.26〜 4.45以下 2
線形回帰のように大きな値に引きずられやすいモデルでは、こうした変換で結果が安定することがあります。決定木系のモデルは値の大小の順番だけを使うので、単調な変換の影響は受けにくいという違いもあります。変換するかどうかは、ヒストグラムで変換前後の形を見比べて決めます。
クラスごとに重ねて、特徴量の効き目を見る
分類問題では、同じ特徴量をクラス(購入した/しなかった、など)ごとに分けてヒストグラムを重ねると、その特徴量でクラスを見分けられそうかの見当がつきます。2つの山がはっきりずれていれば手がかりになりそうで、ほとんど重なっていれば、その特徴量だけでは見分けにくいと考えられます。
データの分布を読む力は機械学習の土台で、テックジムのAIエンジニア養成コース(16章で機械学習とディープラーニングを学ぶコース)では、第0章「データ分析入門とデータ可視化」で可視化を、第6章「AIのための統計学入門」で正規分布などの確率分布を扱います。
階級(ビン)の数の決め方
ヒストグラムは、区間の数によって見え方が大きく変わります。少なすぎると山が2つあっても1つにつぶれ、多すぎると棒がでこぼこになって形が読めません。なるほど統計学園は、通常は5〜10くらいの階級数で描いてみて、散らばりがよく見えなければ階級数を変えてみる方法を紹介し、スタージェスの公式も挙げています。
NumPy の np.histogram_bin_edges には区間の数を自動で決めるルールがあり、公式リファレンスでは次のように説明されています(numpy.histogram_bin_edges)。
| ルール | 公式リファレンスの説明(要約) |
|---|---|
"sturges" |
データの個数だけを使う。正規分布のデータでのみ最適で、大きく偏ったデータでは区間が少なすぎる傾向 |
"fd"(Freedman-Diaconis) |
ばらつきと個数を使う。外れ値に強い |
"auto" |
sturges と fd のうち区間の幅が小さいほうを使う |
"sqrt" |
個数の平方根。Excel などで使われる |
先ほどの購入金額(1,000件、右に裾が長い)で区間の数を比べると、次のようになりました。
for rule in ["sturges", "fd", "auto"]:
e = np.histogram_bin_edges(amount, bins=rule)
print(rule, len(e) - 1)
sturges 11
fd 59
auto 59
同じデータでも、ルールによって区間の数が5倍以上違います。どれが正解というより、いくつか試して形が安定して読める数を選ぶのが実用的です。
Python(matplotlib)でヒストグラムを描く
グラフとして描くには matplotlib の hist() を使います。bins を省略したときの既定は10区間で、bins="auto" のように NumPy と同じルール名も渡せます(matplotlib.pyplot.hist)。
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(1)
amount = rng.lognormal(mean=8, sigma=0.6, size=1000).round()
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
n, bins, patches = axes[0].hist(amount, bins="auto")
axes[0].set_title("amount")
axes[1].hist(np.log10(amount), bins="auto")
axes[1].set_title("log10(amount)")
fig.savefig("hist.png")
print(len(n), "本の棒を描画")
59 本の棒を描画
実行すると、変換前と変換後のヒストグラムを左右に並べた hist.png が保存されます。hist() は各区間の度数(n)と区間の境界(bins)も返すので、グラフと同時に数値でも確認できます。matplotlib の基本は「matplotlibとは?Pythonでグラフを作成する方法」、区間を自分で決めて集計する方法は「pandasのcut()とqcut()の違い」を参照してください。
読み間違えやすいポイント
- 区間の数で形が変わる:1つの設定だけで「山は1つ」と決めつけず、区間の数を変えて確認します。
- 縦軸の意味を確かめる:件数(度数)か、割合や密度か。matplotlib で
density=Trueを指定すると、面積の合計が1になるように縦軸が変わります。 - 件数が少ないと形が偶然に左右される:数十件程度では、たまたまの凸凹が山に見えることがあります。
- ヒストグラムは1つの変数しか見られない:2つの変数の関係は散布図、グループ間の比較は箱ひげ図と組み合わせます。
よくある質問
Q. ヒストグラムは何に使うグラフですか?
数値データの分布の形を見るためのグラフです。データがどのあたりに集まっているか、ばらつきの大きさ、偏り、山の数、外れ値の有無を一度に確認できます。
Q. ヒストグラムからわかることは何ですか?
中心の位置、ばらつきの大きさ、左右どちらに裾が長いか、山が1つか2つ以上か、離れた所に外れ値があるかがわかります。山が2つあれば別の集団が混ざっている可能性があり、右に裾が長ければ平均値が中央値より大きくなります。
Q. ヒストグラムと棒グラフの違いは何ですか?
ヒストグラムの横軸は連続した数値の区間で、並び順を入れ替えられず、1つの変数の分布を表します。棒グラフの横軸は支店名などのカテゴリで、カテゴリごとの量を比べるために使います。
Q. ヒストグラムの階級(ビン)の数はどう決めればいいですか?
5〜10くらいの区間で描いてみて、形が読みにくければ数を変えるのが基本です。NumPy や matplotlib では bins=”auto” や “sturges”、”fd” のように自動で決めるルールも使えますが、ルールによって区間の数が大きく変わるので、いくつか試して確認します。
機械学習の全体像は機械学習とは?仕組み・種類・できることを簡単に解説|Pythonで動く例つきにまとめています。


