013_変数が量的、質的どちらの場合の関係の強さも算出できる

解説

量的な相関の強さは、ピアソンの相関係数か、スピアマンの順位相関係数を利用することで算出できます。

データの内容によって、ピアソンとスピアマンを使い分ける必要があります。
以下の表に、そのデータ制約の違いを記載します。

相関係数種別 使用時のデータ制約
ピアソン データが正規分布に従う
スピアマン データが正規分布に従わない

データが正規分布に従わない例としては、相関関係を求めたい2つのデータが量的データであり、順位付けされている場合などが該当します。
(ex.複数の口紅に対するAさんとBさんの評価(ランキング形式)やアンケートの得点など)

なお、ピアソン、スピアマンの相関係数はrで表現され、その値により、相関の強さを知ることができます。いずれの相関係数も、以下表のとおり、評価の仕方は同じです。

相関係数 相関の強さ
[math]r=0[/math] 全く相関がない
[math]0<| r |≦0.2[/math] ほとんど相関がない
[math]0.2<| r |≦0.4[/math] 弱い相関がある
[math]0.4<| r |≦0.7[/math] 相関がある
[math]0.7<| r |<1.0[/math] 強い相関がある
[math]r = 1.0、 r = -1.0[/math] 完全な正(負)の相関がある

質的な相関の強さは、クラメールの連関係数を利用することで算出できます。
m行×n列の分割表の総観測数をN、カイ二乗値をχ2とおくと、クラメールの連関係数は以下の式で表されます。

[math]\LARGE{V = \sqrt{\frac{\chi^2}{N \times \min (m-1,n-1)}}}[/math]

対象データの関連性が強ければ強いほど、[math]V[/math]は1に近づきます。

より詳細に結果を考察したい場合は、コーエンの統計量wを用います。

[math]\LARGE{w = \sqrt{\frac{χ2} { N} }}[/math]

wの値により、次の目安で解釈することができます。

統計量w 関連性の解釈
[math]0.1<w ≦0.3[/math] 小さい
[math]0.3<w<0.5[/math] 中くらい
[math]0.5≦ w[/math] 大きい

ステップアップ

シャピロウィルク検定を利用することで、検定対象のデータが正規分布に従うかどうかを簡単に調べることができます。
統計学においては、スチューデントのt検定やウェルチのt検定などのパラメトリックな検定手法の前提条件として、検定対象のデータが正規分布に従うことが仮定されているため、非常に重要な検定となります。
なお、シャピロウィルク検定で出力されるp値が[math]0.05[/math]より大きい場合は、対象データを正規分布と判断します。
また、出力される検定値が1に近ければ近いほど、正規分布データとみなせます。当該検定の方法はソースコードに記載しますので参考にしてください。

キーワード

  • ピアソンの相関係数
  • スピアマンの順位相関係数
  • クラメールの連関係数
  • コーエンの統計量w
  • *シャピロウィルク検定

ソースコード

ピアソンの相関係数を求めるソースはこちらの記事を参考にしてください。

correlation_coefficient_spearman.py:与えられた対象データ(量的データ)に対して、スピアマンの相関係数を算出するプログラム

# coding:utf-8

data = [
    (1, 1), (2, 1), (3, 2), (4, 3),
    (5, 5), (6, 7), (7, 6), (8, 8),
    (9, 9), (10, 11), (11, 10), (12, 13),
    (13, 15), (14, 12), (15, 23), (16, 14),
    (17, 19), (18, 16), (19, 20), (20, 15),
]

def correlation_coefficient_spearman(data):
    d = 0
    n = len(data)

    for x, y in data:
        d += (x - y)*(x - y)

    print(u"スピアマンの相関係数:"),
    print(1.0 - 6.0 * d / (n ** 3 - n))

if __name__ == '__main__':
    correlation_coefficient_spearman(data)

このプログラムを実行すると、対象データに対して、スピアマンの相関係数を算出します。

スピアマンの相関係数: 0.911278195489

coefficient_of_association_cramer.py:与えられた対象データ(質的データ)に対して、クラメールの連関係数を算出するプログラム

※プログラムはこちらを参考にしました

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd

# 対象データ
data = pd.DataFrame(
    {'TOKYO': ['sunny', 'sunny', 'rainy', 'sunny', 'snowy', 'cloudy', 'sunny',
                 'sunny', 'sunny', 'sunny', 'sunny', 'sunny', 'sunny', 'sunny',
                 'cloudy', 'sunny', 'sunny', 'sunny', 'sunny', 'snowy', 'cloudy',
                 'cloudy', 'sunny', 'snowy', 'sunny', 'sunny', 'sunny', 'sunny',
],
     'OSAKA': ['sunny', 'sunny', 'sunny', 'sunny', 'rainy', 'cloudy', 'cloudy',
               'sunny', 'sunny', 'sunny', 'sunny', 'sunny', 'sunny', 'sunny',
               'cloudy', 'rainy', 'sunny', 'sunny', 'sunny', 'rainy', 'cloudy',
               'sunny', 'sunny', 'rainy', 'sunny', 'sunny', 'sunny', 'sunny',
               ]})

def correlation_coefficient_cramer(x, y):
    table = np.array(pd.crosstab(x, y)).astype(np.float32)
    n = table.sum()
    colsum = table.sum(axis=0)
    rowsum = table.sum(axis=1)
    expect = np.outer(rowsum, colsum) / n
    chisq = np.sum((table - expect) ** 2 / expect)
    print(u"クラメールの連関係数:"+str(np.sqrt(chisq / (n * (np.min(table.shape) - 1)))))

if __name__ == "__main__":

    correlation_coefficient_cramer(data['TOKYO'], data['OSAKA'])

このプログラムを実行すると、対象データ(質的データ)に対して、クラメールの連関係数を算出します。

クラメールの連関係数:0.777817427777

東京と大阪の天気の関係性を数値で表現しました。
※各都市の天気は適当に定めているので実データではありません

shapirowilk.py:与えられた対象データ(量的データ)に対して、シャピロウィルク検定を実行するプログラム

# coding:utf-8
import numpy as np
import scipy.stats as stats

normal=np.random.normal(100, 10, 1000)  #平均:100, 分散:10の正規分布に従う乱数を 1000 件出力

def shapirowilk(normal):

    # 検定値とp値の計算
    w,p=stats.shapiro(normal)

    # 検定値の表示
    print(u"検定値: " + str(w))

    print(u"p値:" + str(p))

if __name__ == '__main__':
    shapirowilk(normal)

このプログラムを実行すると、正規分布に従う対象データに対して、検定値とp値を算出します。
今回の例では、正規分布に従う乱数を生成し、そのデータに対してシャピロウィルク検定を行っているため、検定値はほぼ1となり、またp値も[math]0.05[/math]を大幅に上回っている数値になっています。

検定値: 0.998356878757
p値:0.464801639318

データセット