【応用編】seabornで深い統計可視化

ソニック

ペアプロット・回帰分析・カテゴリ分析で「データから物語を引き出す」

「データはあるけど、どう分析すればいいか分からない」「上司にデータ分析を頼まれたが、何から始めるべきか」

そんな悩み、データに触れ始めた方なら必ず通る道です。

前回の「seabornで統計グラフを作る」では、基本的な統計グラフの描き方を解説しました。今回はその応用編――**データから「物語」を引き出すための深い統計可視化**を扱います。

データ分析は「綺麗なグラフを描くこと」ではなく、「データに語らせること」。seabornの応用テクニックを身につければ、あなたもデータの物語を読める人になれます。

私自身、データサイエンス業務で日々seabornを使い、顧客の経営判断を支える分析レポートを作成しています。この記事では、現場で本当に使えるテクニックだけを厳選して紹介します。

目次

こんな方におすすめ

  • seabornの基本は分かったが、応用テクニックを学びたい方
  • データから「気づき」を引き出す可視化を実現したい方
  • 将来データ分析を仕事にしたい、副業に活かしたい方

第1章|なぜ「深い統計可視化」が必要か

「綺麗なグラフ」と「物語を語るグラフ」の違い

世の中には2種類のグラフがあります。

  • **綺麗なグラフ**:数字を見やすく並べただけのグラフ
  • **物語を語るグラフ**:データの構造・傾向・異常を「気づかせる」グラフ

ビジネスで価値があるのは、後者です。

Before/After|深い可視化の威力

分析ニーズBefore(基本グラフ)After(応用テクニック)
変数間の関係1つずつ散布図ペアプロットで一気に
回帰の妥当性確認回帰直線だけ表示残差プロットで検証
カテゴリ別の分布箱ひげ図のみviolin+swarmplot
複数指標の比較グラフを並べるFacetGridで自動配置

データ分析の世界への扉

深い統計可視化を身につけることは、データ分析の世界への扉を開くことでもあります。

  • 「データを見る目」が養われる
  • 社内で「数字に強い人」と認識される
  • データ分析業務への転職・副業への道が開く

当ブログでは、今後「データ分析」カテゴリの新設も検討中。重回帰分析・SHAP・LightGBM等の解説も準備しています。

第2章|環境準備+前回記事の復習

この記事は、前回の「seabornで統計グラフを作る完全ガイド」の続編です。基本がまだの方は、先に前回記事をご覧ください。

環境準備

# seabornと関連ライブラリをインストール
uv add seaborn pandas numpy

共通設定(毎回コピペでOK)

import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import pandas as pd
import numpy as np

# 日本語フォント設定(Windows)
matplotlib.rcParams["font.family"] = "Meiryo"
# Macの場合
# matplotlib.rcParams["font.family"] = "Hiragino Sans"

# マイペースブログのカラーパレット
mypace_blue = ["#003d99", "#0066ff", "#4d94ff", "#80b3ff", "#b3d1ff"]
sns.set_theme(style="whitegrid", palette=mypace_blue)

以下、各章のコードはこの共通設定を済ませた前提で進めます。

第3章|ペアプロット|全変数を一気に可視化

ペアプロットとは

**pairplot関数**を使うと、複数の変数の関係を**一気にマトリクス表示**できます。データ分析の初期探索(EDA:探索的データ分析)で頻出のテクニックです。

基本のペアプロット

uv add setuptools
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import pandas as pd
import numpy as np
import japanize_matplotlib

# サンプルデータ:店舗の指標
np.random.seed(42)
n = 100
df = pd.DataFrame({
    "売上": np.random.normal(100, 20, n),
    "広告費": np.random.normal(50, 15, n),
    "来店数": np.random.normal(80, 25, n),
    "気温": np.random.normal(20, 5, n),
})

# ペアプロット:全変数の組み合わせを散布図でマトリクス表示
# 対角線上はヒストグラム、それ以外は散布図
sns.pairplot(df)
plt.show()

**1行のコード**で、4×4=16個のグラフが一気に生成されます。データの全体像が一目で把握できる、データ分析業務の最強テクニックです。

カテゴリ別に色分けしたペアプロット

カテゴリ列を追加して、グループごとに色分けすると更に深い分析になります。

# 店舗カテゴリを追加
df["店舗"] = np.random.choice(["東京", "大阪", "名古屋"], n)

