フリーキーズ | 独学プログラミング

相関分析入門!相関係数でデータの関連性を測る方法を初心者にもわかりやすく解説

リンドくん

リンドくん

先生、「相関分析」って何ですか?データサイエンスを勉強してるとよく出てくるんですけど...

たなべ

たなべ

相関分析は2つのデータの間にどれくらい関係があるかを数値で表す手法なんだよ。
たとえば、RPGゲームで「レベルが上がると攻撃力も上がる」みたいな関係性を数字で証明できるんだ。

リンドくん

リンドくん

へぇ!ゲームで例えると分かりやすいですね。でも、それってどうやって測るんですか?

たなべ

たなべ

それを測るのが相関係数なんだ。今日はその仕組みをゲーム感覚で楽しく学んでいこうか!

データ分析を始めると、必ず出会うのが「相関分析」という手法です。
2つのデータの間にどんな関係があるのかを明らかにすることは、ビジネスの意思決定や機械学習のモデル構築において極めて重要な作業となります。

たとえば、「勉強時間とテストの点数には関係があるのか?」「気温とアイスクリームの売上には関連性があるのか?」といった疑問に、数値的な根拠を持って答えることができるのです。

この記事では、相関分析の基礎から実践的な活用法までを、プログラミング初心者の方でも理解できるよう丁寧に解説していきます。

オンラインコミュニティ運営しています

HackATAは、IT技術を習得する人のために広く開かれたオンラインコミュニティです。 現在、無料コミュニティとして開放していますので、ご気軽に参加してください。

✓ 再立ち上げ

✓ コミュニティの方向性について意見募集中

HackATA公式Webサイト

相関分析とは何か?その基本を理解しよう

リンドくん

リンドくん

そもそも相関って、どういう意味なんですか?

たなべ

たなべ

相関とは「2つのデータが一緒に変化する傾向」のことなんだ。
一方が増えるともう一方も増える、あるいは一方が増えるともう一方は減る、といった関係性のことだよ。

相関の3つのパターン

データ間の関係には、主に以下の3つのパターンがあります。

  • 正の相関 → 一方が増えると、もう一方も増える傾向
  • 負の相関 → 一方が増えると、もう一方は減る傾向
  • 無相関 → 2つのデータに明確な関係性が見られない

たとえば、RPGゲームで考えてみましょう。

# RPGキャラクターのデータ例
character_data = {
    'レベル': [1, 5, 10, 15, 20, 25, 30],
    '攻撃力': [10, 25, 48, 72, 95, 118, 142],
    '防御力': [8, 20, 40, 58, 78, 95, 115],
    '回避率': [15, 14, 12, 11, 9, 8, 7]  # レベルが上がると下がる例
}

この例では、以下のような関係が考えられます。

  • レベルと攻撃力 → 正の相関(レベルが上がると攻撃力も上がる)
  • レベルと防御力 → 正の相関(レベルが上がると防御力も上がる)
  • レベルと回避率 → 負の相関(レベルが上がると回避率は下がる)

なぜ相関分析が重要なのか

相関分析を行うことで、以下のようなメリットが得られます。

  • データの特徴を素早く把握できる → 膨大なデータから重要な関係性を見つけ出せます
  • 予測モデルの構築に役立つ → 機械学習でどの変数を使うべきかの判断材料になります
  • ビジネスの意思決定を支援する → 売上に影響する要因を特定できます
  • 因果関係の仮説を立てられる → ただし、相関があっても因果関係があるとは限りません

特に最後の点は重要です。
「アイスクリームの売上と水難事故の件数には正の相関がある」というデータがあっても、アイスを食べると溺れやすくなるわけではありません。どちらも「気温が高い」という共通の要因によって引き起こされているのです。

このように、相関分析は便利なツールですが、結果の解釈には注意が必要なのです。

相関係数の種類と使い分け

リンドくん

リンドくん

相関係数にも種類があるんですか?

たなべ

たなべ

そうなんだ!代表的なものがピアソンスピアマンケンダルの3つの相関係数だよ。
データの特徴に応じて使い分けることが大切なんだ。

ピアソンの積率相関係数

最も一般的に使われる相関係数で、-1から1の範囲の値を取ります。

  • 1に近い → 強い正の相関
  • 0に近い → 相関なし
  • -1に近い → 強い負の相関

ピアソンの相関係数は、データが直線的な関係にある場合に適しています。
ただし、外れ値の影響を受けやすいという特徴があります。

import numpy as np
from scipy import stats

# レベルと攻撃力のデータ
level = np.array([1, 5, 10, 15, 20, 25, 30])
attack = np.array([10, 25, 48, 72, 95, 118, 142])

# ピアソンの相関係数を計算
correlation, p_value = stats.pearsonr(level, attack)
print(f"ピアソンの相関係数: {correlation:.3f}")
print(f"p値: {p_value:.5f}")

スピアマンの順位相関係数

データの順位に基づいて計算される相関係数です。
ピアソンとは異なり、以下のような特徴があります。

  • 外れ値の影響を受けにくい
  • 非線形の単調な関係も検出できる
  • データが順序尺度の場合に適している
