K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

UpSetプロットで集合の交差を正確に比較

上級

06.7.31

UpSetプロットで集合の交差を正確に比較

最終更新 2026-03-06 読了時間 2 分
まとめ
UpSet プロットは、3 つ以上の集合がどう重なっているかを、下部の「どの集合に属するか」を黒丸で示す行列と、上部の「その組み合わせの件数」を示す棒グラフで表す図です。ベン図は 4 集合以上で面積が件数に比例しなくなりますが、UpSet は組み合わせごとに棒の高さで件数を正確に読めます。Python では upsetplot ライブラリに、各スキルの True / False を列にした DataFrame を set_index で MultiIndex にして value_counts() した Series を渡すだけで描画できます。読み終えると、200 人の中で最も多いスキルの組み合わせを棒の高さから見つけ、min_subset_size で少数パターンを隠し sort_by で並び順を切り替えて自分の集合データを整理できるようになります。

直感 #

社員 200 人が Python・SQL・機械学習・統計・可視化の 5 つのスキルをそれぞれ持つか持たないかを調べたとします。「Python と SQL は両方できるが機械学習はできない人は何人か」という問いに、5 つの円を重ねたベン図は答えられません。5 集合のベン図は 31 個の領域が入り組み、面積と人数も一致しないからです。UpSet プロットは発想を変えて、5 つのスキルを行に並べ、組み合わせを列にします。列の中で黒丸が付いた行がその組み合わせに含まれるスキルで、列の上の棒がその組み合わせの人数です。棒を高い順に並べれば「最も多いスキルセット」が左端に来ます。

Python で描く #

次のコードは、各スキルを異なる確率(Python 65%、SQL 55% など)で独立に持つ 200 人を作り、upsetplot 用の MultiIndex 形式に変換して、3 人以上いる組み合わせだけを件数順に描きます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from upsetplot import UpSet

rng = np.random.default_rng(42)
n = 200

skills = pd.DataFrame({
    "Python": rng.random(n) < 0.65,
    "SQL": rng.random(n) < 0.55,
    "機械学習": rng.random(n) < 0.35,
    "統計": rng.random(n) < 0.40,
    "可視化": rng.random(n) < 0.50,
})

# upsetplot 用の MultiIndex 形式に変換
skills_mi = skills.set_index(list(skills.columns))
counts = skills_mi.index.value_counts()

upset = UpSet(
    counts,
    subset_size="auto",
    show_counts=True,
    sort_by="cardinality",
    min_subset_size=3,
    facecolor="#2563eb",
)

fig = plt.figure(figsize=(12, 6))
upset.plot(fig=fig)
fig.suptitle("社員スキルセットの組み合わせ分析(UpSet プロット)", fontsize=13, y=1.02)

plt.show()

社員スキルセットの組み合わせを示すUpSetプロット

実行結果の読み方 #

上部の棒の高さが各組み合わせの人数で、左端が最も多いスキルセットです。各棒の下の行列で黒丸が付いた行が、その組み合わせに含まれるスキルで、黒丸が 1 つだけの列は「そのスキルしか持たない人」の数になります。左側の横棒は各スキル単独の保有者数(セットサイズ)で、Python が 65% の約 130 人で最大、機械学習が 35% の約 70 人で最小になるはずです。独立に生成したデータなので、たとえば「Python と SQL のみ」の期待人数は \(200 \times 0.65 \times 0.55 \times 0.65 \times 0.60 \times 0.50 \approx 14\) 人で、棒の高さがこの近辺に来ていれば読み方が正しいと確認できます。

使いどころと落とし穴 #

UpSet プロットは、3〜7 集合の交差パターンを件数で正確に比べたいときの図で、ベン図が 4 集合以上で面積の正確さを失うのに対し、棒の高さで件数をそのまま読めます。集合が 2 つなら普通のベン図で十分で、15 集合を超えるとパターン数が数万に膨れて意味のある読解ができないので、集合を絞ってください。5 集合で最大 32 パターンが出るため、min_subset_size で少数パターンを隠さないと図が横に伸びすぎて棒が細くなります。既定の件数順(sort_by="cardinality")が常に最適とは限らず、「1 スキルのみ → 2 スキル → 3 スキル」と構成の複雑さで眺めたいなら sort_by="degree" に切り替えます。集合の包含関係(A は B の部分集合か)だけが関心ならオイラー図、集合間の移動(昨年 A だった人が今年 B へ)が関心ならサンキーダイアグラムが適しています。