Важность функций на основе AUC с использованием случайного леса

Я пытаюсь предсказать двоичную переменную как со случайными лесами, так и с логистической регрессией. У меня сильно несбалансированные классы (примерно 1,5% от Y = 1).

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

Двумя стандартными модулями VIM для выбора функций с помощью RF являются VIM Gini и VIM перестановки. Грубо говоря, VIM Джини интересующего предиктора представляет собой сумму по лесу уменьшений примеси Джини, генерируемую этим предиктором всякий раз, когда он был выбран для разделения, масштабируемый по количеству деревьев.

Мой вопрос: реализован ли такой метод в scikit-learn (например, в пакете R party)? Или, может быть, обходной путь?

PS: этот вопрос связан с другой.


person gowithefloww    schedule 08.07.2015    source источник


Ответы (2)


scoring - это просто инструмент оценки производительности, используемый в тестовом примере, и он не входит во внутренний DecisionTreeClassifier алгоритм на каждом узле разделения. Вы можете указать только criterion (вид функции внутренних потерь на каждом разбитом узле) как gini или information entropy для алгоритма дерева.

scoring можно использовать в контексте перекрестной проверки, где целью является настройка некоторых гиперпараметров (например, max_depth). В вашем случае вы можете использовать GridSearchCV для настройки некоторых из ваших гиперпараметров с помощью функции оценки roc_auc.

person Jianxun Li    schedule 08.07.2015
comment
Я отредактировал свой первоначальный вопрос, который был сбит с толку (потому что я был самим собой). Надеюсь, теперь стало понятнее !. - person gowithefloww; 08.07.2015

После некоторых исследований я пришел к следующему:

from sklearn.cross_validation import ShuffleSplit
from collections import defaultdict

names = db_train.iloc[:,1:].columns.tolist()

# -- Gridsearched parameters
model_rf = RandomForestClassifier(n_estimators=500,
                                 class_weight="auto",
                                 criterion='gini',
                                 bootstrap=True,
                                 max_features=10,
                                 min_samples_split=1,
                                 min_samples_leaf=6,
                                 max_depth=3,
                                 n_jobs=-1)
scores = defaultdict(list)

# -- Fit the model (could be cross-validated)
rf = model_rf.fit(X_train, Y_train)
acc = roc_auc_score(Y_test, rf.predict(X_test))

for i in range(X_train.shape[1]):
    X_t = X_test.copy()
    np.random.shuffle(X_t[:, i])
    shuff_acc = roc_auc_score(Y_test, rf.predict(X_t))
    scores[names[i]].append((acc-shuff_acc)/acc)

print("Features sorted by their score:")
print(sorted([(round(np.mean(score), 4), feat) for
              feat, score in scores.items()], reverse=True))

Features sorted by their score:
[(0.0028999999999999998, 'Var1'), (0.0027000000000000001, 'Var2'), (0.0023999999999999998, 'Var3'), (0.0022000000000000001, 'Var4'), (0.0022000000000000001, 'Var5'), (0.0022000000000000001, 'Var6'), (0.002, 'Var7'), (0.002, 'Var8'), ...]

Результат не очень сексуальный, но идея вы поняли. Слабость этого подхода в том, что важность функции кажется очень зависимой от параметров. Я запустил его, используя разные параметры (max_depth, max_features ..), и получил много разных результатов. Поэтому я решил запустить поиск по сетке по параметрам (scoring = 'roc_auc'), а затем применить этот VIM (Variable Importance Measure) к лучшей модели.

Я черпал вдохновение из этой (великолепной) записной книжки .

Все предложения / комментарии приветствуются!

person gowithefloww    schedule 08.07.2015
comment
Спасибо, что поделились последней ссылкой. - person Simone; 09.07.2015
comment
Необходимо импортировать roc_auc_score: from sklearn.metrics import roc_auc_score - person lstodd; 21.10.2019