# スピアマンの順位相関係数を計算
correlation_spearman, p_value_spearman = stats.spearmanr(level, attack)
print(f"スピアマンの相関係数: {correlation_spearman:.3f}")
print(f"p値: {p_value_spearman:.5f}")

ケンダルの順位相関係数

スピアマンと同様に順位ベースの相関係数ですが、小さいサンプルサイズでより信頼性が高いという特徴があります。

# ケンダルの順位相関係数を計算
correlation_kendall, p_value_kendall = stats.kendalltau(level, attack)
print(f"ケンダルの相関係数: {correlation_kendall:.3f}")
print(f"p値: {p_value_kendall:.5f}")

どの相関係数を使うべきか

状況に応じた使い分けの目安は以下の通りです。

  • ピアソン → データが正規分布に従い、直線的な関係がある場合
  • スピアマン → 外れ値が含まれる、または非線形だが単調な関係がある場合
  • ケンダル → サンプルサイズが小さい場合、または順序データの場合

実際のデータ分析では、複数の相関係数を計算して比較することで、データの特性をより深く理解できます。

Pythonで実践!相関分析の基本コード

リンドくん

リンドくん

実際にPythonで相関分析をやってみたいです!

たなべ

たなべ

いいね!じゃあ、RPGキャラクターのステータスデータを使って実践的なコードを書いてみよう。

必要なライブラリのインポート

まずは、相関分析に必要なライブラリをインポートします。

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

# 日本語フォントの設定(文字化け防止)
plt.rcParams['font.sans-serif'] = ['DejaVu Sans']

サンプルデータの作成

RPGキャラクターのステータスデータを作成します。

# RPGキャラクターのステータスデータ
np.random.seed(42)  # 再現性のため
n_characters = 50

data = {
    'レベル': np.random.randint(1, 101, n_characters),
    '攻撃力': [],
    '防御力': [],
    '素早さ': [],
    'HP': []
}

# レベルに応じた各ステータスを生成(相関を持たせる)
for level in data['レベル']:
    # 攻撃力: レベルと強い正の相関
    data['攻撃力'].append(level * 2 + np.random.randint(-10, 10))
    # 防御力: レベルと中程度の正の相関
    data['防御力'].append(level * 1.5 + np.random.randint(-15, 15))
    # 素早さ: レベルと弱い正の相関
    data['素早さ'].append(level * 0.5 + np.random.randint(-20, 20))
    # HP: レベルと強い正の相関
    data['HP'].append(level * 10 + np.random.randint(-50, 50))

df = pd.DataFrame(data)
print("データの最初の5行:")
print(df.head())

相関係数の計算

pandasを使えば、簡単に相関係数を計算できます。

# 相関係数行列を計算
correlation_matrix = df.corr()

print("\n相関係数行列:")
print(correlation_matrix)

# 特定の2つの変数間の相関係数を取得
level_attack_corr = correlation_matrix.loc['レベル', '攻撃力']
print(f"\nレベルと攻撃力の相関係数: {level_attack_corr:.3f}")

散布図による可視化

相関関係を視覚的に確認するには、散布図が非常に有効です。

# 散布図を作成
plt.figure(figsize=(12, 4))

# レベルと攻撃力
plt.subplot(1, 3, 1)
plt.scatter(df['レベル'], df['攻撃力'], alpha=0.6)
plt.xlabel('Level')
plt.ylabel('Attack')
plt.title(f'Level vs Attack (r={level_attack_corr:.3f})')

# レベルと防御力
plt.subplot(1, 3, 2)
level_defense_corr = correlation_matrix.loc['レベル', '防御力']
plt.scatter(df['レベル'], df['防御力'], alpha=0.6, color='green')
plt.xlabel('Level')
plt.ylabel('Defense')
plt.title(f'Level vs Defense (r={level_defense_corr:.3f})')

# レベルと素早さ
plt.subplot(1, 3, 3)
level_speed_corr = correlation_matrix.loc['レベル', '素早さ']
plt.scatter(df['レベル'], df['素早さ'], alpha=0.6, color='orange')
plt.xlabel('Level')
plt.ylabel('Speed')
plt.title(f'Level vs Speed (r={level_speed_corr:.3f})')

plt.tight_layout()
plt.show()

ヒートマップによる相関行列の可視化

複数の変数間の相関を一度に確認するには、ヒートマップが便利です。

# 相関行列のヒートマップを作成
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', 
            center=0, square=True, linewidths=1)
plt.title('Correlation Matrix Heatmap')
plt.show()

このヒートマップでは、色が濃いほど相関が強いことを示しています。
赤系の色は正の相関、青系の色は負の相関を表します。

注意すべきポイント

相関分析を活用する際は、以下の点に注意が必要です。

  • 相関≠因果関係 → 相関があっても、一方が他方の原因とは限りません
  • 第三の変数の存在 → 共通の原因が隠れている可能性があります
  • 外れ値の影響 → 極端な値が相関係数を歪める可能性があります
  • 非線形関係の見落とし → ピアソンの相関係数では検出できない関係もあります

