пятница, 31 августа 2018 г.

Мультиклассовые нейронные сети: софтмакс

Вспомним, что логистическая регрессия производит результаты между 0 и 1. Например, вывод логистической регрессии равный 0.8 от классификатора писем предполагает, что шанс того, что письмо спам равен 80%, а шанс того, что письмо не спам равен 20%. Очевидно, что сумма вероятностей того, что письмо будет спамом или не спамом будет равна 1.0.

Софтмакс (Softmax) расширяет эту идею в мульти-классовый мир. То есть, софтмакс назначает дробные вероятности каждому классу в мультиклассовой проблеме. Эти дробные вероятности должны составлять вместе 1.0. Это дополнительное ограничение помогает тренировке сойтись быстрее.

Например, для анализа картинок из прошлого поста софтмакс может произвести следующие вероятности того что картинка принадлежит конкретному классу:

Софтмакс реализован через слой нейронной сети прямо перед слоем вывода. Софтмакс слой должен иметь такое же количество узлов как слой вывода.

Софтмакс слой в нейронной сети

Софтмакс опции

Рассмотрим следующие варианты Softmax:

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

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

Одна метка против многих меток

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

  • Можно не использовать софтмакс.
  • Необходимо основываться на многих логистических регрессиях.

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

Мультиклассовые нейронные сети: один против всех

В машинном обучении мультиклассовая классификация - это задача классифицирования примеров в один из трех или более классов. (Классифицирование в один из двух классов называется бинарной классификацией.)

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

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

Один против всех (One vs. all) предоставляет путь решения бинарной классификации. Дана классификационная проблема с N возможными решениями, один-против-всех решение состоит из N отдельных бинарных классификаторов - по одному бинарному классификатору для каждого возможного выхода. В течение тренировки модель проходит через последовательность бинарных классификаторов, тренируя каждый отвечать на отдельный классификационный вопрос. Например, дана картинка собаки, пять различных распознавателей могут быть тренированы, четыре видят изображение как негативный пример (не собака) и один как положительный (собака). То есть:

  • Это изображение яблока? Нет.
  • Это изображение медведя? Нет.
  • Это изображение конфеты? Нет.
  • Это изображение собаки? Да.
  • Это изображение яйца? Нет.

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

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

Один-против-всех (one-vs.-all) нейронная сеть

Тренировка нейронных сетей: провал обратного распространения и регуляризация

В этом посте мы рассмотрим случаи провала обратного распространения и наиболее общий путь регуляризации нейронной сети.

Случаи провала

Существует ряд общих причин провалов в ходе обратного распространения.

Стирающиеся градиенты

Градиенты для нижних слоев (те, которые ближе ко входам) могут стать очень маленькими. В глубоких сетях вычисление этих градиентов может включать в себя взятие произведения многих малых членов.

Когда градиенты стираются до нуля для нижних слоев, эти слои тренируются очень медленно либо не тренируются совсем.

ReLU функция активации может помочь предупредить стирание градиентов.

Взрывающиеся градиенты

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

Пакетная нормализация может помочь предупредить взрывающиеся градиенты.

Мертвые ReLU единицы

Однажды взвешенная сумма для ReLU единицы падает ниже нуля, тогда ReLU единица может застрять. Она выдает нулевую активацию, ничего не отдавая в вывод сети, и градиенты не могут больше течь через нее в ходе обратного распространения. С отключенным источником градиентов ввод в ReLU может никогда больше не измениться достаточно, чтобы поднять взвешенную сумму назад выше нуля.

Снижение скорости обучения может помочь сохранить ReLU единицы от умирания.

Исключающая регуляризация (dropout regularization)

Еще одна форма регуляризации, называемая Исключающей (Dropout), полезна в нейронных сетях. Она работает, случайным образом исключая активацию единиц в сети для отдельного градиентного шага. Чем больше исключений, тем сильнее регуляризация:

  • 0.0 = Нет исключающей регуляризации
  • 1.0 = Исключается все. Модель ничему не обучается.
  • Значения между 0.0 и 1.0 = наиболее полезны

четверг, 30 августа 2018 г.

Анатомия нейронных сетей

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

Нелинейная проблема классификации

"Нелинейная" означает, что мы не можем точно спрогнозировать метку с моделью вида b + w1x1 + w2x2. Другими словами, "поверхность решений" это не линия в данном случае. Ранее мы рассматривали пересечения свойств как один из возможных подходов к моделированию нелинейных проблем.

Рассмотрим следующий набор данных:

Более сложная нелинейная классификационная проблема

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

Чтобы увидеть как нейронные сети могут помочь с нелинейными проблемами, начнем с представления линейной модели как графа:

Линейная модель как граф

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

Как мы можем изменить эту модель, чтобы улучшить ее способность решать нелинейные проблемы?

Скрытые слои

В модели представленной следующим графом был добавлен "скрытый слой" промежуточных значений. Каждый желтый узел в скрытом слое - это взвешенная сумма значений синих входных узлов. Вывод - взвешенная сумма желтых узлов.

Граф двухслойной модели

Эта модель линейная? Да - ее вывод все еще линейная комбинация входов.

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

Граф трехслойной модели

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

Функции активации

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

В модели представленной следующим графом значение каждого узла в скрытом слое 1 трансформировано нелинейной функцией до того как передано в взвешенную сумму следующего слоя. Эта нелинейная функция называется функцией активации.

Граф трехслойной модели с функцией активации

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

Обычные функции активации

Следующая сигмоидная функция активации преобразует взвешенную сумму в значение между 0 и 1.

Вот ее график:

Сигмоидная функция активации

Следующая выпрямленная линейная единица (rectified linear unit) функции активации (или ReLU, кратко) часто работает немного лучше, чем сглаженная функция как сигмоид, при этом также значительно легче для вычисления.

F(x) = max(0,x)

Превосходство ReLU основано на эмпирических находках, вероятно использование ReLU имеет более полезный период ответной реакции. Ответная реакция сигмоида выпадает относительно быстро с обеих сторон.

ReLU функция активации

Фактически любая математическая функция может служить как функция активации. Предположим что σ представляет нашу функцию активации (ReLU, сигмоид). Следовательно, значение узла в сети дано в следующей формуле:

σ(w⋅x+b)

TensorFlow предоставляет "из коробки" поддержку широкого разнообразия функций активации. Рекомендуется начинать с ReLU.

Резюме

Теперь наша модель имеет все стандартные компоненты того, что люди подразумевают под термином "нейронная сеть":

  • Набор узлов, аналогичный нейронам, организованный в слои.
  • Набор весов, представляющих связи между каждым слоем нейронной сети и слоем под ним. Слой ниже может быть другим слоем нейронной сети или каким-либо другим видом слоя.
  • Набор смещений, по одному для каждого узла.
  • Функция активации, которая преобразует вывод каждого узла в слое. Разные слои могут иметь разные функции активации.

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

Регуляризация для разреженных данных: L1 регуляризация

Разреженные векторы часто содержат много измерений. Создание пересечения свойств приводит к еще большему количеству измерений. Если передать такие многомерные вектора в модель, то ее размер может стать огромным и потребует огромное количество RAM.

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

Например, рассмотрим набор данных о домах, который покрывает не только Калифорнию, а весь земной шар. Складывание широты в корзины по минутам (60 минут в одном градусе) даст около 10 000 измерений в разреженном кодировании; складывание долготы по минутам даст около 20 000 измерений. Пересечение этих двух свойств приведет примерно к 200 000 000 измерений. Многие из 200 000 000 измерений представляют области с крайне малым населением (например, в середине океана), так что будет крайне затруднительно использовать эти данные, чтобы генерализоваться эффективно. Будет глупо тратить RAM для хранения этих ненужных измерений. Поэтому, было бы хорошо, сделать веса не значимых измерений равными нулю, что позволит нам избежать траты ресурсов во время использования модели.

Мы можем кодировать эту идею в опитимизационную проблему, выполненную во время тренировки модели, добавив подходящую регуляризацию.

Справится ли L2 регуляризация с этой задачей? К сожалению, нет. L2 регуляризация стимулирует веса быть маленькими, но не приводит их к нулю.

Альтернативная идея будет попробовать применить регуляризацию, которая угнетает модели по количеству ненулевых коэффициентных значений. Увеличение этого количества будет нормализоваться только при достаточной способности модели прогнозировать результаты. К сожалению, хотя такой подход интуитивно приемлем, на деле он оказывается вычислительно-трудным. Поэтому, эта идея, известная как L0 регуляризация, не используется на практике.

Однако, существует L1 регуляризация, которая служит приближением к L0, но имеет преимущество в том, что она вычислительно-эффективная. Таким образом мы можем использовать L1 регуляризацию, чтобы привести многие неинформативные коэффициенты в нашей модели к нулю, и таким образом сохранить RAM во время использования модели.

L1 и L2 регуляризация

L1 и L2 угнетает веса по-разному:

  • L2 угнетает квадрат веса
  • L1 угнетает модуль веса

Следовательно, L1 и L2 имеют разные производные:

  • Производная L2 равна 2*вес
  • Производная L1 равна k (константа, чье значение не зависимо от веса)

Производную L2 можно рассматривать как намеренное удаление x% веса каждый раз. Удаление x процентов даже миллион раз никогда не приведет вес к нулю. Поэтому L2 при любой скорости не приводит веса до 0.

Производную L1 можно рассматривать как намеренное удаление константы от веса каждый раз. Однако, благодаря абсолютным значениям, L1 пересекает 0 при вычитании, но при отрицательном значении просто приводит его к нулю. Например, вычитание уменьшило вес с +0.1 до -0.2, L1 установит вес равным 0. В итоге, L1 приводит веса к нулю.

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

Следует отметить, что это описание истинно для одно-мерных моделей.

среда, 29 августа 2018 г.

Классификация: смещение прогноза

Прогнозы логистической регрессии не должны быть смещены. Таким образом:

"среднее значение прогнозов" должно быть ≈ "среднее значение наблюдений"

Смещение прогноза (prediction bias) - это величина, которая измеряет насколько далеко друг от друга эти средние значения. Таким образом:

Смещение прогноза = среднее значение прогнозов - среднее значение меток в наборе данных

Следует отметить, что "смещение прогноза" - это отличающаяся от смещения величина (b в wx + b).

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

Например, предположим мы знаем, что в среднем 1% всех писем является спамом. Если мы не знаем ничего о данных письмах, тогды нам следует прогнозировать, что примерно 1% является спамом. Схожим образом, хорошая модель поиска спама должна прогнозировать, что в среднем 1% писем является спамом. (Другими словами, если мы усредним спрогнозированную вероятность того, что письмо является спамом, то результат должен быть 1%.) Если же средний прогноз модели равен 20%, то мы можем заключить, что это является смещением прогноза.

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

  • Незавершенный набор свойств
  • "Зашумленный" набор данных
  • Ошибочный рабочий процесс
  • Смещенный тренировочный набор
  • Слишком сильная регуляризация

Возможно вы захотите поправить смещение прогноза послеобработкой обученной модели - то есть, добавлением градуировочного слоя, который приведет в порядок вывод модели и уменьшит смещение прогноза. Например, если модель имеет +3% смещение, можно добавить градуировочный слой, который уменьшит среднее значение прогноза на 3%. Однако, добавление градуировочного слоя - плохая идея по следующим причинам:

  • Вы исправляете симптом, а не причину.
  • Вы построете более хрупкую систему, которую затем придется поддерживать.

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

Следует отметить, что хорошая модель обычно имеет почти нулевое смещение. Хотя низкое смещение прогноза не подтверждает, что модель хороша. Ужасная модель может иметь нулевое смещение прогноза. Например, модель, которая просто прогнозирует среднее значение для всех примеров будет плохой моделью, несмотря на то, что будет иметь нулевое смещение прогноза.

Складывание в корзины (bucketing) и смещение прогноза

Логистическая регрессия прогнозирует значение между 0 и 1. Однако, все примеры с метками либо равны 0 (означая, например, "не спам"), либо 1 (означая, например, "спам"). Следовательно, когда идет проверка смещения прогноза, невозможно определить смещение прогноза, основанное только на одном примере, необходимо оценивать смещение прогноза на "корзине" примеров. То есть, смещение прогноза для логистической регрессии имеет смысл только при наличии достаточного количества сгруппированных вместе примеров, чтобы было возможно сравнить прогнозируемое значение (например, 0.392) с наблюдаемым значением (например, 0.394).