# hue引数で色分け
# diag_kind="kde" で対角線を密度推定に
sns.pairplot(df, hue="店舗", diag_kind="kde")
plt.show()

実務での使い方

  • **初めて見るデータの探索**:データの全体構造を一気に把握
  • **外れ値の発見**:散布図群から異常値を視覚的に検出
  • **特徴量選択**:機械学習で使う変数を選ぶ判断材料
  • **プレゼン資料の起点**:ここから個別の深掘りグラフを作る

第4章|回帰分析の可視化|lmplot・residplot

lmplot|複数のサブグループで回帰直線を比較

**lmplot**は、回帰直線をカテゴリ別に同時に描けます。「店舗別の広告費効果の違い」などを一発で可視化。

# サンプルデータ:3店舗の広告費と売上
np.random.seed(42)
data = []
for store in ["東京店", "大阪店", "名古屋店"]:
    # 店舗ごとに広告効果が異なる設定
    slope = {"東京店": 5, "大阪店": 4, "名古屋店": 3}[store]
    for _ in range(30):
        ad = np.random.uniform(10, 100)
        sales = ad * slope + np.random.normal(0, 30)
        data.append({"店舗": store, "広告費": ad, "売上": sales})

df = pd.DataFrame(data)

# lmplot:カテゴリ別に回帰直線を描く
# col引数で「列ごとに別グラフ」も可能
sns.lmplot(data=df, x="広告費", y="売上", hue="店舗", height=5)
plt.show()

店舗ごとの広告効果の違い(傾き)が一目で分かります。**経営判断に直結する分析**です。

residplot|残差プロットで回帰の妥当性を確認

**residplot**は、回帰モデルの「残差(予測のズレ)」を可視化します。データ分析業務で必須のチェックです。

# 残差プロット
# 残差にパターンがあれば、線形回帰では不十分のサイン
sns.residplot(data=df, x="広告費", y="売上")
plt.title("残差プロット(広告費 vs 売上)")
plt.show()

残差プロットの読み方

  1. **点がランダムに散らばっている** → 線形回帰でOK
  2. **曲線パターンが見える** → 非線形モデル(多項式回帰など)を検討
  3. **ばらつきが偏っている** → 異分散の問題(変数変換が必要)

残差プロットは、データ分析の現場で「モデルが正しいか」を見るための定番チェック。プロのデータアナリストは必ず確認します。

第5章|カテゴリ分析|violinplot・swarmplot

violinplot|分布の形まで見える

**箱ひげ図の進化版**。データの「分布の形状」まで可視化できます。

# サンプルデータ:3店舗×50日分の売上
np.random.seed(42)
data = []
for store in ["東京店", "大阪店", "名古屋店"]:
    base = {"東京店": 100, "大阪店": 90, "名古屋店": 80}[store]
    for _ in range(50):
        data.append({
            "店舗": store,
            "売上": base + np.random.normal(0, 20)
        })

df = pd.DataFrame(data)

# violinplot:分布の形まで表示
sns.violinplot(data=df, x="店舗", y="売上")
plt.title("店舗別売上の分布形状")
plt.show()

箱ひげ図では分からない**分布の偏り(左右非対称・複数ピーク)**まで一目で見えます。

swarmplot|個々のデータ点を全て表示

**swarmplot**は、データ点を重ならないように配置します。「実際のデータ点」を全て見せたい時に最適。

# swarmplot:データ点を全て表示
sns.swarmplot(data=df, x="店舗", y="売上", size=4)
plt.title("店舗別売上(個別データ点)")
plt.show()

violinplot+swarmplotの組み合わせ(最強)

両者を重ねると、「分布の傾向+個別データ」の両方が一目で見える究極の可視化に。

# 2つを重ねる
fig, ax = plt.subplots(figsize=(10, 6))

# 透明度を下げてviolin
sns.violinplot(data=df, x="店舗", y="売上", inner=None, alpha=0.5, ax=ax)

# データ点を重ねる
sns.swarmplot(data=df, x="店舗", y="売上", size=3, color="black", ax=ax)

plt.title("店舗別売上|分布+個別データ")
plt.show()

第6章|時系列データの可視化|lineplot応用

信頼区間付きlineplot

**lineplot**は、複数のサンプルがあれば自動で信頼区間(薄い帯)を描画します。これがseabornの強みです。

