python PR

相関係数を求める方法〜サンプルコード+可視化付き〜【Pythonで統計学】

python 統計学 相関係数
記事内に商品プロモーションを含む場合があります

研究を行っていると、結構な頻度で相関係数を算出することがあります

今回は、相関係数をpythonで算出する方法を解説していきたいと思います

また、以下の記事からpythonで統計学を順序立てて学ぶことができるようにまとめているので、参考にしてみてください

python 統計学
pythonで統計学を学ぶメリット〜実際の学習手順を紹介〜近年、データサイエンティストの需要が高まってきていますが、データサイエンティスト必須能力として、「プログラミング言語」「統計学」が挙げられています。pythonで統計学を扱えれば、データサイエンティストとしての道も開けるでしょう。今回はpythonで統計学を学ぶメリットや実際にどのように学習していくべきかを解説していきたいと思います。...

この記事で学べること
Pythonで相関係数を算出する方法
相関係数の基準
相関関係の可視化

データサイエンスの分野でも統計学は非常に重要になります

データサイエンスに興味がある方は、キカガクでデータサイエンスを学ぶのがおすすめです
キカガクはデータサイエンス・AI・機械学習に特化した動画学習プラットフォームです

※無料オンライン相談や個別相談などさまざまなイベントが開催中

相関係数とは

相関係数というのは、二つの値の間に関係性があるのか?ということを調べるために用います

相関係数を知る前に、相関関係について知っておく必要があります

例えば、Aという値が高く(低く)なれば、一方Bという値も高く(低く)なる、というのを相関関係と呼びます

この時、どのくらい関係しているのか?ということを示すのが、相関係数になります

相関係数の大小の基準

相関係数にはどのくらいの強さなのか?という一定の基準が設けられています

相関係数は-1〜1に収まるようになっており、基準は以下のようになっていますが、明確な基準はないとされています

これは、分野やデータの種類によって異なるためです

相関係数の基準

相関係数が0.7(-0.7)を超えれば相関は強い、
0.2(-0.2)以下であれば、ほとんど相関はないといって良いと思います

相関係数の例

pythonで相関係数を算出する

pythonで相関係数を算出するには、numpyを使用して以下のようにコードを入力します

今回は国語と数学のテストの点数を例に挙げたいと思います

import numpy as np
import seaborn as sns
sns.set() 

japanese = np.array([5, 73, 29, 63, 68, 28, 45, 78, 70, 93,82,88,98,68,78,12,32,18,19,22,34,14])
math = np.array([11, 82, 25, 61, 66, 27, 42, 88, 71, 84,82,95,58,87,68,22,38,15,23,43,15,22])
#相関係数の算出
correlation = np.corrcoef(japanese,math)
#グラフ化
sns.jointplot(japanese, math, kind="reg")

print(correlation[0,1])

>>>出力結果

0.9049139268028888

 

相関係数

各変数の相関の散布図を作成する

相関関係を確認したい変数が複数ある場合には、一度に散布図を作成して表示することも可能です

この時に使用するのは、seabornのpairplot()になります

irisのデータで実際に試していきたいと思います

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns; sns.set()

df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv',index_col=0)

pg=sns.pairplot(df)
plt.show(pg)
iris散布図

hueを追加することで、指定した列名のカテゴリごとに色分けをしたグラフが作成されます

今回はspeciesで色分けしたいと思います

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns; sns.set()

df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv',index_col=0)

pg=sns.pairplot(df,hue='species')
plt.show(pg)
iris散布図色分け

さらに回帰曲線を追加する場合には、kind=’reg’を入力します

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns; sns.set()

df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv',index_col=0)

pg=sns.pairplot(df,hue='species', kind='reg')
plt.show(pg)
iris散布図回帰曲線付き

回帰曲線が少し見にくいので、以下のように変更します

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns; sns.set()

df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv',index_col=0)

pg=sns.pairplot(df,hue='species', kind='reg' 
                ,plot_kws={'ci': None,'marker': '+','scatter_kws': 
                           {'alpha': 0.4},'line_kws': {'linestyle': '--'}})
plt.show(pg)
iris回帰曲線

相関係数と因果関係は別物

相関関係があると、両者のデータ間に因果関係があるように捉えがちです

しかし、あくまでも相関係数は相関係数であって、因果関係とは別物です

よく例に上がるのが「身長と体重」の関係です

身長が高くなると体重も重くなる傾向にはありますが、

身長が高い人は必ずしも体重が重いわけではなく、身長が低い人は必ずしも体重が軽いわけではないですよね

