パッケージ関数などで実はあるのかもしれないが、知らないので自作してみた。
交互作用項とは (超ざっくり)
変数x1と変数x2の積を、x1とx2の交互作用項と呼ぶ。
わかりやすいので回帰分析を例に取ると、変数同士の交互作用がなければ、x1とx2の交互作用項の(偏)回帰係数は0になる。
数式で書くと、
y = b_0 + b_1x_1 + b_2x_2 + b_{12}x_1x_2
とした時に、x1とx2に交互作用がないことと、$b_{12}$が0になるのは同値ということ……だと思う (数学的に本当にそうなのか?やや自信がない)。
交互作用を知りたい時はプロットして目で見る方法もあるが、変数が多いときはそうも言ってられないし、定量的な観点で見るなら交互作用項を入れて回帰分析するのが手っ取り早いときも多い。
機械学習のモデリングでもそこそこ使う。
Rで計算するコード
make_interaction <- function(df, col, .cbind = FALSE) {
## 交互作用項を作成する
# @param df : 対象のデータ (data.frame)
# @param col : 交互作用を計算するカラム名の配列 (str vector)
# @param .cbind : 交互作用項目を元のデータにcbind()して返すかどうか (boolean)
# @return : 交互作用のデータ (data.frame)
interact <- combn(col, 2) # 交互作用を計算するカラムの組
# 交互作用data.frameを作成
df_interact <-
foreach(i = seq(ncol(interact)), .combine = data.frame) %do% {
df[[interact[1,i]]] * df[[interact[2,i]]] # 交互作用項
}
colnames(df_interact) <- interact %>% apply(2, function(x) {paste0(x[1], "_", x[2])}) # 列名を作成する
if (.cbind == TRUE)
return(cbind(df, df_interact))
else
return(df_interact)
}
colがlength=1だったらエラー吐くけど、交互作用なんだからまぁ良いでしょ……ということで。
foreach()文にしているところは、自分が書きやすいからそう書いたけど、別の書き方のほうが良いかも知れない。
試した範囲内では、想定通り動作している模様。
やってみた感想
列が多い場合、colを指定するのが面倒。
パイプ演算子で繋いで使えるようにするには、以下のように事前に列名を取得する必要がある。
col_interact <- c("colA", "colB", "colC", "colD", "colE")
data_interact <- data %>% make_interaction(col_interact, .cbind = T)
これはあまりスマートではない気がするが、なにか良い方法があるだろうか。
最低限、missing(col) == TRUE
の場合、全カラムで交互作用を計算するような仕様にはした方が良いのだろう。