実際のデータ分析では、相関分析だけでなく散布図による視覚的確認も必ず行うことをおすすめします。

よくある間違いと解決法

リンドくん

リンドくん

相関分析でよくある間違いって、どんなものがあるんですか?

たなべ

たなべ

初心者がよく陥る落とし穴がいくつかあるんだ。
事前に知っておけば、避けられるものばかりだよ!

間違い① 相関と因果を混同する

問題点: 相関があるからといって、一方が他方の原因だと結論づけてしまう

# アイスクリームの売上と水難事故の件数に相関があったとしても...
data_example = {
    'アイス売上': [100, 150, 200, 250, 300],
    '水難事故': [5, 8, 12, 15, 18]
}
# どちらも「気温」という第三の変数の影響を受けている

解決法

  • 散布図を確認し、データの分布を視覚的に理解する
  • 因果関係を主張する前に、実験や時系列分析などの追加検証を行う
  • ドメイン知識を活用して、論理的な因果関係を検討する

間違い② 外れ値を無視する

問題点: 極端な値が相関係数を大きく歪めてしまう

# 外れ値の影響を確認
data_with_outlier = {
    'x': [1, 2, 3, 4, 5, 100],  # 100が外れ値
    'y': [2, 4, 6, 8, 10, 12]
}

df_outlier = pd.DataFrame(data_with_outlier)

# 外れ値を含む場合
corr_with = df_outlier.corr().iloc[0, 1]
print(f"外れ値を含む相関係数: {corr_with:.3f}")

# 外れ値を除いた場合
df_clean = df_outlier[df_outlier['x'] < 50]
corr_without = df_clean.corr().iloc[0, 1]
print(f"外れ値を除いた相関係数: {corr_without:.3f}")

解決法

  • 箱ひげ図などで外れ値を検出する
  • スピアマンの相関係数など、頑健な手法を使う
  • 外れ値を除外する場合は、その理由を明確にする

間違い③ サンプルサイズを考慮しない

問題点: 少ないデータで計算した相関係数を過信してしまう

# サンプルサイズによる信頼性の違い
small_sample = np.random.rand(5, 2)
large_sample = np.random.rand(100, 2)

small_corr = np.corrcoef(small_sample[:, 0], small_sample[:, 1])[0, 1]
large_corr = np.corrcoef(large_sample[:, 0], large_sample[:, 1])[0, 1]

print(f"小サンプル(n=5)の相関係数: {small_corr:.3f}")
print(f"大サンプル(n=100)の相関係数: {large_corr:.3f}")

解決法

  • 十分なサンプルサイズ(一般的にn≥30)を確保する
  • p値を確認して統計的有意性を評価する
  • 信頼区間を計算して結果の不確実性を把握する

間違い④ 非線形関係を見落とす

問題点: ピアソンの相関係数では、曲線的な関係を検出できない

# 二次関数の関係(非線形)
x = np.linspace(-5, 5, 100)
y = x**2 + np.random.normal(0, 2, 100)

# ピアソンの相関係数は低く出る
linear_corr = np.corrcoef(x, y)[0, 1]
print(f"二次関数データのピアソン相関係数: {linear_corr:.3f}")

# しかし散布図を見れば明確な関係がある
plt.scatter(x, y, alpha=0.6)
plt.xlabel('x')
plt.ylabel('y = x^2')
plt.title('Non-linear Relationship')
plt.show()

解決法

  • 必ず散布図を確認する
  • スピアマンやケンダルの相関係数も計算する
  • 必要に応じて変数変換(対数変換など)を検討する

これらの間違いを避けることで、より正確で信頼性の高い相関分析が可能になります。

まとめ

リンドくん

リンドくん

相関分析の基本がよく分かりました!早速自分のデータで試してみたいです。

たなべ

たなべ

それは素晴らしいね!
実際に手を動かして分析することが、データサイエンススキル向上の近道なんだよ。まずは身近なデータから始めてみよう!

この記事では、相関分析の基礎から実践的な活用法まで、幅広く解説してきました。
相関係数は2つのデータの関連性を数値化する強力なツールですが、適切に使うことが重要です。

改めて、重要なポイントを整理しましょう。

  • 相関係数の種類を使い分ける → ピアソン、スピアマン、ケンダルの特徴を理解する
  • 視覚化を怠らない → 散布図やヒートマップで関係性を確認する
  • 相関≠因果を忘れない → 相関があっても因果関係があるとは限らない
  • 統計的有意性を確認する → p値やサンプルサイズに注意する

データサイエンスでは、基礎的な統計手法の理解が非常に重要です。
相関分析は、その第一歩となる重要なスキルなのです。

データ分析の楽しさは、データから新しい発見をすることにあります。
相関分析というツールを手に入れた今、あなたのデータサイエンスの旅はもう始まっています。ぜひ、実践を通じてスキルを磨いていってください!

この記事をシェア

関連するコンテンツ