プログラミング初心者の勉強日記

情報科学専攻です. 機械学習と競技プログラミングについて日々勉強しています.

MENU

統計学の基礎知識 : 変動係数、相関係数、偏相関係数

今回は変動係数、相関係数、偏相関係数についての記事です.

最後に簡単なプログラムをpythonで書いたのでそちらも載せておきます.

1. 変動係数

標準偏差の他にデータの散らばり具合を測る指標を紹介します. 標準偏差について知りたい方は下の記事も参照してください.

www.tatsumiya-blog.tokyo

さて、例えばセンター試験の英語(200点満点)と学校の小テスト(30点満点) の平均と標準偏差が以下のように得られたとします. (平均や標準偏差は適当に設定しています.)

  • センター試験の英語 : 平均 = 160点、 標準偏差 = 12
  • 学校の小テスト : 平均 = 23点 、標準偏差 = 2

この時、標準偏差を参考にすると、学校の小テストの方がセンター試験の英語の標準偏差に比べて小さいので、散らばり具合は学校の小テストの方が小さいことになります.

しかし、学校の小テストは30点満点なのでセンター試験の英語に比べて値が散らばらないのは当然です. これは平均が大きく異なることに起因します.

したがって、平均が大きく異なるデータ群同士の散らばり具合を比較した時には単純に標準偏差の比較では間違った解釈となってしまいます.

そこで用いられる指標が変動係数 (CV, coefficient of variation) です. 変動係数は次のように定義されます.

$$ CV = \frac{s}{\overline{x}} $$

ここで、sは標準偏差、\overline{x}は平均です.

標準偏差を平均で標準化することにより異なる平均同士でも比較することができます. 平均に対して標準偏差がどの程度になるかを算出していることに等しいです.

変動係数を用いると、

  • センター試験の英語における変動係数 : \frac{12}{160} = 0.075
  • 学校の小テストにおける変動係数 : \frac{2}{23} = 0.087

となるので、標準偏差の大小関係と逆になっていることが確認できます.

2. 相関係数

例えば、経験的に駅の近さと家賃は関係していると考えられます. (駅から遠いほど家賃が高く、遠いほど家賃が安い)

このように2つの変数がどのような関係にあるかを知りたい時があります. また、このような互いの関係のことを相関 (correlation) と呼びます.

今、(駅までの所要時間、家賃)のデータを(1, 10), (1, 8), (2, 9), (2, 10), (3, 8), (5, 6), (8, 5), (10, 5), (15, 3), (20, 2)とします.

このデータの駅までの所要時間をx、家賃をyとし、二次平面上にプロットすることを考えます. この時できた図を散布図 (scatter diagram)と呼びます.

上の駅までの所要時間と家賃の関係をプロットした散布図を以下に示します.

f:id:linearml:20180922174831p:plain

散布図を見ると、駅から近い物件ほど家賃が安い傾向にあることがわかります.

このように片方の変数が大きくなるともう片方の変数が小さくなることを、負の相関があると呼びます.

逆に片方の変数が大きくなると、もう片方も大きくなる関係のことを、正の相関があると呼びます.

そのどちらでもないものを無相関と呼びます.

また、相関にもはっきりと正または負の関係が現れているものとそうでないものがあります. 前者を強い相関、後者を弱い相関と呼びます.

この強い相関、弱い相関を表す指標が相関係数です. 散布図やその他の表では視覚的に考察できましたが、定量的な評価には向いていませんでした.

そこで、相関係数を用いて定量的な評価をすることを考えます.

相関係数を求めるためには、共分散が必要なので、まず共分散について説明します.

共分散

2変数データ(x_1, y_1), \cdots, (x_n, y_n)が与えられたとします. このとき共分散は以下で定義されます.

$$ s_{xy} = \frac{1}{n} \sum_{i = 1}^{n} (x_i - \overline{x}) (y_i - \overline{y}) $$

(x_i - \overline{x})(y_i - \overline{y}) > 0のとき、x_i, y_iはそれぞれの平均より共に大きいか小さいことになります. 逆に(x_i - \overline{x})(y_i - \overline{y}) \lt 0のときは、どちらかが平均より大きくもう片方が小さいか、その逆となります.

これらを全ての観測値に対して計算し平均をとったものが共分散となります.

相関係数に話を戻します

共分散が正の値を取るならば、正の相関が、負の値を取るならば負の相関があることがわかります.

