Введение

Здравствуйте, меня зовут Энтони Хоземанн, и я изучаю разработку ИТ-программного обеспечения в SAIT. Это мой второй блог о машинном обучении. В этом сообщении блога я продемонстрирую приложение машинного обучения с учителем, которое я создал в java, используя классификатор дерева решений.

Обзор

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

Классификатор

Сначала поговорим о классификаторе. Классификатор — это часть приложения, которая принимает решения и выбирает правильный вывод для любых заданных входных данных. При обучении с учителем классификатор должен быть обучен на обучающих данных, чтобы он был точным. Классификатор использует обучающие данные для изучения и создания правил, которые сделают его более точным. Существует множество различных типов классификаторов машинного обучения, но тот, который я выбрал для приложения в этом сообщении блога, — это классификатор дерева решений.

Тренировочные данные

Теперь, прежде чем я перейду к коду приложения, я покажу вам обучающие данные, которые я буду использовать в своей демонстрации:

Если вы читали мою последнюю запись в блоге о машинном обучении, вы можете узнать эти данные. Это та же таблица данных о фруктах, которую я использовал в своем последнем посте в блоге. Эта таблица содержит список характеристик и этикеток различных фруктов, которые будут использоваться, чтобы помочь классификатору узнать, какие цвета и текстуры соответствуют каким фруктам. Теперь давайте посмотрим, как данные обучения выглядят в коде:

В этом коде я создал одну строку данных, которую я назвал заголовками, в которой хранятся заголовки таблицы данных, которые будут использоваться в классификаторе. Я также создал таблицу данных, создав список ArrayList, содержащий строки данных (ArrayList‹String›). После создания экземпляра 2D ArrayList с именем trainingData я добавлял данные построчно. Все данные, которые я добавил в 2D ArrayList, такие же, как и в приведенной выше таблице обучающих данных.

Кодирование классификатора

Ну что теперь? У нас есть некоторые обучающие данные, но нет классификатора для обучения. Итак, давайте начнем кодировать классификатор. В этом разделе будет много сегментов кода, но если вы предпочитаете смотреть на все приложение целиком, я загрузил его на github, чтобы вы могли увидеть код и там. Классификатор должен быть в состоянии сделать несколько вещей, чтобы он был функциональным. Эти вещи будут:

- Получение уникальных значений в каждом столбце функций. Это важно, потому что обучающие данные в большинстве случаев НАМНОГО больше, чем просто 5 записей, и в некоторых столбцах будут повторяющиеся данные, и мы не хотим перебирать их все при создании вопроса.

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

- Нам также нужен способ расчета примеси Джини и прироста информации для любого заданного набора данных.

- Затем мы можем использовать примесь Джини и прирост информации, чтобы найти вопрос, который лучше всего разделяет данные.

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

Сначала давайте начнем с получения уникальных функций в столбце. Это можно сделать путем повторения обучающих данных и добавления найденных уникальных значений в новый список ArrayList‹String›. Вот код этого метода:

Метод, используемый для подсчета количества меток в заданном наборе данных, очень похож на метод uniqueValues, за исключением того, что теперь вам нужно будет создать ArrayList‹Integer›, который будет отслеживать количество вхождений каждой метки. Вам также не нужно указывать номер столбца в качестве параметра, поскольку столбец метки всегда является последним столбцом. Это код метода countClass:

Нам также нужны методы для расчета примеси Джини и прироста информации. Это код, используемый для расчета примеси Джини:

И это код, используемый для расчета прироста информации:

Теперь нам нужно использовать примесь Джини и прирост информации, чтобы найти вопрос, который лучше всего разделяет данные. Вот код метода findBestSplit:

Наконец, у нас есть один из самых важных методов в классификаторе — метод разделения, который разбивает данные на основе вопроса. Вот код метода разделения:

Построение дерева

Теперь, когда у нас есть таблица данных и начало классификатора, мы можем приступить к созданию методов для построения дерева решений. Для этого нам понадобятся узлы, которые содержат вопросы и ссылки на полученные истинные и ложные ветки, которые я называю узлами принятия решений. Нам также понадобятся конечные узлы, содержащие прогнозы в конце ветви. Наконец, нам нужен рекурсивный метод, который построит дерево с узлами решений и листовыми узлами. Этот метод buildTree будет методом, который обучает наш классификатор идентифицировать определенные типы объектов в наборе данных, поэтому именно его вы должны передать в своей таблице обучающих данных. Вот код метода buildTree:

Теперь, когда у нас есть построенное дерево, мы можем распечатать его, используя другой рекурсивный метод, называемый printTree. То, как я построил этот метод, распечатывает дерево следующим образом:

Это дерево было построено с использованием данных обучения фруктов, которые я предоставил ранее в этом блоге. По мере того, как метод продвигается дальше в ветвях true/false, метод printTree будет добавлять дополнительные пробелы в начало каждой строки, чтобы помочь уточнить, где в дереве вы просматриваете.

Использование классификатора

Мы почти закончили создание классификатора. Последнее, что должен уметь делать классификатор, — это брать неизвестную строку данных и выводить прогноз того, какой объект представляют эти данные. Я назвал этот метод классификацией, и он принимает неизвестную строку данных и дерево решений в качестве параметров и выводит ArrayList‹String›, содержащий прогнозы. Код метода classify таков:

видео

https://vimeo.com/535684281

Вывод

Спасибо, что нашли время, чтобы прочитать мою запись в блоге, и я надеюсь, что вы узнали что-то новое о машинном обучении. Теперь, когда мы рассмотрели основные части классификатора дерева решений, я предлагаю вам проверить его на себе, попробовать изменить и сделать лучше, чем я. Я загрузил весь код на github, чтобы вы могли поиграть с ним и поучиться у него. Ниже я также связал некоторые полезные онлайн-ресурсы, которые помогли мне изучить и понять некоторые концепции машинного обучения.

использованная литература

https://www.guru99.com/supervised-vs-unsupervised-learning.html

https://www.analyticsvidhya.com/blog/2017/09/common-machine-learning-algorithms/

https://www.youtube.com/playlist?list=PLOU2XLYxmsIIuiBfYad6rFYQU_jL2ryal

https://machinelearningmastery.com/types-of-learning-in-machine-learning/

https://towardsdatascience.com/gini-impurity-measure-dbd3878ead33

https://victorzhou.com/blog/information-gain/