Я разрабатываю модель случайного леса двоичного классификатора, используя Python и scikitlearn, в которой я хотел бы получить вероятность того, что мой тестовый набор будет одной из двух меток. Насколько я понимаю, предиктор_проба(xtest) даст мне следующий результат:
Number Of Trees Voted For Classifier / Number Of Trees
Я считаю это слишком неточным, поскольку некоторые узлы дерева могли разделить мои (недетерминированные) выборки на довольно точные листья (100 класс a, 0 класс b) и неточные листья (5 класс a, 3 класс b). Мне бы хотелось реализовать «вероятность», которая принимает общее количество выборок в моих выходных листьях n-классификаторов в качестве доминатора, а общее количество общего выбранного классификатора в выходных листьях в качестве числителя (даже для деревьев и их выходных листьев который выбрал класс, которого не сделало большинство деревьев).
Например (простой):
2 дерева:
Tree 1:
--- 5, 0 Class A (Chosen)
10
--- 2, 3 Class B (Unchosen)
Tree 2:
--- 3, 2 Class A (Chosen)
10
--- 5, 0 Class B (Unchosen)
predict_proba
результаты:
Number of Trees that chose Class A (2) / Number of Trees (2) = 1.0
Желаемые результаты:
Number of Class A Samples in Output Leaves (8) / Total Number Samples in Output Leaves (10) = 0.8
Есть ли у кого-нибудь какие-либо знания о том, как это сделать, или о реализации, которую они используют?
У меня была идея перебрать каждое дерево, получить их вероятности и усреднить их. Однако это приведет к более высокому смещению выходных листов с меньшим количеством выборок (стиль коллегии выборщиков).
Как получить прямой доступ к количеству образцов и их классам выходного листа дерева решений для конкретного образца (или даже просто к индексу листьев и идти оттуда)? А в случае случайного леса их суммирование и усреднение?
Если не полностью переключить платформу/библиотеку? А может просто провернуть количество классификаторов (не оптимально)?
Некоторая потенциально полезная документация?:
dtc.tree_.n_node_samples
dtc.tree_[node_index].n_node_samples ?
🤔 А знаете ли вы, что...
Python обладает обширной документацией и активным сообществом разработчиков.
Я считаю это слишком неточным, поскольку некоторые узлы дерева могли разделить мои (недетерминированные) выборки на довольно точные листья (100 класс a, 0 класс b) и неточные листья (5 класс a, 3 класс b).
Как и в случае с деревьями решений в ансамбле Бэггинга, отдельные ученики дерева решений в случайном лесу обычно полностью расширяются, а не сокращаются. Это предпочтительная методология Hastie et al. в ЭСЛ. Настройки по умолчанию для sklearn.ensemble.RandomForestClassifier
приводят к полностью развернутому дереву. Это означает, что каждое дерево идеально соответствует своим обучающим данным, а энтропия в конечных узлах будет равна нулю (при условии, что для одних и тех же точек выборки нет зашумленных выборок с разными метками). Поэтому с настройками по умолчанию ваш пример просто не может произойти.
В противном случае, если вы ограничиваете свои отдельные деревья, указав соответствующий параметр max_depth
или min_samples_leaf
, вы запрашиваете просто другой алгоритм, чем алгоритм случайного леса, описанный Брейманом и Катлером и реализованный sklearn
. Мне не известна ни одна библиотека, предлагающая такой интерфейс. Однако достичь того, что вы ищете, было бы относительно тривиально, особенно если у вас есть хорошие практические знания алгоритма. Вам просто нужно изменить тип возвращаемого значения метода predict
дерева решений, а затем реорганизовать логику получения большинства голосов в случайном лесу. Незначительные изменения при условии, что у вас есть рабочие реализации модулей «Дерево решений» и «Случайный лес».
А может просто провернуть количество классификаторов (не оптимально)?
Я не уверен, как это поможет вам в целом и в частности в том, что вы, кажется, хотите сделать. При наличии большего количества классификаторов вы по-прежнему будете получать большинство голосов в Случайном лесу, только голосование будет осуществляться за более крупный ансамбль. Более того, в пределе вы можете оказаться в худшем положении: хотя редко у людей возникают проблемы со слишком большим и переоснащаемым ансамблем RandomForest, это может случиться, и слишком много деревьев в лесу может привести к окончательной модели RandomForest с избыточная дисперсия.
Если вы хотите поработать с реализацией sklearn
, то, я думаю, вам следует найти большую часть необходимой для начала информации в разделе Понимание структуры дерева решений. Например, у DecisionTreeClassifier
есть атрибут tree_
, который указывает на экземпляр класса Tree
— представления двоичного дерева решений на основе массива. Этот участник предоставляет доступ к ряду атрибутов низкого уровня, таких как max_depth
или интересующих вас атрибутов tree_.value
. Как указано в документации:
tree_.value array
— это трехмерный массив формы[n_nodes, n_classes, n_outputs]
, который обеспечивает количество образцов, достигающих узла, для каждого класса и для каждого выхода. Каждый узел имеет массив значений, который представляет собой количество взвешенных выборок, достигающих этого узла, для каждого выхода и класса.
Я бы также предложил взглянуть на метод decision_path
RandomForestClassifier
и DecisionTreeClassifier
. Наконец, вы должны спросить себя, действительно ли вам нужна эта функциональность? Есть ли у вас статистическое обоснование того, почему эта модификация улучшит производительность классификаторов? Есть ли конкретная проблема, которую вы пытаетесь решить с помощью этого подхода?
У меня была идея перебрать каждое дерево, получить их вероятности и усреднить их. Однако [...]
Именно так работают склеарнные случайные леса, так называемое «мягкое голосование». Например. из Руководства пользователя:
В отличие от оригинальной публикации [B2001], реализация scikit-learn объединяет классификаторы путем усреднения их вероятностного прогноза вместо того, чтобы позволить каждому классификатору голосовать за один класс.
Тем не менее, если вы хотите, чтобы размеры выборки в листьях имели эффект, вам придется проделать некоторую ручную работу. Вы можете использовать лесной метод apply, чтобы получить индексы листьев, а затем использовать древовидную структуру, на которую вы с Апанасовым ссылались, в частности атрибуты n_node_samples
и values
.