また、体重が重くなると身長が高くなるわけではないですし、体重が軽くなると身長が低くなるわけでもないですよね

このように、どちらか一方がもう一方を決めるわけではないので、因果関係にあるとは言えません

仮に、身長が決まると体重も決定される、という世界があった場合には、これは因果関係と言えるでしょう

今回の例では、国語と数学の点数で相関係数を求めました

確かにこの両者には強い相関がありそうです

しかし、国語の点数が決まると数学の点数が決まるわけではないですよね?

なので、因果関係にあるとは言えません

相関係数と因果関係について学ぶには、次の書籍がおすすめです

相関係数と因果関係をごっちゃに考えてしまう方が多いので、この機会に一度学んでおくとデータサイエンティスト・データアナリティストとして、重宝される可能性が非常に高いです

相関係数と言われると、難しそうな数式を使っているイメージが多いかもしれませんが、こちらの書籍では、難しい数式を使わずに解説してくれています

pandasを使って相関係数を算出する

これまではnumpyを使って、相関係数を算出しましたが、pandasを使用して相関係数を算出することもできます

import pandas as pd

japanese =[5, 73, 29, 63, 68, 28, 45, 78, 70, 93,82,88,98,68,78,12,32,18,19,22,34,14]
math = [11, 82, 25, 61, 66, 27, 42, 88, 71, 84,82,95,58,87,68,22,38,15,23,43,15,22]

df_japanese=pd.DataFrame(japanese,columns=["japanese_score"])
df_math=pd.DataFrame(math,columns=["math_score"])

df=pd.concat([df_japanese,df_math],axis=1)

corr=df.corr()
print(corr)

>>>出力結果

                japanese_score  math_score
japanese_score        1.000000    0.904914
math_score            0.904914    1.000000

numpyで算出した結果と同様の結果になりました

Scipyを使って相関係数を算出する

Pythonで相関係数を出すには、Scipyを使っても可能

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats

# データ生成
x = np.random.rand(100)
y = 2 * x + np.random.normal(0, 0.1, 100)

# ピアソンの相関係数
corrcoef_scipy_pearson, _ = scipy.stats.pearsonr(x, y)

# スピアマンの相関係数
corrcoef_scipy_spearman, _ = scipy.stats.spearmanr(x, y)

# 可視化
plt.scatter(x, y)
plt.title(f'SciPy Pearson: {corrcoef_scipy_pearson:.2f}, Spearman: {corrcoef_scipy_spearman:.2f}')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
Scipyで相関係数の算出

Pythonで相関係数の可視化

データ分析において、数値を出すだけでは意味がありません

相手に伝わりやすいよう、可視化をする必要があります

ここからは、Pythonで相関係数を可視化する方法を4つ紹介します

  • 散布図
  • バブルチャート
  • グラフネットワーク
  • ヒートマップ

散布図

import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
import numpy as np

# 日本語フォントの指定(例: 'IPAexGothic')
plt.rcParams['font.family'] = 'IPAexGothic'

# データ生成
np.random.seed(0)
x = np.random.rand(100)
y = x * 2 + np.random.normal(0, 0.1, 100)

# 散布図
sns.scatterplot(x=x, y=y)
plt.title('散布図')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
散布図

バブルチャート

import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
import numpy as np

# 日本語フォントの指定(例: 'IPAexGothic')
plt.rcParams['font.family'] = 'IPAexGothic'

# データ生成
np.random.seed(0)
x = np.random.rand(100)
y = x * 2 + np.random.normal(0, 0.1, 100)

# サイズデータ生成(例としてxの値に応じたサイズ)
sizes = np.abs(x * 100)

# バブルチャート
sns.scatterplot(x=x, y=y, size=sizes, legend=False, sizes=(20, 200))
plt.title('バブルチャート')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
バブルチャート

グラフネットワーク

グラフネットワークはseabornで作成することはできず、networkxというライブラリが必要です

import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'IPAexGothic'

# 固定の相関行列を作成
corr_matrix = pd.DataFrame({
    'Var1': ,
    'Var2': [0.8, 1, 0.3, -0.6],
    'Var3': [-0.4, 0.3, 1, 0.9],
    'Var4': [0.5, -0.6, 0.9, 1]
}, index=['Var1', 'Var2', 'Var3', 'Var4'])

# グラフネットワークの作成
G = nx.Graph()

# 相関行列を基にエッジを追加(相関係数の絶対値が特定の閾値を超える場合)
for i in range(len(corr_matrix.columns)):
    for j in range(i+1, len(corr_matrix.columns)):
        if np.abs(corr_matrix.iloc[i, j]) > 0.3:
            G.add_edge(corr_matrix.columns[i], corr_matrix.columns[j], weight=corr_matrix.iloc[i, j])

