Есть ли у scikit-learn алгоритм прямого выбора / ступенчатой ​​регрессии?

37

Я работаю над проблемой со слишком многими функциями, и обучение моих моделей занимает слишком много времени. Я реализовал алгоритм прямого выбора для выбора функций.

Однако мне было интересно, есть ли у scikit-learn алгоритм прямого выбора / пошаговой регрессии?

Максуд
источник
Я создал свой собственный класс для этого, но очень удивился, что у sklearn этого нет.
Максуд
1
Использование тестов гипотез - ужасный метод выбора признаков. Вам придется сделать много из них, и, конечно же, вы получите много ложных срабатываний и негативов.
Рикардо Крус

Ответы:

21

Нет, у sklearn нет алгоритма прямого выбора. Тем не менее, он обеспечивает рекурсивное удаление признаков, которое является жадным алгоритмом удаления признаков, подобным последовательному обратному выбору. Смотрите документацию здесь:

http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html

brentlance
источник
3
Хорошее предложение, но проблема с реализацией научного комплекта заключается в том, что важность функции количественно определяется коэффициентами модели, т.е. если модель имеет coef_интерфейс. Это исключило бы метод на основе дерева и т. Д. Однако, я думаю, что @Maksud попросил то, что описано в «Введение в статистическое обучение» Джеймсом, в котором функции рекурсивно добавляются / удаляются по их важности, которую он оценивает с помощью точности набора проверки. , Это позволяет выбирать функции для всех типов моделей, а не только для линейных параметрических.
eggie5
9

Склеарн имеет алгоритм прямого выбора, хотя в scikit-learn он не называется. Метод выбора функции, называемый F_regression в scikit-learn, будет последовательно включать функции, которые улучшают модель в наибольшей степени, до тех пор, пока Kв модели не появятся элементы (K является входом).

Он начинается с регрессии меток на каждом объекте в отдельности, а затем наблюдения за тем, какой объект улучшил модель, используя F-статистику. Затем он включает в себя функцию победы в модели. Затем он перебирает оставшиеся функции, чтобы найти следующую функцию, которая максимально улучшает модель, снова используя F-статистику или F-тест. Это происходит до тех пор, пока в модели не появятся K функций.

Обратите внимание, что остальные функции, которые связаны с функциями, включенными в модель, вероятно, не будут выбраны, поскольку они не коррелируют с остатками (хотя они могут хорошо коррелировать с метками). Это помогает защититься от мультиколлинеарности.

Candic3
источник
1
Однако имейте в
виду
1
Вы имеете в виду Select K-best ?
Нитро
да. Кроме того, вы должны прочитать это: stats.stackexchange.com/questions/204141/… .
Candic3
2
Это своего рода выбор вперед. Но это не универсально - это специфично для модели линейной регрессии, в то время как обычно прямой выбор может работать с любой моделью (независимой от модели), как RFE, и может решать проблемы классификации или регрессии. Но я подозреваю, что большинство людей ищут этот вариант использования, и, конечно, хорошо упомянуть об этом здесь.
Симон
2
Это не выбор STEPWISE, потому что каждое значение p рассчитывается для одномерной регрессии независимо от всех других ковариат.
Дэвид Дейл
9

Scikit-Learn действительно не поддерживает ступенчатую регрессию. Это потому, что то, что обычно известно как «ступенчатая регрессия», представляет собой алгоритм, основанный на p-значениях коэффициентов линейной регрессии, и scikit-learn намеренно избегает логического подхода к обучению модели (тестирование значимости и т. Д.). Более того, чистый OLS является лишь одним из многочисленных алгоритмов регрессии, и с точки зрения scikit-learn он не является ни очень важным, ни одним из лучших.

Однако есть несколько советов для тех, кому все еще нужен хороший способ выбора функций с линейными моделями:

  1. Используйте изначально разреженные модели, такие как ElasticNetили Lasso.
  2. Нормализовать свои функции с StandardScaler, а затем упорядочить свои функции просто model.coef_. Для совершенно независимых ковариат это эквивалентно сортировке по p-значениям. Класс sklearn.feature_selection.RFEсделает это за вас и RFECVдаже оценит оптимальное количество функций.
  3. р2statsmodels
  4. Делайте прямой или обратный выбор, чтобы максимизировать ваш любимый показатель при перекрестной проверке (это может занять приблизительно квадратичное время по числу ковариат). Пакет, совместимый с Scikit-Learn mlxtend, поддерживает этот подход для любой оценки и любого показателя.
  5. Если вы все еще хотите пошаговую регрессию ванили, ее легче основывать statsmodels, поскольку этот пакет вычисляет p-значения для вас. Базовый выбор вперед-назад может выглядеть так:

