Введение в машинное обучение
Полный курс на русском языке можно найти по этой ссылке.
Оригинальный курс на английском доступен по этой ссылке.
Выход новых лекций запланирован каждые 2-3 дня.
Интервью с Себастьяном Труном, CEO Udacity
— И снова всем привет, с вами я, Пейдж и сегодня со мной гость — Себастьян.
— Привет, я Себастьян!
— … человек у которого невероятная карьера, успевшего сделать множество потрясающих вещей! Вы являетесь со-основателем Udacity, вы основали Google X, вы професcор в Стэнфорде. Вы занимались невероятными исследованиями и глубоким обучением на всём протяжении своей карьеры. Что приносило вам наибольшее удовлетворение и в какой из областей вы получали наибольшее вознаграждение за проделанную работу?
— Скажу честно, я очень люблю находиться в Кремниевой долине! Мне нравится находится рядом с людьми, которые значительно умнее меня, и я всегда рассматривал технологии, как инструмент менющий правила игры различными способами — начиная от образования и заканчивая логистикой, здравохранением и т.д. Всё это меняется настолько быстро, и возникает невероятное желание быть участником этих изменений, наблюдать за ними. Ты смотришь на окружающее тебя и понимаешь, что большинство из того, что ты видишь вокруг, не работает так, как это должно — всегда можно изобрести нечто новое!
— Ну что ж, это очень оптимистичный взгляд на технологии! Какой момент на протяжении всей вашей карьеры был самой большой «эврикой»?
— Господи, их было так много! Помню один из дней, когда Ларри Пейдж позвонил мне и предложил создать автопилотируемые автомобили, которые смогли бы проезжать по всем улицам Калифорнии. В то время я считался экспертом, меня к таковым причисляли и, я был тем самым человеком, который сказал «нет, этого нельзя сделать». После этого Ларри убедил меня, что, в принципе, это возможно сделать, стоит только начать и сделать попытку. И мы сделали это! Это был момент, когда я осознал, что даже эксперты ошибаются и говоря «нет» мы на 100% становимся пессимистами. Я думаю мы должны быть более открыты новому.
— Или, например, если вам звонит Ларри Пейдж и говорит, — «Хэй, сделай крутую вещь вроде Google X» и получается нечто достаточно крутое!
— Да, это точно, жаловаться не приходится! Я имею ввиду, что всё это — процесс, который проходит через множество обсуждений на пути к реализации. Мне, действительно, повезло работать и я горжусь этим, в Google X и над другими проектами.
— Потрясающе! Итак, этот курс полностью о работе с TensorFlow. У вас есть опыт использования TensorFlow или может быть вы знакомы (слышали) с ним?
— Да! Я, в буквальном смысле, люблю TensorFlow, конечно! В моей собственной лаборатории мы используем его часто и много, одна из самых значимых работ на основе TensorFlow вышла около двух лет назад. Мы узнали, что iPhone и Android могут быть эффективнее в определении рака кожи, чем лучшие дерматологи в мире. Своё исследование мы опубликовали в Nature и это произвело своего рода переполох в медицине.
— Звучит потрясающе! Значит вы знаете и любите TensorFlow, что само по себе здорово! Вы уже успели поработать с TensorFlow 2.0?
— Нет, к сожалению пока не успел.
— Он будет просто восхитителен! Все студенты этого курса будут работать с этой версией.
— Я завидую им! Обязательно попробую!
— Прекрасно! На нашем курсе очень много студентов, которые в своей жизни ни разу не занимались машинным обучение, от слова «совсем». Для них область может быть нова, возможно для кого-то само программирование будет вновинку. Какой у вас совет для них?
— Я бы пожелал им оставаться открытыми — к новым идеям, методикам, решениям, позициям. Машинное обучение, на самом деле, проще, чем программирование. В процессе программирования вам необходимо учитывать каждый случай в исходных данных, адаптировать под него логику программы и правила. В это самое время, используя TensorFlow и машинное обучение вы, по сути, тренируете компьютер используя примеры, предоставляя компьютеру самому находить правила.
— Это невероятно интересно! Мне не терпится рассказать студентам этого курса немного больше о машинном обучении! Себастьян, благодарю, что нашел время и пришёл сегодня к нам!
— Благодарю! Оставайтесь на связи!
Что такое машинное обучение?
Итак, давайте начнём со следующей задачи — даны входные и выходные значения.
Когда в качестве входного значения у вас значение 0, то в качестве выходного значения — 32. Когда в качестве входного значения у вас 8, то в качестве выходного значения — 46.4. Когда в качестве входного значения у вас 15, то в качестве выходного значения — 59 и так далее.
Присмотритесь к этим значениям и позвольте мне задать вам вопрос. Можете ли вы определить, каким будет выходное значение, если на входе мы получим 38?
Если вы ответили 100.4, то оказались правы!
Итак, как мы могли решить эту задачу? Если присмотреться внимательнее к значениям, то можно заметить, что они связаны выражением:
Где С — градусы Цельсия (входные значения), F — Фаренгейта (выходные значения).
То, что сейчас сделал ваш мозг — сопоставил входные значения и выходные значения и нашел общую модель (связь, зависимость) между ними, — именно это и делает машинное обучение.
По входным и выходным значениям алгоритмы машинного обучения найдут подходящий алгоритм преобразования входных значений в выходные. Это можно представить следующим образом:
Давайте разберём на примере. Представим себе, что мы хотим разработать программу, которая будет преобразовывать градусы Цельсия в градусы Фаренгейта используя формулу F = C * 1.8 + 32 .
Решение, при подходе с точки зрения традиционной разработки программного обеспечения, может быть реализовано на любом языке программирования с использованием функции:
Итак, что мы имеем? Функция принимает входное значение C, затем вычисляет выходное значение F используя явно заданный алгоритм, а затем возвращает вычисленное значение.
С другой стороны, в подходе с машинным обучением, у нас есть только входные и выходные значения, но не сам алгоритм:
Подход с машинным обучением основывается на использовании нейронных сетей для нахождения отношений между входными и выходными значениями.
Вы можете думать о нейронных сетях, как о стопке слоёв, каждый из которых состоит из заранее известной математики (формул) и внутренних переменных. Входное значение поступает в нейронную сеть и проходит сквозь стопку слоёв нейронов. Во время прохождения через слои, входное значение преобразовывается согласно математике (заданным формулам) и значениям внутренних переменных слоёв, производя выходное значение.
Для того, чтобы нейронная сеть смогла обучиться и определить правильные отношения между входными и выходными значениями, нам необходимо её обучить — натренировать.
Мы тренируем нейронную сеть через повторяющиеся попытки сопоставить входные значения выходным.
В процессе тренировки происходит «подгонка» (подбор) значений внутренних переменных в слоях нейронной сети до тех пор, пока сеть не научится генерировать соответствующие выходные значения соответствующим входным значениям.
Как мы увидим в последующем, для того чтобы обучить нейронную сеть и позволить ей подобрать наиболее подходящие значения внутренних переменных, производят тысячи или десятки тысяч итераций (тренировок).
В качестве упрощенного варианта понимания машинного обучения вы можете представить себе алгоритмы машинного обучения как функции, которые подбирают значения внутренних переменных таким образом, чтобы соответствующим входным значениям соответствовали корректные выходные значения.
Существует множество типов архитектур нейронных сетей. Однако, вне зависимости от того, какую архитектуру вы выберете, математика внутри (какие вычисления выполняются и в каком порядке) останется неизменной в процессе тренировки. Вместо изменения математики, меняются внутренние переменные (веса и смещения) во время тренировки.
Например, в задаче конвертации из градусов Цельсия в Фаренгейты, модель начинает с умножения входного значения на некоторое число (вес) и добавления другого значения (смещения). Обучение модели заключается в нахождении подходящих значений для этих переменных, без изменения выполняемых операций умножения и сложения.
А вот одна крутая вещь над которой стоит задуматься! Если вы решили задачу преобразования градусов Цельсия в Фаренгейты, которая обозначена в видео и в тексте ниже, вы, вероятно, решили её потому, что обладали неким предыдущим опытом или знанием, как производить подобного рода преобразования из градусов Цельсия в Фаренгейты. Например, вы могли просто знать, что 0 градусов Цельсия соответствуют 32 градусам по Фаренгейту. С другой стороны, системы основанные на машинном обучении не обладают предыдущими вспомогательными знаниями для решения поставленной задачи. Они учатся решать подобного рода задачи не основываясь на предыдущих знаниях и при их полном отсутствии.
Довольно разговоров — переходим к практической части лекции!
CoLab: преобразуем градусы Цельсия в градусы Фаренгейта
Основы: обучение первой модели
Добро пожаловать в CoLab, где мы будем тренировать нашу первую модель машинного обучения!
Мы постараемся сохранять простоту преподносимого материала и ввести только базовые понятия необходимые для работы. Последующие CoLabs будут содержать более продвинутые техники.
Задача, которую мы будем решать — преобразование градусов Цельсия в градусы Фаренгейта. Формула преобразования выглядит следующим образом:
Безусловно, было бы проще просто написать функцию конвертации на Python или любом другом языке программирования, которая бы выполняла непосредственные вычисления, но в таком случае это не было бы машинным обучением 🙂
Вместо этого мы подадим на вход TensorFlow имеющиеся у нас входные значения градусов Цельсия (0, 8, 15, 22, 38) и их соответствующие градусы по Фаренгейту (32, 46, 59, 72, 100). Затем мы натренируем модель таким образом, чтобы та примерно соответствовала приведённой выше формуле.
Импорт зависимостей
Первым делом импортируем TensorFlow . Здесь и в последующем мы сокращённо называем его tf . Мы так же настраиваем уровень логгирования — только ошибки.
Далее, импортируем NumPy как np . Numpy помогает нам представить наши данные в виде высокоэффективных списков.
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf tf.logging.set_verbosity(tf.logging.ERROR) import numpy as np
Подготовка данных для тренировки
Как мы уже видели ранее, методика машинного обучения с учителем основывается на поиске алгоритма преобразования входных данных в выходные. Так как задачей этого CoLab является создание модели, которая может выдать результат преобразования градусов Цельсия в градусы Фаренгейта, создадим два списка — celsius_q и fahrenheit_a , которые мы используем при обучении нашей модели.
celsius_q = np.array([-40, -10, 0, 8, 15, 22, 38], dtype=float) fahrenheit_a = np.array([-40, 14, 32, 46, 59, 72, 100], dtype=float) for i,c in enumerate(celsius_q): print("<> градусов Цельсия = <> градусов Фаренгейта".format(c, fahrenheit_a[i]))
-40.0 градусов Цельсия = -40.0 градусов Фаренгейта
-10.0 градусов Цельсия = 14.0 градусов Фаренгейта
0.0 градусов Цельсия = 32.0 градусов Фаренгейта
8.0 градусов Цельсия = 46.0 градусов Фаренгейта
15.0 градусов Цельсия = 59.0 градусов Фаренгейта
22.0 градусов Цельсия = 72.0 градусов Фаренгейта
38.0 градусов Цельсия = 100.0 градусов Фаренгейта
Некоторая терминология машинного обучения:
- Свойство — входное(ые) значение нашей модели. В данном случае единичное значение — градусы Цельсия.
- Метки — выходные значения, которые наша модель предсказывает. В данном случае единичное значение — градусы Фаренгейта.
- Пример — пара входных-выходных значений используемых для тренировки. В данном случае это пара значений из celsius_q и fahrenheit_a под определённым индексом, например, (22,72).
Создаём модель
Далее мы создаём модель. Мы будем использовать максимально упрощенную модель — модель полносвязной сети ( Dense -сеть). Так как задача достаточно тривиальна, то и сеть будет состоять из единственного слоя с единственным нейроном.
Строим сеть
Мы назовём слой l0 (layer и ноль) и создадим его, инициализировав tf.keras.layers.Dense со следующими параметрами:
- input_shape=[1] — этот параметр определяет размерность входного параметра — единичное значение. Матрица размером 1×1 с единственным значением. Так как это первый (и единственный) слой, то и размерность входных данных соответствует размерности всей модели. Единственное значение — значение с плавающей запятой, представляющее градусы Цельсия.
- units=1 — этот параметр определяет количество нейронов в слое. Количество нейронов определяет то, как много внутренних переменных слоя будет использовано для обучения при поиске решения поставленной задачи. Так как это последний слой, то его размерность равна размерности результата — выходного значения модели — единственного числа с плавающей запятой представляющего собой градусы Фаренгейта. (В многослойной сети размеры и форма слоя input_shape должны соответствовать размерам и формам следующего слоя).
l0 = tf.keras.layers.Dense(units=1, input_shape=[1])
Преобразуем слои в модель
Как только слои определены их необходимо преобразовать в модель. Sequential -модель принимает в качестве аргументов перечень слоёв в том порядке в котором их необходимо применять — от входного значения до выходного значения.
У нашей модели всего один слой — l0 .
model = tf.keras.Sequential([l0])
Примечание
Достаточно часто вы будете сталкиваться с определением слоёв прямо в функции модели, нежели с их предварительным описанием и последующим использованием:
model = tf.keras.Sequential([ tf.keras.layers.Dense(units=1, input_shape=[1]) ])
Компилируем модель с функцией потерь и оптимизаций
Перед тренировкой модель должна быть скомпилирована (собрана). При компиляции для тренировки необходимы:
- функция потерь — способ измерения того, насколько далеко предсказываемое значение от желаемого выходного значения (измеримая разница называется «потерей»).
- функция оптимизации — способ корректировки внутренних переменных для уменьшения потерь.
model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(0.1))
Функция потерь и функция оптимизации используются во время тренировки модели ( model.fit(. ) упоминаемая ниже) для выполнения первичных вычислений в каждой точке и последующей оптимизации значений.
Действие вычисления текущих потерь и последующее улучшение этих значений в модели — это именно то, чем является тренировка (одна итерация).
Во время тренировки, функция оптимизации используется для подсчета корректировок значений внутренних переменных. Цель — подогнать значения внутренних переменных таким образом в модели (а это, по сути, математическая функция), чтобы те отражали максимально приближённо существующее выражение конвертации градусов Цельсия в градусы Фаренгейта.
TensorFlow использует численный анализ для выполнения подобного рода операций оптимизации и вся эта сложность скрыта от наших глаз, поэтому мы не будем вдаваться в детали в этом курсе.
Что полезно знать об этих параметрах:
Функция потерь (среднеквадратичная ошибка) и функция оптимизации (Adam), используемые в этом примере, являются стандартными для подобных простых моделей, но кроме них доступно множество других. На данном этапе нам не важно каким образом работают эти функции.
На что стоит обратить внимание, так это на функцию оптимизации и параметр — коэффициент скорости обучения ( learning rate ), который в нашем примере равен 0.1 . Это используемый размер шага при корректировке внутренних значений переменных. Если значение слишком маленькое — понадобится слишком много обучающих итераций для обучения модели. Слишком большое — точность падает. Нахождение хорошего значения коэффициента скорости обучения требует некоторых проб и ошибок, оно обычно находится в интервале от 0.01 (по-умолчанию) до 0.1 .
Тренируем модель
Тренировка модели осуществляется методом fit .
Во время тренировки модель получает на вход значения градусов Цельсия, выполняет преобразования используя значения внутренних переменных (называемые «весами») и возвращает значения, которые должны соответствовать градусами по Фаренгейту. Так как первоначальные значения весов установлены произвольными, то и результатирующие значения будут далеки от корректных значений. Разница между необходимым результатом и фактическим вычисляется с использованием функции потерь, а функция оптимизации определяет каким образом должны быть подкорректированы веса.
Этот цикл вычислений, сравнений и корректировки контролируется внутри метода fit . Первый аргумент — входные значения, второй аргумент — желаемые выходные значения. Аргумент epochs определяет какое количество раз этот обучающий цикл должен быть выполнен. Аргумент verbose контролирует уровень логгирования.
history = model.fit(celsius_q, fahrenheit_a, epochs=500, verbose=False) print("Завершили тренировку модели")
В последующих видео мы погрузимся в детали того, каким образом это всё работает и как именно работают полносвязные слои ( Dense -слои) «под капотом».
Отображаем статистику тренировок
Метод fit возвращает объект, который содержит информацию об изменении потерь с каждой последующей итерацией. Мы можем воспользоваться этим объектом для построения соответствующего графика потерь. Высокая потеря означает, что значение градусов Фаренгейта, которые предсказала модель, далеки от истинных значений в массиве fahrenheit_a .
Для визуализации воспользуемся Matplotlib . Как вы можете увидеть, наша модель улучшается очень быстро в самом начале, а затем приходит к стабильному и медленному улучшению до тех пор, пока результаты не становятся «около»-идеальными в самом конце обучения.
import matplotlib.pyplot as plt plt.xlabel('Epoch') plt.ylabel('Loss') plt.plot(history.history['loss'])
Используем модель для предсказаний
Теперь у нас есть модель, которая была обучена на входных значениях celsius_q и выходных значениях fahrenheit_a для определения взаимосвязи между ними. Мы можем воспользоваться методом предсказания для вычисления тех значений градусов Фаренгейта по которым ранее нам неизвестны были соответствующие градусы Цельсия.
Например, сколько будет 100.0 градусов Цельсия по Фаренгейту? Попробуйте угадать перед тем как запускать код ниже.
print(model.predict([100.0]))
Правильный ответ 100×1.8+32=212, так что наша модель справилась достаточно хорошо!
- Мы создали модель с использованием Dense -слоя
- Мы обучили её на 3500 примерах (7 пар значений, 500 обучающих итераций)
Смотрим на веса
Давайте отобразим значения внутренних переменных Dense -слоя.
print("Это значения переменных слоя: <>".format(l0.get_weights()))
Это значения переменных слоя: [array([[1.8261501]], dtype=float32), array([28.681389], dtype=float32)]
Значение первой переменной близко к ~1.8, а второй к ~32. Эти значения (1.8 и 32) являются непосредственными значениями в формуле конвертации градусов Цельсия в градусы Фаренгейта.
Это действительно очень близко к фактическим значениям в формуле! Мы рассмотрим этот момент подробнее в последующих видео, где мы покажем, каким образом работает Dense -слой, а пока стоит знать лишь то, что один нейрон с единственным входом и выходом, содержит в себе простую математику — y = mx + b (как уравнение прямой), которая представляет собой не что иное, как нашу с вами формулу преобразования градусов Цельсия в градусы Фаренгейта, f = 1.8c + 32 .
Так как представления одинаковые, то и значения внутренних переменных модели должны были сойтись к тем, которые представлены в фактической формуле, что и произошло в итоге.
При наличии дополнительных нейронов, дополнительных входных значений и выходных значений, формула становится немного сложнее, но суть остаётся той же.
Немного экспериментов
Ради веселья! Что будет, если мы создадим больше Dense -слоёв с большим количеством нейронов, которые, в свою очередь, будут содержать больше внутренних переменных?
l0 = tf.keras.layers.Dense(units=4, input_shape=[1]) l1 = tf.keras.layers.Dense(units=4) l2 = tf.keras.layers.Dense(units=1) model = tf.keras.Sequential([l0, l1, l2]) model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(0.1)) model.fit(celsius_q, fahrenheit_a, epochs=500, verbose=False) print("Закончили обучение модели") print(model.predict([100.0])) print("Модель предсказала, что 100 градусов Цельсия соответствуют <> градусам Фаренгейта".format(model.predict([100.0]))) print("Значения внутренних переменных слоя l0: <>".format(l0.get_weights())) print("Значения внутренних переменных слоя l1: <>".format(l1.get_weights())) print("Значения внутренних переменных слоя l2: <>".format(l2.get_weights()))
Закончили обучение модели [[211.74748]] Модель предсказала, что 100 градусов Цельсия соответствуют [[211.74748]] градусам Фаренгейта Значения внутренних переменных слоя l0: [array([[-0.5972079 , -0.05531882, -0.00833384, -0.10636603]], dtype=float32), array([-3.0981746, -1.8776944, 2.4708805, -2.9092448], dtype=float32)] Значения внутренних переменных слоя l1: [array([[ 0.09127654, 1.1659832 , -0.61909443, 0.3422218 ], [-0.7377194 , 0.20082018, -0.47870865, 0.30302727], [-0.1370897 , -0.0667181 , -0.39285263, -1.1399261 ], [-0.1576551 , 1.1161333 , -0.15552482, 0.39256814]], dtype=float32), array([-0.94946504, -2.9903848 , 2.9848468 , -2.9061244 ], dtype=float32)] Значения внутренних переменных слоя l2: [array([[-0.13567649], [-1.4634581 ], [ 0.68370366], [-1.2069695 ]], dtype=float32), array([2.9170544], dtype=float32)]
Как вы могли уже заметить, текущая модель тоже способна достаточно хорошо предсказывать соответствующие значения градусов Фаренгейта. Однако, если взглянуть на значения внутренних переменных (веса) нейронов по слоям, то никаких значений похожих на 1.8 и 32 мы уже не увидим. Добавленная сложность модели скрывает «простую» форму преобразования градусов Цельсия в градусы Фаренгейта.
Оставайся на связи и в следующей части мы рассмотрим то, каким образом работают Dense-слои «под капотом».
Краткое резюме
Поздравляем! Вы только что обучили свою первую модель. Мы на практике увидели, каким образом по входным и выходным значениям модель научилась умножать входное значение на 1.8 и прибавлять к нему 32 для получения корректного результата.
Это было по-настоящему впечатляюще, учитывая то, сколько строчек кода нам понадобилось написать:
l0 = tf.keras.layers.Dense(units=1, input_shape=[1]) model = tf.keras.Sequential([l0]) model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(0.1)) history = model.fit(celsius_q, fahrenheit_a, epochs=500, verbose=False) model.predict([100.0])
Приведённый выше пример — общий план для всех программ машинного обучения. Вы будете использовать подобные конструкции для создания и обучения нейронных сетей и для решения последующих задач.
Процесс тренировки
Процесс тренировки (происходящий в методе model.fit(. ) ) состоит из весьма простой последовательности действий, результатом которых должны стать значения внутренних переменных дающих максимально близкий к исходному результаты. Процесс оптимизации, благодаря которому достигаются такие результаты, называется градиентным спуском, использует численный анализ для поиска максимально подходящих значений для внутренних переменных модели.
Чтобы заниматься машинным обучением вам, в принципе, нет необходимости разбираться в этих деталях. Но для тех, кому всё-таки интересно узнать больше: градиентный спуск посредством итераций изменяет значения параметров по-немногу, «вытягивая» их в нужном направлении, до тех пор пока не будут получены наилучшие результаты. В данном случае «лучшие результаты» (лучшие значения) означают, что любое последующее изменение параметра только ухудшит результат модели. Функция, которая измеряет насколько хороша или плоха модель на каждой итерации называется «функцией потерь», и цель каждого «вытягивания» (корректировки внутренних значений) — уменьшить значение функции потерь.
Процесс тренировки начинается с блока «прямое распространение», при котором входные параметры поступают на вход нейронной сети, следуют к скрытым нейронам и затем идут к выходным. Затем модель применяет внутренние преобразования над входными значениями и внутренними переменными для предсказания ответа.
В нашем примере, входным значением является температура в градусах Цельсия и модель предсказывала соответствующее значение в градусах Фаренгейта.
Как только значение предсказано, происходит вычисление разности между предсказанным значением и корректным. Разница называется «потерей» и является формой измерения того, насколько хорошо модель сработала. Значение потери вычисляется функцией потерь, которую мы определили одним из аргументов при вызове метода model.compile(. ) .
После вычисления значения потери, внутренние переменные (веса и смещения) всех слоёв нейронной сети подвергаются корректировке для минимизации значения потери с целью приближения выходного значения к корректному исходному эталонному значению.
Этот процесс оптимизации носит название градиентного спуска. Конкретный алгоритм оптимизации используется для вычисления нового значения для каждой внутренней переменной при вызове метода model.compile(. ) . В приведённом выше примере мы использовали алгоритм оптимизации Adam .
Для этого курса не является обязательным понимание принципов работы процесса тренировки, однако, если вы достаточно любопытны, то можете найти больше информации в Google Crash Course (перевод и практическая часть всего курса заложены у автора в планах к публикации).
К этому моменты вы уже должны быть знакомы со следующими терминами:
- Свойство: входное значение нашей модели;
- Примеры: пары входное+выходное значений;
- Метки: выходные значения модели;
- Слои: коллекция узлов объединенных вместе в рамках нейронной сети;
- Модель: представление вашей нейронной сети;
- Плотный и полностью связный: каждый узел в одном слое связан с каждым узлом из предыдущего слоя.
- Веса и смещения: внутренние переменные модели;
- Потери: разница между желаемым выходным значением и фактическим выходным значением модели;
- MSE: среднеквадратичное отклонение, тип функции потерь, которые считают малое количество больших ошибок вариантом хуже, чем большое количество малых.
- Градиентный спуск: алгоритм, который изменяет внутренние переменные по-немногу при каждой итерации с целью уменьшения значения функции потерь;
- Оптимизатор: конкретная реализация алгоритма градиентного спуска;
- Коэффициент скорости обучения: размер «шага» при снижении потерь во время градиентного спуска;
- Серия: набор данных для обучения нейронной сети;
- Эпоха: полный проход по всей серии исходных данных;
- Прямое распространение: вычисление выходных значение по входным значениям;
- Обратное распространение: вычисление значений внутренних переменных согласно алгоритму оптимизации, начинающегося с выходного слоя и по направлению к входному слою через все промежуточные слои.
Dense-слои
В предыдущей части мы создали модель, которая конвертирует градусы Цельсия в градусы Фаренгейта, используя простую нейронную сеть для нахождения зависимости между градусами Цельсия и градусами Фаренгейта.
Наша сеть состоит из единственного полносвязного слоя. Но что такое полносвязный слой? Чтобы в этом разобраться давайте создадим более сложную нейронную сеть у которой 3 входных параметра, один скрытый слой с двумя нейронами и один выходной слой с единственным нейроном.
Напомним, что нейронную сеть можно представить себе как набор слоёв, каждый из которых состоит из узлов, называемых нейронами. Нейроны на каждом уровне могут быть соединены с нейронами каждого последующего слоя. Тип слоёв, в котором каждый нейрон одного слоя соединён с каждым другим нейроном следующего слоя, называется полностью связным (полносвязным) или плотным слоем ( Dense -слой).
Таким образом, когда мы используем полносвязные слои в keras , мы как бы сообщаем, что нейроны этого слоя должны быть связаны со всеми нейронами предыдущего слоя.
Чтобы создать приведенную выше нейронную сеть нам достаточно следующих выражений:
hidden = tf.keras.layers.Dense(units=2, input_shape=[3]) output = tf.keras.layers.Dense(units=1) model = tf.keras.Sequential([hidden, output])
Итак, мы разобрались с тем, что такое нейроны и как они связаны между собой. Но как на самом деле работают полносвязные слои?
Чтобы понять, что же на самом деле там происходит и что они делают, нам понадобится заглянуть «под капот» и разобрать внутреннюю математику нейронов.
Представим, что наша модель принимает на вход три параметра — х1, х2, х3 , а а1, а2 и а3 — нейроны нашей сети. Помните мы говорили, что у нейрона есть внутренние переменные? Так вот, w* и b* являются теми самыми внутренними переменными нейрона, так же известными как веса и смещения. Именно значения этих переменных подвергаются корректировке в процессе обучения для получения максимально точных результатов сопоставления входных значений выходным.
Что обязательно стоит иметь ввиду — внутренняя математика нейрона остаётся неизменной. Другими словами, в процессе тренировки меняются только веса и смещения.
Когда начинаешь изучать машинное обучение это может показаться странным — тот факт, что это действительно работает, но именно так работает машинное обучение!
Давайте теперь вернёмся к нашему примеру конвертации градусов Цельсия в градусы Фаренгейта.
С единственным нейроном у нас есть только один вес и одно смещение. Знаете что? Это именно то, как выглядит формула конвертации градусов Цельсия в градусы Фаренгейта. Если мы подставим под w11 значение 1.8 , а вместо b1 — 32 , то получим конечную модель преобразования!
Если мы вернёмся к результатам работы нашей модели из практической части, то обратим внимание на то, что показатели веса и смещения были «откалиброваны» таким образом, что примерно соответствуют значениям из формулы.
Мы целенаправленно создали именно такой практический пример, чтобы наглядно показать точное сопоставление между весами и смещениями. Применяя машинное обучение на практике, мы никогда не сможем подобным образом сопоставить значения переменных с целевым алгоритмом, как в приведённом выше примере. Как мы сможем это сделать? Никак, потому что мы даже не знаем целевого алгоритма!
Решая задачи машинного обучения мы тестируем различные архитектуры нейронных сетей с различным количеством нейронов в них — методом проб и ошибок находим наиболее точные архитектуры и модели и надеемся, что они решат поставленную задачу в процессе обучения. В следующей практической части мы сможем изучить конкретные примеры такого подхода.
Оставайтесь на связи, потому что сейчас начнётся самое интересное!
Итоги
В этом уроке мы научились базовым подходам в машинном обучении и узнали как работают полносвязные слои ( Dense -слои). Вы обучили свою первую модель преобразовывать градусы Цельсия в градусы Фаренгейта. Вы так же изучили основные термины используемые в машинном обучении, такие как свойства, примеры, метки. Вы, ко всему прочему, написали основные строчки кода на Python, которые являются костяком любого алгоритма машинного обучения. Вы увидели, что в несколько строчек кода можно создать, обучить и запросить предсказание у нейронной сети с использованием TensorFlow и Keras .
… и стандартные call-to-action — подписывайся, ставь плюс и делай share 🙂
Что такое предикторы в машинном обучении
Выделение признаков: зачем отбирать предикторы и как это правильно сделать — готовим датасет к Data Mining и Machine Learning
Даже после очистки и нормализации данных, выборка еще не совсем готова к моделированию. Для машинного обучения (Machine Learning) нужны только те переменные, которые на самом деле влияют на итоговый результат. В этой статье мы расскажем, что такое отбор или выделение признаков (Feature Selection) и почему этот этап подготовки данных (Data Preparation) действительно необходим.
Что такое отбор признаков и зачем он нужен
Выделение или отбор признаков — это процедура отбрасывания незначащих переменных из очищенной выборки перед запуском машинного обучения и интеллектуального анализа данных (Data Mining). Сокращение числа предикторов необходимо по нескольким причинам:
· значимость признаков — как правило, исходная выборка всегда содержит много «мусорных данных»: шумов, выбросов, а на реальный результат влияют лишь несколько предикторов [1];
· точность решения — некоторые модели Machine Learning чувствительны к величине входного вектора. Например, у нейросетей большое число входных данных может привести к переобучению [2];
· скорость вычислений — чем меньше переменных, тем быстрее будут идти расчеты.
Таким образом, снижение размерности задачи — необходимый этап подготовки данных, который оказывает решающее значение на итоговый результат.
Снижение размерности задачи — обязательная процедура подготовки данных к моделированию
Как отбирать признаки: методы Feature Selection
Методы отбора признаков принято делить на несколько категорий:
· методы фильтрации (filter methods), основанные на теории вероятностей и статистических подходах. Наиболее популярными в этой группе методов считаются IG-индексирование (вычисление information gain), хи-квадрат (chi-square) и mRmR, которые позволяют ранжировать признаки по значимости, оценив степень корреляции каждого из них с целевой переменной. Далее модель машинного обучения использует только те предикторы, которые соответствуют определенным критериям. Методы фильтрации хороши тем, что они достаточно быстро работают: у них низкая стоимость вычислений, которая зависит линейно от общего количества предикторов. Однако, они рассматривают каждый признак изолированно, не учитывая их взаимное влияние друг на друга в частности и на целевую переменную вообще. Поэтому точность моделирования с этими методами отбора признаков недостаточно высока [2].
· оберточные методы (wrapper methods) — поисковые алгоритмы, которые рассматривают предикторы как входы, а эффективность модели как выходы, которые должны быть оптимизированы [1]. Классификатор запускается на разных подмножествах признаков исходной тренировочной выборки. В этой категории есть 2 подхода: включение (forward selection) и исключение (backwards selection) предикторов. Методы включения начинают с пустого подмножества, куда постепенно добавляются разные признаки. В случае исключения метод стартует с исходного множества признаков, постепенно удаляя из него переменные и пересчитывая классификатор. Далее выбирается подмножество признаков с наилучшими параметрами на обучающей выборке и тестируется на контрольном (тестовом) датасете [2]. Есть много способов перебора предикторов: рекурсивное удаление и добавление, генетические алгоритмы, имитация отжига и т.д. [1]. Оберточные методы отслеживают взаимосвязи между признаками, однако они требуют большего количества времени, чем фильтрация. А в случае большого количества признаков и небольшого размера тренировочного сета существует опасность переобучения [2].
· встроенные методы (embedded methods), которые не разделяют отбор признаков и обучение классификатора, а выделяют предикторы во время процесса расчета модели. Эти алгоритмы требуют меньше вычислений, чем оберточные методы, но больше, чем фильтрация. Основным методом этой категории является регуляризация [2] — добавление дополнительных ограничений (штрафов) к условиям задачи, чтобы построить алгоритм, минимизирующий ошибку и количество используемых переменных. При этом выделяют 2 подхода: L1 (лассо, lasso regression, регуляризация через манхэттенское расстояние) и L2 (регуляризация Тихонова или ридж-регрессия, ridge regression) [3]. Регуляризация позволяет выявить взаимовлияние переменных, но занимает больше времени, чем методы фильтрации [2].
Анализ взаимовлияния предикторов — важная задача Feature Selection
Как реализовать Feature Selection на практике и другие особенности Data Preparation в нашем новом курсе обучения для data scientist и аналитиков больших данных в Москве: подготовка данных для Data Mining. Следите за новостями!
Оценка и выбор переменных для моделей машинного обучения
В статье будут рассмотрены особенности выбора, предподготовки и оценки входных переменных для использования в моделях машинного обучения. Будут рассмотрены множественные методы нормализации и их особенности. Будут указаны важные моменты этого процесса, сильно влияющие на конечный результат обучения моделей. Рассмотрим и оценим новые и малоизвестные методы определения информативности входных данных и визуализации их.
С помощью пакета «RandomUniformForests» вычислим и рассмотрим понятие важности переменной на различных уровнях и в различных сочетаниях, соответствие предикторов и целевой, а также взаимодействие между предикторами, выбор оптимального набора предикторов с учетом всех аспектов важности.
С помощью пакета «RoughSets» рассмотрим эту же проблему выбора предикторов под другим углом и на основании другой концепции. Покажем, что не только набор предикторов может быть оптимальным, но и набор примеров для обучения тоже может быть оптимизирован.
Все расчеты и эксперименты будут проводиться на языке R, конкретнее на Revolution R Open 3.2.1 .
1. Входные переменные (признаки, предикторы)
Все переменные, и входные (независимые, предикторы), и выходные (целевые) , могут быть следующих типов:
Номинальные (факторы), имеют конечное количество уровней. Например фактор «день_недели» имеет семь уровней, каждый из которых может быть поименован (понедельник, вторник и т. д.). Факторы могут быть упорядоченными и неупорядоченными. Например фактор «час_суток» имеет 24 уровня и он упорядочен. Фактор «район_города» с 32 уровнями не упорядочен, так как все уровни имеют равную значимость. При объявлении упорядоченного фактора нужно явно об этом указывать.
Количественные (числовые) непрерывные. Диапазон непрерывных переменных от — Inf (бесконечности) до +Inf.
В качестве числовых входных переменных не используют «сырые» данные котировок (OHLC). Применяют логарифм разности или логарифм отношения котировок. Но чаще применяются разнообразные индикаторы, объединенные в наборы. Как правило, набор входных данных формируют в виде матрицы, если все переменные однородны, или, что чаще, в виде датафрейма, в котором каждый столбец — переменная, строка — состояние переменных в конкретный момент. В последней (или первой) колонке располагают целевую переменную.
1.1. Очистка
Под очисткой понимают:
а) Удаление или преобразование пропущенных (неопределенных) данных «NA».
Многие модели не допускают во входных данных пропуски. Поэтому или удаляем строки с пропущенными данными, или заполняем пропуски интерполированными данными. Во многих пакетах для этого предусмотрены соответствующие функции. Удаление неопределенных данных NA, как правило, заложено в моделях по умолчанию, но лучше это сделать самому через na.omit(dt) до начала обучения.
б) Удаление «нуль-вариантных» переменных (числовых и номинальных).
В некоторых ситуациях (особенно при трансформации или преобразовании переменных) могут появится предикторы с единственным уникальным значением или несколькими такими значениями, происходящими с очень низкой частотой. Для многих моделей это может привести к краху или к нестабильной работе. Эти «почти-нулевой-дисперсии» («near-zero-variance») предикторы должны быть выявлены и устранены до моделирования. Для выявления и удаления таких предикторов в пакете «caret» существует специальная функция caret::nearZeroVar(). Обязательность этого пункта не бесспорна.
в) Выявление и удаление коррелированых предикторов (числовых).
В то время как некоторые модели отлично справляются с коррелированными предикторами (например PLS, LARS и подобные, использующие регуляризацию L1), другие модели могут получить преимущества от снижения уровня корреляции между предикторами. Для выявления и удаления сильно коррелированных предикторов (задается порог коэффициента корреляции, например > 0.9) используем функцию caret::findCorrelation() из того же пакета «caret». Очень мощный пакет, рекомендую для изучения.
г) Выявление и удаление линейных зависимостей (факторы).
Функция caret::findLinearCombos() используя QR-разложение матрицы перечислений устанавливает линейные комбинации из них (если они есть). Например рассмотрим следующую матрицу:
Обратите внимание, что столбцы 2 и 3 являются дополнениями первого. Аналогично, 4, 5 и 6 столбец складываются в первый. Функция caret::findLinearCombos() вернет список, который перечислит эти зависимости, а также вектор позиций столбцов, которые могут быть удалены для устранения линейной зависимости.
Этот тип зависимостей может возникнуть, когда используется большое число бинарных предикторов, или когда факторные предикторы преобразовываются в «dummy».
1.2. Трансформация, препроцессинг данных
Многие модели требуют, чтобы числовые входные данные находились в определенном диапазоне (нормализация, стандартизация) или были преобразованы определенным образом (факторы). Например нейросети и машины опорных векторов (SVM) воспринимают входные данные в диапазоне [-1:1] или [0:1]. Многие пакеты в языке R предлагают специальные функции для такого преобразования либо самостоятельно преобразовывают их. Необходимо помнить, что определение параметров препроцессинга выполняется только на тренировочном наборе входных данных. Тестовый и валидационный наборы и новые данные, поступающие модели для предсказания, преобразовываются с параметрами, полученными на тренировочном наборе.
Нормализация (масштабирование)
Общая формула приведения переменной в диапазон . В зависимости от необходимого диапазона h = +1; l = (-1 или 0). В некоторых источниках рекомендуют сужать диапазон до или с тем, чтобы не использовать участки насыщения функций активации (tanh/sig). Это относится к нейросетям, SVM и другим моделям с названными функциями активации.
Xn = (x — min(x)) / (max(x) — min(x)) * (h — l) + l;
Обратное преобразование (денормализация) производится по формуле
x = (x — l) / (h — l) * (max(x) — min(x)) + min(x);
Стандартизация
Если известно, что распределение переменной близко к нормальному, можно нормализовать по формуле
x = (x — mean(x)) / sd(x)
В некоторых пакетах для препроцессинга предусмотрены специальные функции. Так, в пакете «caret» функция preProcess() предоставляет следующие методы препроцессинга: «BoxCox», «YeoJohnson», «expoTrans», «center», «scale», «range», «knnImpute», «bagImpute», «medianImpute», «pca», «ica» и «spatialSign».
«BoxCox», «YeoJohnson», «expoTrans»
Yeо-Johnson преобразование немного схоже с моделью Бокс-Кокс, но может принять предикторы с нулевыми или отрицательными значениями (в то время как значения предикторов для Бокс-Кокс преобразования должны быть строго положительными). Экспоненциальное преобразование Мэнли (1976) может также использоваться для положительных или отрицательных данных.
«range» преобразование масштабирует данные в пределах [0, 1]. Важно! Если новые образцы будут иметь значения больше или меньше, чем те, что были в обучающем наборе, значения будут за пределами этого диапазона, и результат прогноза будет некорректным.
«center» — вычитается среднее, «scale» — делим на стандартное отклонение (шкалирование). Как правило, применяются вместе, и это называется «стандартизация».
«knnImpute», «bagImpute», «medianImpute» — вычисление пропущенных или неопределенных данных различными алгоритмами.
«spatialSign» — трансформация, проецирует данные предикторов на единичную окружность в р измерениях, где р — число предикторов. По сути, вектор данных делится на его норму. Данные перед трансформацией должны быть центрированы и шкалированы.
«pca» — в некоторых случаях существует необходимость в использовании анализа главных компонент (principal component analysis) для преобразования данных в меньшее подпространство, где новые переменные не коррелируют друг с другом. При использовании этого метода автоматически проводится центрирование и шкалирование, и изменяются имена столбцов на РС1, РС2 и т.д.
«isa» — точно так же, анализ независимых компонент (independent component analysis) может быть использован, чтобы найти новые переменные, которые являются линейными комбинациями исходного набора, такими, что компоненты являются независимыми (в отличии от некоррелированных в PCA). Новые переменные будут помечены как IC1, IC2 и т.д.
В отличном пакете «clusterSim», предназначенном для поиска оптимальных процедур кластеризации данных, имеется функция dataNormalization() , которая нормализует данные 18 способами, причем не только по столбцам, но и по строкам. Просто перечислю:
n1 — (standardization) стандартизация ((x – mean) / sd);
n2 — (positional standardization) позиционная стандартизация ((x – median) / mad);
n3 — unitization ((x – mean) / range);
n3а — positional unitization ((x – median) / range);
n4 — unitization with zero minimum ((x – min) / range);
n5 — (normalization in range) нормализация в диапазон ((x – mean) / max(abs(x – mean)));
n5a — positional normalization in range ((x – median) / max(abs(x-median)));
n6 — (quotient transformation) долевая трансформация (x/sd);
n6a — (positional quotient transformation) позиционная долевая трансформация (x/mad);
n7 — quotient transformation (x/range);
n8 — quotient transformation (x/max);
n9 — quotient transformation (x/mean);
n9a — positional quotient transformation (x/median);
n10 — quotient transformation (x/sum);
n11 — quotient transformation (x/sqrt(SSQ));
n12 — normalization ((x-mean)/sqrt(sum((x-mean)^2)));
n12a — positional normalization ((x-median)/sqrt(sum((x-median)^2)));
n13 — (normalization with zero being the central point) нормализация, когда ноль является центральной точкой ((x-midrange)/(range/2)).
«Dummy Variables» — многие модели требуют преобразовывать факторные предикторы в «фиктивные переменные». Для этого может быть использована функция dummyVar() из пакета «caret». Функция принимает формулу и набор данных и выводит объект, который можно использовать для создания фиктивных переменных.
2. Выходные данные (целевая переменная)
Поскольку мы решаем задачу классификации, целевая переменная является фактором с некоторым количеством уровней (классов). Большинство моделей дают лучшие результаты при обучении на целевой с двумя классами. При наличии большего количества классов принимаются специальные дополнительные меры для решения таких задач. Целевая переменная при подготовке данных для обучения кодируется, а после предсказания декодируется.
Кодируются классы несколькими способами. В пакете RSNNS «Симулятор нейросетей Штутгартского университета» предусмотрены две функции — decodeClassLabels() кодирует вектор с классами в матрицу, содержащую столбцы, соответствующие классам, и encodeClassLabels(), которая делает обратное преобразование после предсказания модели. Просто для примера:
Таким образом, количество выходов модели равно количеству классов целевой. Это не единственный способ кодирования (один-к-одному), применяемый для целевой. Если целевая имеет два класса, можно обойтись одним выходом. Кодирование целевой переменной в матрицу имеет ряд преимуществ.
3. Оценка и выбор предикторов
Как показывает практика, увеличение количества входных данных (предикторов) не всегда ведет к улучшению модели, а скорее наоборот. Как правило, на результат реально влияют 3-5 предикторов. Во многих агрегирующих пакетах, таких как «rminer», «caret», «SuperLearner» и «mlr», существуют встроенные функции по вычислению «важности» переменных (importance of variable) и их отбору. Большинство подходов по сокращению количества предикторов могут быть разнесены в две категории (используя терминологию John, Kohavi и Pfleger, 1994):
-
Фильтрация. Методы фильтрации оценивают актуальность предикторов вне моделей предсказания, и впоследствии модель использует только те предикторы, которые соответствуют каким-либо критериям. Например, для задач классификации каждый предиктор может быть индивидуально оценен, чтобы проверить, есть ли правдоподобное отношение между ним и наблюдаемыми классами. Только предикторы с важными прогностическими зависимостями будут затем включены в классификационную модель.
Обертка. Оберточные методы оценивают различные модели, используя процедуры, которые добавляют и/или удаляют предикторы для поиска оптимальной комбинации, оптимизирующей эффективность модели. В сущности, оберточные методы — это поисковые алгоритмы, которые рассматривают предикторы как входы и используют эффективность модели как выходы, которые должны быть оптимизированы. Существует множество способов перебора предикторов (рекурсивное удаление/добавление, генетические алгоритмы, имитация отжига и многие другие).
Оба подхода имеют свои преимущества и недостатки. Методы фильтров, как правило, вычислительно более эффективны чем методы обертки, но критерии отбора непосредственно не связаны с эффективностью модели. Недостатком метода оберток является то, что оценивание множества моделей (которые могут потребовать настройку гиперпараметров) приводит к резкому увеличению времени вычисления и, как правило, к переобучению модели.
В настоящей статье мы не будем рассматривать оберточные методы, а рассмотрим новые методы и подходы методов фильтрации, которые, по моему мнению, устраняют указанные выше недостатки.
3.1. Фильтрация
С помощью различных сторонних методов и критериев определяют важность (информативность) предикторов. Под важностью здесь понимается вклад каждой переменной в повышение качества предсказания модели.
После этого, как правило, возможны три варианта:
Берется конкретное количество предикторов с наибольшей важностью.
Берется процент от общего количества предикторов с наибольшей важностью.
Во всех случаях возможна оптимизация количества, процента или порога.
Для рассмотрения конкретных методов и проведения экспериментов давайте сформируем набор входных и выходных данных.
Входные данные
Во входной набор включим 11 индикаторов (осцилляторов) без предварительных предпочтений. Из некоторых индикаторов возьмем по нескольку переменных. Напишем функцию, формирующую входной набор из 17 переменных.
Берем котировки из последних 4000 баров на ТФ = М30 /EURUSD.
Эти индикаторы общеизвестны и широко применяемы. Не будем разбирать их снова. Прокомментирую только применяемый при вычислении метод «pipe»(%>%) из пакета «magrittr» на примере индикатора MACD. В порядке записи:
Вычисляем индикатор, который возвращает две переменных (macd, signal).
Преобразовываем полученную матрицу в датафрейм.
Добавляем в датафрейм новую переменную vsig ( в порядке записи):
- берем переменную signal;
- вычисляем первую разность;
- добавляем в начало вектора NA, так как при вычислении первой разности вектор короче исходного на единицу;
- умножим его на 10.
Выберем из датафрейма только нужные нам переменные (столбцы) vsig, signal.
Превратим датафрейм в матрицу.
Этот способ вычислений очень удобен в случае, когда промежуточные результаты вычислений нам не нужны. Кроме того, формулы намного легче читаются и понимаются.
Получим матрицу входных данных и посмотрим на содержание.
Выходные данные (целевая)
В качестве целевой переменной возьмем сигналы, полученные с ZZ. Формула вычисления зигзага и сигнала:
В параметрах функции:
- pr = price — матрица котировок OHLCMed;
- ch — минимальная длина колена зигзага в пунктах (4 знака);
- mode — применяемая цена (m — средняя, hl — High и Low, cl — Close). По умолчанию применяем среднюю.
Функция возвращает матрицу с двумя переменными — собственно зигзаг и сигнал, полученный на базе наклона зигзага в диапазоне [-1;1].
Вычисляем сигналы для двух ZZ с разной длиной колен:
На графике они будут выглядеть так:
https://amdy.su/wp-admin/options-general.php?page=ad-inserter.php#tab-8
Рис. 1. Зигзаги с минимальной длиной колен 25/75 п
Дальше будем использовать первый ZZ с меньшим коленом. Объединим входные переменные и целевую в общий датафрейм, уберем неопределенные данные, данные, где состояние = «0» и уберем из целевой класс «0».
Посмотрим на распределение классов в целевой:
Как видим, классы хорошо сбалансированы. Сейчас у нас готов набор входных и выходных данных, и мы можем приступить к оценке важности предикторов.
Сначала проверим, насколько коррелированы входные данные:
У каких входных переменных корреляция более 90%?
Это rsi и SMI. Сформируем набор данных без этих двух и посмотрим корреляцию оставшихся.
Для оценки «важности переменных» (Variable Importance, VI) используем новый пакет «Random Uniform Forests», в котором есть широкий набор инструментов для ее глубокого анализа и визуализации. По замыслу разработчиков пакета: основная цель определения важности переменных — это оценка того, какие переменные, когда, где и как влияют на решаемую проблему.
Пакет предоставляет различные меры важности переменной по глубине. Рассмотрим их, прежде чем пойдем к более глубоким оценкам.
Глобальная важность переменной (Global Variable Importance) — определяет переменные, которые сильнее уменьшают ошибку предсказания, но она ничего не говорит нам о том, как важная переменная влияет на отклики.
Мы хотели бы знать, например, какие переменные сильнее влияют на отдельный класс или мы хотели бы знать взаимодействие между переменными.
Важность переменной измеряется по всем узлам и всем деревьям, что позволяет всем переменным иметь значение, так как точки нарезки случайны. Следовательно, каждая переменная имеет равные шансы быть выбранной, но она будет получать важность, только если будет сильнее остальных уменьшать энтропию в каждом узле.
Локальная важность переменной (Local Variable Importance)
Определение: Предиктор локально важен в первом порядке, если для того же наблюдения и всех деревьев это тот, который имеет самую высокую частоту возникновения в терминальном узле.
Частичная важность (Partial importance)
Определение: Предиктор частично важен, если для того же наблюдения, одного класса и на всех порядках это тот, который имеет самую высокую частоту возникновения на терминальном узле.
Взаимодействия (Interactions)
Мы хотим знать, как предикторы влияют на проблему, когда мы рассматриваем их все. Например, некоторые переменные могут иметь низкое относительное влияние на проблему, но сильное влияние на более релевантные переменные, или переменная может иметь множество взаимодействий с другими, что делает переменную влиятельной. Дадим определение взаимодействию.
Определение: Предиктор взаимодействует с другим, если по тому же наблюдению и для всех деревьев оба имеют соответственно первую и вторую высшую частоту встречаемости в терминальном узле.
Частичные зависимости (Partial dependencies)
Это инструменты, которые позволяют определить, насколько переменная (или пара переменных) влияет на значение отклика, зная значения всех других переменных. Более наглядно, частичная зависимость — это участок, где проявляется максимальный эффект влияния переменной на значение отклика. Идея частичной зависимости пришла от Фридмана (Friedman, 2002), который использовал ее в Gradient Boosting Machines (GBM), но в Random Uniform Forests она реализована различно.
В соответствии с идеями пакета Random Uniform Forests мы можем определить важность переменной по следующей схеме: Важность = вклад + взаимодействия, где вклад является влиянием переменной (по отношению к воздействию всех) на ошибки предсказания, а взаимодействие — влияние на другие переменные.
Перейдем к экспериментам
Разобьем наш набор данных data.f[] на тренировочный и тестовый c соотношением 2/3, нормализуем в диапазон -1;1 и протестируем пробно модель. Для разбиения используем функцию rminer::holdout() , которая стратифицированно разделяет набор на два. Для нормализации используем функцию caret::preProcess() и метод method = c(«spatialSign»). При обучении модели пакет автоматически распараллеливает вычисления между наличными ядрами процессора минус один, используя пакет «doParallel». Можно указать конкретное число ядер, которое нужно использовать при вычислениях с помощью опции «threads».
- Ошибка при обучении (внутренняя ошибка) с учетом 1% отклонения = 21.26%.
- Breiman’s bounds — теоретические свойства, предложенные Breiman (2001), так как Random Uniform Forests наследуют свойства Random Forests, то они применимы здесь. Для классификации это дает две границы ошибки предсказания, среднюю коррелляцию между деревьями, прочность (strength) и стандартное отклонение прочности.
- Ожидаемая ошибка предсказания = 18.42%. Верхняя граница ошибки = 27.76%.
- Ошибка при тестировании = 19.97% (внешняя ошибка). (Если внешняя оценка меньше или равна внутренней оценке и меньше верхней границы Breiman’s bounds, переобучение скорее всего не произойдет.)
Посмотрим график ошибки обучения:
Рис. 2. Ошибка обучения в зависимости от количества деревьев
Смотрим глобальную важность предикторов.
Мы видим, что все наши входные переменные значимы и важны. Указано, в каких классах переменные появляются чаще.
И еще немного статистики:
Рис. 3. Кривая точности-отзыва
Рис. 4. ROC-кривая или кривая ошибок
Если остановиться на этом, а это, как правило, и предлагают многие пакеты фильтров, то нам нужно было бы выбрать несколько предикторов с наилучшими показателями глобальной важности. Такой выбор не дает хороших результатов, так как он не учитывает взаимное влияние предикторов.
Локальная важность
Как видим, важность переменных на базе взаимодействия с другими выделяет десять лучших, которые не совпадают с порядком по глобальной важности. И наконец, важность переменных по классам с учетом их вклада и взаимодействия. Обратите внимание, что переменная tr, которая на базе глобальной важности была на последнем месте и по идее должна была быть отброшена, на базе сильного взаимодействия поднялась на шестое место.
Таким образом, 10 лучших переменных:
Проверим, как улучшилось качество модели с набором наиболее важных предикторов.
Рис. 5. ROC-кривая или кривая ошибок
Рис. 6. Кривая точности-отклика
Как видим, качество улучшилось. Ошибка предсказания на тестовом наборе 17.55% меньше верхней границы 28.18%, значит, переобучение маловероятно. Модель имеет множество других гиперпараметров, тюнинг которых может позволить еще более повысить качество модели, но это не есть задача настоящей статьи.
Продолжим изучать входные переменные в оптимальном наборе.
Рис. 7. Важность переменных на базе информационной ценности
Как видим, глобальная важность переменных практически выровнялась, но важность переменных по классам ранжирована совсем по-другому. Переменная tr — на третьем месте.
Частичная зависимость над предиктором
Рассмотрим частичную зависимость наиболее важных переменных.
Рис. 8. Частичная зависимость переменной cci
На рисунке выше показана частичная зависимость над предиктором cci. Разделение данных предиктора между классами относительно неплохое, хотя и есть перекрытие.
Рис. 9. Частичная зависимость переменной signal
Совсем другая картина частичной зависимости для предиктора signal на рисунке выше. Практически полное перекрытие данных для обоих классов.
Частичная зависимость предиктора tr показывает неплохое разделение по классам, но и здесь есть значительное перекрытие.
Рис. 10. Частичная зависимость переменной tr
Частичная зависимость предиктора chv совсем плачевна. Полное перекрытие данных по классам.
Рис. 11. Частичная зависимость переменной chv
Таким образом можно визуально определить, как связаны данные предикторов с классами, насколько они разделяемы.
Важность переменной на классах
«Важность переменной» по классам обеспечивает локальную точку зрения: класс фиксируется, это означает, что сначала принимается решение фиксировать класс, рассматривая переменные, которые важны и действуют как константы, после чего рассматриваются важные переменные для каждого класса. Следовательно, каждая переменная имеет важность, как если бы другие классы не существовали.
Здесь мы не интересуемся переменными, которые привели к выбору класса, но переменными, которые будут важны в классе, когда этот последний будет выбран. Порядок переменных дает их сводное ранжирование относительно их ранга в каждом классе, без учета важности класса.
Что показывает нам график? Предиктор tr гораздо важнее для класса «1», чем для класса «-1». И наоборот, предиктор oscK для класса «-1» намного более важен, чем для класса «1». Предикторы имеют различную важность в разных классах.
Рис. 12. Важность переменных по классам
Важность переменной на базе взаимодействия
Диаграмма ниже показывает, как каждая переменная представлена при объединенном взаимодействии с любой другой переменной. Одно важное замечание: самой важной является не обязательно первая переменная, но та, которая имеет наибольшее взаимное влияние с другими.
Рис. 13. Важность переменных на базе взаимодействий
Взаимодействие переменных на наблюдениях
Рис. 14. Важность переменных на наблюдениях
Рисунок выше показывает взаимодействия первого и второго порядка для всех предикторов в соответствии с определением, которое мы дали для взаимодействия. Его площадь равна единице. Первый порядок указывает, что переменные (упорядоченные по убыванию влияния) являются самыми важными, если решение должно быть принято, принимая во внимание одну и только одну переменную. Второй порядок указывает, что если неизвестная переменная уже выбрана в первом порядке, тогда вторая по важности переменная будет одной из тех во втором порядке.
Чтобы было яснее, взаимодействия предоставляют таблицу упорядоченных возможностей. Первый порядок дает упорядоченные возможности наиболее важных переменных. Второй порядок дает упорядоченные возможности вторых по важности переменных. Пересечение пары переменных дает их относительное взаимное влияние из всех возможных взаимных влияний. Можно отметить, что эти измерения зависят как от модели, так и от данных. Следовательно, уверенность в измерениях напрямую зависит от уверенности в предсказаниях. Можно также отметить, что появляется мета-переменная, называемая «другие признаки» , означающая, что мы позволяем алгоритму показать вид по умолчанию для визуализации сгруппированных переменных, которые являются менее актуальными.
Частичная важность
Можно посмотреть частичную важность на базе наблюдений x.tst над классом «-1».
Рис. 15. Частичная важность переменных на базе наблюдений на классе «-1»
Как видим, для класса «-1» наиболее важны пять предикторов, показанных на рисунке выше.
Теперь то же, но для класса «+1»
Рис. 16. Частичная важность переменных на базе наблюдений на классе «+1»
Видим, что предикторы отличаются как по составу, так и по ранжированию.
Посмотрим частичную зависимость между предикторами cci и atr, которые наиболее важны в первом и втором порядке взаимодействия предикторов.
Рис. 17. Частичная зависимость между предикторами cci и atr
Рис. 18. Зависимость между предикторами atr и cci
Рис. 19. Теплокарта зависимости предикторов atr и cci
Глобальная важность переменной была определена, чтобы описать, какие переменные в глобальном масштабе имеют наибольшее влияние на снижение ошибки предсказания.
Локальная важность переменной описывает то, что делает переменную влиятельной, используя ее взаимодействие с другими.
Это приводит к частичной важности, которая показывает, когда переменная является более важной. Последний шаг в анализе важности переменной — это частичная зависимость, определяющая, где и/или как каждая переменная связана с ответом.
Подводя итог: важность переменной в Random Uniform Forests идет от высшего уровня к нижнему с детализацией. Во-первых, мы узнаем, какие переменные важны, нюансы по весу в каждом классе. Затем мы находим, что делает их влиятельными, рассматривая их взаимодействия, и делаем выбор переменной, сперва рассматривая все классы как один. Следующий шаг — узнаем, где они получают свое влияние, рассматривая внутри каждого класса, когда он фиксирован. Наконец, мы получаем, когда и как переменная бывает важной, глядя на «частичную зависимость». Все измерения, кроме «глобальной важности переменной», работают на любом тренировочном или тестовом наборе.
Представленная многоуровневая оценка предикторов позволяет отобрать наиболее важные предикторы и сформировать оптимальные наборы, значительно понизив размерность данных и улучшив качество предсказания.
Можно оценить и выбрать не только предикторы, но и наиболее информативные экземпляры наблюдений.
Рассмотрим другой интересный пакет — «RoughSet».
Краткое описание: Есть две основные части, рассматриваемые в этом пакете — это Теория приближенных множеств (Rough Set Theory (RST)) и Теория нечетких приближенных множеств (Fuzzy Rough Set Theory (FRST)). RST была предложена Z. Pawlak (1982, 1991), она предоставляет сложные математические инструменты для моделирования и анализа информационных систем, которые включают неоднородности и неточности. Используя отношения неразличимости между объектами, RST не требует дополнительных параметров для извлечения информации.
Теория FRST, расширение RST, была предложена D. Dubois и H. Prade (1990), она сочетает понятия неопределенности и неразличимости, которые выражены в нечетких множествах, предложенных L.A. Zadeh (1965), и RST. Эта концепция позволяет анализировать непрерывные атрибуты (переменные) без предварительной дискретизации данных. На основании вышеописаных концепций многие методы были предложены и применены в нескольких различных областях. Для того чтобы решать проблемы, методы используют отношение неразличимости и концепцию нижней и верхней апроксимации.
Небольшое отступление
Способ представления знаний в информационной системе играет, как правило, большую роль. Наиболее известными способами представления знаний в системах индуктивного формирования понятий являются: продукционные правила, решающие деревья, исчисление предикатов и семантические сети.
При извлечении и обобщении знаний, хранящихся в реальных информационных массивах, возникают следующие основные проблемы:
- Данные являются разнородными (количественными, качественными, структурными).
- Реальные базы данных, как правило, велики, а потому алгоритмы экспоненциальной сложности для извлечения знаний из баз данных могут оказаться неприемлемыми.
- Информация, содержащаяся в реальных массивах данных, может быть неполна, избыточна, искажена, противоречива, а также некоторые значения ряда атрибутов могут вовсе отсутствовать. Поэтому для построения классификационных правил следует использовать только существенные атрибуты.
В настоящее время для извлечения знаний из баз данных (Data Mining) теория приближенных множеств (rough sets theory) все чаще используется как теоретическая база и набор практических методов.
Приближенные множества — это множества с неопределенными границами, т.е. множества, которые не могут быть точно описаны доступным набором признаков.
Теория приближенных множеств была предложена Здиславом Павлаком в 1982 году и явилась новым математическим инструментом работы с неполной информацией. Важнейшими понятиями данной теории являются так называемые верхняя и нижняя аппроксимации (lower and upper approximation) приближенного множества, позволяющие оценить возможность или необходимость принадлежности элемента множеству с «размытыми» границами .
Нижнюю аппроксимацию (приближение) составляют элементы, которые точно принадлежат X, верхнюю аппроксимацию (приближение) составляют элементы, которые возможно принадлежат X . Граничной областью (boundary region) множества X называется разность между верхней и нижней аппроксимацией, т.е. в граничную область входят элементы множества Х, принадлежащие верхней аппроксимации и не принадлежащие нижней аппроксимации.
Простая, но мощная концепция приближенных множеств стала базовой как в теоретических исследованиях — логике, алгебре, топологии, так и в прикладных — задачах искусственного интеллекта, приближенных рассуждениях, интеллектуальном анализе данных, теории принятия решений, обработке изображений и распознавании образов.
Концепция «приближенного множества» имеет дело с «несовершенством данных» (imperfection), относящимся к «гранулярности» информации (granularity). Эта концепция по своей природе является топологической и дополняет другие известные подходы, используемые для работы с неполной информацией, такие как нечеткие множества (fuzzy sets), методы Байеса (Bayesian reasoning), нейронные сети (neural networks), эволюционные алгоритмы (evolutionary algorithms), статистические методы анализа данных.
Продолжим. Все методы, представленные в этом пакете, можно сгруппировать следующим образом:
Базовые понятия RST и FRST. В этой части мы можем видеть четыре различные задачи — отношение неразличимости (indiscernibility relation), нижнее и верхнее приближение (lower and upper approximation), положительный регион (positive region) и матрица отличий (discernibility matrix).
Дискретизация. Он используется для преобразования вещественных данных в номинальные. С точки зрения RST эта задача пытается поддержать различимость (discernibility) между объектами.
Выбор предикторов (Feature selection). Это процесс нахождения подмножества предикторов, которые пытаются получить то же качество, что и полный набор предикторов. Иными словами, цель заключается в выборе существенных особенностей и ликвидации их зависимости. Это полезно и необходимо, когда мы сталкиваемся с наборами данных, содержащих большое количество признаков. С точки зрения RST и FRST выбор предикторов относится к поиску superreducts и reducts.
Выбор экземпляров (Instance selection). Этот процесс направлен на удаление шумных, лишних или противоречивых экземпляров из учебных наборов данных, но сохранение согласованных. Таким образом, хорошая точность классификации достигается путем удаления экземпляров, которые не дают позитивного вклада.
Индукция правил (Rule induction). Как мы уже говорили, задача индукции правил используется для генерации правил, представляющих знания таблицы решений. Как правило, этот процесс называется фазой обучения в машинном обучении.
Прогноз/классификация (Prediction/classification). Эта задача используется для предсказания значения переменной от нового набора данных (тестового набора).
Из этого перечня мы будем исследовать два — выбор предикторов и выбор экземпляров.
Сформируем наборы входных и выходных данных. Будем использовать те же данные, которые мы получили выше, но преобразуем их в класс «DecisionTable», с которым оперирует пакет.
Как мы сказали выше, RST использует номинальные данные. Поскольку у нас данные числовые непрерывные, мы преобразуем их в номинальные с помощью одной из специализированных функций дискретизации, имеющихся в пакете.
Посмотрим, что у нас в результате
Мы видим, что предикторы дискретизированы различно. Такие переменные, как slowD, sign, вообще не разделены. Переменные signal, vsig, cci, oscDX просто разделены на два участка. Остальные переменные разбиты от 3 до 6 классов.
Выберем важные переменные:
Те данные, которые не были разделены (slowD, sign), выброшены из набора. Проведем дискретизацию тестового набора и преобразуем их в соответствии с проведенной редукцией.
А теперь, используя одну замечательную возможность пакета, которая называется «индукция правил», извлечем набор правил, которые связывают предикторы и целевую. Используем одну из функций:
Проверим на тестовом наборе, как работают эти правила при предсказании:
Ну а теперь — выбор значимых примеров:
Около 300 примеров были оценены как незначительные и отброшены. Извлечем набор правил из этого набора и сравним качество предсказания с предыдущим набором.
Качество выше, чем в предыдущем случае. Нужно заметить, что как и в случае с RandomUniformForests, получить воспроизводимые результаты при повторных экспериментах невозможно. Каждый новый запуск дает немного различный результат.
Как выглядят правила? Посмотрим:
Это лист, содержащий следующие данные:
- $idx — индексы предикторов, участвующие в этом правиле. В примере выше это 6(«atr») , 4(«ar») и 11(«vsig»).
- $values — диапазон значений индикаторов, в котором работает это правило.
- $consequent — решение (следствие): . На «человеческом» это звучит так: если «atr»в диапазоне «(85.1, Inf]» И «ar»в диапазоне «(0.00137, Inf]» И «vsig»в диапазоне «(0.0374, Inf]» ТО .
- $support — индексы примеров, поддерживающих это решение.
- $laplace — оценка уровня доверия для этого правила.
Вычисление правил занимает значительное время.
Заключение
Мы рассмотрели новые возможности по оценке предикторов, их визуализации, выбору наиболее значимых. Рассмотрели различные уровни важности, зависимости предикторов и их влияние на отклики. Результаты экспериментов будут применены в следующей статье, где мы рассмотрим глубокие сети с RBM.
Что такое предикторы в машинном обучении
Предварительная обработка данных в машинном обучении – это важный шаг, который помогает повысить качество данных. Предобработка данных в машинном обучении относится к технике подготовки необработанных данных с целью сделать их пригодными для построения и обучения моделей машинного обучения. Иными словами, это метод интеллектуального анализа данных, который преобразует необработанные данные в понятный и читаемый формат.
Предварительная обработка данных является одним из основных этапов, от качества выполнения которого зависит получение качественных результатов процесса анализа данных. Без подготовки данных не обходится ни один нейросетевой метод. Как правило, при описании различных нейроархитектур предполагается, что данные для обучения уже представлены в том виде, в котором требует нейросеть, однако на практике дела обстоят совсем иначе, именно этап предобработки данных может занимать большую часть времени, отведенного на проект в целом. Результат обучения нейросети также может зависеть от того, в каком виде представлена информация для ее обучения. Таким образом, предварительная обработка данных позволяет повысить качество как интеллектуального анализа данных, так и самих данных.
Цель исследования – рассмотрение этапов предварительной обработки данных и основ разработки признаков, а также обзор конструирования категориальных признаков.
Материалы и методы исследования
При создании модели машинного обучения предварительная обработка данных служит первым шагом. Как правило, реальные данные являются неполными, непоследовательными, могут содержать ошибки или выбросы, а также в них могут отсутствовать конкретные значения или атрибуты. Именно здесь используется предобработка данных: она помогает очищать, форматировать и упорядочивать необработанные данные, тем самым делая их готовыми к работе с моделями машинного обучения.
Предобработка данных состоит из пяти этапов:
− очистка данных, которая направлена на повышение качества данных за счет присваивания пропущенных значений и удаления выбросов;
− сокращение объема данных, которое уменьшает объем данных и, следовательно, снижает связанные с ними вычислительные мощности;
− масштабирование данных – направлено на преобразование исходных данных в аналогичные диапазоны для прогнозного моделирования;
− преобразование, целью которого является организация исходных данных в подходящие форматы для различных алгоритмов интеллектуального анализа данных;
− разделение, которое делит весь набор данных на различные подмножества для более глубокого анализа.
Существует два общих способа обработки отсутствующих значений при построении оперативных данных. Первый – просто отбросить выборки данных с пропущенными значениями, так как большинство алгоритмов получения данных не могут обрабатывать данные с пропущенными значениями. Такой метод применим только тогда, когда доля отсутствующих значений незначительна. Второй – применение методов интерполяции пропущенных значений для замены пропущенных данных значениями, полученными в результате расчетов.
Как показано на рисунке 1, распространенные методы интерполяции отсутствующих значений можно разделить на две группы, т.е. одномерные и многомерные методы.
Рис. 1. Методы интерполяции пропущенных значений для построения данных
К первым относятся средняя интерполяция, прямая или обратная интерполяция и методы скользящего среднего. В этом случае недостающие значения выводятся на основе характеристик данных только одной переменной и поэтому называются одномерными методами. Метод интерполяции среднего или медианы заменяет недостающие значения средним или медианой этой переменной. Прямой или обратный метод просто заменяет отсутствующее значение предыдущим или следующим измерением данных. Эти два метода просты в реализации, но не учитывают временные корреляции на временных этапах и могут не сделать правильную замену данных [1].
В основном используются два метода обнаружения выбросов – статистические методы и методы, основанные на кластеризации.
Сокращение данных обычно проводится в двух направлениях, т.е. по строкам для сокращения выборки данных и по столбцам для сокращения переменных данных. Для сокращения данных по строкам могут применяться различные методы выборки данных, такие как случайная и стратифицированная выборка.
Существуют три основных метода сокращения переменных данных по столбцам. Первый заключается в использовании знаний о домене для прямого отбора интересующих переменных. Второй – использование статистических методов отбора признаков для выбора важных переменных для дальнейшего анализа. Третий – использование методов извлечения признаков для построения полезных признаков для анализа данных.
Масштабирование данных часто необходимо для обеспечения достоверности прогностического моделирования, особенно когда входные переменные имеют различные масштабы. Нормализация max-min (т.е., x′=x-xmin/xmax-xmin) и стандартизация z-score (т.е., x′=x-μ/σ) – два наиболее широко используемых метода, где min(x) и max(x) означают минимум и максимум переменной x, значения переменной μ – среднее значение, а σ – стандартное отклонение.
Метод нормализации max-min чувствителен к выбросам данных, поскольку их присутствие может резко изменить диапазон данных. В отличие от него метод стандартизации z-score менее подвержен влиянию выбросов. Он обычно используется для реформирования переменной, чтобы она была нормально распределена со средним значением, равным нулю, и стандартным отклонением, равным единице. Теоретически, нормализация по z-score работает лучше всего, когда данные нормально распределены. Нормализация по методу max-min рекомендуется, когда эксплуатационные данные не соответствуют нормальному распределению и не содержат явных выбросов. Другой тип метода масштабирования данных может изменять структуры данных. Например, исходные данные могут быть отображены в новое пространство с помощью определенных математических функций, таких как логарифмическая, сигмоидальная функции или арктангенс. Такие методы часто используются для минимизации дифференциалов в переменных данных [2].
Преобразование данных в основном применяется для преобразования числовых данных в категориальные для обеспечения совместимости с алгоритмами интеллектуального анализа данных. Методы равной ширины и равной частоты широко используются благодаря своей простоте. Количество интервалов обычно предопределяется пользователем на основе знаний о предметной области. По сравнению с методом равной ширины метод равной частоты менее чувствителен к выбросам [3].
Преобразование данных также может применяться для преобразования категориальных переменных в числовые для облегчения разработки моделей прогнозирования. Для этой цели широко используется метод однократного кодирования, при котором для категориальной переменной с L уровнями создается матрица из L – 1 столбцов [4]. Все признаки могут быть следующих видов:
− бинарные, которые принимают два значения (да/нет, 0/1, true/false);
− номинальные, которые имеют конечное количество уровней. Также они могут быть упорядоченными и неупорядоченными;
− количественные значения в диапазоне от –∞ до +∞.
Признак – это переменная, которая описывает отдельную характеристику объекта. В табличном представлении выборки признаки – это столбцы таблицы, а объекты – строки. Входные, независимые переменные для модели машинного обучения называются предикторами, а выходные, зависимые – целевыми признаками.
Признаки могут извлекаться из данных любого типа, в том числе из текста, изображений и геоданных. При обработке текстовой информации сначала выполняется ее токенизация, а затем лемматизация и цифровизация – перевод слов в числовые вектора. В случае изображений часто анализируется не только содержание картинки как набора пикселей различного цвета, но и метаданные графического файла: дата съемки, разрешение, модель камеры и т.д. Географические данные чаще всего представлены в виде адресов или пар [5].
Разработка признаков – очень важный аспект машинного обучения и науки о данных, и его нельзя игнорировать. Основная цель разработки признаков – получить наилучшие результаты от алгоритмов. В науке о данных производительность модели зависит от предварительной обработки и обработки данных. Если модель построена без обработки данных, то точность будет составлять около 70%. Применив генерацию признаков к той же модели, производительность можно повысить на несколько десятков процентов. Проще говоря, благодаря генерации признаков улучшается производительность модели.
Выбор признаков – это не что иное, как выбор необходимых независимых признаков. Выбор важных независимых признаков, которые имеют большую связь с зависимым признаком, поможет построить хорошую модель. Существует несколько методов отбора признаков [6].
В случае одномерного массива статистические тесты могут использоваться для отбора независимых признаков, которые имеют наиболее сильную связь с зависимым признаком. Метод SelectKBest может быть использован с набором различных статистических тестов для выбора определенного количества признаков (рис. 2). Признак, имеющий наивысший балл, будет более связан с зависимым признаком, и эти признаки будут выбраны для модели.
Метод ExtraTreesClassifier помогает определить важность каждого независимого признака с зависимым признаком. Важность признака дает оценку для каждого признака данных: чем выше оценка, тем важнее или релевантнее признак текущей выходной переменной (рис. 3).
Тепловая карта – это графическое представление двумерных данных (рис. 4). Здесь каждое значение данных представлено в матрице. Необходимо построить парный график между всеми независимыми и зависимыми функциями, в итоге получится отношение между двумя признаками. Если отношение между независимой и зависимой функциями меньше 0,2, тогда эта независимая функция выбирается для построения модели.
Рис. 2. Пример одномерного отбора
Рис. 3. Пример метода ExtraTreeClassifier
Рис. 4. Пример тепловой карты
Категориальные данные – это тип данных, который используется для группировки информации с похожими характеристиками, в то время как числовые данные – это тип данных, выражающих информацию в виде чисел. Примером категориальных данных может служить пол человека [7].
Большинство алгоритмов машинного обучения не могут работать с категориальными переменными, если их не преобразовать в числовые значения. Производительность многих алгоритмов даже зависит от того, как закодированы категориальные переменные.
Категориальные переменные можно разделить на две категории:
− номинальные, которые не имеют определенного порядка;
− порядковые, между значениями которых существует определенный порядок.
Заключение
Предобработка данных является важнейшим этапом построения моделей машинного обучения, она занимает большую часть времени, так как от подготовки данных зависит корректность будущей модели. В случае ошибки при первичном анализе возможны переобучение модели или утечка данных, которые могут нарушить корректность работы модели. Таким образом, предварительная обработка данных позволяет значительно повысить качество как самих данных, так и результата анализа.
Лучший выбор подмножества в машинном обучении (объяснение и примеры)
В области машинного обучения нас часто интересует построение моделей с использованием набора переменных-предикторов и переменной отклика.Наша цель — построить модель, которая может эффективно использовать переменные-предикторы для предсказания значения переменной отклика.
Учитывая набор из p общих переменных-предикторов, мы потенциально можем построить много моделей. Один из методов, который мы можем использовать для выбора лучшей модели, известен как лучший выбор подмножества , и он работает следующим образом:
1. Пусть M 0 обозначает нулевую модель, не содержащую переменных-предикторов.
2. Для к = 1, 2, . р:
- Соответствуйте всем p C k моделям, которые содержат ровно k предикторов.
- Выберите лучшую из этих моделей p C k и назовите ее M k.Определить «лучшую» как модель с самым высоким R 2 или, что эквивалентно, с самым низким RSS.
3. Выбрать единственную лучшую модель из числа M 0 …M p с использованием ошибки прогнозирования перекрестной проверки, Cp, BIC, AIC или скорректированного R 2 .
Обратите внимание, что для набора p переменных-предикторов существует 2 p возможных моделей.
Пример выбора лучшего подмножества
Предположим, у нас есть набор данных с p = 3 переменными-предикторами и одной переменной ответа, y. Чтобы выполнить лучший выбор подмножества с этим набором данных, мы подогнали бы следующие модели 2 p = 2 3 = 8:
- Модель без предикторов
- Модель с предиктором x 1
- Модель с предиктором x 2
- Модель с предиктором x 3
- Модель с предикторами x 1 , x 2
- Модель с предикторами x 1 , x 3
- Модель с предикторами x 2 , x 3
- Модель с предикторами x 1 , x 2 , x 3
Затем мы выбираем модель с наибольшим значением R 2 среди каждого набора моделей с k предикторами. Например, мы можем выбрать:
- Модель без предикторов
- Модель с предиктором x 2
- Модель с предикторами x 1 , x 2
- Модель с предикторами x 1 , x 2 , x 3
Затем мы проводим перекрестную проверку и выбираем наилучшую модель, которая приводит к наименьшей ошибке предсказания, Cp, BIC, AIC или скорректированному R 2 .
Например, мы могли бы в конечном итоге выбрать следующую модель как «лучшую» модель, потому что она дала наименьшую ошибку прогнозирования с перекрестной проверкой:
- Модель с предикторами x 1 , x 2
Критерии выбора «лучшей» модели
Последний шаг выбора наилучшего подмножества включает в себя выбор модели с наименьшей ошибкой предсказания, наименьшим Cp, наименьшим BIC, наименьшим AIC или самым высоким скорректированным R 2 .
Вот формулы, используемые для расчета каждой из этих метрик:
Cp: (RSS+2dσ̂)/n
AIC: (RSS+2dσ̂ 2 ) / (nσ̂ 2 )
БИК: (RSS+log(n)dσ̂ 2 ) / n
Скорректированный R 2 : 1 – ((RSS/(nd-1))/(TSS/(n-1))
- d: количество предикторов
- n: Всего наблюдений
- σ̂: оценка дисперсии ошибки, связанной с каждым измерением отклика в регрессионной модели.
- RSS: Остаточная сумма квадратов регрессионной модели
- TSS: общая сумма квадратов регрессионной модели.
Плюсы и минусы выбора лучшего подмножества
Лучший выбор подмножества предлагает следующие плюсы:
- Это простой подход к пониманию и интерпретации.
- Это позволяет нам определить наилучшую возможную модель, поскольку мы рассматриваем все комбинации переменных-предикторов.
Однако этот метод имеет следующие недостатки:
- Это может быть вычислительно интенсивным. Для набора p предикторов существует 2 p возможных моделей. Например, при наличии 10 переменных-предикторов необходимо рассмотреть 2 ·10 = 1000 возможных моделей.
- Поскольку он рассматривает такое большое количество моделей, он потенциально может найти модель, которая хорошо работает на обучающих данных, но не на будущих данных. Это может привести к переоснащению .
Вывод
Хотя выбор наилучшего подмножества прост в реализации и понимании, он может оказаться неосуществимым, если вы работаете с набором данных с большим количеством предикторов, и это потенциально может привести к переоснащению.
Альтернативой этому методу является пошаговый отбор , который более эффективен в вычислительном отношении.
Похожие публикации:
- Powershell как вставить из буфера
- Как возвести в дробную степень на калькуляторе
- Как сделать выписку по счету киви кошелька
- Как убрать ложь в excel
Выбор слоя активации в нейронных сетях: как правильно выбрать для вашей задачи
В машинном обучении и нейронных сетях слои активации играют очень важную роль в процессе обработки данных. В этой статье мы рассмотрим, что такое слои активации, как они работают и как выбрать наиболее подходящий слой для вашей задачи.
Что такое слои активации?
Слои активации — это один из основных типов слоев, которые используются в нейронных сетях. Они представляют собой функцию, которая добавляет нелинейность к выходу предыдущего слоя. Это позволяет нейронной сети лучше моделировать сложные функции и более точно предсказывать результаты.
Как работают слои активации?
Слои активации принимают на вход результаты предыдущего слоя, называемые входом, и преобразуют их в выходное значение, которое передается следующему слою. Для этого они используют функцию активации, которая определяет, каким образом данные будут преобразованы.
Сигмойда
Код создания графика сигмойды на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры сигмоиды x = np.linspace(-100, 100, 1000) y = 1 / (1 + np.exp(-x)) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('sigmoid(x)') plt.title('График сигмоиды') # Настраиваем значения осей координат plt.xlim(-10, 10) plt.ylim(0, 1) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=5) plt.grid(True) # Отображаем график plt.show()
Сигмоидная функция активации — это нелинейная функция, которая преобразует входное значение в диапазоне от отрицательной бесконечности до положительной бесконечности в значение от 0 до 1. Эта функция активации часто используется в нейронных сетях для задач бинарной классификации.
Математически сигмоидная функция активации определяется следующим образом:
Графически сигмоидная функция активации выглядит как S-образная кривая, которая монотонно возрастает и имеет асимптоты на 0 и 1. В частности, если x > 0, то f(x) > 0.5, а если x < 0, то f(x) < 0.5. Значение 0.5 достигается при x = 0.
Сигмоидная функция активации используется для преобразования выходного значения нейрона в вероятность, т.е. вероятность того, что входное значение относится к классу 1, если мы работаем с задачей бинарной классификации. Если значение сигмоидной функции близко к 1, то вероятность того, что входное значение относится к классу 1, высока. Если значение близко к 0, то вероятность того, что входное значение относится к классу 1, низкая.
Однако сигмоидная функция активации имеет недостаток, который называется проблемой затухания градиента (vanishing gradient problem). Это означает, что при использовании сигмоидной функции активации в глубоких нейронных сетях градиенты могут становиться очень маленькими, что затрудняет обучение. В таких случаях часто используется другая функция активации, например, ReLU (Rectified Linear Unit).
ReLU
Код создания графика ReLU на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры сигмоиды x = np.linspace(-100, 100, 1000) y = np.maximum(x, 0) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('ReLU(x)') plt.title('График функции ReLU') # Настраиваем значения осей координат plt.xlim(-5, 5) plt.ylim(-0.5, 5) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=5) plt.grid(True) # Отображаем график plt.show()
ReLU (Rectified Linear Unit) — это нелинейная функция активации, которая широко используется в глубоком обучении. Она преобразует входное значение в значение от 0 до положительной бесконечности. Если входное значение меньше или равно нулю, то ReLU выдает ноль, в противном случае — входное значение.
Математически ReLU определяется следующим образом:
где max — функция, возвращающая максимальное значение из двух.
Графически ReLU выглядит как линейная функция с нулевым отсечением на оси абсцисс в точке 0. Это значит, что функция имеет постоянный наклон во всех точках, кроме точки 0, где происходит отсечение.
ReLU имеет несколько преимуществ по сравнению со сигмоидной функцией активации. Во-первых, ReLU более вычислительно эффективна, поскольку она является простой и быстрой операцией, которая не требует вычисления экспоненты. Во-вторых, ReLU решает проблему затухания градиента, так как она не вызывает затухания градиента при обратном распространении ошибки, как это происходит в случае с сигмоидной функцией активации.
Однако, ReLU имеет некоторые недостатки. Во-первых, при использовании ReLU, некоторые нейроны могут «умереть» (dead neurons), т.е. они могут получить отрицательное значение и оставаться неактивными на всем протяжении обучения. Во-вторых, ReLU несимметрична относительно нуля, поэтому может возникнуть проблема «расслоения» (clustering), когда нейроны могут выдавать только положительные значения. Для решения этих проблем могут быть использованы другие функции активации, такие как Leaky ReLU или ELU.
Leaky ReLU
Код создания графика Leaky ReLU на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры функции Leaky ReLU x = np.linspace(-10, 10, 1000) alpha = 0.1 y = np.where(x > 0, x, alpha*x) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('Leaky ReLU(x)') plt.title('График функции Leaky ReLU') # Настраиваем значения осей координат plt.xlim(-5, 5) plt.ylim(-0.5, 5) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=5) plt.grid(True) # Отображаем график plt.show()
Leaky ReLU (Rectified Linear Unit) — это функция активации, которая используется в нейронных сетях для введения нелинейности в выходные данные каждого нейрона.
Обычный ReLU принимает входные значения и преобразует их, оставляя только положительные значения без изменения, а все отрицательные значения заменяет на 0. Однако у этого метода есть один недостаток, а именно «умирание ReLU». Это происходит в том случае, если входное значение отрицательное, то нейрон не будет активироваться и не будет вносить вклад в выходную функцию.
Для решения этой проблемы был разработан Leaky ReLU. В отличие от ReLU, Leaky ReLU возвращает само значение при положительном входном значении, а при отрицательных значениях возвращает линейную функцию от входа, умноженную на небольшой коэффициент, называемый отрицательным уклоном (leak). Таким образом, у нейрона всегда есть возможность вносить вклад в выходную функцию, даже если входные данные отрицательны.
Формула для Leaky ReLU выглядит следующим образом:
где a (alpha) — отрицательный уклон, который является маленьким положительным числом, например, 0,01.
Преимуществом Leaky ReLU является устойчивость к «умиранию» нейронов и лучшая сходимость в процессе обучения, что приводит к более быстрому и точному обучению нейронных сетей.
ELU
Код создания графика ELU на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры функции ELU x = np.linspace(-10, 10, 1000) alpha = 1.0 y = np.where(x > 0, x, alpha * (np.exp(x) - 1)) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('ELU(x)') plt.title('График функции ELU') # Настраиваем значения осей координат plt.xlim(-5, 5) plt.ylim(-2, 5) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=5) plt.grid(True) # Отображаем график plt.show()
ELU (Exponential Linear Unit) — это функция активации, которая была предложена в 2015 году в статье «Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)». Она представляет собой измененную версию ReLU (Rectified Linear Unit), которая помогает ускорить обучение глубоких нейронных сетей и справляется с проблемой «мертвых нейронов» (dead neurons).
ELU определяется следующим образом:
где a (alpha) — это параметр, который может быть установлен в значение 1 по умолчанию.
ELU работает так же, как и ReLU, возвращая исходное значение входа, если он больше нуля. Однако, если значение входа меньше или равно нулю, то ELU использует экспоненциальную функцию, чтобы получить значение, которое ближе к нулю, чем значение, возвращаемое ReLU. Это позволяет избежать «мертвых нейронов» и ускорить обучение глубоких нейронных сетей.
Кроме того, ELU имеет свойство гладкости, которое так же помогает избежать проблемы «взрывающегося градиента» (exploding gradient), которая может возникать при использовании других функций активации, таких как ReLU. Это делает ELU более стабильной и более эффективной функцией активации для обучения глубоких нейронных сетей.
Однако, как и любая другая функция активации, ELU не подходит для всех задач и может давать неоптимальные результаты в некоторых случаях. Поэтому при выборе функции активации необходимо учитывать особенности конкретной задачи и проводить эксперименты для определения оптимальной функции.
SiLU
Код создания графика SiLU на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры функции SiLU x = np.linspace(-10, 10, 1000) y = x * (1 / (1 + np.exp(-x))) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('SiLU(x)') plt.title('График функции SiLU') # Настраиваем значения осей координат plt.xlim(-5, 5) plt.ylim(-1.5, 1.5) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=2) plt.grid(True) # Отображаем график plt.show()
SiLU (Sigmoid-weighted Linear Unit) — это нелинейная функция активации, которая была предложена в 2017 году в статье «Sigmoid-Weighted Linear Units for Neural Network Function Approximation in Reinforcement Learning». SiLU сочетает в себе линейные и нелинейные свойства и имеет ряд преимуществ по сравнению с другими функциями активации.
Функция активации — это нелинейная функция, которая применяется к выходу каждого нейрона в нейронной сети. Она используется для добавления нелинейности в вычисления нейрона и позволяет модели учиться более сложным функциям. Различные функции активации могут влиять на скорость обучения модели, точность и стабильность её предсказаний.
Одной из самых распространенных функций активации является сигмоидная функция, которая представляет собой «сжимающую» функцию и применяется для преобразования значений в диапазон от 0 до 1. Однако, сигмоидная функция имеет некоторые недостатки, включая «затухание градиентов» и «эффект насыщения», что может затруднять обучение нейронных сетей.
SiLU — это функция активации, которая решает проблемы «затухание градиентов» и «эффект насыщения». Она является гладкой, монотонно возрастающей и не имеет «эффекта насыщения» как у сигмойдной функции, что позволяет модели обучаться более эффективно и быстро сходиться к оптимальному решению.
где: σ(x) — функция сигмойды, формула написанная ниже, и подробнее объяснена в пункте выше «Сигмойда».
В области компьютерного зрения SiLU часто используется в сверточных нейронных сетях (CNN), где она может помочь увеличить точность и скорость обучения моделей. Например, её используют в модели YOLOv8. Но, к сожалению, этой модели нет в библиотеки TensorFlow, и использовать её просто так, у вас не получиться.
Гиперболический тангенс
Код создания графика гиперболический тангенс на matplot
import numpy as np import matplotlib.pyplot as plt # Задаем параметры сигмоиды x = np.linspace(-100, 100, 1000) y = np.tanh(x) # Строим график plt.plot(x, y) # Настраиваем оси координат и заголовок plt.xlabel('x') plt.ylabel('tanh(x)') plt.title('График гиперболического тангенса') # Настраиваем значения осей координат plt.xlim(-10, 10) plt.ylim(-1, 1) # Строим график, настраиваем ширину линии и добавляем сетку plt.plot(x, y, linewidth=5) plt.grid(True) # Отображаем график plt.show()
Гиперболический тангенс (tanh) является одной из наиболее распространенных функций активации в нейронных сетях. Он используется как для классификации, так и для регрессии, а также для обработки изображений и других типов данных.
Это функция активации, которая преобразует входные значения в диапазоне от -1 до 1. Формула для вычисления гиперболического тангенса выглядит следующим образом
Гиперболический тангенс очень похож на сигмоидальную функцию, которая также используется в нейронных сетях. Он принимает входные значения и преобразует их в диапазон от -1 до 1, что может использоваться для задач регрессии. Значения, близкие к -1, интерпретируются как отрицательные значения, а значения, близкие к 1, как положительные значения. Значения, близкие к нулю, обрабатываются как нейтральные.
По сравнению со сигмоидальной функцией, гиперболический тангенс имеет более пологую кривую, что позволяет сети лучше распознавать сложные зависимости в данных. Также гиперболический тангенс имеет гладкую производную, что позволяет использовать алгоритмы оптимизации, которые требуют вычисления градиента.
Softmax
К сожалению, функция Softmax визуально представляется в виде кривой, что затрудняет ее графическое отображение на графике. Поэтому будет демонстрация на примере заданного вектора.
Код создания функции Softmax с заданным вектором на matplot
import numpy as np import matplotlib.pyplot as plt def softmax(z): # Преобразуем вектор в массив, чтобы избежать ошибок типа "integer division or modulo by zero" z = np.array(z) # Вычисляем экспоненты каждого элемента вектора exp_z = np.exp(z) # Вычисляем сумму экспонент всех элементов вектора sum_exp_z = np.sum(exp_z) # Вычисляем вероятности для каждого элемента вектора softmax_z = exp_z / sum_exp_z return softmax_z # Задаем входной вектор z = [1, 2, 3, 4, 1, 2, 3] # Вычисляем значения Softmax softmax_z = softmax(z) # Выводим значения на экран print("Softmax(z) =", softmax_z) # Строим график вероятностного распределения plt.bar(range(len(z)), softmax_z) plt.title("Softmax Distribution") plt.xlabel("Class") plt.ylabel("Probability") plt.show()
В этом примере мы задаем входной вектор z , затем вычисляем значения с помощью функции softmax() . Затем мы выводим значения на экран и строим график вероятностного распределения. График отображает вероятности для каждого элемента входного вектора в виде столбчатой диаграммы. Более детальные значения, вы можете увидеть ниже:
Softmax(z) = [0.02364054 0.06426166 0.1746813 0.474833 0.02364054 0.06426166 0.1746813 ]
Функция Softmax используется для преобразования вектора значений в вероятностное распределение, которое суммируется до 1. Она особенно полезна в многоклассовой классификации, где необходимо определить вероятности для каждого класса.
Формула функции Softmax выглядит следующим образом:
где z_i — это элемент входного вектора, а k — это общее число элементов в векторе.
График функции Softmax представляет собой гладкую кривую, начинающуюся от 0 и заканчивающуюся на 1, что соответствует сумме вероятностей всех элементов вектора. Кривая функции Softmax имеет свойство, что вероятность любого элемента вектора увеличивается, если значения других элементов уменьшаются, что позволяет использовать эту функцию для многоклассовой классификации.
Хотя функция Softmax имеет множество применений в машинном обучении, она также может иметь недостатки, такие как чувствительность к выбросам и несбалансированным данным, что может приводить к неверным вероятностным оценкам.
Как выбрать подходящий слой активации?
Выбор подходящего слоя активации зависит от задачи машинного обучения, типа данных и модели, которую вы хотите создать. Вот несколько рекомендаций, которые могут помочь в выборе подходящего слоя активации:
- Для задач классификации, используйте Softmax, если вы хотите получить вероятности классов в качестве выходных данных. Используйте Sigmoid или Tanh, если вы хотите получить двоичный вывод.
- Для задач регрессии, используйте ReLU или его модификации, такие как LeakyReLU или ELU. Эти функции обычно дают лучшую производительность в задачах регрессии.
- Для моделей глубокого обучения, ReLU является общим выбором для скрытых слоев, так как она может ускорить обучение, но можно также использовать другие функции, например, PReLU или Swish.
- Для рекуррентных нейронных сетей, обычно используются функции активации Tanh.
- Если вы не уверены, какую функцию активации использовать, попробуйте использовать несколько функций активации и сравните их производительность на валидационном наборе данных.
- Кроме того, при выборе функции активации необходимо учитывать свойства функции, такие как производная, способность обеспечивать нелинейность и способность предотвращать затухание градиента.
В целом, выбор подходящего слоя активации зависит от конкретной задачи и экспериментальных результатов. Необходимо тщательно подбирать функцию активации и изменять ее, чтобы получить оптимальные результаты для вашей модели.
Важно также помнить, что выбор подходящего слоя активации может зависеть от структуры и архитектуры вашей нейронной сети, а также от данных, на которых вы обучаете модель. Поэтому важно экспериментировать с разными функциями активации и выбирать ту, которая работает лучше всего для вашей конкретной задачи.
В заключение, слои активации являются одним из ключевых элементов в нейронных сетях, которые позволяют моделировать сложные функции и более точно предсказывать результаты. В этой статье были перечислены далеко не все виды слоев активации, а только те, что наиболее популярны, на слуху, или я сам лично использовал их в своей работе.
Спасибо за прочтение!
- искуственный интеллект
- нейронные сети
- функция активации
- машинное обучение
- градиентный спуск
- затухание нейронов
- мертвые нейроны
- взрыв градиента
Краткое введение в машинное обучение
Машинное обучение является одной из самых влиятельных и быстро растущих областей в компьютерных технологиях. Если вы заинтересованы в машинном обучении, вам необходимо ознакомиться с основными понятиями, относящимися к данной области, такими как алгоритмы, переменные и различные типы анализа моделей. Несмотря на то, что объемы изучения гораздо больше, чем то, что описано в этой статье, этот краткий ускоренный курс по машинному обучению предоставит вам некоторые определения / понятия, касающиеся основных моментов машинного обучения.
Что такое машинное обучение?
Давайте начнем с определения машинного обучения. В конце концов, трудно осваивать дисциплину, если вы даже не понимаете, что означает термин «машинное обучение». Говоря кратко, машинное обучение — это процесс, позволяющий компьютеру выполнять задачу без явного программирования для этого. Вместо того, чтобы писать каждую отдельную строку кода, необходимую для выполнения алгоритма, специалист по машинному обучению создаст систему, которая принимает некоторые данные в качестве вводных данных, изучает изменения этих данных и затем выводит решение о том, что делать с этим данные. Компьютер анализирует изменения в данных и «узнает», как вводные данные связаны с выходными данными, поэтому он может обобщить любые изменения для новых данных в будущем.
Определение признаков и меток
Система машинного обучения состоит из трех компонентов:
— Вводные данные
— Алгоритмы
— Исходящие данные
Литература по машинному обучению часто говорит о признаках и метках, но что это за понятия? Признаки являются частями вводных данных, и их можно рассматривать как переменные, представляющие интерес для задачи машинного обучения, переменные, которые система будет анализировать для изучения изменений. Выводы системы являются метками. Это прогноз, сделанный моделью в отношении класса, к которому относятся вводные данные.
Два типа машинного обучения: под наблюдением и без присмотра
Существует два типа машинных заданий: обучение без сопровождения и обучение под наблюдением. В чем разница? Основное различие между контролируемым и неконтролируемым обучением состоит в том, что у первого есть данные, о которых узнает сеть, помеченные основополагающей правдой, а у второго — нет. Иными словами, при контролируемом обучении известны правильные выходные значения для набора вводных данных, но при неконтролируемом обучении выходные значения неизвестны, поэтому цель двух типов обучения различна.
В контролируемом обучении цель обучения модели состоит в том, чтобы определить некоторую функцию, которая наилучшим образом представляет взаимосвязь между вводными данными и наблюдаемыми выходными данными, чтобы найти модель, минимизирующую ошибку между истиной и предсказанием модели. Напротив, смысл алгоритма обучения без присмотра заключается в том, что он должен вывести взаимосвязь между многими различными точками данных, поскольку он не имеет доступа к помеченным выходным данным.
Основное использование для контролируемых алгоритмов обучения — классификация, которая выполняется, когда вводные метки должны быть связаны с выходными метками, или для регрессии, когда вводные данные должны быть сопоставлены с последовательностью непрерывных выходных данных. Напротив, неконтролируемое обучение обычно применяется к таким задачам, как обучение представлению, кластеризация и оценка плотности. Эти задачи требуют, чтобы модель определяла структуру данных, даже если она явно не помечена.
Понимание общих контролируемых алгоритмов обучения
Некоторые из наиболее распространенных алгоритмов для контролируемого обучения включают в себя:
— Наивный байесовский классификатор
— Опорные векторные машины
— Логистическая регрессия
— Случайные Леса
— Искусственные нейронные сети.
Давайте подробнее рассмотрим каждый из этих алгоритмов.
Опорные векторные машины
Машина опорных векторов группирует точки данных в разные классы, рисуя линию между разными кластерами точек данных. Точки данных, найденные на одной стороне линии, принадлежат определенному классу, в то время как точки, найденные на другой стороне линии, принадлежат другому. Расстояние от линии разделения до точек по обе стороны от нее отражает уверенность классификатора в том, какая точка принадлежит какому классу, и классификатор пытается максимизировать расстояние между линией и точками, найденными по обе стороны от линии.
Логистическая регрессия
Логистическая регрессия — это алгоритм, который делает прогнозы относительно точек в данных тестирования, давая им двоичную метку, помечая их как один или ноль. Если значение точки данных равно 0,5 или выше, оно классифицируется как принадлежащее к классу 1, а 0,49 или ниже классификатора помечает его как 0. Логистическая регрессия подходит для случаев, когда между точками данных существует линейная зависимость.
Деревья решений / Случайные Леса
Деревья решений работают путем разделения набора данных на более мелкие подмножества на основе различных критериев сортировки. С каждым разделением набора данных создается новое подмножество, и число примеров в любом данном подмножестве уменьшается. После того, как сеть разделяет данные на категории, содержащие отдельные точки данных, эти примеры классифицируются в соответствии с назначенным ключом. Именно так работает классификатор дерева решений, а классификатор случайных лесов создается путем связывания множества классификаторов дерева решений.
Наивный байесовский классификатор
Наивный байесовский классификатор вычисляет вероятность того, что какое-то событие или точка данных произойдет, основываясь на некотором предшествующем событии. Наивный байесовский классификатор размещает точки данных в классах в соответствии с вероятностью, которую он присваивает им на основе некоторого входного события. Предположение наивного байесовского классификатора состоит в том, что все предикторы класса имеют одинаковый вес / влияние на результат этого класса, и что предикторы не зависят друг от друга.
Искусственная нейронная сеть
Искусственная нейронная сеть (ИНС) — это система, вдохновленная человеческим мозгом. ИНС состоят из разных слоев «нейронов», соединенных вместе, причем каждый нейрон представляет собой математическую функцию. В середине находится входной слой, выходной слой и «скрытый» слой. В этом скрытом слое происходит обучение: данные, которыми манипулируют многие математические функции, объединенные вместе, способны изучать более сложные паттерны, чем другие алгоритмы.
Изучать неконтролируемые алгоритмы
Наиболее часто используемые алгоритмы в задачах обучения без присмотра включают в себя:
— Кластеризация методом k-средних
— Автокодировщик
— Анализ главных компонентов
Кластеризация методом k-средних
Целью кластеризации K-средних является разделение точек данных на группы отдельных кластеров. Это дает возможность обнаружить базовые шаблоны, которые делают точки данных в одном кластере более похожими друг на друга, чем точки в другом кластере.
Количество желаемых кластеров / классов выбирается пользователем, и алгоритм запускается путем помещения соответствующего количества «центроидов» (или гипотетических центров) для кластера. После того, как центроиды размещены, пробуются различные назначения точек в наборе данных. Алгоритм стремится минимизировать расстояние от назначенных точек до центроидов, заканчивая, когда он нашел расположение центроидов с кратчайшим расстоянием до точек, окружающих их.
Метод главных компонент
Метод главных компонент — это метод обучения без надзора, который уменьшает размерность данных, «сжимая» данные в меньшем пространстве. Это полезно, потому что оно сохраняет отношения между исходными точками данных, как расстояние друг от друга, но точки теперь находятся в гораздо меньшем / более простом для анализа пространстве.
Акт извлечения «основных компонентов» означает, что могут быть созданы новые функции для набора данных, функции, которые облегчают обучение без контроля.
Автокодировщик
Автокодировщики — это специальные приложения нейронных сетей, полезные при выполнении неконтролируемых задач обучения. Автокодировщики принимают входные данные без меток и кодируют их в форму, которую может использовать сеть.
Автокодировщик пытается реорганизовать входные данные максимально точно, поэтому он должен попытаться определить, какие функции являются наиболее важными. Это означает, что автокодировщик извлекает наиболее релевантные функции из немаркированных данных, или, другими словами, они маркируют свои собственные данные обучения.
Типы Анализа
После того, как вы определились с алгоритмом для использования и применили его к своим данным обучения и тестирования, как вы можете определить, насколько хорошо работает ваша модель? Анализ — это то, где метрики вступают в силу.
Метрика, которую вы должны использовать, зависит от типа проблемы обучения, которую вы пытаетесь решить. Общие виды анализа для задач классификации:
- Точность классификации
- Матрица неточностей
- Классификационный отчет
Точность классификации дает вам количество правильных прогнозов, деленное на общее количество прогнозов. Точность классификации обычно используется, поскольку она очень проста, но она работает лучше всего, когда число примеров в классе примерно эквивалентно.
Матрица неточностей — это диаграмма, которая отображает точность вашей модели по общему количеству классов. Матрицы неточностей может быть немного трудно интерпретировать, но прогнозы основаны на оси X, а фактическая точность — на оси Y, при этом правильные прогнозы выполняются по диагонали сверху вниз, слева направо.
Классификационный отчет содержит метрики точность, плотнота и f-мера и является одним из наиболее полезных методов оценки, поскольку он дает несколько типов ценной информации.
Средняя абсолютная ошибка — это среднее от общей разницы между фактическими значениями и прогнозами, в то время как Средняя квадратическая ошибка очень похожа, разница в том, что вы можете взять квадратный корень из средней абсолютной ошибки и преобразовать их обратно в исходный результат. Метрика r-квадрата дает «соответствие», где 0 — полная ошибка, а 1 — идеальное соответствие.
С точки зрения обучения без надозра стандартизированных метрик не существует, поскольку успех алгоритма обучения без учителя субъективен. Тем не менее, некоторые распространенные практики включают визуализацию выходных данных для поиска тенденций или использование сгенерированных функций в задаче кластеризации, чтобы увидеть, как они представляют взаимоотношения/зависимости данных.
Выводы
Подводя итог, можно сказать, что машинное обучение имеет два типа задач: обучение без надзора и обучение под наблюдением. Каждый тип обучения имеет свои алгоритмы и метрики анализа.
Машинное обучение является мощной технологией и быстро развивающейся областью. Если вы заинтересованы в дальнейшем изучении машинного обучения, курсы по машинному обучению Эндрю Нг на Coursera или вводный курс по машинному обучению Udacity обеспечивают превосходный охват алгоритмов машинного обучения, переменных и форм анализа.
Присоединяйтес к нашему конкурсу статей
Хотите больше технического контента? Посетите blog.kambria.io. А еще лучше — участвуйте в конкурсе контента Kambria и поделитесь своими знаниями и опытом с нашим растущим сообществом разработчиков. Вы можете получить более 200 долларов за лучший материал. Чтобы получить полную информацию о нашем конкурсе контента, нажмите здесь.
Команда Kambria