У чому полягають відмінності між регресією Рейджа за допомогою Rm glmnet та Python's scikit-learn?


11

Я переглядаю розділ LAB §6.6, присвячений хребтовій регресії / Лассо, в книзі «Вступ до статистичного навчання з додатками в R» Джеймса, Віттена, Хасті, Тібширані (2013).

Більш конкретно, я намагаюся застосувати модель scikit-learn Ridgeдо набору даних "Hitters" з пакету R "ISLR". Я створив той самий набір функцій, що і в коді R. Однак я не можу наблизитися до результатів glmnet()моделі. Я вибрав один параметр настройки L2 для порівняння. (аргумент 'альфа' в scikit-learn).

Пітон:

regr = Ridge(alpha=11498)
regr.fit(X, y)

http://nbviewer.ipython.org/github/JWarmenhoven/ISL-python/blob/master/Notebooks/Chapter%206.ipynb

R:

Зверніть увагу , що аргумент alpha=0в glmnet()засобі , яке повинно бути застосоване покарання L2 (Рідж регресія). Документація попереджає не вводити єдине значення для lambda, але результат такий же, як у ISL, де використовується вектор.

ridge.mod <- glmnet(x,y,alpha=0,lambda=11498)

Що викликає відмінності?

Редагувати:
При використанні penalized()з пенізованого пакету в R коефіцієнти такі ж, як у scikit-learn.

ridge.mod2 <- penalized(y,x,lambda2=11498)

Можливо, тоді може виникнути і запитання: «Яка різниця між регресією Рейда glmnet()та penalized()коли відбувається?

Нова обгортка python для фактичного коду Fortran, який використовується в gl-пакеті пакета R
https://github.com/civisanalytics/python-glmnet


5
Цілком незнайомий з регресним хребтом glmnet. Але, за замовчуванням, sklearn.linear_model.Ridgeчи не визначена оцінка перехоплення (стандартна), і штраф такий, який ||Xb - y - intercept||^2 + alpha ||b||^2мінімізований для b. Перед штрафом можуть бути фактори 1/2або 1/n_samplesабо обидва, що робить результати відразу різними. Щоб вирішити проблему масштабування штрафних санкцій, встановіть покарання 0 в обох випадках, вирішіть всі розбіжності там, а потім перевірте, що додає штраф. І btw IMHO тут - правильне місце, щоб задати це питання.

Відповіді:


9

У моїй відповіді відсутній коефіцієнт , див. Відповідь @visitors нижче для правильного порівняння.1N


Ось два посилання, які повинні з’ясувати стосунки.

Документація sklearn говорить, що linear_model.Ridgeоптимізує наступну цільову функцію

|Xβy|22+α|β|22

У статті glmnet йдеться про те, що еластична сітка оптимізує наступну цільову функцію

|Xβy|22+λ(12(1α)|β|22+α|β|1)

Зауважте, що обидві реалізації використовують абсолютно різними способами, sklearn використовує для загального рівня регуляризації, тоді як glmnet використовує для цієї мети, резервуючи для торгівлі між хребтом та ласо-регуляризацією. α λ αααλα

Порівнюючи формули, це виглядає як встановлення і у glmnet має відновити рішення з .λ = 2 α склеарнα=0λ=2αsklearnlinear_model.Ridge


І я цілком пропустив це у коментарі @eickenberg. Я повинен використовувати standardize = FALSEв , glmnet()щоб отримати однакові результати.
Джорді

@Jordi Ви, безумовно, повинні стандартизуватися, якщо використовуєте їх linear_model.Ridgeдля аналізу реального світу.
Меттью Друрі

Я розумію, що linear_model.Ridgeмодель sklearn стандартизує функції автоматично. Нормалізація не є обов'язковою. Цікаво, чому мені тоді потрібно деактивувати стандартизацію glmnet()для отримання моделей для отримання однакових результатів.
Джорді

10

Відповідь Метью Дрірі повинен мати коефіцієнт 1 / N. Точніше...

У документації про glmnet зазначено, що еластична сітка мінімізує функцію втрат

1NXβy22+λ(12(1α)β22+αβ1)

Документація sklearn говорить, що linear_model.Ridgeмінімізує функцію втрат

Xβy22+αβ22

що рівнозначно мінімізації

1NXβy22+αNβ22

Для отримання однакового рішення від glmnet та sklearn обидві їх функції втрати повинні бути рівними. Це означає, що встановити та у glmnet.α=0λ=2Nαsklearn

library(glmnet)
X = matrix(c(1, 1, 2, 3, 4, 2, 6, 5, 2, 5, 5, 3), byrow = TRUE, ncol = 3)
y = c(1, 0, 0, 1)
reg = glmnet(X, y, alpha = 0, lambda = 2 / nrow(X))
coef(reg)

Вихід glmnet: –0,03862100, –0.03997036, –0.07276511, 0.42727955

import numpy as np
from sklearn.linear_model import Ridge
X = np.array([[1, 1, 2], [3, 4, 2], [6, 5, 2], [5, 5, 3]])
y = np.array([1, 0, 0, 1])
reg = Ridge(alpha = 1, fit_intercept = True, normalize = True)
reg.fit(X, y)
np.hstack((reg.intercept_, reg.coef_))

висновок sklearn: –0,03862178, –0.0399697, –0.07276535, 0.42727921


4
Різні визначення параметрів та їх масштабування, що використовуються в різних бібліотеках, є загальним джерелом плутанини.
AaronDefazio

1
Я не очікував, що ми з Гунгом помиляємось.
Майкл Р. Черник

2
Так, ви обоє зрозуміли. Ваші причини відхилення моєї редакції дають зрозуміти, що ви обоє не бачили мого коментаря "Фактор відсутності 1 / N" на stats.stackexchange.com/review/sugges-edits/139985
відвідувач

Вашу редакцію, ймовірно, відхилили, оскільки вона змінила набагато більше, ніж лише те, про що ви заявляєте. Якщо ви хочете відредагувати мою публікацію та змінити лише фактор, що відсутній, будь ласка, зробіть це, але зміна моїх посилань та формулювань та коду є надмірною. Зауваження щодо вашого недобросовісного поводження у вашій відповіді є невідповідними та не мають відношення до змісту питання, видаліть їх. Ваше формулювання також зривало мою відповідь, це не правильний спосіб відповісти на відхилену редакцію. Ми б хотіли, щоб ваш цінний внесок у нашу громаду був, але будь ласка, ознайомтеся з нашими нормами, перш ніж нас викреслювати.
Метью Друрі

1
@visitor Вибачте, якщо я вийшов трохи грубим. Мені справді слід просто намагатись повідомити, що ви здаєтесь хорошим потенційним учасником сайту, і я хочу, щоб ви мали хороший досвід. У нас є деякі соціальні норми, як і в будь-якій іншій групі, і ви будете мати кращий досвід, якщо будете знати їх. Я все ще думаю, що "відповідь Метью Дрірі невірний" є досить суворим, є, безумовно, кращі способи повідомлення, що в моїй відповіді помилково відсутній фактор . "Відповідь X неправильна" читається як особиста атака. 1N
Метью Друрі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.