データ分析において変数を扱うと、常に疑問が生じる。変数がどのように依存し、リンクし、お互いに変化しているのか?共分散と相関の測定は、これを確立するのに役立つ。
共分散と相関はこれを確立するのに役立ちます。
共分散は、変数間のばらつきをもたらす。共分散は、2つの変数がお互いにどれだけ変化するかを測定するために使用します。相関は、変数間の関係を明らかにします。2つの変数が互いにどの程度強く結びついているかを判断するために相関を用います。
今回は、Pythonで共分散と相関を計算する方法を学びます。
共分散と相関 – 簡単な用語説明
共分散と相関はどちらも変数間の関係である.共分散は、変数間の方向性のある関連性を定義する。共分散の値は-infから+infの範囲で、正の値は両方の変数が同じ方向に動くことを示し、負の値は両方の変数が反対方向に動くことを示す。
相関は、2つの変数がどの程度線形的に関連しているか(一定の割合で一緒に変化しているかという意味)を表す標準化された統計指標である。2つの変数間の関係の強さと方向の関連性が相関によって定義され、その範囲は-1から+1までである。共分散と同様に、正の値は両方の変数が同じ方向に動くことを示し、負の値はそれらが逆方向に動くことを伝える。
共分散と相関はともに、データ探索における特徴選択と多変量解析に使用される重要なツールである。例えば、ポートフォリオのリスクを分散させたい投資家は、価格が同時に上昇することを示唆する共分散が高い銘柄を探すかもしれません。しかし、同じような動きをしているだけでは十分ではありません。そこで投資家は、相関性の指標を用いて、それらの株価が互いにどの程度強く結びついているかを判断することになる。
Pythonコードのセットアップ – サンプルデータの取得
前節で学んだ基本を踏まえて、pythonで共分散を計算するために先に進みましょう。この例では、よく知られているIrisのデータセットを扱うことにします。具体的には setosa
という種だけを扱うので、これは紫のかわいい花に関するデータセットの単なるサンプルになります。
それでは、これから分析を行うデータセットを見てみましょう。
これから2つのカラム、 sepal_length
と sepal_width
を選んで分析します。
新しいPythonファイル(名前は covariance_correlation.py
)に、花の sepal_length
と sepal_width
のプロパティの値からなる2つのリストを作成することから始めましょう。
with open('iris_setosa.csv','r') as f:
g=f.readlines()
# Each line is split based on commas, and the list of floats are formed
sep_length = [float(x.split(',')[0]) for x in g[1:]]
sep_width = [float(x.split(',')[1]) for x in g[1:]]
データサイエンスでは、作業中のデータを視覚化することは常に助けになります。ここでは、これらのセトーサの特性を異なる軸で表したSeaborn回帰プロット(散布図+線形回帰のフィット)を示します。
視覚的にデータポイントは回帰線に近い高い相関を持っているように見えます。我々の観測値が共分散と相関の値に一致するか見てみよう。
Pythonで共分散を計算する。
共分散は以下の式で計算されます。
上の式で
- xi, yi – x と y の系列の個々の要素です。
- x̄, y̅ – x と y の系列の数学的平均値
- N – 系列の要素数
分母はデータセット全体の場合は N
であり,サンプルの場合は N - 1
である.今回のデータセットはIrisのデータセット全体のうちの小さなサンプルなので、N - 1
を使用します。
上記の数式を参考に、純粋なPythonでこの関数を作ってみましょう。
def covariance(x, y):
# Finding the mean of the series x and y
mean_x = sum(x)/float(len(x))
mean_y = sum(y)/float(len(y))
# Subtracting mean from the individual elements
sub_x = [i - mean_x for i in x]
sub_y = [i - mean_y for i in y]
numerator = sum([sub_x[i]*sub_y[i] for i in range(len(sub_x))])
denominator = len(x)-1
cov = numerator/denominator
return cov
with open('iris_setosa.csv', 'r') as f:
...
cov_func = covariance(sep_length, sep_width)
print("Covariance from the custom function:", cov_func)
まず、データセットの平均値を求めます。次にリスト内包を使って2つのデータ系列の各要素を繰り返し、それらの値を平均値から引きます。お好みであれば、forループを使ってもよいでしょう。
次に、2つの系列の中間値を使用して、別のリスト内包で互いに掛け合わせます。そのリストの結果を合計して numerator
として保存します。分母は計算が簡単なので、サンプルデータの共分散を求めるときは、必ず 1 で割ってください!
そして、numerator
をdenominator
で割ったときの値、つまり共分散を返します。
このスクリプトを実行すると、このような出力が得られます。
Covariance from the custom function: 0.09921632653061219
正の値は、両方の変数が同じ方向に動くことを示す。
Pythonで相関を計算する
相関係数の計算式として最も広く使われているのがPearsonの「r」です。
上の式で
- xi, yi – x, y系列の個々の要素
- 分子は共分散に対応する。
- 分母は、x と y の個々の標準偏差に対応します。
この連載で、相関を求めるために必要なことはすべて説明したようなものですね!では、相関を計算してみましょう。
では、相関を計算してみましょう。
def correlation(x, y):
# Finding the mean of the series x and y
mean_x = sum(x)/float(len(x))
mean_y = sum(y)/float(len(y))
# Subtracting mean from the individual elements
sub_x = [i-mean_x for i in x]
sub_y = [i-mean_y for i in y]
# covariance for x and y
numerator = sum([sub_x[i]*sub_y[i] for i in range(len(sub_x))])
# Standard Deviation of x and y
std_deviation_x = sum([sub_x[i]**2.0 for i in range(len(sub_x))])
std_deviation_y = sum([sub_y[i]**2.0 for i in range(len(sub_y))])
# squaring by 0.5 to find the square root
denominator = (std_deviation_x*std_deviation_y)**0.5 # short but equivalent to (std_deviation_x**0.5) * (std_deviation_y**0.5)
cor = numerator/denominator
return cor
with open('iris_setosa.csv', 'r') as f:
...
cor_func = correlation(sep_length, sep_width)
print("Correlation from the custom function:", cor_func)
この値は2つの変数の共分散を必要とするので、この関数はその値をもう一度計算することになります。共分散が計算されると、次にそれぞれの変数の標準偏差が計算されます。そこから、相関は単に共分散を標準偏差の二乗で割ったものになります。
このコードを実行すると次のような出力が得られ、これらの特性が正(値の符号、0なら+、-、なし)の強い(値が1に近い)関係を持っていることが確認されます。
Correlation from the custom function: 0.7425466856651597
結論
この記事では、共分散と相関という2つの統計手法を詳しく学びました。それらの値がデータに対して何を意味するのか、数学でどのように表現されるのか、そしてPythonでどのように実装するのかを学びました。この2つの尺度は、2つの変数間の関係を判断するのにとても役に立ちます。