しかし、共分散は単位によって大きさが異なるため、2つの標準偏差で割ります. 2つの標準偏差で割ることで、相関係数の値は単位によらず、-1から1の間の値を取ることになります.

$$ r_{xy} = \frac{s_{xy}}{s_x s_y} $$

相関係数の値の絶対値が大きいほど強い相関となります.

3. 偏相関係数

相関がそんなに強くなくても上の相関係数の絶対値が大きくなることがあります.

例えば、ある県における各市の喫茶店の数とゲームセンターの数の2変数について考えます.

このとき、相関係数を計算すると0.86となったとします. 0.86は十分強い相関であると言えますが、経験的に喫茶店の数とゲームセンターの数の間に直接強い相関があるようには思えません.

f:id:linearml:20180922201811p:plain

これは、人口密度という第三の変数が、喫茶店の数とゲームセンターの数のそれぞれと強い相関があるため、見かけ上の相関が生じた可能性があります. (第3の変数によって現れる2変数の相関を見かけ上の相関と呼びます.)

ここで、x=喫茶店の数、y= ゲームセンターの数、z=人口密度の数とし、それぞれの相関係数を以下のように得られたとします.

  • 喫茶店の数とゲームセンターの数 0.86
  • 喫茶店の数と人口密度 0.87
  • ゲームセンターの数と人口密度 0.98

f:id:linearml:20180922201826p:plain

ここで、考えるのは、喫茶店の数とゲームセンターの数の間に強い相関があるように見えたのは、人口密度が影響していると考え、人口密度の影響を覗いた後の喫茶店の数とゲームセンターの数の間の相関を考えます. この第3の変数の影響を取り除いた後の2変数の相関係数を偏相関係数 (partial correlation coefficient)と呼び、r_{(xy\cdot z)}と書きます.

偏相関係数は以下のように定義されます.

$$ r_{(xy\cdot z)} = \frac{r_{xy} - r_{xz}r_{yz}}{\sqrt{1 - r_{xz}^{2}}\sqrt{1 - r_{yz}^{2}}} $$

この偏相関係数を用いると喫茶店の数とゲームセンターの数の偏相関係数は、 $$ r_{(xy\cdot z)} = \frac{0.80 - 0.87 \times 0.98}{\sqrt{1 - 0.87^{2}}\sqrt{1 - 0.98^{2}}} = 0.08 $$

となり、実際には相関が強くないことがわかります.

4. 実装例

最後に簡単ではありますが、pythonで書いたプログラムを載せておきます.

import math

A = [0.39, 0.72, 1.00, 1.52, 5.20, 9.54, 19.19, 30.07]
B = [0.24, 0.62, 1.00, 1.88, 11.86, 29.46, 84.01, 164.79]

def calMean(d) :
    sum_v = 0.0
    for di in d :
        sum_v += di
    rsl = sum_v / len(d)
    return rsl

def calVariance(d) :
    sum_v = 0.0
    mean_d = calMean(d)
    for di in d :
        sum_v += pow(di - mean_d, 2)
    rsl = sum_v / len(d) 
    return rsl

def calStandardDeviation(d) :
    variance_d = calVariance(d)
    rsl = math.sqrt(variance_d)
    return rsl

def calCovariance(x, y) :
    mean_x = calMean(x)
    mean_y = calMean(y)

    sum_v = 0.0
    for xi, yi in zip(x, y) :
        sum_v += (xi - mean_x) * (yi - mean_y)
    rsl = sum_v / len(x)
    return rsl

def calCorrelationCoefficient(x, y) :
    covariance_xy = calCovariance(x, y)
    sd_x = calStandardDeviation(x)
    sd_y = calStandardDeviation(y)

    rsl = covariance_xy / (sd_x * sd_y)
    return rsl

def calPartialCorrelationCoefficient(x, y, z) :
    r_xy = calCorrelationCoefficient(x, y)
    r_xz = calCorralationCoefficient(x, z)
    r_yz = calCorrelationCoefficient(y, z)

    rsl = (r_xy - r_xz * r_yz) / (math.sqrt(1 - pow(r_xz, 2)) * math.sqrt(1 - pow(r_yz, 2)))
    
    return rsl
calCovariance(x, y)

で共分散を、

calCorrelationCoefficient(x, y)

で相関係数を、

calPartialCorrelationCoefficient(x, y, z)

で偏相関係数、r_{(xy\cdot z)}を計算できます.