Регуляризованная регрессия с использованием glmnet: нет разницы между группами?

#r #regression #glmnet #lasso-regression #regularized

#r #регрессия #glmnet #лассо-регрессия #регуляризованная

Вопрос:

Я использую регуляризованную регрессию для выбора нескольких белков, которые наилучшим образом различают состояние здоровья (двоичное: либо болезнь, либо отсутствие болезни). Цель его использования — уменьшить размерность (выбор переменных), чтобы мы могли иметь меньший набор белков, которые наилучшим образом различают две группы.

Параметры настройки были выбраны соответствующим образом (я полагаю …) с использованием функции cv.glmnet в R. (В частности, альфа была выбрана на основе скорости прогнозирования, и я использовал lambda.1se. Поскольку выбранная альфа была равна 0,5, я фактически использую регрессию эластичной сети.)

В результате 16 белков (из почти 500 белков) имели ненулевые коэффициенты, и я предполагаю, что это те белки, которые лучше всего «различают» два состояния: либо болезнь, либо отсутствие болезни. Для визуализации я сделал прямоугольные графики, используя эти выбранные белки.

Однако я заметил, что один белок (TRAP1; внизу на рисунке) не показывает какой-либо заметной средней разницы или дисперсии между двумя группами.

введите описание изображения здесь

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

Кто-нибудь может мне помочь, пожалуйста?

Большое вам спасибо!!

Ответ №1:

Lasso не гарантирует, что ваш предиктор покажет статистическую значимость, когда вы его тестируете. В большинстве случаев, если есть возможность прогнозирования, вы увидите корреляцию между выбранными переменными lasso и вашей зависимой переменной.

Когда вы устанавливаете alpha = 0.5, это налагает штраф L1 (минимизируя величину ваших коэффициентов) и штраф L2 (выбирая переменные с 0/1), поэтому, глядя на распределение вашей переменной, большая ее часть равна нулю, поэтому уменьшение ее до низкого значения должно заставить ее «избежать»Штраф L2.

Если целью вашего лассо является выбор переменных, я бы предложил две вещи: 1. удалите функции, которые в основном имеют нули или низкую дисперсию, как показано выше, и 2. запустите полное лассо с альфа = 1. Сравните точность ваших прогнозов.

У меня нет ваших данных, но я могу проиллюстрировать с помощью набора mtcars данных, в котором я ввожу бессмысленный предиктор и сначала вычисляю значения предикторов :

 set.seed(111)
dat = iris
dat$Species = ifelse(dat$Species=="versicolor",1,0)
noise_var = data.frame(matrix(runif(750),nrow=150))
colnames(noise_var) = paste0("noise",1:ncol(noise_var))
dat  = cbind(noise_var,dat)

p = sapply(dat[,-ncol(dat)],function(i)cor.test(i,dat$Species)$p.value)
 

Подгонка с использованием полного лассо:

 set.seed(222)
fit_lasso = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=1)
cbind(coef(fit_lasso,lambda="1se")[-1],p)

                                   p
noise1        0.0000000 5.089346e-01
noise2        0.0000000 2.722532e-01
noise3        0.0000000 9.564023e-02
noise4        0.0000000 7.743330e-01
noise5        0.0000000 7.324517e-02
Sepal.Length  0.0000000 3.341524e-01
Sepal.Width  -0.3073508 1.595624e-09
Petal.Length  0.0000000 1.329302e-02
Petal.Width   0.0000000 1.507473e-01
 

Вы можете видеть, что ненулевые коэффициенты значимы, а некоторые другие значимые не включены, это связано с корреляцией.

Теперь установите эластичную сеть, вы можете видеть, что переменная шума включена с низким коэффициентом:

 set.seed(222)
fit_enet = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=0.5)
cbind(coef(fit_enet,lambda="1se")[-1],p)

                                    p
noise1        0.00000000 5.089346e-01
noise2        0.00000000 2.722532e-01
noise3        0.00000000 9.564023e-02
noise4        0.00000000 7.743330e-01
noise5       -0.04636756 7.324517e-02
Sepal.Length  0.00000000 3.341524e-01
Sepal.Width  -0.31452496 1.595624e-09
Petal.Length  0.00000000 1.329302e-02
Petal.Width   0.00000000 1.507473e-01
 

Также имейте в виду, что решение или выбор нестабильны, см. Этот пост, если вы запустите его под другим исходным кодом, вы получите другой результат:

 set.seed(333)
fit_enet = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=0.5)
cbind(coef(fit_enet,lambda="1se")[-1],p)

                                   p
noise1        0.0000000 5.089346e-01
noise2        0.0000000 2.722532e-01
noise3        0.0000000 9.564023e-02
noise4        0.0000000 7.743330e-01
noise5        0.0000000 7.324517e-02
Sepal.Length  0.0000000 3.341524e-01
Sepal.Width  -0.2393709 1.595624e-09
Petal.Length  0.0000000 1.329302e-02
Petal.Width   0.0000000 1.507473e-01
 

Конечно, вы можете выполнить это для нескольких начальных значений, чтобы увидеть, насколько стабилен выбор коэффициента, но имейте в виду, что при большой корреляции это сложно

Комментарии:

1. рад, что это полезно 🙂 получайте удовольствие от своих белков