Можно формировать корзины следующими путями:

  • Линейное разбиение целевых прогнозов.
  • Формирование квантилей.

Рассмотрим следующий калибровочный график из отдельной модели. Каждая точка представляет корзину из 1000 значений. Оси имеют следующие значения:

  • x-ось представляет среднюю величину значений, которую модель спрогнозировала для этой корзины
  • y-ось представляет действительную среднюю величину значений в наборе данных для этой корзины

Обе оси в логарифмическом масштабе.

Кривая сдвига прогноза (логарифмические масштабы)

Почему прогнозы настолько слабы только в отдельной части модели? Вот возможные причины:

  • Тренировочный набор неадекватно представляет определенные поднаборы в области данных.
  • Некоторые поднаборы данных "зашумленней", чем другие.
  • Модель слишком сильно регуляризована. (Попробуйте уменьшить значение лямбда.)

Классификация: ROC и AUC

ROC кривая

ROC кривая (кривая рабочей характеристики приемника (receiver operating characteristic curve)) - это граф, показывающий производительность модели классификации при всех возможных значениях классификационных порогов. Эта кривая - график двух параметров:

  • Истинно положительная скорость (True Positive Rate)
  • Ложно положительная скорость (False Positive Rate)

Истинно положительная скорость (TPR) - это синоним отзыва и поэтому, определяется следующим образом:

TPR = TP / (TP + FN)

Ложно положительная скорость (FPR) определяется следующим образом:

FPR = FP / (FP + TN)

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

TP и FP скорость при разных классификационных порогах.

Чтобы вычислить точки на ROC кривой мы можем оценить модель логистической регрессии много раз с разными классификационными порогами, но это будет неэффективно. К счастью, существует эффективный, основанный на сортировке, алгоритм, который может предоставить нам эту информацию, называемый AUC.

AUC: область под ROC кривой

AUC обозначает "область под ROC кривой" ("Area under the ROC Curve"). AUC измеряет всю двухмерную область под всей ROC привой (то есть вычисляет интеграл) от (0,0) до (1,1).

AUC (область под ROC кривой)

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

Прогнозы ранжированные в восходящем порядке счета логистической регрессии.

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

AUC выдает результаты в периоде от 0 до 1. Модель, чьи прогнозы 100% ошибочны, имеет AUC равную 0.0, а модель со 100% верными прогнозами имеет AUC равную 1.0.

AUC привлекательна по следующим двум причинам:

  • AUC не обращает внимание на масштаб. Она измеряет насколько хорошо прогнозы ранжированы, а не их абсолютные значения.
  • AUC не обращает внимание на классификационный порог. Она измеряет качество прогнозов модели вне зависимости от того какой классификационный порог выбран.

Однако, обе эти причины имеют ограничения, которые могут ограничить полезность AUC в определенных случаях:

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

Классификация: точность и отзыв

Точность (Precision)

Точность пытается ответить на следующий вопрос:

Какая порция позитиных результатов была на самом деле правильной?

Точность определяется следующим образом:

Precision = TP / (TP + FP)

Следует отметить, что модель, которая не выдает ложно положительных результатов имеет точность равную 1.0.

Попробуем рассчитать точность для модели из предыдущего поста, которая анализирует опухоли:

  • Истинно положительные (TP): 1
  • Ложно положительные (FP): 1
  • Ложно отрицательные (FN): 8
  • Истинно отрицательные (TN): 90

Precision = TP / (TP + FP) = 1 / (1 + 1) = 0.5

Наша модель имеет точность 0.5 - другими словами, когда она прогнозирует, что опухоль злокачественная, это на самом деле верно только в 50% случаев.

Отзыв (Recall)

Отзыв пытается ответить на следующий вопрос:

Какая порция на самом деле позитивных примеров была определена правильно?

Математически, отзыв определяется следующим образом:

Recall = TP / (TP + FN)

Следует отметить, что модель, которая не выдает ложно отрицательных результатов имеет отзыв равный 1.0.

Попробуем рассчитать отзыв для модели, которая анализирует опухоли:

  • Истинно положительные (TP): 1
  • Ложно положительные (FP): 1
  • Ложно отрицательные (FN): 8
  • Истинно отрицательные (TN): 90

Recall= TP / (TP + FN) = 1 / (1 + 8) = 0.11

Наша модель имеет отзыв 0.11 - другими словами, она верно определяет только 11% всех злокачественных опухолей.

Точность и отзыв: перетягивание каната

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

Классифицирование электронных писем как "спам" или "не спам"

Попробуем рассчитать точность и отзыв, основываясь на результатах предыдущего графика:

  • Истинно положительные (TP): 8
  • Ложно положительные (FP): 2
  • Ложно отрицательные (FN): 3
  • Истинно отрицательные (TN): 17

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

Precision = TP / (TP+FP) = 8 / (8+2) = 0.8

Отзыв измеряет процент на самом деле спам-писем, которые были правильно классифицированы - то есть, процент зеленых точек справа от линии порога на предыдущем графике:

Recall = TP / (TP+FN) = 8 / (8+3) = 0.73

Следующий график показывает эффект от увеличения классификационного порога:

Увеличенный классификационный порог

Количество ложно положительных результатов уменьшилось, но ложно отрицательных возросло. Как результат, точность увеличилась, а отзыв уменьшился:

  • Истинно положительные (TP): 7
  • Ложно положительные (FP): 1
  • Ложно отрицательные (FN): 4
  • Истинно отрицательные (TN): 18

Precision = TP / (TP+FP) = 7 / (7+2) = 0.88
Recall = TP / (TP+FN) = 7 / (7+4) = 0.64

Напротив, следующий график показывает эффект от уменьшения классификационного порога (по отношению к изначальному варианту):

Уменьшенный классификационный порог

Количество ложно положительных результатов возросло, а ложно отрицательных уменьшилось. Как результат, точность уменьшилась, а отзыв увеличился:

  • Истинно положительные (TP): 9
  • Ложно положительные (FP): 3
  • Ложно отрицательные (FN): 2
  • Истинно отрицательные (TN): 16

