この講義では、「2つの変数の記述統計」をとりあげます。 これは、2つの変数を対象として、変数同士の関係を捉える、というものです。 特に量的変数同士と、質的変数同士の関係を取り上げます。
学習項目です
量的データとは、対象の量や大きさを表すもので、数値で表されます。これは次の2つに分けることができます。
質的データとは、対象の性質や種類などを表すもので、言葉や記号で表わされるものです。 </UL> 例えば、数学のテストの点数や物理のテストの点数は『量的データ』です。 ここであるクラスの学生について考えると、個々人の数学テストの点数は「数学テストの点数」という変数のいろいろな具体的データとみなせます。同様に個々人の物理テストの点数も「物理テストの点数」という変数のいろいろな具体例とみなせます。これらを量的変数といい、2つの量的変数の間の関係を相関と言います。
一方、あるクラスの学生について、「数学が好きかきらいか」というデータは質的データと考えられ、「数学の好き嫌い」という変数の具体例とみなせます。このような変数を質的変数といい、 例えば『数学の好き嫌い』と『物理の好き嫌い』という2つの質的変数の間の関係を連関と言います。
ここでは、相関と連関について学びます。
2つの変数、例えば、同じ人の「数学テストの点数」と「英語テストの点数」の間の関係を考えるのに、図を書いてみるということがよく行われます。
散布図</font>とは、学生の2つの科目の成績のように、対応のあるデータを2次元の平面上にプロットして得られる図のことです。これは2つのデータの間の関係を調べるのに利用されます。例えば、あるクラスの数学と英語の成績が以下のようだったとします。ここで、数学と英語の点数は学籍番号順に並んでいる、つまり学籍番号が3番の学生は数学の成績が14点、英語は12点だったとします。
Math = np.array([17, 13, 14, 7, 12, 10, 6, 8, 15, 4, 14, 9, 6, 10, 12, 5, 12, 8, 8, 12, 15, 18])
Eng = np.array([14, 10, 12, 9, 10, 12, 1, 6, 16, 1, 12, 13, 11, 11, 16, 8, 11, 12, 6, 14, 17, 20])
この散布図はmatplotlib.pltモジュールのscatter関数を用いて次のようにして得られます。
(plot
関数を使ってもできますが、オプションを設定する必要があります)
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
Math = np.array([17, 13, 14, 7, 12, 10, 6, 8, 15, 4, 14, 9, 6, 10, 12, 5, 12, 8, 8, 12, 15, 18])
Eng = np.array([14, 10, 12, 9, 10, 12, 1, 6, 16, 1, 12, 13, 11, 11, 16, 8, 11, 12, 6, 14, 17, 20])
plt.scatter(Math, Eng)
plt.xlabel('Math')
plt.ylabel('Eng')
plt.plot(Math, Eng,'o') # 'o'のような引数がないと線が描画される
plt.xlabel('Math')
plt.ylabel('Eng')
# 表示される範囲がかなりぎりぎりになるのでaxis関数で表示範囲を設定したほうが良い
plt.axis([2,20,0,25])
ここでは数学の成績をx座標、英語の成績をy座標として、それぞれの学生の2つの科目の成績を平面上に表示しました。このグラフを見ると、数学(x)と英語(y)の成績はなんとなく関係がありそうに見えます。つまり、xの値が増加するとyの値が増加するという関係です。これは、xとyの間に正の相関があるといいます。これとは逆にxの値が増加するとyの値が減少する関係もあります。このときはxとyの間に負の相関があるといいます。もちろんこのような関係がない場合もあります。その場合、xとyは無相関であるといいます:
下の図の(1)と(2)は相関があるとみなせる場合の散布図、(3)は無相関とみなせる場合の散布図です。直線はy=xを表す直線で、これに沿った点が多いほど正の相関があると考えられます。また楕円はその中に多くのデータが入るよう書いたものです。(2)の弱い相関の場合、(1)とくらべて散らばりが広がっていること、無相関の場合はデータをカバーする楕円がほぼ円になっていることが見て取れます。
ここでは数学の成績をx座標、英語の成績をy座標として、それぞれの学生の2つの科目の成績を平面上に表示しました。このグラフを見ると、数学(x)と英語(y)の成績はなんとなく関係がありそうに見えます。つまり、xの値が増加するとyの値が増加するという関係です。これは、xとyの間に正の相関があるといいます。これとは逆にxの値が増加するとyの値が減少する関係もあります。このときはxとyの間に負の相関があるといいます。もちろんこのような関係がない場合もあります。その場合、xとyは無相関であるといいます:
下の図の(1)と(2)は相関があるとみなせる場合の散布図、(3)は無相関とみなせる場合の散布図です。直線はy=xを表す直線で、これに沿った点が多いほど正の相関があると考えられます。また楕円はその中に多くのデータが入るよう書いたものです。(2)の弱い相関の場合、(1)とくらべて散らばりが広がっていること、無相関の場合はデータをカバーする楕円がほぼ円になっていることが見て取れます。
|
|
|
(1)正の相関 | (2)弱い相関 | (3)無相関 |
相関係数(r) | 大きさの評価 |
---|---|
$-0.2 \leq r \leq 0.2$ | ほとんど相関なし |
$-0.4 \leq r < -0.2$ および $0.2 < r\leq 0.4$ | 弱い相関あり |
$-0.7 \leq r < -0.4$ および $0.4 <r \leq 0.7$ | 中程度の相関あり |
$-1.0 \leq r < -0.7$ および $0.7 < r \leq 1.0$ | 強い相関あり |
Rでは相関係数を
np.corrcoef(Math,Eng)
数学と英語の成績の相関係数が0.79という値が出ました。これは先の表から、強い相関がありそうだ、ということがわかりました。
このように強い相関があるとき、yとxの関係を
np.polyfit( Math,Eng,1) # 1次関数を求める
help(np.polyfit)
この結果から、Eng = 0.936 * Math + 1.001という方程式で説明できそうということがわかりました。なおこのような分析を単回帰分析と言います。
せっかくですから、これを先の散布図に重ねて表示してみましょう。
lm = np.polyfit(Math, Eng, 1)
plt.plot(Math, Eng,'o') # 'o'のような引数がないと線が描画される
plt.xlabel('Math')
plt.ylabel('Eng')
# 表示される範囲がかなりぎりぎりになるのでaxis関数で表示範囲を設定したほうが良い
plt.axis([2,20,0,25])
x = np.linspace(2.0, 30.0, 10000)
plt.plot(x, lm[0]*x+lm[1],"g")
クロス集計表とは、質的変数同士の関係を見るのに使われます。 例えば、数学の好き・嫌いと統計学の好き・嫌いの間に連関があるかどうかは、それぞれの変数 (「Math(数学)」と「Stat(統計学)」)が質的変数ですから、クロス集計表を書いて調べることになります。
ここで数学変数と統計学変数の値を次のように定めることにしましょう:
import numpy as np
Math = np.array(["嫌い","嫌い","好き","好き","嫌い","嫌い","嫌い","嫌い","嫌い","好き","好き","嫌い",
"好き","嫌い","嫌い","好き","嫌い","嫌い","嫌い","嫌い"])
Stat = np.array(["好き","好き","好き","好き","嫌い","嫌い","嫌い","嫌い","嫌い","嫌い","好き","好き",
"好き","嫌い","好き","嫌い","嫌い","嫌い","嫌い","嫌い"])
クロス集計表を作るにはpandasモジュールのcrosstab関数を用います:
import pandas as pd
data = pd.DataFrame({'Math':Math, 'Stat':Stat})
pd.crosstab(data.Math,data.Stat,margins=True)
help(pd.crosstab)
ここで、質的変数に対する「特殊な相関係数」であるファイ係数を紹介します。 ファイ係数は、1と0からなる変数(二値変数)に対して計算される相関係数です。 したがって、質的変数に対してこれを適用するには、まずデータを0, 1の値に変換しなければなりません。 それを先ほど取り上げた数学変数と統計学変数に対して適用し、ファイ係数を求めてみることにしましょう。
まず、二値変数にするには、下に示すようにリストの内包記法を使えばできます。
MathDigitize = np.array([1 if x == "好き" else 0 for x in Math])
print(MathDigitize)
StatDigitize = np.array([1 if x == "好き" else 0 for x in Stat])
print(StatDigitize)
これで変数の値が数値化されましたので、関数corrcoefを適用して、ファイ係数が求まりました:
np.corrcoef(MathDigitize,StatDigitize)
この結果からは、数学変数と統計学変数の間には弱い連関があるということが言えそうです。
目的 | 関数名とモジュール | 使い方 |
---|---|---|
散布図を書く | plt.scatter(データ1, データ2) | plt.scatter([17, 13, 14, 7], [12, 10, 6, 8]) |
散布図を書く(別版) | plt.plot(データ1, データ2, 'o') : 第3引数には'+'や'*'などのマークが選べる | np.plot([17, 13, 14, 7], [12, 10, 6, 8],'o') |
分散共分散行列を求める | np.cov(データ1, データ2) | np.cov([17, 13, 14, 7], [12, 10, 6, 8]) |
相関係数を求める | np.corrcoef(データ1, データ2) | np.corrcoef([17, 13, 14, 7], [12, 10, 6, 8]) |
単回帰分析を行う | np.polyfit(データ1, データ2, 1) | np.polyfit(([17, 13, 14, 7], [12, 10, 6, 8], 1) |
クロス集計表を作る | pd.crosstab(配列1, 配列2, margins=True) | pd.crosstab(np.array([0,1,0,0,1]), np.array([1,1,1,0,0]),margins=True) |
次は20人に対し、食事の好み(洋食か和食)と味の好み(甘党か辛党か)についてアンケート調査したものである。これに対しクロス集計表を求め、ファイ係数を求めよ。(注意: 番号のデータは使わない)
# のデータ
import pandas as pd
df = pd.DataFrame({'Food':["洋食","和食","和食","洋食","和食","洋食","洋食","和食","洋食","洋食","和食","洋食",
"和食","洋食","和食","和食","洋食","洋食","和食","和食"],
'Taste':["甘党","辛党","甘党","甘党","辛党","辛党","辛党","辛党","甘党","甘党","甘党","甘党",
"辛党","辛党","甘党","辛党","辛党","甘党","辛党","辛党"]})
#演習問題2-3
import numpy as np
x = np.array([69, 70, 76, 69, 68, 74, 63, 79, 82, 74, 73, 66, 69, 71, 63, 73, 69, 63, 57, 71,
77, 74, 66, 73, 63, 75, 68, 66, 69, 77])
y = np.array([71, 75, 73, 59, 72, 53, 55, 72, 70, 65, 76, 63, 58, 52, 63, 57, 62, 59, 47, 51,
74, 52, 56, 61, 55, 70, 62, 66, 61, 63])