Лассо не сходится и ElasticNet использует все коэффициенты - PullRequest
0 голосов
/ 17 октября 2019

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

Что я сделал:

  • Iочистил набор данных, удалил выбросы и т. д. *
  • Сделал набор поездов - тест расщепления (0,75 (19693 балла) - 0,25 (6565 балла))
  • Выполнен случайный лес наЗатем наборы обучающих данных предсказывают набор тестов, в результате чего получается массив (6565,) со всеми прогнозами.
  • Сетка Поиск лучшего случайного леса, в результате которого получается оптимальное количество деревьев (n_estimators) из 1200.
  • Запуск оптимального случайного леса и поиск каждого прогноза для каждого дерева с использованием следующего кода predictions_all = np.array([tree.predict(test_features) for tree in rf.estimators_]), в результате чего получается матрица (6565,1200) (т. Е. Если вы сделаете среднее значение для каждой строки, вы получите прогноз случайного леса).
  • объединить эту матрицу с моей целевой переменной, в результате чего получится матрица (6565,1201).
  • Настройка набора поездов - Split Test (0,75 (4923 obs) - 0.25 (1642 obs)).
  • Выполнение Ridge / Lasso / adaptiveLasso / ElasticNet на обучающем наборе и, если последний учитывает только некоторые коэффициенты (например, деревья), сравните агрегированное среднее со случайным лесом, который мы сделали на шаге 3, чтобы увидеть, выполняет ли Лассо в случайном лесулучше, чем сам Случайный лес.

Проблема в том, что когда я пробую Ridge, Lasso & Adaptive Lasso, он не сходится, если alpha != 0 (OLS)

from sklearn.linear_model import Lasso
lasso00001 = Lasso(alpha=0.0001, max_iter=10000,normalize=True)
lasso00001.fit(train_features,train_labels)
train_score00001=lasso00001.score(train_features,train_labels)
test_score00001=lasso00001.score(test_features,test_labels)
coeff_used00001 = np.sum(lasso00001.coef_!=0)

print("training score for alpha=0.0001:", train_score00001 )
print("test score for alpha =0.0001: ", test_score00001)
print("number of features used: for alpha =0.0001:", coeff_used00001)

В результате

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/coordinate_descent.py:475: ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Duality gap: 104843192290351.6, tolerance: 137819106237.78107
  positive)

Я пробовал с max_iter=100000 и max_iter=1000000, но он также не сходится.

Кто-нибудь знает почему?

Однако, сходясь в ElasticNet, я попробовал GridSearchCV и выяснил оптимальное значение ElasticNet

from sklearn.linear_model import ElasticNet


EN = ElasticNet(alpha=0.02, max_iter=1000000, normalize=True, l1_ratio = 0.8)
EN.fit(train_features,train_labels)
train_EN=EN.score(train_features,train_labels)
test_EN=EN.score(test_features,test_labels)
coeff_used = np.sum(EN.coef_!=0)

print("training score:", train_EN)
print("test score: ", test_EN)
print("number of features used:", coeff_used)
print("coefs:", EN.coef_)

В результате:

training score: 0.6679234101432687
test score:  0.6414639586584302
number of features used: 1200
coefs: [0.00070865 0.00107221 0.00048273 ... 0.00062971 0.00057734 0.00033563]

Что означает, что он использовал каждые 1200 деревьев (переменных). Что странно, что мне нужно иметь alpha = 6500, чтобы он использовал только 1199 деревьев (переменных).

Я что-то упустил? Это потому, что все мои переменные (деревья)разумно то же самое, что он использует каждую переменную (дерево)?

1 Ответ

0 голосов
/ 17 октября 2019

То, что вы пропустили
Да, это вполне нормально. На самом деле, вы делаете штрафованную регрессию по очень (очень-очень) коррелированным переменным. По сути, каждое дерево обучается одинаково, но это лишь набор данных, на котором они обучаются, который немного отличается (это называется упаковкой в ​​пакеты). Но так как они отличаются лишь незначительно, это приведет к сильно коррелированным переменным.

Немного философии
Я не понимаю, почему вы хотели бы сделать это. Наказанная регрессия используется, когда вы хотите сохранить только несколько переменных, достаточных для прогнозирования (т. Е. Существует множество бесполезных переменных). Если у вас было много деревьев, которые были бесполезны, лучше сохранить меньше раньше.

Наконец, в Случайном Лесу количество деревьев не является лучшей вещью для поиска по сетке, потому что большее количество деревьев, как правило, дает лучшую производительность. То, что вы хотите, - это иметь меньше, чтобы иметь меньше алгоритмов, отнимающих много времени ... Более интересно искать в сетке всю глубину вашей модели.

Упаковка в мешки: https://en.wikipedia.org/wiki/Bootstrap_aggregating, https://becominghuman.ai/ensemble-learning-bagging-and-boosting-d20f38be9b1e

...