Precision = TP / (TP+FP) = 9 / (9+3) = 0.75
Recall = TP / (TP+FN) = 9 / (9+2) = 0.82

Были разработаны различные метрики, основывающиеся одновременно на точности и отзыве. Например, F1 счет.

вторник, 28 августа 2018 г.

Классификация: аккуратность

Аккуратность (Accuracy) - это одна из метрик для оценки моделей классификации. Неформально, аккуратность - это порция прогнозов, которые модель сделала правильно. Формально, аккуратность имеет следующее определение:

Аккуратность = Количество правильных прогнозов / Общее количество прогнозов

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

Accuracy = (TP + TN) / (TP + TN + FP + FN)

Где TP = Истинно позитиный, TN = Истинно негативный, FP = Ложно позитивный, and FN = Ложно негативный.

Попробуем рассчитать аккуратность для следующей модели, которая классифицирует 100 опухолей как злокачественные (позитивный класс) или доброкачественные (негативный класс):

    • Истинно положительный (True Positive (TP))
    • Реальность: злокачественная
    • Модель спрогнозировала: злокачественная
    • Количество истинно положительных результатов: 1
    • Ложно положительный (False Positive (FP))
    • Реальность: доброкачественная
    • Модель спрогнозировала: злокачественная
    • Количество ложно положительных результатов: 1
    • Ложно отрицательный (False Negative (FN))
    • Реальность: злокачественная
    • Модель спрогнозировала: доброкачественная
    • Количество ложно отрицательных результатов: 8
    • Истинно отрицательный (True Negative (TN))
    • Реальность: доброкачественная
    • Модель спрогнозировала: доброкачественная
    • Количество истинно отрицательных результатов: 90

Accuracy = (TP + TN) / (TP + TN + FP + FN) = (1 + 90) / (1 + 90 + 1 + 8) = 0.91

Аккуратность оказалась 0.91, или 91% (91 правильный прогноз из 100 примеров). Это означает, что классификатор опухолей выполняет прекрасную работу по определению злокачественности, верно?

Из 100 примеров опухолей, 91 доброкачественная (90 TNs и 1 FP) и 9 злокачественных (1 TP и 8 FN).

Из 91 доброкачественных опухолей модель правильно определила 90 как доброкачественные. Это хорошо. Однако, из 9 злокачественных опухолей модель правильно определила только одну как злокачественную - ужасный результат, 8 из 9 опухолей неверно диагностированы.

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

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

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

Классификация: истинный и ложный, положительный и отрицательный

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

Эзопова басня: мальчик, который кричал "Волк!" (сжатая)

Мальчику-пастуху наскучило пасти сельское стадо. Чтобы немного развлечься, он закричал: "Волк!", - хотя никакого волка поблизости не было. Сельчане побежали защищать стадо, и сильно разозлились, когда поняли, что мальчик играет с ними, и это была шутка.

[Итерировать предыдущий параграф N раз.]

Одной ночью мальчик-пастух увидел, что настоящий волк приближается к стаду и закричал: "Волк!" Сельчане не хотели быть обманутыми снова и остались в своих домах. Голодный волк уничтожил все стадо. В селе начался голод, поднялась паника.

Определим следующие термины:

  • "Волк" - позитивный класс
  • "Нет волка" - негативный класс

Мы можем подвести итог по нашей модели "прогнозирование волка", используя матрицу 2x2, которая изображает все 4 возможных исхода:

    • Истинное положительный (True Positive (TP))
    • Реальность: угрожает волк
    • Пастух говорит: "Волк"
    • Результат: пастух - герой
    • Ложно положительный (False Positive (FP))
    • Реальность: волка нет
    • Пастух говорит: "Волк"
    • Результат: сельчане злы, что пастух разбудил их напрасно
    • Ложно отрицательный (False Negative (FN))
    • Реальность: угрожает волк
    • Пастух говорит: "Волка нет"
    • Результат: волк съедает всех овец
    • Истинно отрицательный (True Negative (TN))
    • Реальность: волка нет
    • Пастух говорит: "Волка нет"
    • Результат: все в порядке

Истинно положительный - вывод, где модель правильно прогнозирует положительный класс. Аналогично, истинно отрицательный - вывод, где модель правильно прогнозирует отрицательный класс.

Ложно положительный - вывод, где модель неправильно прогнозирует положительный класс. Аналогично, ложно отрицательный - вывод, где модель неправильно прогнозирует отрицательный класс.

В следующих постах мы рассмотрим как оценивать модели классификации, используя метрики, полученные из этих четырех выводов.

Классификационный порог

Логистическая регрессия возвращает вероятность. Можно использовать возвращенную вероятность "как есть" (например, вероятность, что пользователь будет кликать на эту рекламу рана 0.00023) или преобразовать возвращенную вероятность в бинарное значение (например, это письмо спам или нет).

Модель логистической регрессии для определения спама, которая возвращает 0.9995 для отдельного письма, прогнозирует, что это письмо с очень высокой вероятностью является спамом. С другой стороны, другое письмо с предсказанным счетом 0.0003 от той же самой модели логистической регрессии - с высокой вероятностью не является спамом. Однако, что насчет письма с предсказанным счетом равным 0.6? Чтобы создать карту соответствия значения логистической регрессии и бинарной категории необходимо определить классификационный порог (также называемый порог решения). Значение выше порога обозначает спам, значение ниже порога означает не спам. Это заманчивая перспектива - предположить, что классификационный порог всегда должен быть равен 0.5, но порог зависит от ситуации и, следовательно, является значением, которое необходимо настраивать.

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

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

понедельник, 27 августа 2018 г.

Логистическая регрессия: тренировка модели

Функция потери для логистической регрессии

Функция потери для линейной регрессии - это квадрат потери. Функция потери для логистической регрессии - логарифм потери, который определяется следующим образом:

где:

  • (x,y)∈D - набор данных, содержащий много примеров с метками, которые представляют собой (x,y) пары.
  • y - метка в примере с меткой. Ввиду того, что это логистическая регрессия, каждое значение y должно быть равным 0 или 1.
  • y' - спрогнозированное значение (где-то между 0 и 1), учитывающее набор свойств в x.

