
テックラボの岸部です。
本日はデータ分析で身近である相関係数の実装について色々調べた内容を共有したいと思います。
はじめに
~これは架空の話です~
ある企業にデータサイエンティストがいました。
とあるアンケートデータを分析しています。
ある設問で、「はい」か「いいえ」と答えた人の違いを分析すべく、
アンケートの回答データをpandasのデータフレームで読み込み、相関係数をcorrメソッドを適用して算出しました。
相関係数の値が大きい(小さい)変数を分析レポートにまとめました。
この話を聞いて、「大丈夫か?」と思えた方は立派なデータサイエンティストでしょう(大げさ?)。
「え、別に普通じゃない?」と思った方は、一緒に相関係数について勉強しましょう。
wikipediaによれば、一般に相関係数といえば、ピアソンの積率相関係数を指すようです。
ChatGPTに「一般に相関係数といえば、どのアルゴリズムのものを指しますか?」 と聞くと、 「一般に「相関係数」といえば、ピアソンの積率相関係数(Pearson correlation coefficient)を指します。これは、2つの変数の間の線形関係の強さと方向を測定するために使用される統計的指標です。」 と答えてくれました。
ChatGPTの回答の中にもありますが、このピアソンの積率相関係数は2つの変数間の線形関係の強さを表すものです。
2つの変数間に線形関係がない場合はこの相関係数は適さないということになります。
今回の架空の話の場合、「はい」か「いいえ」の回答を1と0に置き換えれば、他の変数(例えば年齢など)との相関係数は計算できますが、それはピアソンの積率相関係数の前提としている線形関係があるとは限らないので、適用には注意が必要です。
今回は、pandasで相関係数を算出するメソッドcorrのドキュメントをベースに、世界的に有名なタイタニックデータを使用して、相関係数の挙動を見ていきたいと思います。
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.corr.html
相関係数の種類
pandasのcorrメソッドのmethodパラメータで用意されている相関係数の計算方法は以下の3種類です。
| パラメータ | アルゴリズム | 用途 |
|---|---|---|
| pearson | ピアソンの積率相関係数 | 2変数間の線形関係の強さと向きを表す(デフォルト) |
| kendall | ケンドールの順位相関係数 | 2変数間の順序関係の強さを表す |
| spearman | スピアマンの順位相関係数 | 2変数間の順序関係の強さを表す |
各アルゴリズムの計算方法はさておき、おおまかな使い分けとしては、
2変数間が線形関係→pearson
2変数間が順序関係→kendallかspearman
と指定すればいいようです。
相関係数を色々計算してみる
実際にタイタニックデータを使って相関係数を計算してみましょう。 タイタニックデータにはカテゴリ変数も含まれており、本来は慎重に扱う必要がありますが、実験のため敢えて変数の尺度は気にしないで相関係数を計算してみたいと思います。
タイタニックデータはpandasのgithubのデータを利用します。
まずはpandasのデータフレームにロードします。
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/pandas-dev/pandas/refs/heads/main/doc/data/titanic.csv")
データの中身を見てみましょう。

タイタニック事故で生き残ったか否か(Survived)を分類する問題が有名です。 では、早速、ピアソンの積率相関係数を算出しましょう。
df.corr(method='pearson') もしくは df.corr()
出力結果は以下です。

Survivedと相関が強い変数は以下の2つです。
Pclass -0.338481
Fare 0.25307
Pclassは、乗船チケットのクラス(1-3)を表しており、数値が小さいほど高い部屋を利用している乗客です。 Fareは、乗車料金を表しており、この値が大きいほど高いお金を払って乗船していることを表します。 当たり前ですが、Pclassが小さいほど高いFareを払っているので、両者の相関係数が-0.549500となっているのも納得ですね。
この結果から、 Pclassが小さいほうが生き残っている(=Survivedと負の相関関係がある) Fareが大きいほうが生き残っている(=Survivedと生の相関関係がある) ということがわかります。
Survivedは名義尺度、Pclassは順序尺度、Fareは間隔尺度であり、変数間に線形関係があるのか判断に悩みますが、結果的には不都合はないようです。
では、次にケンドールの順位相関係数を算出してみましょう。
df.corr(method='kendall')

Pclass -0.323533
Fare 0.266229
最後にスピアマンの順位相関係数を算出してみます。
df.corr(method='spearman')

Pclass -0.339688
Fare 0.323736
3つの相関係数の値をまとめると以下のようになります。
| 相関関係 | ピアソン | ケンドール | スピアマン |
|---|---|---|---|
| SurvivedとPclass | -0.338481 | -0.323533 | -0.339688 |
| SurvivedとFare | 0.25307 | 0.266229 | 0.323736 |
結論
こんなことを言うと専門家に怒られてしまいそうですが、どのアルゴリズムを使っても結果は大きくは変わりませんでした。
強いて言えば、スピアマンの順位相関係数が一番よさそうかなと思います。
おまけ カテゴリカルデータの相関係数
カテゴリカルデータに対応した相関係数として、ポリコリック相関係数というものがあります。
最後にこちらの相関係数を出してみましょう。
ポリコリック相関係数はpandasには実装されていませんが、semopyというライブラリで計算できます。
pandasのcorrメソッドのmethodには、任意の関数をcallbackで指定できるようになっているので、こちらの機能を利用して
import semopy
def polychoric(var1,var2):
return semopy.polycorr.polychoric_corr(var1,var2)
df.corr(method=polychoric)
と実行すれば、その他の相関係数と同様に相関係数行列が得られます。
結果を見てみると、

Fare 0.417176
と、pandasで実装されている3つの相関係数と比較して、より強く相関を捉えられている結果になりました。
本当のまとめ
万能な相関係数というものは存在せず、また「順序尺度にピアソンの積率相関係数を用いてはならない」というようなルールは存在しないと思いますが、使用するデータに合わせて適切な相関係数を選択する行動は大事だと思いました。
今回の実験の結果だけの判断になりますが、カテゴリデータを含む場合は、ポリコリック相関係数を検討するのがいいと思いました。