`` `

from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import statsmodels.api as sm

data = load_boston()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target


def stepwise_selection(X, y, 
                       initial_list=[], 
                       threshold_in=0.01, 
                       threshold_out = 0.05, 
                       verbose=True):
    """ Perform a forward-backward feature selection 
    based on p-value from statsmodels.api.OLS
    Arguments:
        X - pandas.DataFrame with candidate features
        y - list-like with the target
        initial_list - list of features to start with (column names of X)
        threshold_in - include a feature if its p-value < threshold_in
        threshold_out - exclude a feature if its p-value > threshold_out
        verbose - whether to print the sequence of inclusions and exclusions
    Returns: list of selected features 
    Always set threshold_in < threshold_out to avoid infinite looping.
    See https://en.wikipedia.org/wiki/Stepwise_regression for the details
    """
    included = list(initial_list)
    while True:
        changed=False
        # forward step
        excluded = list(set(X.columns)-set(included))
        new_pval = pd.Series(index=excluded)
        for new_column in excluded:
            model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included+[new_column]]))).fit()
            new_pval[new_column] = model.pvalues[new_column]
        best_pval = new_pval.min()
        if best_pval < threshold_in:
            best_feature = new_pval.argmin()
            included.append(best_feature)
            changed=True
            if verbose:
                print('Add  {:30} with p-value {:.6}'.format(best_feature, best_pval))

        # backward step
        model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
        # use all coefs except intercept
        pvalues = model.pvalues.iloc[1:]
        worst_pval = pvalues.max() # null if pvalues is empty
        if worst_pval > threshold_out:
            changed=True
            worst_feature = pvalues.argmax()
            included.remove(worst_feature)
            if verbose:
                print('Drop {:30} with p-value {:.6}'.format(worst_feature, worst_pval))
        if not changed:
            break
    return included

result = stepwise_selection(X, y)

print('resulting features:')
print(result)

Этот пример напечатает следующий вывод:

Add  LSTAT                          with p-value 5.0811e-88
Add  RM                             with p-value 3.47226e-27
Add  PTRATIO                        with p-value 1.64466e-14
Add  DIS                            with p-value 1.66847e-05
Add  NOX                            with p-value 5.48815e-08
Add  CHAS                           with p-value 0.000265473
Add  B                              with p-value 0.000771946
Add  ZN                             with p-value 0.00465162
resulting features:
['LSTAT', 'RM', 'PTRATIO', 'DIS', 'NOX', 'CHAS', 'B', 'ZN']
Дэвид Дейл
источник
Размещенный код прямой пошаговой регрессии работает неправильно. Он должен давать идентичные результаты для обратной ступенчатой ​​регрессии, но это не так. Возвращает факторы с p-значениями, которые превышают пороговое значение при повторном запуске регрессии. Я также запустил один и тот же набор данных со STATA и те же пороги, используя пошаговое обратное направление, и получил существенно разные результаты. По сути, не используйте его. Я собираюсь написать свой собственный пошаговый регрессионный код, используя его шаблон.
Майкл Корли MBA LSSBB
Прямая и обратная ступенчатые регрессии никоим образом не гарантируют сходство к одному и тому же решению. И если вы заметили ошибку в моем решении, пожалуйста, приложите код, чтобы воспроизвести его.
Дэвид Дейл
1

На самом деле есть хороший алгоритм под названием «Forward_Select», который использует Statsmodels и позволяет вам устанавливать свою собственную метрику (AIC, BIC, Adjusted-R-Squared или что угодно) для постепенного добавления переменной в модель. Алгоритм можно найти в разделе комментариев этой страницы - прокрутите вниз, и вы увидите его в нижней части страницы.

https://planspace.org/20150423-forward_selection_with_statsmodels/

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

Попробуйте и убедитесь сами.

Рам Сешадри
источник
0

На самом деле у sklearn нет алгоритма прямого выбора, хотя в апреле 2017 года в репозитории Scikit-Learn ожидается пул- запрос с реализацией прямого выбора функций.

В качестве альтернативы в mlxtend есть прямой и обратный выбор на один шаг вперед . Вы можете найти его документ в Sequential Feature Selector.

Ynjxsjmh
источник