第1章 2つの変数の間の関係を見る
単回帰分析
2つの変量の大まかな関係が1次式で表されることがあり、単回帰モデルと呼ばれている。図1のデータ(ファイル名:data1_1.xlsx)を考える。
図1
図1のデータは、<岡本安晴「心理学データ分析と測定」勁草書房>の表1.1.1の一部を抜き出したものである。図1のデータは、次のスクリプトで読み込むことができる。
xlsx =
pd.ExcelFile('data1_1.xlsx') # 入力ファイル名の設定
data = pd.read_excel(xlsx) # 読み込み
読み込まれたデータはDataFrame型としてdataで表されている。このdataからExcelファイルの1行目に設定されている変数名と、それぞれの変数名の列に設定されているデータ値を読み込み、散布図を描くスクリプトは以下のようになる。
CaseLabel = data.columns[0]
# 第0列目の変数名
CaseID = data[CaseLabel].values
# CaseLabelの表す名前の列のデータを取り出してCaseIDで表す
print(CaseID)
YLabel = data.columns[1] # 第1列目の変数名
Y = data[YLabel].values
# YLabelの表す名前の列のデータを取り出してYで表す
print(Y)
XLabel = data.columns[2]
# 第2列目の変数名
X = data[XLabel].values
# XL+abelの表す名前の列のデータを取り出してXで表す
print(X)
#
#
(X, Y)の散布図
#
plt.plot(X, Y, 'bo')
plt.xlabel(XLabel)
plt.ylabel(YLabel)
plt.show()
上のスクリプトの実行により図2の散布図が描かれる。
図2
変量Xの値が増加すると変量Yの値も増加する傾向にあることがわかる。この傾向を次式の単回帰モデルで表す。
式番号(1.3.1)は<岡本安晴「心理学データ分析と測定」勁草書房>におけるものである。本ウェブサイトにおける式番号などは、本拙著におけるものを用いる。
回帰モデルの係数は次式
で与えられるが、この計算は次のスクリプトで行っている。
X_mean = X.mean()
Y_mean = Y.mean()
num = ((X - X_mean) * (Y -
Y_mean)).sum()
den = ((X - X_mean) ** 2).sum()
b1 = num / den
b0 = Y_mean - b1 * X_mean
求められた回帰係数による回帰直線は、次のスクリプトで描いている。
plt.plot(X, Y, 'bo')
plt.plot([X.min(), X.max()], [b0 + b1
* X.min(), b0 + b1 * X.max()], 'g')
plt.title('b0 = {0:.3}, b1 = {1:.3}'.format(b0, b1), fontsize =
16)
plt.xlabel(XLabel, fontsize = 14)
plt.ylabel(YLabel, fontsize = 14)
plt.show()
図2のウィンドウの右上のXアイコンをクリックして閉じ、上の回帰直線を描くスクリプトを実行すると図3のグラフが描かれる。
図3
描かれた図は、「保存」ボタンのクリックでファイルに保存できる。
決定係数は次式で与えられる。
これは、次のスクリプトで計算できる。
SSReg = (((b0 + b1 * X) - Y_mean) **
2).sum()
SSTol = ((Y - Y_mean) ** 2).sum()
R2 = SSReg / SSTol
帰無仮説「」に対するt値と、その両側検定におけるp値は、次のスクリプトで計算できる。
n = len(Y)
SSE = ((Y - (b0 + b1 * X)) ** 2).sum()
MSE = SSE / (n - 2)
SSX = ((X - X_mean) ** 2).sum()
s2_b1 = MSE / SSX
s_b1 = s2_b1 ** 0.5
t = b1 / s_b1
pvalue = (1 - ss.t.cdf(t, n - 2)) *
2
信頼区間(式(1.3.8))を求めるスクリプトは、以下のようである。
t_975 = ss.t.ppf(0.975, n - 2)
print('\n95% CI = [{0:<.5},
{1:<.5}]'.format(b1 - t_975 * s_b1, b1 + t_975 * s_b1))
上のスクリプトを1つにまとめたものをリスト1に示す。ファイルは、圧縮ファイルfiles1.zipにまとめたので、ダウンロードすれば自由に利用できる。
リスト1 単回帰分析のPythonスクリプト例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as ss
xlsx =
pd.ExcelFile('data1_1.xlsx') # 入力ファイル名の設定
data = pd.read_excel(xlsx)
# 読み込み
CaseLabel = data.columns[0]
# 第0列目の変数名
CaseID = data[CaseLabel].values
# CaseLabelの表す名前の列のデータを取り出してCaseIDで表す
print(CaseID)
YLabel = data.columns[1]
# 第1列目の変数名
Y = data[YLabel].values
# YLabelの表す名前の列のデータを取り出してYで表す
print(Y)
XLabel = data.columns[2]
# 第2列目の変数名
X = data[XLabel].values
# XL+abelの表す名前の列のデータを取り出してXで表す
print(X)
#
#
(X, Y)の散布図
#
plt.plot(X, Y, 'bo')
plt.xlabel(XLabel)
plt.ylabel(YLabel)
plt.show()
#
# b0とb1の計算
#
X_mean = X.mean()
Y_mean = Y.mean()
num = ((X - X_mean) * (Y -
Y_mean)).sum()
den = ((X - X_mean) ** 2).sum()
b1 = num / den
b0 = Y_mean - b1 * X_mean
print('\nb0 = ', b0)
print('b1 = ', b1)
#
# 回帰直線と散布図の描画
#
plt.plot(X, Y, 'bo')
plt.plot([X.min(), X.max()], [b0 + b1
* X.min(), b0 + b1 * X.max()], 'g')
plt.title('b0 = {0:.3}, b1 = {1:.3}'.format(b0, b1), fontsize =
16)
plt.xlabel(XLabel, fontsize = 14)
plt.ylabel(YLabel, fontsize = 14)
plt.show()
#
# 決定係数R^2の計算
#
SSReg = (((b0 + b1 * X) - Y_mean) **
2).sum()
SSTol = ((Y - Y_mean) ** 2).sum()
R2 = SSReg / SSTol
print('\nR2 = ', R2)
#
# t値の計算
#
n = len(Y)
SSE = ((Y - (b0 + b1 * X)) ** 2).sum()
MSE = SSE / (n - 2)
SSX = ((X - X_mean) ** 2).sum()
s2_b1 = MSE / SSX
s_b1 = s2_b1 ** 0.5
t = b1 / s_b1
pvalue = (1 - ss.t.cdf(t, n - 2)) *
2
# 両側検定
print('t = ', t, ' p = ', pvalue)
#
# 95%信頼区間
#
t_975 = ss.t.ppf(0.975, n - 2)
print('\n95% CI = [{0:<.5},
{1:<.5}]'.format(b1 - t_975 * s_b1, b1 + t_975 * s_b1))