Уравнение для логарифма потери тесно связано измерением энтропии Шеннона из информационной теории. Это также отрицательный логарифм функции схожести, предполагающей распределение Бернулли для y. На самом деле, уменьшение функции потери выводит оценку максимального правдоподобия.

Регуляризация в логистической регрессии

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

  • L2 регуляризация
  • Ранняя остановка, которая ограничивает количество тренировочных шагов или скорость обучения.

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

К счастью, использование L2 или ранней остановки предупредит возникновение этой проблемы.

Резюме

Модели логистической регрессии генерируют вероятности.

Логарифм потери - это функция потери для логистической регрессии.

Логистическая регрессия широко используется на практике.

Логистическая регрессия: вычисление вероятности

Многие задачи требуют вероятностной оценки как вывод. Логистическая регрессия - это крайне эффективный механизм для расчета вероятностей. Возвращаемую вероятность можно использовать любым из следующих способов:

  • "Как есть"
  • Преобразовать в бинарную категорию.

Посмотрим как мы можем использовать вероятность "Как есть". Предположим, мы создаем модель логистической регрессии, чтобы прогнозировать вероятность того, что собака будет лаять в середине ночи. Мы будем называть эту вероятность так:

p(bark | night)

Если модель логистической регрессии прогнозирует p(bark | night) равной 0.05, тогда в течение года владельцы собак должны быть испуганы приблизительно 18 раз:

startled = p(bark | night) * nights
18 ~= 0.05 * 365

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

Как может модель логистической регрессии обеспечивать вывод, который всегда попадает в промежуток между 0 и 1? Как оказывается, сигмоидная функция, определенная следующим образом, производит вывод, имеющий те же самые характеристики:

Сигмоидная функция выводит следующий график:

Сигмоидная функция

Если z представляет вывод линейного слоя модели, тренированной логистической регрессией, тогда функция sigmoid(z) будет выводить значение (вероятность) между 0 и 1. В математических терминах:

где:

  • y' - это вывод модели логистической регрессии для отдельного примера
  • z равен b + w1x1 + w2x2 + ... wNxN

    • w значения - это веса и смещения, которым обучилась модель
    • x значения - это значения свойств для отдельного примера

Следует отметить, что z, также называют логарифмическими коэффициентами, потому что инверсия сигмоида констатирует, что z может быть определена как логарифм вероятности метки "1" (например, "собака лает") деленной на вероятность метки "0" (например, "собака не лает"):

Вот сигмоидная функция с метками машинного обучения:

Вывод логистической регрессии

четверг, 23 августа 2018 г.

Регуляризация для упрощения модели: лямбда

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

minimize(Loss(Data|Model)+λ complexity(Model))

Выполнение L2 регуляризации оказывает следующий эффект на модель:

  • Приближает значения весов к нулю (но не до самого нуля)
  • Приближает среднее значение весов к нулю, с нормальным (колоколообразным или Гауссовым) распределением.

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

Гистограмма весов

Снижение значения лямбды приводит к более пологой гистограмме:

Гистограмма весов, пройзведенная значением лямбда поменьше.

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

  • Если значение лямбда слишком большое, тогда модель будет простой, но появится риск недообучения данным. Модель не будет достаточно обучаться тренировочным данным, поэтому будет плохо прогнозировать результаты.
  • Если значение лямбда слишком маленькое, тогда модель будет более сложной, и увеличится риск переобучения. Модель будет обучаться излишним особенностям тренировочных данных и не сможет генерализоваться на новых данных.

Задание лямбда равной нулю полностью отменяет регуляризацию. В этом случае тренировка сфокусирована исключительно на минимизации потери и приводит к высокому риску переобучения.

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

Существует тесная связь между скоростью обучения и лямбда. Сильная L2 регуляризация значений приводит к приближению весов свойств к нулю. Низкая скорость обучения (с ранней остановкой) часто производит такой же эффект, потому что шаги от нуля не такие большие. Следователно, настраивание скорости обучения и лямбда одновременно может иметь смешанный эффект.

Ранняя остановка означает окончание тренировки до того как модель полностью приблизится. На практике, часто сталкиваются с неясностью с ранней остановкой, когда тренируют в онлайн (постоянном) режиме.

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

Регуляризация для упрощения модели: L2 регуляризация

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

Потеря на тренировочном и валидационном наборе

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

Другими словами, вместо простой цели уменьшить потерю (эмпирическая минимизация риска):

minimize(Loss(Data|Model))

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

minimize(Loss(Data|Model) + complexity(Model))

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

Сложность модели можно представлять двумя путями:

  • Сложность модели - функция весов всех свойств модели.
  • Сложность модели - функция общего количества свойств с ненулевыми весами.

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

Мы можем сделать сложность подсчитываемой, используя формулу L2 регуляризации, которая определяет регуляризацию как сумму квадратов всех весов свойств:

В этой формуле веса близкие к нулю слабо воздействуют на сложность модели, в то время как веса с экстремальными значениями могут иметь огромное влияние.

Например, линейная модель со следующими весами:

Имеет L2 регуляризацию 26.915:

Но w3 (выделенное жирным шрифтом), с значением, возведенным в квадрат, равным 25, составляет почти всю величину сложности. Сумма квадратов других пяти весов добавляет всего 1.915 к L2 регуляризации.

среда, 22 августа 2018 г.

Пересечения свойств: пересечение одноразовых векторов

В прошлом посте мы говорили о скрещивании двух индивидуальных нецельночисловых свойств. На практике модели машинного обучения редко скрещивают свойства с недискретными значениями. Однако, модели часто скрещивают свойства с одноразовыми векторами. Рассматривайте скрещения свойств с одноразовыми векторами как логические объединения. Предположим мы имеем два свойства: страну и язык. Одноразовое кодирование каждого из них создает вектора с бинарными свойствами, которые можно интерпретировать как country=USA, country=France или language=English, language=Spanish. Тогда, если произвести скрещивание таких одноразовых кодировок, получим бинарные свойства, которые можно рассматривать как логические объединения, такие как:

country:usa AND language:spanish

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

binned_latitude = [0, 0, 0, 1, 0]
binned_longitude = [0, 1, 0, 0, 0]

