重回帰分析 Last modified: Sep 21, 2009
目的
重回帰分析を行う。
変数選択を行うには,「sreg 関数」を使用のこと。
(R では lm 関数を使うのがよい)
使用法
mreg(dat, func.name=c("solve", "ginv"))
引数
dat データ行列。従属変数は最終列におき,それ以外は独立変数と見なす。
func.name 逆行列を計算する関数名(solve か ginv)。
正規方程式が特異行列になる場合以外はどちらを使っても結果は同じ
省略時は solve
ムーア・ペンローズ型一般化逆行列を使うときは ginv
ソース
インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/mreg.R", encoding="euc-jp")
# 重回帰分析
mreg <- function( dat, # データ行列
func.name=c("solve", "ginv")) # 逆行列を計算する関数の選択
{
dat <- subset(dat, complete.cases(dat)) # 欠損値を持つケースを除く
n <- nrow(dat) # ケース数
nc <- ncol(dat) # 列数
nv <- nc-1 # 独立変数の個数(最後の一つは従属変数)
if (is.null(colnames(dat))) { # 変数名が付いていないときには仮の名前を付ける
colnames(dat) <- paste("Var", 1:nc, sep="")
}
r <- cor(dat) # 相関係数行列
m <- colMeans(dat)[-nc] # 独立変数の平均値ベクトル
if (match.arg(func.name) == "solve") {
inverse <- solve
betas <- inverse(r[-nc, -nc], r[,nc][-nc]) # 標準化偏回帰係数
}
else {
library(MASS)
inverse <- ginv
betas <- inverse(r[-nc, -nc]) %*% r[,nc][-nc] # 標準化偏回帰係数
}
variance <- var(dat)*(n-1) # 変動共変動行列
prop <- diag(variance) # 対角成分
prop <- (prop/prop[nc])[-nc] # 偏回帰係数に変換するための係数(独立変数の変動/従属変数の変動)
b <- betas/sqrt(prop) # 偏回帰係数
Sr <- variance[,nc][-nc]%*%b # 回帰による変動
St <- variance[nc, nc] # 全変動
Se <- St-Sr # 誤差変動
SS <- c(Sr, Se, St) # 平方和(変動)ベクトル
dfr <- nv # 回帰による変動の自由度
dfe <- n-nv-1 # 誤差変動の自由度
dft <- n-1 # 全変動の自由度
df <- c(dfr, dfe, dft) # 自由度ベクトル
Ms <- SS/df # 平均平方ベクトル
f <- Ms[1]/Ms[2] # F 値
fvalue <- c(f, NA, NA)
p <- c(pf(f, dfr, dfe, lower.tail=FALSE), NA, NA) # P 値
b0 <- mean(dat[,nc])-sum(b*m) # 定数項
b <- c(b, b0) # 偏回帰係数ベクトル
inv <- inverse((n-1)*cov(dat)[-nc, -nc])
SEb <- c(sapply(1:nv, function(i) sqrt(inv[i, i]*Ms[2])), sqrt((1/n+m%*%inv%*%m)*Ms[2]))
tval <- b/SEb # 偏回帰係数の有意性検定
pval <- pt(abs(tval), n-nv-1, lower.tail=FALSE)*2 # P 値
tolerance <- 1/diag(inverse(cor(dat)[-nc, -nc])) # トレランス
result <- cbind(b, SEb, tval, pval, c(betas, NA), c(tolerance, NA))
rownames(result) <- c(colnames(dat)[1:nv], "定数項")
colnames(result) <- c("偏回帰係数", "標準誤差", "t 値", "P 値", "標準化偏回帰係数", "トレランス")
R2 <- 1-Se/St # 重相関係数の二乗
R <- sqrt(R2) # 重相関係数
R2s <- 1-Ms[2]/Ms[3] # 自由度調整済み重相関係数の二乗
loglik <- -0.5*n*(log(2*pi)+1-log(n)+log(Se)) # 対数尤度
AIC <- 2*nc+2-2*loglik # AIC
Rs <- c("重相関係数"=R, "重相関係数の二乗"=R2, "自由度調整済重相関係数の二乗"=R2s,
"対数尤度"=loglik, "AIC"=AIC)
anova <- cbind(SS, df, Ms, fvalue, p) # 分散分析表
rownames(anova) <- c("回帰", "残差", "全体")
colnames(anova) <- c("平方和", "自由度", "平均平方", "F 値", "P 値")
return(structure(list(result=result, anova=anova, Rs=Rs), class="mreg"))
}
# print メソッド
print.mreg <- function( obj, # mreg が返すオブジェクト
digits=5) # 結果の表示桁数
{
print(obj$result, digits=digits, na.print="")
cat("\n回帰の分散分析表\n\n")
print(obj$anova, digits=digits, na.print="")
cat("\n")
sapply(1:length(obj$Rs), function(i) cat(names(obj$Rs)[i], "=", round(obj$Rs[i], digits), "\n"))
}
使用例
> dat <- matrix(c( # 3 列目が従属変数
+ 1.2, 1.9, 0.9,
+ 1.6, 2.7, 1.3,
+ 3.5, 3.7, 2.0,
+ 4.0, 3.1, 1.8,
+ 5.6, 3.5, 2.2,
+ 5.7, 7.5, 3.5,
+ 6.7, 1.2, 1.9,
+ 7.5, 3.7, 2.7,
+ 8.5, 0.6, 2.1,
+ 9.7, 5.1, 3.6
+ ), byrow=TRUE, nc=3)
> (a <- mreg(dat))
偏回帰係数 標準誤差 t 値 P 値 標準化偏回帰係数 トレランス
Var1 0.20462 0.0075643 27.0506 2.4192e-08 0.67067 0.98358
Var2 0.28663 0.0108015 26.5365 2.7638e-08 0.65793 0.98358
定数項 0.14918 0.0545063 2.7368 2.9050e-02
回帰の分散分析表
平方和 自由度 平均平方 F 値 P 値
回帰 6.671644 2 3.3358218 823.48 4.9319e-09
残差 0.028356 7 0.0040509
全体 6.700000 9 0.7444444
重相関係数 = 0.99788
重相関係数の二乗 = 0.99577
自由度調整済重相関係数の二乗 = 0.99456
対数尤度 = 15.13807
AIC = -22.27614
解説ページ
直前のページへ戻る
E-mail to Shigenobu AOKI