# グラフネットワークの描画
pos = nx.circular_layout(G)  # ノードの配置
edges, weights = zip(*nx.get_edge_attributes(G, 'weight').items())

edge_colors = ['blue' if weight > 0 else 'red' for weight in weights]  # エッジの色
edge_widths = [5 * np.abs(weight) for weight in weights]  # エッジの太さ

# edges=edgesは不要なので削除する
nx.draw(G, pos, with_labels=True, node_size=3000, node_color='skyblue', 
        edge_color=edge_colors, width=edge_widths, font_size=15)



# エッジラベルの描画(位置の調整を含む)
for edge in G.edges(data=True):
    # エッジの中点を見つける
    x0, y0 = pos[edge[0]]
    x1, y1 = pos[edge]
    x_mid = (x0 + x1) / 2
    y_mid = (y0 + y1) / 2
    
    # エッジの重み(相関係数)を取得
    weight = edge['weight']
    
    # エッジの重みに応じてラベルの位置を微調整
    plt.text(x_mid, y_mid, f'{weight:.2f}', 
             horizontalalignment='center', verticalalignment='center',
             bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=0.1'))
    
plt.title('変数間の相関係数を示したグラフネットワーク')
plt.axis('off')  # 座標軸を非表示
plt.show()
グラフネットワーク

ヒートマップ

最後に算出した相関係数をヒートマップで可視化していきます

ヒートマップの可視化にはseabornのheatmap()を使用します

import pandas as pd
import seaborn as sns
sns.set()

japanese =[5, 73, 29, 63, 68, 28, 45, 78, 70, 93,82,88,98,68,78,12,32,18,19,22,34,14]
math = [11, 82, 25, 61, 66, 27, 42, 88, 71, 84,82,95,58,87,68,22,38,15,23,43,15,22]

df_japanese=pd.DataFrame(japanese,columns=["japanese_score"])
df_math=pd.DataFrame(math,columns=["math_score"])

df=pd.concat([df_japanese,df_math],axis=1)

corr=df.corr()
print(corr)

sns.heatmap(corr,vmax=1,vmin=-1,center=0)
python 相関係数 可視化

相関係数とp値を算出する

スピアマンの順位相関係数とピアソンの積率相関係数を使用すれば、相関係数とともにPythonでp値を算出することができます

スピアマンの順位相関係数・ピアソンの積率相関係数は、どちらもscipyを使用すると算出することができます

また、PandasとNumpyで算出している相関係数は、どちらもピアソンの積率相関係数です

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

スピアマンの順位相関係数はscipyを使用すれば算出可能

from scipy import stats
math    = [5, 73, 29, 63, 68, 28, 45, 78, 70, 93,82,88,98,68,78,12,32,18,19,22,34,14]
japanese = [11, 82, 25, 61, 66, 27, 42, 88, 71, 84,82,95,58,87,68,22,38,15,23,43,15,22]

correlation, pvalue = stats.spearmanr(math, japanese)
print(correlation,pvalue)

>>>出力結果

相関係数:0.8464801016852547 p値:6.854250491094454e-07

ピアソンの積率相関係数

ピアソンの相関係数はscipy.pearsonrを使用します

from scipy import stats
math    = [5, 73, 29, 63, 68, 28, 45, 78, 70, 93,82,88,98,68,78,12,32,18,19,22,34,14]
japanese = [11, 82, 25, 61, 66, 27, 42, 88, 71, 84,82,95,58,87,68,22,38,15,23,43,15,22]

correlation, pvalue = stats.pearsonr(math, japanese)
print(correlation,pvalue)

>>>出力結果

相関係数:0.9049139268028887 p値:7.328961270615418e-09

今回のスピアマンの順位相関係数とピアソンの積率相関係数とpandas・numpyで算出した相関係数を比較すると、ピアソンの積率相関係数とpandas・numpyで算出した結果が同じになるため、pandasとnumpyはピアソンの積率相関係数を算出していると考えてOKです

スピアマンの順位相関係数とピアソンの積率相関係数の使い分けは以下のようになります

相関の検定の使い方

ノンパラ・パラメトリックについては以下の記事を参考にしてください

python ノンパラ パラメトリック
【pythonで統計学】ノンパラメトリックとパラメトリック検定について統計検定を選択するときに、「ノンパラメトリック(ノンパラ)」「パラメトリック」という文字を見るかと思います。初めて統計に触れる方は、これが何を意味していて、何がどう違うのかがわからないと思います。検定手法を選ぶ際に、ノンパラかパラメトリックかはとても大切な事項になります。今回は、ノンパラとパラメトリックの違いについてと、pythonでどのように判断するかの方法について解説していきたいと思います...

Pandasでピアソンの積率相関係数以外を算出する方法

Pandasで算出しているのは、ピアソンの積率相関係数ですが、Pandasのコードに手を加えると、「スピアマンの順位相関係数」と「ケンドールの順位相関係数」を算出できます

# スピアマンの順位相関係数
import pandas as pd

# データフレームの作成
data = {
    'x': ,
    'y': 
}
df = pd.DataFrame(data)

# スピアマンの順位相関係数を算出
spearman_corr = df.corr(method='spearman')
print(spearman_corr)
# ケンドールの順位相関係数
import pandas as pd

# データフレームの作成
data = {
    'x': ,
    'y': 
}
df = pd.DataFrame(data)

# ケンドールの順位相関係数を算出
kendall_corr = df.corr(method='kendall')
print(kendall_corr)

まとめ

  • 相関係数は0.7を超えると強い相関、0.2以下はほぼ相関なし
  • pandasとnumpyはピアソンの積率相関係数を算出している
  • 相関係数と散布図を合わせてみる
  • 相関関係と因果関係は別物
  • pairplotはおしゃれ

pythonで統計学を学びたい方は、こちらを参考にしていただくと、一通り学ぶことができます

python 統計学
pythonで統計学を学ぶメリット〜実際の学習手順を紹介〜近年、データサイエンティストの需要が高まってきていますが、データサイエンティスト必須能力として、「プログラミング言語」「統計学」が挙げられています。pythonで統計学を扱えれば、データサイエンティストとしての道も開けるでしょう。今回はpythonで統計学を学ぶメリットや実際にどのように学習していくべきかを解説していきたいと思います。...

統計学だけではなく、データサイエンスに興味がある方は、キカガクでデータサイエンスを学ぶのがおすすめです

キカガクはデータサイエンス・AI・機械学習に特化した動画学習プラットフォームです

ちょっと気になるな…という方は、ぜひ説明会に参加してみてください

0からデータサイエンスを学び始める方に向けて、有料講座のプレゼントもあります

※無料オンライン相談や個別相談などさまざまなイベントが開催中

pythonで統計学を学ぶ上で必須書籍

pythonのスキルを高める方法

python スクールpythonのスキルを高めるには、pythonを学べるプログラミングスクールに通うのが一つの方法です

以下の記事では、pythonが学べて、無料体験できるおすすめのプログラミングスクールを紹介しているので、ぜひ参考にしてみてください

これから先、pythonを使える社会人は重宝される時代が来るので、今のうちに学んでおくと、社会に出た時に有利に働きます

python プログラミングスクール
Pythonや機械学習を学べるプログラミングスクールおすすめ5選「pythonを学ぶのに、プログラミングスクールに通いたい」「pythonを学べるプログラミングスクールがたくさんあって、よくわからない」「結局、pythonを学ぶのにおすすめのプログラミングスクールってどこなの?」といった疑問をお持ちの方に、pythonを学ぶのにおすすめのプログラミングスクールを紹介していきたいと思います。...
おすすめプログラミングスクール

DMMWEBCAMP
  • WEBCAMPはコスパ最強
  • WEBCAMPは初心者に優しい充実したサポート付き
  • 16週間プランを選択して、返金してもらおう
WEBCAMPの公式ページはこちら WEBCAMPの口コミ・評価はこちら
テックアカデミー  
  • テックアカデミーは費用対効果抜群
  • テックアカデミーのサポートは個人の能力に応じつつ、python初心者に優しい
  • まずは無料体験でテックアカデミーを知ってから受講を決める
テックアカデミーの公式ページはこちら テックアカデミーの口コミ・評価はこちら
キカガク
  • 多種多様なスキルコース
  • 初心者から専門家まで対象
  • 給付金利用で費用を抑えられる
キカガクの公式ページはこちら キカガクの口コミ・評価はこちら
Aidemy Premium
  • 完全オンラインで、時間や場所に縛られず学習したい
  • マンツーマン学習サポートにより実践に近い経験をしたい
  • 未経験から機械学習エンジニアになりたい
Aidemy Premiumの公式ページはこちら Aidemy Premiumの口コミ・評価はこちら
My Agile Privacy
This website uses technical and profiling cookies. Clicking on "Accept" authorises all profiling cookies. Clicking on "Refuse" or the X will refuse all profiling cookies. By clicking on "Customise" you can select which profiling cookies to activate.