Предположим вы создали пересечение двух этих векторов:

binned_latitude X binned_longitude

Это пересечение свойств - 25-элементный одноразовый вектор (24 нуля и 1 единица). Единственная единица в пересечении идентифицирует отдельное объединение широты и долготы. Модель может тогда обучиться отдельным ассоциациям о таком объединении.

Предположим мы храним в ящиках широту и долготу намного большими отрезками:

binned_latitude(lat) = [
  0 < lat <= 10
  10 < lat <= 20
  20 < lat <= 30
]

binned_longitude(lon) = [
  0 < lon <= 15
  15 < lon <= 30
]

Создание пересечения свойств этих больших ящиков приведет к синтетическому свойству, имеющему следующие значения:

binned_latitude_X_longitude(lat, lon) = [
  0 < lat <= 10 AND 0 < lon <= 15
  0 < lat <= 10 AND 15 < lon <= 30
  10 < lat <= 20 AND 0 < lon <= 15
  10 < lat <= 20 AND 15 < lon <= 30
  20 < lat <= 30 AND 0 < lon <= 15
  20 < lat <= 30 AND 15 < lon <= 30
]

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

  • Тип поведения (лай, скуление и пр.)
  • Время суток

Если мы построим пересечение свойств из обоих этих свойств:

[behavior type X time of day]

тогда мы получим намного более полезное свойство, чем любое из свойств по отдельности. Например, радостный лай собаки в 5 вечера, когда хозяин возвращается с работы, будет отличным положительным предсказателем удовлетворения хозяина. Громкое скуление в 3 часа ночи, когда хозяин спит, будет сильным негативным предсказателем удовлетворения хозяина.

Заключение

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

Пересечение свойств: кодирование нелинейности

На следующих графиках представим следующее:

  • Синие точки представляют больные деревья.
  • Оранжевые точки представляют здоровые деревья.

Эта проблема линейная?

Можем ли мы провести черту, которая точно отделит больные деревья от здоровых? Конечно. Это линейная проблема. Линия не будет идеальна. Одно или два больных дерева могут попасть на "здоровую" сторону, но в целом линия будет хорошим предсказателем.

Теперь взглянем на следующий график:

Эта проблема линейная?

Можем ли мы провести единственную прямую линию, которая точно отделит больные деревья от здоровых? Нет. Это нелинейная проблема. Любая линия будет плохим предсказателем.

Единственная линия не может разделить классы

Чтобы решить нелинейную проблему создадим пересечение свойств. Пересечение свойств - это синтетическое свойство, которое кодирует нелинейность в пространстве свойств, умножая два или более входящих свойств друг на друга. Создадим пересечение свойств, названное x3, скрестив x1 и x2:

x3 = x1x2

Мы используем это новое свойство x3 как и любое другое свойство. Линейная формула становится:

y = b + w1x1 + w2x2 + w3x3

Линейный алгоритм может обучиться весу для w3 также как и для w1 и w2. Другими словами, хотя w3 кодирует нелинейную информацию, не требуется менять то, как линейная модель тренируется, чтобы определить значение w3.

Типы пересечений свойств

Можно создать много разных типов пересечений свойств:

  • [A X B]: пересечение свойств, сформированное умножением значений двух свойств
  • [A x B x C x D x E]: пересечение свойств, сформированное умножением значений пяти свойств
  • [A X А]: пересечение свойств, сформированное возведением единственного свойства в квадрат

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

вторник, 21 августа 2018 г.

Представление: очистка свойств

В этом посте мы поговорим об очистке данных. Этот этап часто занимает значительное время в машинном обучении.

Масштабирование значений свойств

Масштабирование означает преобразование нецельночисловых значений свойств из их естественного периода значений (например, от 100 до 900) в стандартный период (например, от 0 до 1 или от -1 до +1). Если набор свойств состоит только из единственного свойства, тогда масштабирование дает мало пользы либо не дает его совсем. Однако, если набор свойств состоит из многих свойств, тогда масштабирование свойств дает следующие преимущества:

  • Помогает градиентному спуску приблизиться (прийти к окончательному результату) быстрее
  • Помогает избегать ловушек NaN, в которых одно число в модели становится NaN (например, когда значение в ходе тренировки превышает лимит точности нецельночислового числа), и в ходе математических операций другие числа в модели становятся NaN.
  • Помогает модели обучаться подходящим весам для каждого свойства. Без масштабирования модель будет уделять слишком много внимания к свойствам, имеющим широкий диапазон значений.

Не обязательно задавать каждому нецельночисловому свойству одинаковый масштаб. Ничего ужасного не случится, если свойство А масштабировано от -1 до +1, в то время как свойство В масштабировано от -3 до +3. Однако, модель будет слабо реагировать, если свойство В масштабировано от 5000 до 100000.

Очевидный способ масштабировать числовые данные - это линейно картировать [мин значение, макс значение] в маленький масштаб, такой как [-1, +1].

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

scaledvalue = (value − mean) / stddev

Например, даны:

Среднее значение = 100
Стандартное отклонение = 20
Оригинальное значение = 130
тогда:

scaled_value = (130 - 100) / 20
scaled_value = 1.5

Масштабирование с Z количествами означает, что наибольшие масштабированные значения будут в диапазоне от -3 до +3, но небольшое количество значений будет немного больше или меньше диапазона.

Обработка экстремальных значений

Следующий график представляет свойство, названное roomsPerPerson (количество комнат на человека), из набора California Housing. Значение roomsPerPerson было рассчитано делением общего количества комнат в районе на население района. График показывает, что подавляющее большинство районов Калифорнии имеют одну или две комнаты на человека. Но обратите внимание на x-ось.

Очень длинный хвост

Как можно минимизировать влияние таких экстремальных значений? Один из способов - взять логарифм для каждого значения:

Логрифмическое масштабирование все равно оставляет хвост

Логарифмическое масштабирование справляется немного лучше, но все равно присутствует значительный хвост экстремальных значений. Существует другой подход. Что если мы просто "накроем" или "приклеим" максимальные значения roomsPerPerson к условно выбранному значению, например к 4.0?

Прикрепление значений свойства к 4.0