# サンプルデータ:12ヶ月×3店舗×複数日の売上
np.random.seed(42)
data = []
for month in range(1, 13):
    for store in ["東京店", "大阪店", "名古屋店"]:
        # 各月に複数のデータポイントを生成
        for _ in range(10):
            base = {"東京店": 100, "大阪店": 90, "名古屋店": 80}[store]
            seasonal = 20 * np.sin(month * np.pi / 6)  # 季節性
            data.append({
                "月": month,
                "店舗": store,
                "売上": base + seasonal + np.random.normal(0, 10)
            })

df = pd.DataFrame(data)

# lineplot:自動で信頼区間が描画される
sns.lineplot(data=df, x="月", y="売上", hue="店舗", marker="o")
plt.title("月別売上推移(信頼区間付き)")
plt.show()

**薄い帯**が信頼区間です。「この帯が狭い=予測の確実性が高い」と読み取れます。

FacetGrid|カテゴリ別に複数グラフを自動生成

**FacetGrid**は、カテゴリ別にグラフを自動でレイアウトしてくれます。

# 店舗ごとに別グラフ
g = sns.FacetGrid(df, col="店舗", height=4, aspect=1.2)
g.map_dataframe(sns.lineplot, x="月", y="売上", marker="o")
g.set_titles("{col_name}")
g.fig.suptitle("店舗別売上推移", y=1.05)
plt.show()

**サブプロットを自分で組まなくても**、カテゴリ別に綺麗に並んだグラフが完成します。

第7章|実務スクリプト|売上データの統計探索

シナリオ

「3店舗の売上データを受け取った。これから経営層に分析報告したい」――そんな時の**統計探索一括スクリプト**です。

完成スクリプト

import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import pandas as pd
import numpy as np
from datetime import datetime

# === 共通設定 ===
matplotlib.rcParams["font.family"] = "Meiryo"
mypace_blue = ["#003d99", "#0066ff", "#4d94ff", "#80b3ff", "#b3d1ff"]
sns.set_theme(style="whitegrid", palette=mypace_blue)

# === サンプルデータ生成 ===
# 実務では pd.read_excel() などで読み込む
np.random.seed(42)
n = 300

df = pd.DataFrame({
    "日付": pd.date_range(start="2026-01-01", periods=n, freq="D"),
    "店舗": np.random.choice(["東京店", "大阪店", "名古屋店"], n),
    "商品": np.random.choice(["商品A", "商品B", "商品C"], n),
    "広告費": np.random.uniform(10, 100, n),
    "売上": np.random.normal(50000, 15000, n).astype(int),
    "来店数": np.random.normal(80, 20, n).astype(int),
})

# === ステップ1:全変数の関係を可視化 ===
# ペアプロットで全体像を把握
print("ステップ1:ペアプロット作成中...")
sns.pairplot(df[["広告費", "売上", "来店数"]], height=2.5)
plt.suptitle("変数間の関係性(ペアプロット)", y=1.02)
plt.savefig(f"01_ペアプロット_{datetime.now().strftime('%Y%m%d')}.png", dpi=150, bbox_inches="tight")
plt.show()

# === ステップ2:店舗別の広告費効果を回帰分析 ===
print("ステップ2:店舗別回帰分析中...")
sns.lmplot(data=df, x="広告費", y="売上", hue="店舗", height=5)
plt.title("店舗別|広告費の売上への効果")
plt.savefig(f"02_店舗別回帰_{datetime.now().strftime('%Y%m%d')}.png", dpi=150, bbox_inches="tight")
plt.show()

# === ステップ3:店舗別売上の分布を比較 ===
print("ステップ3:分布比較中...")
fig, ax = plt.subplots(figsize=(10, 6))
sns.violinplot(data=df, x="店舗", y="売上", inner=None, alpha=0.5, ax=ax)
sns.swarmplot(data=df, x="店舗", y="売上", size=2, color="black", ax=ax)
plt.title("店舗別売上分布")
plt.savefig(f"03_店舗別分布_{datetime.now().strftime('%Y%m%d')}.png", dpi=150, bbox_inches="tight")
plt.show()

# === ステップ4:相関ヒートマップ ===
print("ステップ4:相関分析中...")
corr = df[["広告費", "売上", "来店数"]].corr()
plt.figure(figsize=(8, 6))
sns.heatmap(corr, annot=True, cmap="coolwarm", vmin=-1, vmax=1, fmt=".2f")
plt.title("指標間の相関係数")
plt.savefig(f"04_相関ヒートマップ_{datetime.now().strftime('%Y%m%d')}.png", dpi=150, bbox_inches="tight")
plt.show()

