Машинное обучение это весело!

Posted by Vasiliy Zemlyanov on October 4, 2016

Перевод статьи: Machine Learning is Fun!

Это мой первый опыт перевода статей, об найденных ошибках просьба сообщать на почту (re9ulusV@gmail.com).

Машинное обучение это весело!

Самое простое введение в машинное обучение.

Вы слышали как люди говорят об Машинном обучении но имеете довольно смутное представление об этом странном термине? Давайте изменим это!


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

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


Что такое машинное обучение?

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

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

Machine learning algorithm is a black box

Машинное обучение это обобщающий термин, включающий множество обобщенных алгоритмов.

Два типа алгоритмов машинного обучения

Упрощенно можно разделить все алгоритмы машинного обучения на 2 основные категории — обучение с учителем (supervised learning) и обучение без учителя (unsupervised learning). Отличие простое, но действительно важное.

Обучение с учителем

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

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

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

Кол-во комнат Кв. метры Район Цена продажи
3 2000 Нормгород $250.000
2 800 Хипстервиль $300.000
2 850 Нормгород $150.000
1 550 Нормгород $78.000
4 2000 Отшиб $150.000

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

Кол-во комнат Кв. метры Район Цена продажи
3 2000 Хипстервиль ???

Этот подход называется Обучением с учителем (Supervised learning). Вы знаете, за сколько был продан каждый дом, другими словами, знаете ответ задачи и можете продвигаться обратно к условию, конструируя логику решения в обратном порядке.

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

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

Math quiz 1

Вы можете выяснить какая задача поставлена в тесте? Нужно что-то сделать с числами слева для получения ответа справа.

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

Обучение без учителя

Вернемся к примеру с агентом по недвижимости. Что, если вы не знаете, за сколько были проданы дома? Даже если известны только размер недвижимости, ее местоположение и другие параметры (но неизвестна цена), вы все еще можете сделать интересные вещи. Это называется Обучением без учителя (Unsupervised learning).

Кол-во комнат Кв. метры Район
3 2000 Нормгород
2 800 Хипстервиль
2 850 Нормгород
1 550 Нормгород
4 2000 Отшиб

Как если бы кто-то дал вам лист бумаги исписанный цифрами и сказал: “Я не знаю что это за цифры, но может у тебя получится найти в них закономерность — удачи!”.

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

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

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

Замечание для педантов: Существует множество других типов алгоритмов машинного обучения. Но для начала нам хватит этих двух.

Все здорово, но почему оценка стоимости недвижимости считается “обучением” ?

Человеческий мозг может найти подход практически к любой ситуации и научиться справляться с ней без четких инструкций. Если вы давно продаете недвижимость, то инстинктивно “знаете” правильную стоимость, лучший рынок, заинтересованных клиентов и тому подобное. Цель исследований о Сильном ИИ повторить эту возможность с помощью компьютеров.

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

К сожалению, “Машинное нахождение уравнения для решения определенной задачи на основе данных из примера” не самое изящное название. Поэтому остановились на “Машинном обучении”.

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

Напишем программу!

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

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

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0
  # В моей области средняя стоимость квадратного метра $200 за 1 кв. м.
  price_per_sqft = 200
  if neighborhood == "hipsterton":
    # Но в некоторых районах стоимость дороже
    price_per_sqft = 400
  elif neighborhood == "skid row":
    # А в некоторых дешевле
    price_per_sqft = 100
  # Начнем с базовой цены умноженной на площадь недвижимости
  price = price_per_sqft * sqft
  # Сделаем поправку на количество спален
  if num_of_bedrooms == 0:
    # Аппартаменты-студии дешевые
    price = price - 20000
  else:
    # Недвижимость с большим количеством спален обычно дороже
    price = price + (num_of_bedrooms * 1000)
 return price

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

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

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = компьютер_будь_добр_реши_математику_за_меня()
  return price

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

Это упростит нашу первоначальную функцию (со всеми сумасшедшими условиями) до чего-то простого, например:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
    price = 0
    # щепотку этого
    price += num_of_bedrooms * .841231951398213
    # и большую щепотку вот этого
    price += sqft * 1231.1231231
    # может немного этого
    price += neighborhood * 2.3242341421
    # и наконец, тщательно взвещенная щепотка соли
    price += 201.23432095
    return price

