Variance Inflation Factor を計算するループを作成しようとしています。これを実行できる関数とパッケージがあることは理解していますが、何らかのカスタマイズが必要です。
サンプルデータ
library(MASS)
library(clusterGeneration)
set.seed(2)
num.vars <- 30
num.obs<-200
cov.mat<- genPositiveDefMat(num.vars,covMethod="unifcorrmat")$Sigma
rand.vars<- mvrnorm(num.obs,rep(0,num.vars),Sigma=cov.mat)
cov.mat <- as.data.frame(cov.mat)
names(cov.mat) <- rep(paste0("X",1:30))
このデータフレームには 30 列 (予測子) があります。
ループの私のロジックは次のとおりです。
1) 各予測変数を他の予測変数に対して回帰し、R2 を計算します。VIF = 1/1 - R2 を使用して R2 を VIF に変換します。これにより、30 個の VIF 値が得られます。
2) VIF 値をソートします。上位の予測変数の VIF が 10 を超える場合、その予測変数を から削除しcov.mat
ます。cov.mat
現在、29 個の予測変数があります。
3) ステップ 1 を繰り返します。つまり、各予測変数を他の予測変数に対して回帰させ、VIF を再度計算します (今回は 29 VIF)。最大 VIF > 10 の場合、VIF が最も高い変数を削除し、最大 VIF <= 10 になるまで続けます。
ただし、キャッチは、特定の反復で VIF > 10 であっても、 X4 、 X6 、および X10 を保持したいということです。したがって、上記のプロセスで、反復で X4 または X6 または X10 が最高の VIF (> 10) を持つことが判明した場合、2 番目に高い VIF を持つ変数を削除します (2 番目に高い VIF も > 10 であり、X4 またはX6 または X10)。これが明確であることを願っています
mat <- matrix(, ncol = 2, nrow = nrow(cov.mat)) # this will store the 30 VIFs
for(i in 1:ncol(cov.mat)){
mdl <- lm(cov.mat[,i] ~ ., data = cov.mat) # this will regress each column against other columns but throws an error when i = 2
r.squared <- unlist(summary(mdl)[8]) # this gives the r-squared of predictor i
vif <- 1/(1- r.squared^2) # calcualtion of VIF for predictor i
mat[i,2] <- vif
mat[i,1] <- names(cov.mat[i])
}
上記のループが正常に機能し、最初の列が変数名で、2 番目の列が VIF 値のマトリックスがあるとします。
df <- data.frame(mat)
names(df) <- c("variable", "vif")
df <- df[sort(df$vif),]
ifelse(df[1,2] <= 10, stop, ifelse(df[1,2] > 10 & names(df[1,1]) != "X4" | names(df[1,1]) != "X6" | names(df[1,1]) != "X10", ....
これは私が迷っているところです。
最初に、最も高い VIF を持つ変数が 10 を超えており、X4 または x6 と X10 の間にないかどうかを確認し、変数を dataframe から削除する必要がありますcov.mat
。最高の VIF を持つ変数 (VIF > 10 の場合) が X4 または X6 または X10 のいずれかである場合、2 行目に移動し、df
その VIF > 10 であるかどうか、および X4、X6 または X10 のいずれでもないかどうかを評価します。条件を満たしている場合は、 から削除してcov.mat
、反復を再度開始します。
編集
元のデータ フレームには 51 列と 1458 行があります。上記の関数を実行すると、エラーが発生しますthere are aliased coefficients in the model
。なぜこうなった?