print("\n完了:4種類の分析グラフを保存しました")

このスクリプトでできること

  • **ステップ1**:データ全体像をペアプロットで把握
  • **ステップ2**:店舗別の回帰分析で「どの店舗が広告効果が高いか」を可視化
  • **ステップ3**:分布の比較で「ばらつきの違い」を発見
  • **ステップ4**:相関ヒートマップで「どの指標が連動しているか」を確認

**4枚の画像が高解像度で保存**され、そのまま経営報告に使える品質のレポート素材になります。

第8章|つまずき対処&まとめ+次のステップ

よくあるトラブル

トラブル1:ペアプロットが重い

対処:

変数が多すぎる、またはデータ量が多すぎる可能性があります。

# 変数を絞る
sns.pairplot(df[["売上", "広告費", "来店数"]])

# データをサンプリング
sns.pairplot(df.sample(500))

トラブル2:lmplotとregplotの違いは?

解説:

  • **regplot**:1つのグラフに1本の回帰直線
  • **lmplot**:カテゴリ別に色分け・分割表示が可能(FacetGrid内蔵)

トラブル3:violinplotの軸が見づらい

対処:

# y軸の範囲を調整
ax = sns.violinplot(data=df, x="店舗", y="売上")
ax.set_ylim(0, df["売上"].max() * 1.1)

この記事のまとめ

  • ペアプロットは「データ全体像把握」の最強テクニック
  • lmplot+residplotで回帰分析の妥当性まで確認
  • violinplot+swarmplotで分布と個別データを同時に可視化
  • FacetGridでカテゴリ別グラフを自動生成
  • 実務では「ペアプロット→深掘り」の流れが定石

FAQ

Q1. 機械学習を始める前に何をすべきですか?

本記事のような「探索的データ分析(EDA)」を必ず行いましょう。データの分布・関係性・外れ値を把握しないと、機械学習モデルの精度が出ません。データサイエンスの現場では、EDAに全体の30〜40%の時間をかけるのが普通です。

Q2. 統計の知識がなくても使えますか?

本記事で紹介した可視化テクニックは、統計の専門知識がなくても使えます。ただし、結果を「正しく読む」には基礎的な統計知識(平均・分散・相関・回帰)があると深い分析ができます。

Q3. データが少ない場合は?

30件以下のデータでは、信頼区間が広くなり統計的な意味が薄れます。最低でも50〜100件、可能であれば数百件以上のデータを集めてから分析しましょう。

Q4. 経営層に説明する時のコツは?

「グラフを見せる」より「グラフから得た示唆を伝える」のが重要です。例:「東京店は広告効果が大阪店の1.3倍。広告予算は東京店に集中させるべき」のように、行動につながる示唆を添えましょう。

Q5. もっと高度な分析を学ぶには?

次は「重回帰分析」「ロジスティック回帰」「決定木」などの機械学習に進みましょう。当ブログでも今後、データ分析カテゴリを新設して解説予定です。

次にやるべき3つの行動

  • **今すぐ**:自分の手元にある業務データに対して、ペアプロットを実行してみる
  • **今日中**:相関ヒートマップで「意外な関係性」を1つ発見する
  • **今週中**:実務スクリプトを応用して、上司や同僚に1枚の分析レポートを提出してみる

データを「見る」から「読む」へ。この一歩が、あなたのキャリアを大きく変えます。

データ分析の世界、次のステップへ

seabornの応用テクニックを身につけたあなたは、もう「ただのExcel使い」ではありません。**データから物語を引き出せる人**です。

当ブログでは、今後**データ分析カテゴリ**の新設を計画しています。具体的には:

  • 重回帰分析|複数要因の影響を定量化する
  • SHAP|AI予測の「なぜ」を説明可能にする
  • LightGBM|実務で使える機械学習モデル
  • クラスタリング|顧客セグメント分析

X(旧Twitter)でも更新情報を発信していますので、最新記事を見逃さないようぜひフォローしてください。

この記事を書いた人

ソニック|バックオフィス出身の業務効率化ブロガー。データサイエンス業務でクライアント向けの分析レポート作成にseabornを毎日活用。「データに物語らせる」可視化を信条に、リアルな実体験をもとにしたノウハウを発信中。

→ 詳しいプロフィールはこちら→ はじめての方へ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次