Обратите внимание на волшебные числа: .841231951398213, 1231.1231231, 2.3242341421 и 201.23432095. Это веса функции. Если мы выясним идеальные веса, которые подойдут для любого дома, наша функция сможет предсказывать стоимость недвижимости!

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

Шаг 1:

Инициализируем каждый вес значением 1.0:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0
  # щепотку этого
  price += num_of_bedrooms * 1.0
  # и большую щепотку вот этого
  price += sqft * 1.0
  # может немного этого
  price += neighborhood * 1.0
  # и наконец, тщательно взвещенная щепотка соли
  price += 1.0
  return price

Шаг 2:

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

Кол-во комнат Кв. метры Район Цена продажи Наша догадка
3 2000 Нормгород $250.000 $178.000
2 800 Хипстервиль $300.000 $371.000
2 850 Нормгород $150.000 $148.000
1 550 Нормгород $78.000 $101.000
4 2000 Скид Роу $150.000 $121.000

Например, если первый дом был продан за $250.000, а наша функция предсказывает $178.000, мы недооценили этот дом на $72.000.

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

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

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

Шаг 3:

Будем повторять Шаг 2 снова и снова для всех возможных комбинаций весов. Использовать будем комбинацию, которая дает наименьшую ошибку. Как только мы найдем подходящие веса — решим задачу!

Мозговыносящий поворот

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

А теперь немного мозговыносящих фактов:

  1. Исследования во многих областях (например лингвистика/переводы) за последние 40 лет показывают, что “приготовление рагу из чисел” показывает лучшие результаты, чем подходы, в которых люди пытаются составить набор правил самостоятельно. “Глупый” подход машинного обучения в итоге превосходит экспертов-людей. (прим. переводчика. По моему области для примера подобраны неудачно. Распознавание изображений более впечатляющий пример.)

  2. Полученная нами функция невероятно глупа. Она не знает ничего о “квадратных метрах” или “спальнях”. Все, что она знает, как смешать все эти числа и получить правильный ответ.

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

  4. Представим, что вместо “квадратных метров” и “количества комнат” наше предсказание основано на массивах чисел. Пусть каждое число представляет яркость одного пикселя изображения, которое снимает камера, установленная на крыше машины. А теперь, допустим, что вместо предсказания “цена” функция возвращает предсказание “угол_поворота_ведущего_колеса”. Мы только что разработали простой автопилот!

Легкое сумасшествие, не правда ли?

А что там с “переберем все числа” на шаге 3?

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

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

Сначала напишем простое уравнение, описывающее шаг #2:

Теперь перепишем это уравнение используя лексикон машинного обучения (можно пропустить на данном этапе):

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

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

Graph of cost function

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

Graph of cost function with dots

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

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

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

Это обобщенное краткое описание одного из способов найти наилучшие веса функции стоимости известного как градиентный спуск (batch gradient descent). Не бойтесь копнуть глубже если вам интересно изучить детали.

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

О чем еще ты умолчал?

Трехшаговый алгоритм, описанный выше называется множественной линейной регрессией (multivariative linear regression). Вы оцениваете уравнение для линии, которая описывает все данные о недвижимости. Затем используете это уравнение для предсказания цены недвижимости, которую раньше не видели, на основе того, где эта недвижимость окажется на вашей линии. Это действительно мощная идея, с помощью которой можно решать реальные задачи.

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

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

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

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

Машинное обучение - это магия?

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

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

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

Model of relationship

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

Как узнать больше о машинном обучении

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

Курс Машинное обучение Andrew Ng просто восхитителен. Я очень рекомендую начать с него. Он должен быть понятен любому человеку со степенью в Компьютерных науках и для тех кто помнит немного математики.

Еще вы можете поиграть с огромным количеством алгоритмов машинного обучения используя SkLearn. Это python фреймворк, реализующий “black box” версии стандартных алгоритмов.

Прим. переводчика: На русском языке есть замечательные Специализация МФТИ и Яндекса по Машинному обучению и курс Введение в Машинное обучение.