総当たり法による重回帰分析     Last modified: Aug 27, 2009

目的

総当たり法による重回帰分析を行う。

使用法

All.possible.subset.selection(df, limit)
print.All.possible.subset.selection(obj, sort.by=c("adj", "rsq", "AIC"), models=20)

引数

df        データフレーム(従属変数を最後の列に置く)
limit     独立変数の個数の制限値。標準では 10 個
          注意:独立変数が多いと莫大な計算時間がかかり,出力行数も増える
             独立変数が1個増えるだけで,計算時間はほぼ 2 倍になり,出力行数は 2 倍になる
obj       
sort.by   モデルの適否を表す3種の統計量のどれでソートして結果を表示するかの選択
          デフォルト("adj")では 結果を自由度調整済み重相関係数の二乗(adj.r.square)の大きい順にソートして出力する。
          "rsq" を指定すると,結果を重相関係数の二乗(決定係数 r.square)の大きい順にソートして出力する。
          "AIC" を指定すると,結果を AIC の小さい順にソートして出力する。
models    よいモデルから mmodels 番目までを表示する(デフォルトは 20)

ソース

インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/All_possible_subset_selection.R", encoding="euc-jp")

# 総当たり法による重回帰分析を行う
#  データフレームには,分析に使用する独立変数と従属変数のみを含むこと。
#  また,従属変数は最終列に置くこと。
#
All.possible.subset.selection <- function(df,                                # データフレーム(独立変数,従属変数)
                                          limit=10)                     # 独立変数の個数の上限(数が多いと計算時間が指数的に増える)
{
        df <- subset(df, complete.cases(df))                         # 欠損値を持つケースを除く
        nv <- ncol(df)-1                                             # 独立変数の個数
        if (nv > limit) {                                               # limit より多いと分析を中断する
                stop(paste("独立変数が", limit,
                "個以上である(多すぎる)。\n",
                "limit 引数で変更できる", paste=""))
        }
        n <- 2^nv                                                    # 独立変数を取り出す取り出し方
        bincomb <- matrix(FALSE, nrow=n, ncol=nv)                    # e1071 パッケージの bincombinations より
        for (j in 1:nv) {
                bincomb[, j] <- rep(c(rep(FALSE, n/2^j), rep(TRUE, n/2^j)), length = n)
        }
        bincomb <- bincomb[-1,]
        n <- n-1
        name <- names(df)                                            # 変数名を取り出す
        depname <- name[nv+1]
        name <- name[1:nv]
        result4 <- character(n)                                              # 数値型ベクトル確保
        result1 <- result2 <- result3 <- numeric(n)                    # 数値型ベクトル確保
        for (i in 1:n) {                                                # 独立変数の全ての組み合わせについて,
                str <- name[bincomb[i,]]                             # どの独立変数が使われるかを割り出す
                form <- reformulate(str, depname)                    # モデル式を作る("formula" クラス)
                ans <- lm(form, df)                                  # 重回帰分析の結果
                result <- summary(ans)
                result1[i] <- result$r.square                                # 重相関係数の二乗(決定係数)
                result2[i] <- result$adj.r.square                    # 自由度調整済み重相関係数の二乗
                result3[i] <- AIC(ans)                                       # AIC
                temp <- as.character(form)                           # モデル式を文字列に変換
                result4[i] <- paste(temp[2], "~", temp[3])           # モデル式を記録
        }
        return(structure(list(rsq=result1, adj=result2, AIC=result3, form=result4),
        class="all.possible.subset.selection"))
}
print.all.possible.subset.selection <- function( obj,                        # "all.possible.subset.selection" クラスのオブジェクトをプリント
                                                 sort.by=c("adj", "rsq", "AIC"), # 結果を何で並べ替えるかを指示
                                                 models=20)             # 良い方から何番目まで出力するか
{
        result <- data.frame(obj$rsq, obj$adj, obj$AIC, obj$form)
        sort.by <- match.arg(sort.by)
        o <- order(switch (sort.by, "rsq"=result[,1], "adj"=result[,2], "AIC"=result[,3]), decreasing = sort.by != "AIC")
        result <- result[o,]
        cat("\nR square  Adjusted R square       AIC       Formula\n")  # 表頭
        models <- min(models, nrow(result))
        apply(result[1:models,], 1, function(x)                         # 各行の出力
                cat(sprintf("%8.5f %13.5f  %13.5f       %s\n",
                as.double(x[1]), as.double(x[2]), as.double(x[3]), x[4])))
        invisible(result)
}


使用例

All.possible.subset.selection(iris[1:4])	# 1〜3列目を独立変数,4列目(Petal.Width)を従属変数とする

> str(iris)	# iris の構成は以下の通り
`data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versic..",..: 1 1 1 1 1 1 1 1 1 1 ...

出力結果例

> All.possible.subset.selection(iris[1:4]) # デフォルトでは自由度調整済みの重相関係数の二乗で並べ替える

R square  Adjusted R square       AIC       Formula
 0.93785       0.93657      -63.50218       Petal.Width ~ Sepal.Length + Sepal.Width + Petal.Length
 0.92975       0.92879      -47.11940       Petal.Width ~ Sepal.Width + Petal.Length
 0.92902       0.92806      -45.58470       Petal.Width ~ Sepal.Length + Petal.Length
 0.92711       0.92662      -43.59109       Petal.Width ~ Petal.Length
 0.74293       0.73943      147.46929       Petal.Width ~ Sepal.Length + Sepal.Width
 0.66903       0.66679      183.37107       Petal.Width ~ Sepal.Length
 0.13405       0.12820      327.64025       Petal.Width ~ Sepal.Width

> a <- All.possible.subset.selection(iris[1:4]) # 他の基準で並べ替えるときは,付値してから,
> print(a, sort.by="AIC")                          # print メソッドの sort.by 引数で指定する

R square  Adjusted R square       AIC       Formula
 0.93785       0.93657      -63.50218       Petal.Width ~ Sepal.Length + Sepal.Width + Petal.Length
 0.92975       0.92879      -47.11940       Petal.Width ~ Sepal.Width + Petal.Length
 0.92902       0.92806      -45.58470       Petal.Width ~ Sepal.Length + Petal.Length
 0.92711       0.92662      -43.59109       Petal.Width ~ Petal.Length
 0.74293       0.73943      147.46929       Petal.Width ~ Sepal.Length + Sepal.Width
 0.66903       0.66679      183.37107       Petal.Width ~ Sepal.Length
 0.13405       0.12820      327.64025       Petal.Width ~ Sepal.Width

・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI

Made with Macintosh