Вопрос относительно реализации выбора подмножества OLS

Вопрос или проблема

На этом сайте я нашел реализацию на Python для выбора набора предикторов в обычной линейной регрессии, включающую Метод Лучшего Подмножества, Прямой Пошаговый Отбор и др. Это должно быть дополнением к книге An Introduction to Statistical Learning Джеймса, Уиттена, Хастие и Тибширени.
Функция, подбирающая одну модель и также вычисляющая соответствующее RSS, представлена следующим образом:

def processSubset(feature_set):
    # Подбор модели по feature_set и вычисление RSS
    model = sm.OLS(y,X[list(feature_set)])
    regr = model.fit()
    RSS = ((regr.predict(X[list(feature_set)]) - y) ** 2).sum()
    return {"model":regr, "RSS":RSS}

и функция, реализующая один шаг в Прямом Пошаговом Отборе:

def forward(predictors):

# Извлекаем предикторы, которые нам еще нужно обработать
remaining_predictors = [p for p in X.columns if p not in predictors]

tic = time.time()

results = []

for p in remaining_predictors:
    results.append(processSubset(predictors+[p]))

# Собираем все в красивый DataFrame
models = pd.DataFrame(results)

# Выбираем модель с наименьшим RSS
best_model = models.loc[models['RSS'].argmin()]

toc = time.time()
print("Обработано ", models.shape[0], "моделей на", len(predictors)+1, "предикторах за", (toc-tic), "секунд.")

# Возвращаем лучшую модель вместе с другой полезной информацией о модели
return best_model

Мне кажется, что это не может быть корректным, поскольку свободный член по умолчанию не включается в регрессию? Скорее его рассматривают как отдельный предиктор, и запуск этого на некоторых смоделированных данных приводит к тому, что свободный член включается на некотором шаге, где он дает наибольшее улучшение. Я что-то упускаю? Разве строка, создающая модель, не должна выглядеть следующим образом:

model = sm.OLS(y,sm.add_constant(X[feature_set]))

чтобы точно соответствовать процедуре, описанной в книге? Заранее спасибо!

Ответ или решение

Ваш вопрос о реализации выбора подмножеств в контексте метода наименьших квадратов (OLS) в Python очень уместен. Давайте разберемся с тем, как правильно учесть интерсепт в модели и почему ваше замечание о необходимости добавления константы справедливо.

В statsmodels, когда вы используете sm.OLS, интерсепт модели не добавляется автоматически, если вы не укажете это явно. Таким образом, если вы создаете свою модель, используя только предикторы, ваш результат может быть искажен, потому что интерсепт будет отсутствовать, что может привести к неверным оценкам коэффициентов и тем больше к неверной оценке величины ошибков квадратов (RSS).

Ваша поправка, где вы предлагаете использовать sm.add_constant(X[feature_set]), совершенно правильна. Это гарантирует, что интерсепт будет включен в модель, что соответствует практикам, описанным в книге "An Introduction to Statistical Learning". Модель должна выглядеть следующим образом:

model = sm.OLS(y, sm.add_constant(X[list(feature_set)]))

Таким образом, код функции processSubset будет корректно обрабатывать добавление константы. В результате точность ваших предсказаний и расчетов RSS существенно повысится.

Ниже приведен исправленный код с учетом вашей правки:

def processSubset(feature_set):
    # Добавляем константу в модель
    model = sm.OLS(y, sm.add_constant(X[list(feature_set)]))
    regr = model.fit()
    RSS = ((regr.predict(sm.add_constant(X[list(feature_set)])) - y) ** 2).sum()
    return {"model": regr, "RSS": RSS}

Теперь с этим исправлением функция будет учитывать интерсепт. Это также повлияет на шаг Forward Stepwise Selection, поскольку на каждом шаге будет рассчитываться RSS с учетом интерсепта, и в конечном итоге вы сможете выбрать более подходящую модель.

Надеюсь, это решение поможет вам корректно реализовать выбор подмножеств в линейной регрессии. Если у вас возникнут дополнительные вопросы или нужна помощь по другим частям кода, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...