Прикрепление значения свойства к 4.0 не означает, что мы игнорируем все значения больше 4.0. Скорее это означает, что все значения, которые были больше 4.0, теперь стали равны 4.0. Это объясняет холмик на графике в 4.0. Несмотря на холмик, масштабированный набор свойств теперь более полезен, чем изначальные данные.

Хранение в ящиках

Следующий график показывает относительную распространенность домов в различных широтах Калифорнии. Следует отметить кластеризацию - Лос Анджелес около 34 широты и Сан Франциско около 38 широты.

Дома по широтам

В наборе данных широта это нецельночисловое значение. Однако, это не имеет смысла, представлять широты как нецельночисловые свойства в нашей модели. Это потому, что нет линейной зависимости между широтой и домами. Например, дома на широте 35, а не на 34/35, более дорогостоящи (или менее), чем дома на широте 34. И еще, отдельные широты вероятно отличный предсказатель значений домов.

Чтобы сделать широту полезным предсказателем, разделим широты на отдельные "ящики" как показано на следующем графике:

Значения рапределенные по "ящикам"

Вместо одного нецельночислового свойства, у нас теперь 11 различных булевых свойств (LatitudeBin1, LatitudeBin2, ..., LatitudeBin11). Наличие 11 отдельных свойств не очень элегантно, но позволяет объединить их в один 11-элементный вектор. Выполнение такой операции позволяет нам представить широту 37.4 следующим образом:

[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]

Благодаря хранению в ящиках наша модель теперь может обучиться совершенно другим весам для каждой широты.

Чистка (скрабирование)

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

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

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

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

  • Макимум и минимум
  • Среднее значение и медиана
  • Стандартное отклонение

Учитывайте генерирование листов наиболее частых значений для отдельных свойств. Например, пусть количество примеров с country:uk соответствует числу, которое вы предполагали. А должен ли language:jp быть наиболее частым языком в таком наборе данных?

Понимание данных

Следуйте следующим правилам:

  • Помните всегда о том как ваши данные должны выглядеть.
  • Проверяйте, что данные соответствуют вашим ожиданиям (или объясните почему они не соответствуют)
  • Дважды проверьте, что тренировочные данные соответствуют, используя разные методы проверки
  • Бережно обращайтесь со своими данными, как с критически важным кодом. В машинном обучении хорошие результаты основываются на хороших данных.

Представление: качества хороших свойств

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

Избегайте редко используемые отдельные значения свойств

Полезные значения свойства должны появляться более 5 раз в наборе данных. Применение такого подхода позволяет модели обучиться тому, как это значение свойства относится к метке. Таким образом, наличие многих примеров с таким же дискретным значением дает модели шанс увидеть свойство при других настройках, и в свою очередь, определить, когда оно является хорошим предсказателем для метки. Например, свойство house_type с большой вероятностью будет содержать много примеров, в которых его значение будет "викторианский":

#Это правильно
house_type: victorian

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

#Это пример уникального значения. Следует избегать использования такого свойства

unique_house_id: 8SK982ZZ1242Z


Предпочтительны ясные и очевидные значения

Каждое свойство должно иметь ясное и очевидное значение. Например, предположим следующее значение свойства для возраста дома, которое мгновенно узнаваемо как возраст в годах:

#Пример ясного значения
house_age: 27

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

#Пример неясного значения, которое следует избегать

house_age: 851472000

В некоторых случаях "шумовые" данные (скорее чем плохие инженерные решения) служат причиной неясных значений. Например, следующее значение свойства user_age пришло из источника, который не проверял подходящие значения:

#Пример "шумовых"/плохих данных, который следует избегать

user_age: 277


Не смешивайте "магические" значения с реальными данными

Хорошие нецельночисловые свойства не содержат необычных не входящих в диапазон или "магических" значений. Например, предположим, свойство содержит нецельночисловое значение между 0 и 1. Тогда значения, как следующие, будут правильными:

quality_rating: 0.82
quality_rating: 0.37

Однако, если пользователь не ввел quality_rating, возможно набор данных представит отсуствующие значения как следующее "магическое" значение:

# Пример "магического" значения, которое следует избегать

quality_rating: -1

Обходной путь для "магических" значений - преобразование одного свойства в два свойства:

  • Одно свойство хранит только качественный рейтинг, без "магических" значений
  • Другое свойство хранит булево значение, обозначающее был ли предоставлен quality_rating. Дайте этому булеву свойству название is_quality_rating_defined.

Учитывайте исходящую нестабильность

Определение свойства не должно меняться с течением времени. Например, следующее значение правильное, поскольку название города вероятно не изменится. (Следует отметить, что все равно необходимо преобразовывать строку типа "br/sao_paulo" в одноразовый вектор)

city_id: "br/sao_paulo"

Но прием значения выведенного другой моделью несет дополнительные расходы. Возможно значение "219" на данный момент представляет Сан Паулу, но такое представление может легко измениться в будущем при использовании другой модели:

# Пример значения, которое может измениться и которое следует избегать

inferred_city_cluster: "219"

понедельник, 20 августа 2018 г.

Представление: разработка свойств

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

Картирование сырых данных в свойства

Левая сторона следующего графика представляет сырые данные из входящего источника данных. Правая сторона представляет вектор свойств, представляющий собой набор нецельночисловых значений, соотвествующий примерам в наборе данных. Разработка свойств означает преобразование сырых данных в вектор свойств. Зачастую на разработку свойств уходит значительное количество времени.

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

Разработка свойств картирует сырые данные в свойства для машинного обучения

Картирование числовых значений

Цельночисловые и нецельночисловые данные не нуждаются в дополнительном кодировании, поскольку они могут быть умножены на числовые веса. Как отображено в следующем графике, преобразование сырого цельночислового значения 6 в значение свойства 6.0 тривиальная задача:

Картирование цельночисловых значений в нецельночисловые свойства

Картирование категоризированных значений

Категоризированные свойства имеют заданный набор возможных значений. Например, может быть свойство называемое street_name со значениями, которые включают:

{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}

Поскольку модель не может умножать строки на обученные веса, нам необходимо использовать разработку свойств, чтобы преобразовать строки в числовые значения.

