Подмножество переменной в матрице на основе положительных корреляций для построения составного показателя - PullRequest
1 голос
/ 12 марта 2019

Я стремлюсь к созданию составного индикатора. Важным шагом, прежде чем приступить к правилам взвешивания и агрегирования и как описано в Справочнике ОЭСР по построению составных показателей , является рассмотрение корреляций между показателями .

Обратите внимание, что почти всегда будет некоторая положительная корреляция между различными показателями одного и того же агрегата. Таким образом, практическое правило должно быть введено для определения порога, за пределами которого корреляция является признаком двойного счета.

Чтобы продолжить это (, т.е. выбирая только положительно индикаторы с определенным порогом корреляции ), я попытался сделать следующее - в приведенном ниже примере

df <- data.frame(
  indic1 = c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0), 
  indic2 = c(0.28571, 0.5714285, 0.4285714, 0.142857, 0.285714, 1, 0.71428, 0.14285, 0.5714, 0.142, 0, 0.14285, 0.8571, 0.8571427, 0.4285), 
  indic3 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0), 
  indic4 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0), 
  indic5 = c(0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0.5), 
  indic6 = c(0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0), 
  indic7 = c(0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 0, 1, 1, 1, 0.5, 1, 0.5, 0), 
  indic8 = c(0, 0, 0.3333, 1, 0.3333, 0.3333, 0.3333, 1, 0, 0.3333, 0.3333, 0.3333, 0, 0, 1), 
  indic9 = c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1), 
  indic10 = c(0, 0.2, 1, 0.2, 0.8, 0.4, 0, 0.4, 0.4, 0.8, 0.4, 0.6, 0.4, 0, 0.2), 
  indic11 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0), 
  indic12 = c(0.5, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0.5, 0, 0, 0, 0), 
  indic13 = c(1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0), 
  indic14 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0), 
  indic15 = c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1), 
  indic16 = c(1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1), 
  indic17 = c(0.3333, 0.3333, 0.6666, 0, 0.6666, 0.1666, 1, 0.3333, 0.8333, 0.5, 0.1666, 0.5, 0, 0.8333, 0.1666), 
  indic18 = c(0.857142, 0.428571, 0.85714, 0.142857, 0.714285, 0.5714, 0.714285, 0, 0.42857, 0.857142, 0, 0, 1, 0.2857, 0), 
  row.names = c("Area1", "Area2", "Area3", "Area4", "Area5", "Area6", "Area7", "Area8", "Area9", "Area10", "Area11", "Area12", "Area13", "Area14", "Area15"))

## now correlation matrix
    corr.matrix <- cor(df, method = "pearson",  use = "pairwise.complete.obs")

## Visualization with ggplot  
  ggcorrplot(corr.matrix ,
                        method = "circle",
                        hc.order = TRUE,
                        type = "upper")

enter image description here

Далее следует установить подмножество матрицы корреляции для определенного порога (следуя приведенному здесь примеру: R: Фильтровать матрицу корреляции по значениям> и <</a>

Таким образом, код будет:

corr.matrix0 <- corr.matrix
diag(corr.matrix0) <- 0

##set up threshold
threshold <- 0.6

## Now subsetting but here without absolute value
#ok <- apply(abs(corr.matrix0) >= threshold, 1, any)
ok <- apply( corr.matrix0 >= threshold, 1, any)

## or
# ok <- sort(unique( c(which(abs(corr.matrix0) >= threshold, arr = TRUE))))
# ok <- sort(unique( c(which(corr.matrix0 >= threshold, arr = TRUE))))

corr.matrixnew <-  corr.matrix[ok, ok]
ggcorrplot(corr.matrixnew ,
           method = "circle",
           hc.order = TRUE,
           type = "upper")

Но, как видно из результатов, это не сработало ... поскольку я все еще вижу некоторые отрицательные корреляции ...
enter image description here

Я полагаю, что должен быть процесс оптимизации, основанный на матрице корреляции - вроде как лассо , чтобы сделать это?

У кого-нибудь есть сценарий для этого? Или, может быть, я что-то упустил ..

Заранее спасибо!

1 Ответ

0 голосов
/ 12 марта 2019

самый простой вариант - сделать это с findCorrelation из caret.Он создан именно для этой ситуации.

# do it with cart
library(caret)
to_remove <- findCorrelation(corr.matrix, cutoff = threshold)

corr.matrix_2 <- cor(df[, -to_remove], method = "pearson",  use = "pairwise.complete.obs")

ggcorrplot(corr.matrix_2 ,
           method = "circle",
           hc.order = TRUE,
           type = "upper")

enter image description here

В качестве альтернативы вы можете сделать это вручную, просто используя базовую R:

# do it manually
df2 <- as.data.frame(corr.matrix)
df2[lower.tri(corr.matrix, diag = TRUE)] <- NA

to_remove_2 <- (which(sapply(df2,function(x) any(abs(x) > threshold, na.rm = TRUE))))

corr.matrix_3 <- cor(df[, -to_remove_2], method = "pearson",  use = "pairwise.complete.obs")

ggcorrplot(corr.matrix_3 ,
           method = "circle",
           hc.order = TRUE,
           type = "upper")

enter image description here

РЕДАКТИРОВАТЬ: Возможно, я неправильно вас понял.Я думал, что вы хотите удалить тех, у кого корреляция> порог.

Но, если вы хотите сохранить их и удалить других:

df2 <- as.data.frame(corr.matrix)
diag(df2) <- NA
to_keep <- (which(sapply(df2,function(x) any(x > threshold, na.rm = TRUE))))

corr.matrix_4 <- cor(df[, to_keep], method = "pearson",  use = "pairwise.complete.obs")

ggcorrplot(corr.matrix_4 ,
           method = "circle",
           hc.order = TRUE,
           type = "upper")

enter image description here

Это может по-прежнему иметь отрицательную корреляцию, потому что, хотя попарная корреляция переменных высока, некоторые их взаимодействия являются отрицательными.

Пример: от A до B> 0,6, от C до D> 0,6, ноОт A до C <0 </p>

Если вы хотите, чтобы все они были высокими, это не парная корреляция ...

EDIT_2:

выбор только положительно индикаторов с определенным порогом корреляции)

Если вы просто хотите сделать это для построения графиков: удалите отрицательные числа (или те, которые ниже порога) из матрицы корреляции и постройте ее.

# corr.matrix_4[corr.matrix_4 <= 0] <- NA
corr.matrix_4[corr.matrix_4 <= threshold] <- NA


library(GGally) 
# Using GGally here as ggcorrplot doesn't handle NAs
# Or do it manually: http://www.sthda.com/english/wiki/ggplot2-quick-correlation-matrix-heatmap-r-software-and-data-visualization

ggcorr(corr.matrix_4, cor_matrix = corr.matrix_4, labbel = TRUE)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...