0x00 сводка
В этой статье мы попытаемся использовать простой для понимания способ, максимально не используя математические формулы, а исходя из общей идеи, используя перцептивное и интуитивное мышление для объяснения.интегрированное обучение. А конкретные сценарии приложений расширены из известной книги, чтобы помочь вам углубить эту концепцию.
В процессе машинного обучения будет много непонятных понятий и множество связанных с ними математических формул, которые очень сложно понять каждому. Столкнувшись с похожей ситуацией, мы должны начать думать с интуитивной точки зрения, используя аналогии или примеры для иллюстрации.Партнер, что часто приводит к лучшим результатам.
В процессе объяснения и изложения я ставлю перед собой требования: найти пример в жизни или в известной книге, а затем объяснить его своими словами.
0x01 Связанные концепции
1. Смещение против дисперсии
- Квадрат смещения, который представляет собой разницу между средним прогнозом для всех наборов данных и ожидаемой функцией регрессии.
- Дисперсия, которая измеряет, насколько хорошо решение, данное моделью, колеблется вокруг среднего значения для отдельных наборов данных.
дисперсияОн измеряет изменение эффективности обучения, вызванное изменением обучающей выборки того же размера, и измеряет степень изменения результата оценки алгоритма обучения при столкновении с разными обучающими выборками того же размера (ошибка, связанная с выборка наблюдения, которая отображает точность и специфичность алгоритма обучения: высокая дисперсия означает слабое совпадение), которая фиксирует влияние возмущений данных.
ПредвзятостьОн измеряет степень отклонения между ожидаемым предсказанием алгоритма обучения и фактическим результатом, а также измеряет степень, в которой средний оценочный результат определенного алгоритма обучения может приблизиться к цели обучения (независимо от ошибки обучающей выборки, он описывает точность и качество сопоставления: высокое смещение означает плохое совпадение), что характеризует способность самого алгоритма обучения к подгонке.
Лучший пример в Интернете - это пример цели, вы можете пойти и посмотреть
- Высокая дисперсия, низкое смещение соответствует тому, что все точки попадают в яблочко, но разбросаны, поэтому цель точная, но рука не обязательно стабильна.
- Низкая дисперсия, высокий уклон соответствует тому, что точки очень сконцентрированы, но не обязательно в яблочко, рука очень стабильна, но прицеливание не точное.
Вот попытка объяснить эти две концепции из Water Margin.
2. Возьмите Ляншань в качестве примера, чтобы популярно сказать «дисперсия».
比如说五虎将,武力平均值就是呼延灼,其下是秦明,董平;其上是林冲,关胜。
假设武力值是 秦明 95,董平 96,呼延灼 97,关胜 98,林冲 99
针对这个样本,其方差就是秦明,董平,林冲,关胜这四人的武力值和呼延灼差距多少。
如果都和呼延灼需要大战八百回合才能分出胜负,那么说明方差小。如果大战三百合就能分出胜负,那说明方差大。
3. Возьмите Ляншань в качестве примера, чтобы сказать, что предвзятость
假设马军八骠骑的武力值如下:徐宁 92、索超 90、张清 86、朱仝 90、史进 88、穆弘 85,花荣 90、杨志 95。
如果有一个模型,用八骠骑来拟合五虎将。这个模型是:任意选取一个八骠骑来拟合。( 实际工作中偏置应该是取八骠骑平均值,这里偏置是任选一个,是为了说明方便 )
如果用杨志来拟合五虎将,则最能逼近五虎将,这时候偏置小。如果选出的是穆弘,则偏置最大。
对于没遮拦穆弘,大家估计都是只知其名不知其事,可见其武力值最低。
当然穆弘的故事可能是在古本《水浒》有,但是后来世代相传中从今本《水浒》中被删除,所以被低视。
水浒故事有系统的文字记录首见《宣和遗事》。该书讲述先后落草太行山梁山、后来《水浒》说成是入伙鲁西梁山泊的人物共三十八名。其中的没遮拦穆横无疑就是《水浒》中的穆弘。
《宣和遗事》中的穆横是押运花石纲的十二指使之一。这十二人因公务而结义,后又因营救杨志而同往太行山落草,遂成为开创山寨的基本成员。《水浒传》处理这十二指使,有八人是和穆横完全一样待遇的(林冲、花荣、张清、徐宁、李应、关胜、孙立、杨志)。
这八人全都在《水浒》里成了独当一面的人物。如果一切顺应传统去发展,穆弘总不致变成一个有名无实的空白人物。
Далее следует «Наследие Сюаньхэ».
Во-первых, когда Чжу Юнь перевозил Хуа Шигана, его отправили к озеру Тайху и в другие места двенадцать человек, в том числе Ян Чжи, Ли Цзиньи, Линь Чун, Ван Сюн, Хуа Жун, Чай Цзинь, Чжан Цин, Сюй Нин, Ли Ин, Му Хэн, Гуань Шэн и Сунь Ли, заключенный нес цветы и камни.
Двенадцать получили текст и стали братьями, поклявшись спасти друг друга в случае бедствия. Ли Цзиньи и еще десять человек прибыли в столицу, чтобы перевезти цветочные камни; только Ян Чжи был в Инчжоу, ожидая прибытия Сунь Ли, и там был завал снега. Как насчет снежной сцены: чайный дым в доме монаха влажный, а спиртное в караоке слабое. Затем Ян Чживэй ждал прихода Сунь Ли, а дни были снежные, он путешествовал в нищете и без фруктов, поэтому ему пришлось продать заветный нож с рынка. Цена никогда не подлежит обсуждению. По пути в Рибу он встретил злого молодого человека, который хотел продать заветный меч, и они сражались друг с другом Ян Чжи полоснул молодого человека ножом, и его шея упала с ножом. Ян Чжи попал под ярмо, принял уведомление и отправил его в тюрьму для расследования. После закрытия дела префект сказал: «Хотя Ян Чжиши большой человек, его чувства поистине жалки. Сожгите все семейное прошлое Ян Чжигао и сопоставьте его с военным городом Вэйчжоу». Когда он шел во второй раз, он наткнулся на ханьца и закричал: «Директор Ян!» Ян Чжи поднял глаза, но узнал командира Сунь Ли. Сунь Ли был удивлен: «Как я могу совершить преступление?» Ян Чжи один за другим рассказывал Сунь Ли о продаже ножей для убийства людей. Скажи, все идут. Этот Сунь Ли подумал в своем сердце: "Ян Чжиинь ждал меня и совершил это преступление. Когда он был женат, он поклялся спасти его в беде". и другие, чтобы узнать причину преступления Ян Чжи. Ли Цзиньи обсудил это с Сунь Ли, и одиннадцать братьев отправились на берег Хуанхэ, дождались прихода Ян Чжи, убили солдат, выступающих против шпионажа, и отправились на гору Тайхан, чтобы попасться на удочку пиратов.
0x02 ансамблевое обучение
1. Зачем интегрировать
В теории ансамблевого обучения мы называем слабых учащихся (или базовые модели) «моделями», которые можно использовать в качестве строительных блоков для разработки более сложных моделей. В большинстве случаев эти базовые модели не очень хорошо работают сами по себе либо потому, что они имеют высокие смещения (например, модели с низкой степенью свободы), либо потому, что их дисперсия слишком велика, чтобы быть надежной сильной (например, модели с высокой степенью свободы).
Например, существуют определенные различия между слабыми классификаторами (такие как разные алгоритмы или разные конфигурации параметров для одного и того же алгоритма), которые приведут к разным границам решений классификации, а это означает, что они будут делать разные ошибки при принятии решений.
Идея методов ансамбля состоит в том, чтобы создать «сильного ученика» (или «модель ансамбля») путем объединения предубеждений и/или отклонений этих слабых учеников, что приводит к повышению производительности.
Ансамблевое обучение — это парадигма машинного обучения. Основная идея такова: «Три сапожника превзошли Чжугэ Ляна». "Единство это сила". «Учиться на сильных сторонах других».
При ансамблевом обучении мы обучаем несколько моделей (часто называемых «слабыми учениками») для решения одной и той же задачи и объединяем их для получения лучших результатов. Наиболее важным предположением является то, что при правильном сочетании слабых моделей мы можем получить более точные и/или надежные модели.
Мы можем сделать обобщение идеи ансамблевого обучения. Для данных тренировочного набора мы можем, наконец, сформировать сильного ученика, обучив нескольких отдельных учеников и используя определенную комбинированную стратегию, чтобы достичь цели обучения на сильных сторонах других.
-
Ансамблевое обучение строит набор базовых классификаторов из обучающих данных, а затем классифицирует путем голосования по прогнозам каждого базового классификатора.
-
Строго говоря, ансамблевое обучение — это не классификатор, а метод объединения классификаторов.
-
Если один классификатор сравнивается с лицом, принимающим решения, метод ансамблевого обучения эквивалентен тому, что несколько лиц, принимающих решения, принимают решение вместе.
2. Классификация
Для классификации ансамблевого обучения существует два общих метода классификации:
Категория 1
Отдельных учащихся можно разделить на две категории в зависимости от того, существует ли зависимость между отдельными учащимися:
- Между отдельными учащимися существует сильная зависимость, и серию отдельных учащихся в основном необходимо генерировать последовательно, а репрезентативным алгоритмом является повышающая серия алгоритмов;
- Между отдельными учащимися нет сильной зависимости, и ряд отдельных учащихся может быть сгенерирован параллельно.Репрезентативными алгоритмами являются алгоритмы мешков и алгоритмов серии Random Forest.
Категория 2
В соответствии с соотношением между основными классификаторами ансамблевое обучение можно разделить на гетерогенное ансамблевое обучение и гомоморфное ансамблевое обучение.
-
Гетерогенное ансамблевое обучение относится к разнице между слабыми классификаторами;
-
Гомоморфное ансамблевое обучение означает, что сами слабые классификаторы одинаковы, но параметры разные.
3. Основные вопросы
Есть две основные проблемы с ансамблевым обучением, которые необходимо решить:
1) Как тренировать каждый алгоритм? То есть, как получить несколько отдельных учеников.
2) Как интегрировать каждый алгоритм? То есть, как выбрать комбинированную стратегию, чтобы собрать этих отдельных учеников в сильного ученика.
Как получить индивидуального ученика?
В основном из следующих пяти аспектов:
- Различен тип самого базового классификатора, то есть алгоритм его составления;
- Различная обработка данных, такая как бустинг, бэггинг, суммирование, перекрестная проверка, тест на выносливость;
- Обработка и выбор входных признаков;
- Обработать выходные результаты, такие как код исправления ошибок, предложенный некоторыми учеными;
- Ввести случайные помехи;
Важный момент: наш выбор слабых учеников должен соответствовать тому, как мы объединяем эти модели. Если мы решим иметьнизкое смещение, высокая дисперсия, мы должны использовать метод агрегирования, который имеет тенденцию уменьшать дисперсию, тогда как, если мы решим иметьнизкая дисперсия, высокое смещение, мы должны использовать метод агрегирования, который имеет тенденцию уменьшать систематическую ошибку.
Как выбрать стратегию связывания
После того, как слабые ученики выбраны, нам все еще нужно определить, как они подходят (какую информацию из предыдущей модели следует учитывать при подборе текущей модели?) и как агрегировать (как агрегировать текущую модель в предыдущую модель?).
Напрашивается вопрос, как совместить эти модели. Мы можем использовать три основных «мета-алгоритма», направленных на объединение слабых учеников:
-
Бэггинг, который обычно рассматривает однородных слабых учеников, изучает этих слабых учеников параллельно, независимо друг от друга, и объединяет их в соответствии с некоторым детерминированным процессом усреднения.
-
Повышение, которое обычно рассматривает однородных слабых учащихся. Он последовательно изучает этих слабых учеников (каждая базовая модель зависит от предыдущей модели) в высоко адаптивном подходе и объединяет их в соответствии с некоторой детерминированной стратегией.
-
Наложение, этот метод обычно рассматривает разнородных слабых учеников, изучает их параллельно и объединяет их путем обучения «метамодели» для вывода окончательного результата прогнозирования в соответствии с результатами прогнозирования различных слабых моделей.
Грубо говоря, мы можем сказать, что бэггинг направлен на получение модели ансамбля с меньшей дисперсией, чем ее компоненты, тогда как бустинг и суммирование в основном будут создавать сильные модели с более низким смещением, чем ее компоненты (даже дисперсия может быть уменьшена).
Мы можем видеть, как стратегия комбинирования применяется в Water Margin.
梁山要打某座州府,究竟用什么办法呢?
听吴学究的嘛?
吴学究在生辰纲的表现实在不行,漏洞太多。打大名府等也基本就是一招:事先混进城里,然后里应外合。
所以还是应该集思广益,采用集成学习。
可以采用两个办法
办法1
神机军师朱武,混江龙李俊,智多星吴用,入云龙公孙胜,混世魔王樊瑞五个人都分别出一个主意,然后投票选出一个综合方案。
方法2
吴用先出一个主意,然后朱武针对这个主意做些调整补漏,给出了一个新主意。李俊再针对朱武的主意进行修补,给出了第三个主意...... 最后给出一个最终主意。
办法1 就是bagging方式的近似模拟
办法2 就是boosting方式的近似模拟
0x03 Bootstrap
Прежде всего, нам нужно представить Bootstrap, который на самом деле является не интегрированным обучением, а статистическим методом, который принадлежит пионеру интегрированного обучения.
Boostrap означает ремешки ботинок. Название происходит от «подтянуть свои собственные бустеры», что означает улучшить себя, потянув за ботинки. Первоначально это означало нечто, что не могло произойти, но позже превратилось в улучшение вещей с помощью ваши собственные усилия хорошо. Помещение его в комбинированный классификатор означает повышение производительности классификации за счет самого классификатора.
Bootstrap — это метод выборки.
Люди хотят получить всю информацию о целом, потому что тогда они могут заниматься «стратегическим планированием» — целое знает, есть ли какой-то образец, который мы не можем уловить? На самом деле получить общую информацию сложно или даже невозможно, поэтому в статистике присутствует «выборка». Другими словами, мы можем получить информацию только о некоторых выборках в целом, и ожидается, что эта ограниченная информация о выборке может быть использована для максимально точной оценки генеральной совокупности, чтобы обеспечить основу для принятия решений. Метод Bootstrap полагает, что, поскольку полученные выборки «вытягиваются» из совокупности, почему нельзя рассматривать эти выборки как единое целое, из которогоповторно извлекатьШерстяная ткань? Этот метод кажется простым, но на самом деле он очень эффективен.
Конкретный метод:
(1)采用重复抽样的方法每次从n个原始样本中抽取m个样本(m自己设定)
(2)对于m个样本计算统计量
(3)重复步骤(1)(2)N次(N一般大于1000),这样就可以算出N个统计量
(4)计算这N个统计量的方差
比如说,我现在要对一些未知样本做分类,分类算法选取一种,比如SVM。我要估计的总体参数是准确率(accuracy)。对于n个原始样本,从步骤(1)开始,每次对抽取出的样本用SVM训练出一个模型,然后用这个模型对未知样本做分类,得到一个准确率。重复N次,可以得到N个准确率,然后对计算出的N个准确率做方差。
为什么要计算这N个统计量的方差而不是期望或者均值。方差表示的是一组数据与其平均水平的偏离程度,如果计算的方差值在一定范围之内,则表示这些数据的波动不是很大,那么他们的均值就可以用来估计总体的参数,而如果方差很大,这些样本统计量波动很大,那么总体的参数估计就不太准确?
Это кажется слишком простым, поэтому причина, по которой автору Эфрона отказали, когда он представил свою рукопись в топовые статистические журналы, — «слишком простая».
Bootstrap предоставляет только идею комбинированного метода, который заключается в комплексном анализе результатов обучения базового классификатора и других названий, таких как бэггинг. Повышение является конкретным выводом комбинаторного подхода. Итак, начиная с метода Bootstrap, мы импортируем его в ансамблевое обучение.
Метод упаковки 0x04
Бэггинг, сокращенно от Boostrap агрегация, также известная как самопомощь агрегация, представляет собой метод многократной выборки (с заменой) из данных в соответствии с однородным распределением вероятностей.Что касается того, почему это называется агрегацией начальной загрузки, потому что она использует метод начальной загрузки при извлечении обучающих выборок!
Размер набора выборок подобучения такой же, как у исходного набора данных. При построении обучающих выборок каждого подклассификатора, поскольку исходный набор данных отбирается с заменой, одни и те же данные выборки могут появляться несколько раз в одном и том же наборе обучающей выборки.
1. Процесс стратегии упаковки
- Используйте выборку Bootstrap для выбора n обучающих выборок из набора выборок (верните их обратно, потому что другие классификаторы также будут использовать их при выборке обучающих выборок).
- Для всех атрибутов обучите классификатор (CART или SVM или...) с этими n выборками.
- Повторите два вышеуказанных шага m раз, вы можете получить m классификаторов (CART или SVM или...)
- Прогоните данные по этим m классификаторам, и, наконец, механизм голосования (большинство подчиняется меньшинству) увидит, к какой категории оно принадлежит (проблема классификации)
- Для задач классификации: результаты классификации генерируются голосованием; для задач регрессии: среднее значение результатов прогнозирования n моделей используется в качестве окончательного результата прогнозирования. (одинаковое значение для всех моделей)
2. Кратко о методе упаковки
- Бэггинг улучшает ошибку обобщения за счет уменьшения дисперсии базового классификатора.
- Его производительность зависит от стабильности базового классификатора; если базовый классификатор нестабилен, бэггинг помогает уменьшить ошибку, вызванную случайными флуктуациями обучающих данных; если он стабилен, ошибка ансамблевого классификатора в основном вызвана смещением базовый классификатор
- Поскольку каждая выборка имеет одинаковую вероятность быть выбранной, пакетирование не фокусируется на каком-либо конкретном экземпляре в наборе обучающих данных.
0x05 Случайный лес
Случайный лес — это ансамбль, который сочетает в себе идею Брейманса «объединение начальной загрузки» и «метод случайных подпространств» Хо для построения деревьев решений. которыйБэггинг + деревья решений = случайный лес. Это случайный выбор k функций из дерева решений с m функциями для формирования n деревьев решений, а затем выбор режима результатов прогнозирования (если это проблема регрессии, выберите среднее значение).
1. Как применять функции бэггинга
Предполагая, что в общей сложности N образцов и M признаков, давайте взглянем на различные особенности Бэгинга.
Выборка с помощью Bootstrap (приложение с функцией упаковки):Каждое дерево имеет случайно выбранную обучающую выборку, которая заменяется.Здесь 2/3 выборок выбираются случайным образом в качестве обучающей выборки, а затем есть случайно выбранные m признаков, которые заменяются в качестве основы для ветвей дерева.
случайный:Один из них - случайный выбор образца(Приложение функции упаковки), один заключается в случайном выборе функций. Это строит дерево. Затем из случайно выбранных признаков выбирается оптимальный. Это может сделать деревья решений в случайном лесу отличными друг от друга, повысить разнообразие системы и, таким образом, повысить эффективность классификации.
Выберите лучшие функции:Настоящая сила случайного леса заключается не в том, что он объединяет несколько деревьев для получения конечного результата, а в том, что деревья в лесу продолжают становиться лучше в процессе итерации (деревья в лесу используют лучшие свойства для ветвления).
Повторите, чтобы получить несколько классификаторов (приложение функции «Бэгинг»):Выполните вышеуказанные шаги итеративно несколько раз, чтобы постепенно удалять относительно плохие объекты, каждый раз создавая новый лес, пока количество оставшихся объектов не станет равным m. Предположим, что выполняется x раз, в результате получается x лесов.
Голосование (приложение с функцией бэггинга):Используйте оставшуюся 1/3 выборок (также называемых выборками из пакета) в качестве тестового набора, чтобы делать прогнозы для итерированных x лесов. Предсказав результаты всех выборок, сравните их с реальными значениями и выберите лес с наименьшей частотой ошибок вне корпуса в качестве окончательной модели случайного леса.
2. Выберите выдающиеся функции
заВыберите лучшие функцииЭто нужно объяснить еще раз.
Идея случайного леса состоит в том, чтобы строить хорошие деревья, а хорошим деревьям нужны хорошие характеристики. Затем нам нужно знать важность каждой функции. Для каждого дерева есть функция.Чтобы узнать, играет ли функция роль в этом дереве, вы можете случайным образом изменить значение этой функции, чтобы «не имело значения, имеет ли эта функция эту функцию в этом дереве», и затем сравните до и после изменения Частота ошибок тестового набора, разница частоты ошибок используется как важность признака в дереве, а тестовый набор — это оставшиеся выборки (выборки из пакета) после выполняется выборка дерева (ошибка, вызванная отсутствием выборки в тестовом наборе, называется ошибкой отсутствия упаковки).
В дереве каждая функция вычисляется один раз, и можно рассчитать важность каждой функции в дереве. Мы можем рассчитать, насколько важны функции всех деревьев в соответствующих деревьях. Но это может представлять только важность этих признаков в дереве, а не важность признаков во всем лесу. Так как же рассчитать важность каждой функции в лесу?Каждая функция появляется в нескольких деревьях, и среднее значение важности значения этой функции в нескольких деревьях является важностью функции в лесу. Это придает важность всем особенностям леса. Отсортируйте все объекты по их важности, удалите в лесу некоторые объекты с низкой важностью и получите новый набор признаков. На данный момент это эквивалентно тому, что мы вернулись к исходной точке, что является истинным завершением итерации.
0x06 Способ повышения
Основная идея «Бустирования» состоит в том, чтобы в каждом раунде базового ученика уделять больше внимания неверным образцам предыдущего раунда в процессе обучения..
Методы бустинга работают так же, как и методы бэггинга: мы создаем серию моделей и объединяем их, чтобы получить более эффективного сильного ученика. Однако, в отличие от бэггинга, который фокусируется на снижении дисперсии, бустинг фокусируется на последовательной подгонке нескольких слабых учеников высокоадаптивным способом: каждая модель в последовательности уделяет больше внимания тем последовательностям во время подбора наблюдений, с которыми предыдущие модели плохо справлялись.
Повышение — это итеративный алгоритм, который обучает разные классификаторы (слабые классификаторы) для одного и того же обучающего набора, а затем выполняет классификацию с малыми весами для правильно классифицированных выборок и большими весами для неправильно классифицированных выборок (обычно выборки вблизи границы). классификатор представляет собой линейную суперпозицию (взвешенную комбинацию) многих слабых классификаторов, и классификатор довольно прост. По сути, это простой процесс усиления слабого алгоритма классификации.
В процессе добавления образцов каждый раз обычно присваиваются разные веса в соответствии с точностью их классификации в предыдущем раунде. Данные часто повторно взвешивают, чтобы усилить классификацию ранее неправильно классифицированных точек данных.
По мере запуска каждой модели Boost отслеживает, какие выборки данных были наиболее успешными, а какие нет. Наборы данных с наибольшим количеством ошибочно классифицированных результатов получают больший вес. Эти данные считаются более сложными и требуют большего количества итераций для правильного обучения модели.
На этапе фактической классификации бустинг также по-разному обрабатывает модель. При повышении частота ошибок модели отслеживается по мере того, как лучшим моделям присваиваются лучшие веса. То есть чем меньше ошибка слабого классификатора, тем больше вес. Таким образом, когда происходит «голосование», например, бэггинг, модель с лучшими результатами имеет более сильное влияние на окончательный результат.
0x07 AdaBoost
Из-за различных используемых функций потерь алгоритм Boosting имеет разные типы.AdaBoost — это алгоритм Boosting, функция потерь которого представляет собой экспоненциальную потерю. Причина использования экспоненциальных потерь заключается в том, что каждый раунд минимизации экспоненциальных потерь фактически обучает модель логистической регрессии, которая аппроксимирует логарифмические шансы.
1. Два основных вопроса
Алгоритм повышения — это процесс обновления «слабого алгоритма обучения» до «сильного алгоритма обучения». Алгоритм, реализуемый идеей Boosting, должен решить две основные проблемы.
- Как выбрать набор слабых учеников с разными сильными и слабыми сторонами, чтобы они могли дополнять друг друга.
- Как объединить результаты слабых учеников, чтобы в целом повысить эффективность принятия решений.
Этим двум проблемам соответствуют аддитивная модель и алгоритм прямого шага.
- Аддитивная модель означает, что сильный классификатор формируется путем линейного добавления ряда слабых классификаторов.
- Шаг вперед означает, что в процессе обучения классификатор, сгенерированный следующей итерацией, обучается на основе предыдущего раунда.
Алгоритм прямого распределенияСкажите: «Я могу предоставить структуру, независимо от формы базовой функции и функции потерь, пока ваша модель является аддитивной моделью, вы можете следовать указаниям моей структуры, чтобы решить ее». Алгоритм прямого шагаОбщий метод изучения аддитивной модели.Различные формы базисных функций и разные формы функций потерь могут использовать этот общий метод для нахождения оптимальных параметров аддитивной модели.Это метаалгоритм.
Идея прямого пошагового алгоритма такова: в аддитивной модели есть M базисных функций и M соответствующих коэффициентов, и каждый раз можно изучать одну базисную функцию и ее коэффициенты спереди назад.
2. Решение AdaBoost
Выберите слабого ученика
чтобы решитьПервый вопрос, подход AdaBoost заключается в изменении веса образцов в конце каждого раунда. Таким образом, AdaBoost позволяет каждому вновь добавленному слабому учащемуся отражать некоторые новые закономерности в данных.
Для этого AdaBoost поддерживает распределение веса для каждой обучающей выборки. То есть для любой выборки xi существует соответствующее ей распределение D(i), представляющее важность этой выборки.
При измерении успеваемости слабых учащихся AdaBoost учитывает вес каждого образца. Неправильно классифицированные образцы с большими весами будут вносить больший вклад в частоту ошибок обучения, чем неправильно классифицированные образцы с меньшими весами. Чтобы получить меньшую взвешенную частоту ошибок, слабый классификатор должен больше ориентироваться на выборки с большим весом, чтобы гарантировать точные прогнозы по ним.
Вы также можете понять смысл увеличения веса точки ошибки таким образом.: когда «следующий классификатор» снова неправильно классифицирует эти точки, это увеличит общую частоту ошибок «следующего классификатора», что приведет к тому, что «следующий классификатор» будет иметь очень маленький вес, что в конечном итоге приведет к этой классификации. вес классификатора во всем смешанном классификаторе становится меньше.
Изменяя вес D(i) выборки, распределение вероятностей выборки также изменяется, фокусируясь на неправильно классифицированных выборках, уменьшая веса выборок, которые были правильно классифицированы в предыдущем раунде, и увеличивая те, которые были неправильно классифицированы. веса образцов. Это направляет слабого ученика к изучению различных частей обучающих образцов.
Во время обучения мы используем частоту ошибок слабого ученика в предыдущей итерации, чтобы обновить вес тренировочного набора и так далее.
Объединение слабых учеников
Теперь, когда у нас есть набор подготовленных слабых учеников с разными сильными и слабыми сторонами, как их эффективно объединить, чтобы они дополняли друг друга и производили более точный общий эффект прогнозирования? Этовторой вопрос.
Для второго вопроса AdaBoost использует метод голосования взвешенным большинством, чтобы увеличить вес слабых классификаторов с небольшой частотой ошибок классификации и уменьшить вес слабых классификаторов с большой частотой ошибок классификации. Это легко понять: слабые классификаторы с высокой точностью, конечно, должны иметь большее влияние на сильных классификаторов.
Каждый слабый ученик обучается с разным распределением веса Мы видим, что разным слабым ученикам назначаются разные задачи, и каждый слабый ученик старается изо всех сил выполнить данную задачу. Интуитивно, когда мы хотим объединить суждения каждого слабого ученика в окончательный результат прогнозирования, если слабый ученик преуспеет в предыдущей задаче, мы будем больше доверять ему, и наоборот, если слабый ученик Чем хуже выполнение предыдущей задачи, тем меньше мы в это верим.
Другими словами, мы объединяем взвешенные значения слабых учеников и присваиваем каждому слабому ученику значение wi, которое представляет собой степень уверенности, которая зависит от его результатов в поставленной задаче, чем лучше результаты, тем выше wi. меньше.
0x08 Получите пример из Water Margin, чтобы увидеть, как использовать ансамблевое обучение.
Давайте рассмотрим пример, чтобы подробно увидеть, как использовать концепцию ансамблевого обучения. Теперь Ляншань должен проголосовать, чтобы принять решение о приеме на работу. Сун Цзян сказал, что мы хотим принимать решения научно и демократично, поэтому мы используем новейшие технологии: интегрированное обучение.
1. Bagging
Первым соображением является метод упаковки
如果采用了bagging方法。样本有放回,而且投票可以并行。
每次抽取 5 个人投票是否接受。
第一次抽出 徐宁 、索超 、朱仝 、花荣、杨志。则 5 票都是 接受招安
第二次抽出 鲁智深,武松,朱贵,刘唐,李逵。则 5 票都是 反对招安
第三次抽出 徐宁 、索超,鲁智深,武松,阮小二。则 2 票接受,3 票反对,则这次样本是 反对招安。
最后综合三次的结果是:反对招安。
现在情况已经对招安不利了,如果再并行进行投票,那么对结果就更无法估计。
这样的话,对于是否招安就真的是梁山群体民主评议,公明哥哥和吴学究没办法后台黑箱操控了。
Если Сун Цзян хочет работать в «черном ящике», он не может использовать метод бэггинга, а должен выбрать бустинг, потому что выбор обучающей выборки этого алгоритма не является независимым манипулированием.
2. Boosting
Поэтому Сун Цзян решил применить метод повышения.Вы можете видеть, как Сун Цзян использует повышение, чтобы шаг за шагом корректировать предвзятость, чтобы наилучшим образом соответствовать окончательным ожиданиям «принятия на работу».
"Boosting"的基本思想是通过某种方式使得每一轮基学习器在训练过程中更加关注上一轮学习错误的样本
所以我们有两套方案。
方案一:每次每次剔除异常数值
方案二:每次调整异常数值权重
-----------------------------------------------------------------
方案一:每次剔除异常数值,这种适合宋江的样本全部无法控制的情况
迭代1
样本:鲁智深,武松,朱贵,刘唐,李逵。则 5 票都是 反对招安
宋江说:出家人与世无争,就不要参与投票了,改换为徐宁,索超两位兄弟。
宋江跟踪错误率,因为本次弱分类器误差太大,所以本次权重降低。
迭代2
样本:徐宁,索超,朱贵,刘唐,李逵。则 2 票接受,3 票反对,则这次样本是 反对招安
宋江说:铁牛兄弟不懂事,乱投票,来人乱棒打出去,换成杨志兄弟。
宋江跟踪错误率,因为本次弱分类器误差太大,所以本次权重降低。
迭代3
样本:徐宁,索超,朱贵,刘唐,杨志。则 3 票接受,2 票反对,则这次样本是 接受招安
宋江说:朱贵兄弟平时总是打点酒店,对于时政缺少认知,换成关胜兄弟。
宋江跟踪错误率,因为本次弱分类器误差较小,所以本次权重增加。
迭代4
样本:徐宁,索超,关胜,刘唐,杨志。则 4 票接受,1 票反对,则这次样本是 接受招安
宋江说:刘唐兄弟头发染色了,不利用梁山形象,换成花荣兄弟。
宋江跟踪错误率,因为本次弱分类器误差较小,所以本次权重增加。
迭代5
样本:徐宁,索超,关胜,花荣,杨志。则 5 票接受,则这次样本是 接受招安。
宋江跟踪错误率,因为本次弱分类器没有误差,所以本次权重增加。
即误差率小的分类器,在最终分类器中的重要程度大。
最后综合 5 次选举结果,梁山最后决定接受招安。
-----------------------------------------------------------------
方案二:每次降低异常数值权重,这种适合样本中有宋江可以控制的头领
迭代1
样本:武松,花荣,朱贵,杨志,李逵。则 2 票接受,3 票反对,则本次结论是 反对招安
宋江说:出家人与世无争,降低武松权重为 1/2 。
宋江跟踪错误率,因为本次弱分类器误差太大,所以本次权重降低。
迭代2
样本:武松(权重1/2),花荣,朱贵,杨志,李逵。则 2 票接受,2又1/2 票反对,则这次结论是 反对招安
宋江说:铁牛兄弟不懂事,乱投票,降低李逵权重为 1/2。
宋江跟踪错误率,因为本次弱分类器误差太大,所以本次权重降低。
迭代3
样本:武松(权重1/2),花荣,朱贵,杨志,李逵(权重1/2)。则 2 票接受,2 票反对,则这次结论是 无结论
宋江说:朱贵兄弟平时打点酒店,对于时政缺少认知,降低朱贵权重为 1/2。
宋江跟踪错误率,因为本次弱分类器无结论,所以本次权重为零。
迭代4
样本:武松(权重1/2),花荣,朱贵(权重1/2),杨志,李逵(权重1/2)。则 2 票接受,1又1/2 票反对,则这次结论是 接受招安
宋江说:这次好,花荣做过知寨,有见地,增加花荣权重。继续投票。
宋江跟踪错误率,因为本次弱分类器误差较小,所以本次权重增加。
迭代5
样本:武松(权重1/2),花荣(权重2),朱贵(权重1/2),杨志,李逵(权重1/2)。则 3 票接受,1又1/2 票反对,则这次结论是 接受招安
宋江说:这次好,杨志做过制使,有见地,增加杨志权重。继续投票。
宋江跟踪错误率,因为本次弱分类器误差较小,所以本次权重增加。
迭代6
样本:武松(权重1/2),花荣(权重2),朱贵(权重1/2),杨志(权重2),李逵(权重1/2)。则 4 票接受,1又1/2 票反对,则这次结论是 接受招安
宋江跟踪错误率,因为本次弱分类器误差较小,所以本次权重增加。
最后综合 6 次选举结果,梁山最后决定接受招安。
-----------------------------------------------------------------
这里能看出来,Boosting算法对于样本的异常值十分敏感,因为Boosting算法中每个分类器的输入都依赖于前一个分类器的分类结果,会导致误差呈指数级累积。
宋江每一次选择的训练集都依赖于上一次学习的结果。每次剔除异常数值 或者 调整异常数值权重。(在实际boosting算法中是增加异常数值的权重)。
宋江也根据每一次训练的训练误差得到该次预测函数的权重。
3. Почему бэггинг уменьшает дисперсию, а бустинг уменьшает предвзятость?
Смещение описывает разрыв между ожидаемым результатом прогнозирования вывода модели, подобранной в соответствии с выборкой, и фактическим результатом выборки, Проще говоря, насколько хорошо он соответствует выборке. Если вы хотите хорошо работать при смещении и низком смещении, вы должны усложнить модель и увеличить параметры модели, но это легко переобучить.
Дисперсия описывает производительность модели, обученной на выборке на тестовом наборе.Чтобы хорошо работать с дисперсией и низкой дисперсией, необходимо упростить модель и уменьшить параметры модели, но это легко недообучить ( неподходящий).
从我们例子能看出来。
1. Bagging
bagging没有针对性的对分类器进行调整,只是单纯的增加样本数量和采样次数,以此来让平均值逼近结果。
所以bagging的基模型应该本身就是强模型(偏差低方差高)。
所以,bagging应该是对许多强(甚至过强)的分类器求平均。在这里,每个单独的分类器的bias都是低的,平均之后bias依然低;而每个单独的分类器都强到可能产生overfitting的程度,也就是variance高,求平均的操作起到的作用就是降低这个variance。
2. Boosting
boosting就是为了让每一次分类器的结果逐渐接近期望目标。即宋江期望一步一步的boosting到最终接受招安这个结果。这样才能在样本上最好拟合“招安”这个期望结果,从最初的“拒绝招安”这个high bias过渡到“接受招安”这个期望结果。
boosting是把许多弱的分类器组合成一个强的分类器。弱的分类器bias高,而强的分类器bias低,所以说boosting起到了降低bias的作用。variance不是boosting的主要考虑因素。
Boosting 是迭代算法,每一次迭代都根据上一次迭代的预测结果对样本进行加权,所以随着迭代不断进行,误差会越来越小,所以模型的 bias 会不断降低。这种算法无法并行,例子比如Adaptive Boosting。
4. Bagging vs Boosting
Отсюда мы можем сравнить бэггинг и бустинг:
- С точки зрения выбора выборки: Бэгинг использует случайную выборку Bootstrap с заменой, и каждый обучающий набор независим, в то время как выбор повышающего обучающего набора не является независимым, и каждый раз выбираемый обучающий набор зависит от результатов предыдущего обучения. Если обучающая выборка не меняется, то меняется только вес каждой выборки.
- Вес выборки: Бэггинг использует равномерную выборку, и каждая выборка имеет одинаковый вес; Повышение корректирует вес выборки в соответствии с частотой ошибок, и чем больше частота ошибок, тем больше вес выборки.
- Функция прогнозирования: веса всех функций прогнозирования в Бэггинге равны, Повышение получает вес функции прогнозирования в соответствии с ошибкой обучения каждого обучения, Чем меньше ошибка, тем больше вес функции прогнозирования.
- Параллельные вычисления: Каждая функция предсказания Бэггинга может быть сгенерирована параллельно, каждая функция предсказания Буста должна быть итеративно сгенерирована по порядку.
0x09 код случайного леса
Заинтересованные учащиеся могут использовать код для демонстрации Бэгинга. Вот два кода.
один изblog.CSDN.net/Colou Body Lotion _ это…
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 26 16:38:18 2018
@author: aoanng
"""
import csv
from random import seed
from random import randrange
from math import sqrt
def loadCSV(filename):#加载数据,一行行的存入列表
dataSet = []
with open(filename, 'r') as file:
csvReader = csv.reader(file)
for line in csvReader:
dataSet.append(line)
return dataSet
# 除了标签列,其他列都转换为float类型
def column_to_float(dataSet):
featLen = len(dataSet[0]) - 1
for data in dataSet:
for column in range(featLen):
data[column] = float(data[column].strip())
# 将数据集随机分成N块,方便交叉验证,其中一块是测试集,其他四块是训练集
def spiltDataSet(dataSet, n_folds):
fold_size = int(len(dataSet) / n_folds)
dataSet_copy = list(dataSet)
dataSet_spilt = []
for i in range(n_folds):
fold = []
while len(fold) < fold_size: # 这里不能用if,if只是在第一次判断时起作用,while执行循环,直到条件不成立
index = randrange(len(dataSet_copy))
fold.append(dataSet_copy.pop(index)) # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
dataSet_spilt.append(fold)
return dataSet_spilt
# 构造数据子集
def get_subsample(dataSet, ratio):
subdataSet = []
lenSubdata = round(len(dataSet) * ratio)#返回浮点数
while len(subdataSet) < lenSubdata:
index = randrange(len(dataSet) - 1)
subdataSet.append(dataSet[index])
# print len(subdataSet)
return subdataSet
# 分割数据集
def data_spilt(dataSet, index, value):
left = []
right = []
for row in dataSet:
if row[index] < value:
left.append(row)
else:
right.append(row)
return left, right
# 计算分割代价
def spilt_loss(left, right, class_values):
loss = 0.0
for class_value in class_values:
left_size = len(left)
if left_size != 0: # 防止除数为零
prop = [row[-1] for row in left].count(class_value) / float(left_size)
loss += (prop * (1.0 - prop))
right_size = len(right)
if right_size != 0:
prop = [row[-1] for row in right].count(class_value) / float(right_size)
loss += (prop * (1.0 - prop))
return loss
# 选取任意的n个特征,在这n个特征中,选取分割时的最优特征
def get_best_spilt(dataSet, n_features):
features = []
class_values = list(set(row[-1] for row in dataSet))
b_index, b_value, b_loss, b_left, b_right = 999, 999, 999, None, None
while len(features) < n_features:
index = randrange(len(dataSet[0]) - 1)
if index not in features:
features.append(index)
# print 'features:',features
for index in features:#找到列的最适合做节点的索引,(损失最小)
for row in dataSet:
left, right = data_spilt(dataSet, index, row[index])#以它为节点的,左右分支
loss = spilt_loss(left, right, class_values)
if loss < b_loss:#寻找最小分割代价
b_index, b_value, b_loss, b_left, b_right = index, row[index], loss, left, right
# print b_loss
# print type(b_index)
return {'index': b_index, 'value': b_value, 'left': b_left, 'right': b_right}
# 决定输出标签
def decide_label(data):
output = [row[-1] for row in data]
return max(set(output), key=output.count)
# 子分割,不断地构建叶节点的过程
def sub_spilt(root, n_features, max_depth, min_size, depth):
left = root['left']
# print left
right = root['right']
del (root['left'])
del (root['right'])
# print depth
if not left or not right:
root['left'] = root['right'] = decide_label(left + right)
# print 'testing'
return
if depth > max_depth:
root['left'] = decide_label(left)
root['right'] = decide_label(right)
return
if len(left) < min_size:
root['left'] = decide_label(left)
else:
root['left'] = get_best_spilt(left, n_features)
# print 'testing_left'
sub_spilt(root['left'], n_features, max_depth, min_size, depth + 1)
if len(right) < min_size:
root['right'] = decide_label(right)
else:
root['right'] = get_best_spilt(right, n_features)
# print 'testing_right'
sub_spilt(root['right'], n_features, max_depth, min_size, depth + 1)
# 构造决策树
def build_tree(dataSet, n_features, max_depth, min_size):
root = get_best_spilt(dataSet, n_features)
sub_spilt(root, n_features, max_depth, min_size, 1)
return root
# 预测测试集结果
def predict(tree, row):
predictions = []
if row[tree['index']] < tree['value']:
if isinstance(tree['left'], dict):
return predict(tree['left'], row)
else:
return tree['left']
else:
if isinstance(tree['right'], dict):
return predict(tree['right'], row)
else:
return tree['right']
# predictions=set(predictions)
def bagging_predict(trees, row):
predictions = [predict(tree, row) for tree in trees]
return max(set(predictions), key=predictions.count)
# 创建随机森林
def random_forest(train, test, ratio, n_feature, max_depth, min_size, n_trees):
trees = []
for i in range(n_trees):
train = get_subsample(train, ratio)#从切割的数据集中选取子集
tree = build_tree(train, n_features, max_depth, min_size)
# print 'tree %d: '%i,tree
trees.append(tree)
# predict_values = [predict(trees,row) for row in test]
predict_values = [bagging_predict(trees, row) for row in test]
return predict_values
# 计算准确率
def accuracy(predict_values, actual):
correct = 0
for i in range(len(actual)):
if actual[i] == predict_values[i]:
correct += 1
return correct / float(len(actual))
if __name__ == '__main__':
seed(1)
dataSet = loadCSV('sonar-all-data.csv')
column_to_float(dataSet)#dataSet
n_folds = 5
max_depth = 15
min_size = 1
ratio = 1.0
# n_features=sqrt(len(dataSet)-1)
n_features = 15
n_trees = 10
folds = spiltDataSet(dataSet, n_folds)#先是切割数据集
scores = []
for fold in folds:
train_set = folds[
:] # 此处不能简单地用train_set=folds,这样用属于引用,那么当train_set的值改变的时候,folds的值也会改变,所以要用复制的形式。(L[:])能够复制序列,D.copy() 能够复制字典,list能够生成拷贝 list(L)
train_set.remove(fold)#选好训练集
# print len(folds)
train_set = sum(train_set, []) # 将多个fold列表组合成一个train_set列表
# print len(train_set)
test_set = []
for row in fold:
row_copy = list(row)
row_copy[-1] = None
test_set.append(row_copy)
# for row in test_set:
# print row[-1]
actual = [row[-1] for row in fold]
predict_values = random_forest(train_set, test_set, ratio, n_features, max_depth, min_size, n_trees)
accur = accuracy(predict_values, actual)
scores.append(accur)
print ('Trees is %d' % n_trees)
print ('scores:%s' % scores)
print ('mean score:%s' % (sum(scores) / float(len(scores))))
Второй исходит изGitHub.com/Найди волнение…
# -*- coding: utf-8 -*-
"""
@Env: Python2.7
@Time: 2019/10/24 13:31
@Author: zhaoxingfeng
@Function:Random Forest(RF),随机森林二分类
@Version: V1.2
参考文献:
[1] UCI. wine[DB/OL].https://archive.ics.uci.edu/ml/machine-learning-databases/wine.
"""
import pandas as pd
import numpy as np
import random
import math
import collections
from sklearn.externals.joblib import Parallel, delayed
class Tree(object):
"""定义一棵决策树"""
def __init__(self):
self.split_feature = None
self.split_value = None
self.leaf_value = None
self.tree_left = None
self.tree_right = None
def calc_predict_value(self, dataset):
"""通过递归决策树找到样本所属叶子节点"""
if self.leaf_value is not None:
return self.leaf_value
elif dataset[self.split_feature] <= self.split_value:
return self.tree_left.calc_predict_value(dataset)
else:
return self.tree_right.calc_predict_value(dataset)
def describe_tree(self):
"""以json形式打印决策树,方便查看树结构"""
if not self.tree_left and not self.tree_right:
leaf_info = "{leaf_value:" + str(self.leaf_value) + "}"
return leaf_info
left_info = self.tree_left.describe_tree()
right_info = self.tree_right.describe_tree()
tree_structure = "{split_feature:" + str(self.split_feature) + \
",split_value:" + str(self.split_value) + \
",left_tree:" + left_info + \
",right_tree:" + right_info + "}"
return tree_structure
class RandomForestClassifier(object):
def __init__(self, n_estimators=10, max_depth=-1, min_samples_split=2, min_samples_leaf=1,
min_split_gain=0.0, colsample_bytree=None, subsample=0.8, random_state=None):
"""
随机森林参数
----------
n_estimators: 树数量
max_depth: 树深度,-1表示不限制深度
min_samples_split: 节点分裂所需的最小样本数量,小于该值节点终止分裂
min_samples_leaf: 叶子节点最少样本数量,小于该值叶子被合并
min_split_gain: 分裂所需的最小增益,小于该值节点终止分裂
colsample_bytree: 列采样设置,可取[sqrt、log2]。sqrt表示随机选择sqrt(n_features)个特征,
log2表示随机选择log(n_features)个特征,设置为其他则不进行列采样
subsample: 行采样比例
random_state: 随机种子,设置之后每次生成的n_estimators个样本集不会变,确保实验可重复
"""
self.n_estimators = n_estimators
self.max_depth = max_depth if max_depth != -1 else float('inf')
self.min_samples_split = min_samples_split
self.min_samples_leaf = min_samples_leaf
self.min_split_gain = min_split_gain
self.colsample_bytree = colsample_bytree
self.subsample = subsample
self.random_state = random_state
self.trees = None
self.feature_importances_ = dict()
def fit(self, dataset, targets):
"""模型训练入口"""
assert targets.unique().__len__() == 2, "There must be two class for targets!"
targets = targets.to_frame(name='label')
if self.random_state:
random.seed(self.random_state)
random_state_stages = random.sample(range(self.n_estimators), self.n_estimators)
# 两种列采样方式
if self.colsample_bytree == "sqrt":
self.colsample_bytree = int(len(dataset.columns) ** 0.5)
elif self.colsample_bytree == "log2":
self.colsample_bytree = int(math.log(len(dataset.columns)))
else:
self.colsample_bytree = len(dataset.columns)
# 并行建立多棵决策树
self.trees = Parallel(n_jobs=-1, verbose=0, backend="threading")(
delayed(self._parallel_build_trees)(dataset, targets, random_state)
for random_state in random_state_stages)
def _parallel_build_trees(self, dataset, targets, random_state):
"""bootstrap有放回抽样生成训练样本集,建立决策树"""
subcol_index = random.sample(dataset.columns.tolist(), self.colsample_bytree)
dataset_stage = dataset.sample(n=int(self.subsample * len(dataset)), replace=True,
random_state=random_state).reset_index(drop=True)
dataset_stage = dataset_stage.loc[:, subcol_index]
targets_stage = targets.sample(n=int(self.subsample * len(dataset)), replace=True,
random_state=random_state).reset_index(drop=True)
tree = self._build_single_tree(dataset_stage, targets_stage, depth=0)
print(tree.describe_tree())
return tree
def _build_single_tree(self, dataset, targets, depth):
"""递归建立决策树"""
# 如果该节点的类别全都一样/样本小于分裂所需最小样本数量,则选取出现次数最多的类别。终止分裂
if len(targets['label'].unique()) <= 1 or dataset.__len__() <= self.min_samples_split:
tree = Tree()
tree.leaf_value = self.calc_leaf_value(targets['label'])
return tree
if depth < self.max_depth:
best_split_feature, best_split_value, best_split_gain = self.choose_best_feature(dataset, targets)
left_dataset, right_dataset, left_targets, right_targets = \
self.split_dataset(dataset, targets, best_split_feature, best_split_value)
tree = Tree()
# 如果父节点分裂后,左叶子节点/右叶子节点样本小于设置的叶子节点最小样本数量,则该父节点终止分裂
if left_dataset.__len__() <= self.min_samples_leaf or \
right_dataset.__len__() <= self.min_samples_leaf or \
best_split_gain <= self.min_split_gain:
tree.leaf_value = self.calc_leaf_value(targets['label'])
return tree
else:
# 如果分裂的时候用到该特征,则该特征的importance加1
self.feature_importances_[best_split_feature] = \
self.feature_importances_.get(best_split_feature, 0) + 1
tree.split_feature = best_split_feature
tree.split_value = best_split_value
tree.tree_left = self._build_single_tree(left_dataset, left_targets, depth+1)
tree.tree_right = self._build_single_tree(right_dataset, right_targets, depth+1)
return tree
# 如果树的深度超过预设值,则终止分裂
else:
tree = Tree()
tree.leaf_value = self.calc_leaf_value(targets['label'])
return tree
def choose_best_feature(self, dataset, targets):
"""寻找最好的数据集划分方式,找到最优分裂特征、分裂阈值、分裂增益"""
best_split_gain = 1
best_split_feature = None
best_split_value = None
for feature in dataset.columns:
if dataset[feature].unique().__len__() <= 100:
unique_values = sorted(dataset[feature].unique().tolist())
# 如果该维度特征取值太多,则选择100个百分位值作为待选分裂阈值
else:
unique_values = np.unique([np.percentile(dataset[feature], x)
for x in np.linspace(0, 100, 100)])
# 对可能的分裂阈值求分裂增益,选取增益最大的阈值
for split_value in unique_values:
left_targets = targets[dataset[feature] <= split_value]
right_targets = targets[dataset[feature] > split_value]
split_gain = self.calc_gini(left_targets['label'], right_targets['label'])
if split_gain < best_split_gain:
best_split_feature = feature
best_split_value = split_value
best_split_gain = split_gain
return best_split_feature, best_split_value, best_split_gain
@staticmethod
def calc_leaf_value(targets):
"""选择样本中出现次数最多的类别作为叶子节点取值"""
label_counts = collections.Counter(targets)
major_label = max(zip(label_counts.values(), label_counts.keys()))
return major_label[1]
@staticmethod
def calc_gini(left_targets, right_targets):
"""分类树采用基尼指数作为指标来选择最优分裂点"""
split_gain = 0
for targets in [left_targets, right_targets]:
gini = 1
# 统计每个类别有多少样本,然后计算gini
label_counts = collections.Counter(targets)
for key in label_counts:
prob = label_counts[key] * 1.0 / len(targets)
gini -= prob ** 2
split_gain += len(targets) * 1.0 / (len(left_targets) + len(right_targets)) * gini
return split_gain
@staticmethod
def split_dataset(dataset, targets, split_feature, split_value):
"""根据特征和阈值将样本划分成左右两份,左边小于等于阈值,右边大于阈值"""
left_dataset = dataset[dataset[split_feature] <= split_value]
left_targets = targets[dataset[split_feature] <= split_value]
right_dataset = dataset[dataset[split_feature] > split_value]
right_targets = targets[dataset[split_feature] > split_value]
return left_dataset, right_dataset, left_targets, right_targets
def predict(self, dataset):
"""输入样本,预测所属类别"""
res = []
for _, row in dataset.iterrows():
pred_list = []
# 统计每棵树的预测结果,选取出现次数最多的结果作为最终类别
for tree in self.trees:
pred_list.append(tree.calc_predict_value(row))
pred_label_counts = collections.Counter(pred_list)
pred_label = max(zip(pred_label_counts.values(), pred_label_counts.keys()))
res.append(pred_label[1])
return np.array(res)
if __name__ == '__main__':
df = pd.read_csv("source/wine.txt")
df = df[df['label'].isin([1, 2])].sample(frac=1, random_state=66).reset_index(drop=True)
clf = RandomForestClassifier(n_estimators=5,
max_depth=5,
min_samples_split=6,
min_samples_leaf=2,
min_split_gain=0.0,
colsample_bytree="sqrt",
subsample=0.8,
random_state=66)
train_count = int(0.7 * len(df))
feature_list = ["Alcohol", "Malic acid", "Ash", "Alcalinity of ash", "Magnesium", "Total phenols",
"Flavanoids", "Nonflavanoid phenols", "Proanthocyanins", "Color intensity", "Hue",
"OD280/OD315 of diluted wines", "Proline"]
clf.fit(df.loc[:train_count, feature_list], df.loc[:train_count, 'label'])
from sklearn import metrics
print(metrics.accuracy_score(df.loc[:train_count, 'label'], clf.predict(df.loc[:train_count, feature_list])))
print(metrics.accuracy_score(df.loc[train_count:, 'label'], clf.predict(df.loc[train_count:, feature_list])))
0xEE Личная информация
★★★★★★Думая о жизни и технологиях★★★★★★
Публичный аккаунт WeChat:мысли Росси
Если вы хотите получать своевременные новости о статьях, написанных отдельными лицами, или хотите видеть технические материалы, рекомендованные отдельными лицами, обратите внимание.
ссылка 0xFF
Введение в «самый простой» метод Bootstrap в статистике и его приложенияblog.CSDN.net/sun JW_2017/…
Комбинированный метод классификатора Bootstrap, Boosting, Bagging, Random Forest (1)blog.CSDN.net/Эта вещь часто после/искусство…
Принцип ансамблевого алгоритма обучения и алгоритма бустингаBaijiahao.Baidu.com/is?ID=161998…
Алгоритм машинного обучения GBDT
Наконец-то кто-то прояснил - алгоритм XGBoost
Принцип xgboost не так сложен, как вы думаетеу-у-у. Краткое описание.com/afraid/7467oh616…
Почему никто не применил идею бустинга к глубокому обучению?Ууху. Call.com/question/53…
Принцип ансамблевого алгоритма обучения и алгоритма бустингаBaijiahao.Baidu.com/is?ID=161998…
Метод бэггинга и метод бустинга метода ансамблевого обученияblog.CSDN.net/QQ_30189255…
Резюме: Bootstrap (метод самопомощи), Bagging, Boosting (буст)Краткое описание.com/afraid/708 Tofufang 71's…
blog.CSDN.net/Эта вещь часто после/искусство…
ансамблевое обучениеblog.CSDN.net/Wen Yiduo, авторы некоторых людей/искусство…
Вводное руководство по Adaboost — самое простое для понимания введение в принципыWoohoo.UML.org.capable/включая секретные документы/2019…
Повышение и бэггинг: как разработать надежный алгоритм машинного обученияЛюбовь.51CTO.com/art/201906/…
Почему бэггинг уменьшает дисперсию, а бустинг уменьшает предвзятость?blog.CSDN.net/День мертвых_25394…
Понимание предвзятости и дисперсии двух интегрированных моделей бэггинга и бустингаblog.CSDN.net/Шен Сяомин…
Препарирование случайных лесов простым для понимания способомblog.CSDN.net/success896406166…
Python реализует случайный лесblog.CSDN.net/Colou Body Lotion _ это…
Анализ данных (инструменты) — бустингzhuanlan.zhihu.com/p/26215100
Подробное объяснение принципа AdaBoost
Статьи базы знаний — проблема классификации на основе AdaBoostWoohoo.Краткое описание.com/afraid/ah 6426 сделал 4 из 4…
Дерево повышения градиента для вопросов интервью по интеллектуальному анализу данныху-у-у. Краткое описание.com/afraid/0 ох 5CCC88's…