Мы можем достичь этого, определив карту значений свойств к числам, к которой мы будем ссылаться как к словарю возможных свойств. Ввиду того что не каждая улица в мире появится в нашем наборе данных, мы можем сгруппировать все остальные улицы в категорию "другие", известную как OOV (out-of-vocabulary)(не-в-словаре) корзина.

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

  • картируем Charleston Road как 0
  • картируем North Shoreline Boulevard как 1
  • картируем Shorebird Way как 2
  • картируем Rengstorff Avenue как 3
  • картируем все остальное (OOV) как 4

Однако, если мы встроим эти индексные числа напрямую в нашу модель, это приведет к некоторым ограничениям, которые могут быть проблематичны:

  • Мы будем обучаться единственному весу, который будет применяться ко всем улицам. Например, если мы присвоим в ходе обучение вес равный 6 для street_name, тогда мы будем умножать это на 0 для Charleston Road, на 1 для North Shoreline Boulevard, 2 для Shorebird Way и т.д. Предположим модель, которая будет прогнозировать цену домов, используя street_name как свойство. Вряд ли существует линейная зависимость цен от названия улиц и кроме того, предполагается, что улицы были отсортированы на основе их средней цены на жилье. Наша модель требуется в большей гибкости в обучении различных весов для каждой улицы, которая будет добавлена в цену, рассчитанную по другим свойствам.
  • Мы не учли случаев, когда street_name может иметь несколько значений. Например, многие дома расположены на углу двух улиц, и нет пути кодировать такую информацию в значение street_name если оно может содержать только один индекс.

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

  • Для значений, которые применяются к примеру, установить соотвествующий вектор элементов равный 1
  • Установить все остальные элементы равными 0

Длина этого вектора соответствует количеству элементов в словаре. Это представление называется одноразовое кодирование, когда только одно значение равно 1, и многоразовое кодирование, когда несколько значений равны 1.

Следующий график показывает одноразовое кодирование определенной улицы: Shorebird Way. Элемент бинарного вектора для Shorebird Way имеет значение 1, в то время как остальные элементы для всех остальных улиц имеют значение 0.

Картирование адреса улицы через одноразовое кодирование

Этот подход эффективно создает булевы переменные для каждого значения свойства (например, название улицы). Так, если дом расположен на Shorebird Way, тогда бинарное значение равно 1 только для Shorebird Way. То есть модель использует только вес для Shorebird Way.

Аналогично, если дом расположен на углу двух улиц, тогда два бинарных значения равны 1 и модель использует оба этих веса.

Одноразовое кодирование также применяется к числовым данным, которые вы не хотите напрямую умножать на вес, такие как почтовый индекс.

Разреженное представление

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

Валидационный набор

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

На графике "Tweak model" означает изменение чего-либо в модели - от изменения скорости обучения, до добавления либо удаления свойств, чтобы полностью создать модель с нуля. В конце рабочего процесса мы получаем модель, которая отлично выполняет работу на тестовом наборе.

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

Разделение набора данных на три части

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

В этом улучшенном рабочем процессе:

  • берем модель, которая успешно справляется на валидационном наборе
  • затем проводим вторую проверку на тестовом наборе

Этот рабочий процесс дает лучшие результаты, поскольку меньше взаимодействует с тестовым набором, поэтому проверка на нем становится более достоверной.

Резюме

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

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

Тренировочный и тестовый набор: разделение данных

В предыдущем посте было упомянуто о разделении данных на два набора:

  • тренировочный набор - набор для того, чтобы тренировать модель
  • тестовый набор - набор для того, чтобы тестировать модель

Можно изобразить данное разделение следующим образом:

Разделение набора данных на тренировочный и тестовый набор.

Тестовый набор должен соотвествовать следующим требованиям:

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

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

Проверка тренированной модели на тестовых данных.

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

Например, возьмем модель, которая оценивает является ли электронное письмо спамом или нет, используя поле Тема, сообщение в письме, и адрес отправителя как свойства для модели. Разделим данные на тренировочный и тестовый набор в соотношении 80-20. После тренировки модель достигла точности 99% в тренировочном и тестовом наборе. Мы предполагали более низкую точность на тестовом наборе. Взглянув на данные, мы обнаружили, что многие из примеров в тестовом наборе являются копиями примеров тренировочного набора (мы пренебрегли очисткой данных от копий перед разделением данных). Таким образом, получилось так, что мы ненароком тренировали модель на части данных из тестового набора, и в результате не можем оценить насколько хорошо модель генерализуется на новых данных.

воскресенье, 19 августа 2018 г.

Генерализация: опасность переобучения

В этом посте мы поговорим о генерализации. С целью представить что это такое приведем три графика. Предположим, что каждая точка на этих графиках представляет положение дерева в лесу. Два цвета имеют следующие значения:

  • Синие точки представляют больные деревья.
  • Оранжевые точки представляют здоровые деревья.

Больные (синие) и здоровые (оранжевые) деревья.

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

Сложная модель, отделяющая больные деревья от здоровых

Следующий график показывает что случилось, когда модели были переданы новые данные. Оказалось, что модель очень слабо адаптируется к новым данным. Необходимо отметить что модель неправильно категоризировала многие примеры из новых данных.

Модель выполнила плохое предсказание по новым данным.

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

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

Уильям Оккам, монах и философ, живший в 14 веке, любил простоту. Он верил, что ученым следует предпочитать более простые формулы и теории, чем сложные. Применив бритву Оккама в условия машинного обучения получим: чем менее сложна модель, тем вероятнее она даст хорошие результаты в прогнозировании, а не просто учтет особенности тренировочных данных.

На данное время бритва Оккама формализована в областях теории статистического обучения и теории вычислительного обучения. В этих областях разработаны границы генерализации - статистическое описание способности модели генерализоваться к новым данным основано на следующих факторах:

  • сложность модели
  • производительность модели на тренировочных данных

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

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

  • тренировочный набор - поднабор для того чтобы тренировать модель
  • тестовый набор - поднабор для того чтобы тестировать модель

Хорошая производительность на тестовых данных служит индикатором хорошей производительности на новых данных в целом, но при условиях того что:

  • тестовый набор достаточно большой
  • тестовый набор не используется снова и снова

Главное

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