Машинное обучение для школьников (заметки)

Посвящается Михаилу Абрамовичу Ройтбергу
(27.12.1952 — 16.08.2017), моему учителю и потрясающему человеку, который заразил меня преподаванием.

Алексей Драль
27.12.2019

Conference, Machine Learning and Very Large Data Sets

1st October, 2013, Moscow, Russia
Занятие #5 (13.08.2016): Модель регрессии, бустинг и принцип репки

Курс "Экосистема Python и Машинное Обучение" проводился в рамках школы молекулярной и теоретической биологии,
Barcelona Biomedical Research Park, Барселона, Испания.

Целью занятия является создание программы, способной предсказать цену дома по ряду его известных характеристик. Такие программы мы называем моделью регрессии (см. ниже). Модель регрессии будем создавать в виде блокнота (Jupyter notebook) с помощью библиотеки SKLearn. Ниже каждый раздел текста соответствует очередной ячейке блокнота и небольшому заданию на языке программирования Python (в русском языке распространено название Питон или Пайтон).

Замечание. В машинном обучении (Machine Learning) есть несколько типовых задач - задачи классификации и задачи регрессии.
1. В задачах классификации нужно уметь "классифицировать" новый объект к одному из классов. Например, определить кто изображен на фотографии - "кошка" или "собака". Для решения такой задачи будет строиться модель классификации (или классификатор);
2. В задачах регрессии нам нужно предсказать численное значение. Примеры: предсказать цену дома в зависимости от его характеристик; количество лайков Вашего поста в социальных сетях; вероятность поступить в конкретных ВУЗ на бюджет на основе успеваемости и посещаемости. Для решения таких задач будет строиться модель регрессии. Слово регрессор имеет много смыслов, поэтому для однозначности мы будем использовать именно "модель регрессии" (но не "регрессор" / regressor).

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

1. Библиотеки Python для занятия

Стандартные библиотеки для решения задач машинного обучения в Python:

  • matplotlib - библиотека для рисования графиков (очень удобно для визуализации данных или результатов экспериментов)
  • numpy - библиотека для эффективной работы с матрицами (одномерные массивы, двумерные, …, многомерные)
  • pandas - "Excel" для Python (удобно для анализа "табличных" данных, расчета базовых статистик)
  • sklearn - набор алгоритмов (классификаторов, моделей регрессии, …) для решения задач машинного обучения. Например, на занятии рассмотрим GradientBoostingRegressor - бустинг на решающих деревьях

Для простоты настройки окружения для выполнения заданий рекомендуется воспользоваться сервисом Google Colab:

Все указанные библиотеки там уже доступны для работы. Создайте новый ноутбук, напишите следующий код и выполните ячейку с кодом:
import matplotlib
import numpy
import pandas
import sklearn
print("Все отлично работает!")
2. Наборы данных

Питон содержит много наборов данных (datasets). Доступ к ним возможен с помощью модуля datasets. Загрузим набор данных "boston" с ценами на дома в городе Бостон:
from sklearn import datasets
boston = datasets.load_boston()
print(boston.DESCR)
На экране Вы увидите содержание набора данных (см. ПРИЛОЖЕНИИ 1.). Среди характеристик будут такие показатели как транспортная доступность, расстояние до реки и т.п.
3. Подготовка данных для проведения эксперимента

Данные нужно:
1. Перемешать;
2. И разделить на обучающую и тестовую выборку (train and test parts)

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

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

Программный интерфейс:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=100500, train_size=0.9)
В данном случае у нас 90% данных используется для обучения модели регрессии, а 10% для оценки качества. train_test_split перемешивает данные и делит данные на выборки train и test.
4. Контейнер для модели регрессии

Сделаем "заготовку модели регрессии". По научному эта заготовка называется "контейнер". В контейнере описывается общий алгоритм построения модели регрессии. В нашем случае - это алгоритм BoostingRegressor (см. ПРИЛОЖЕНИЕ 2). Установим значения параметров для обучения n_estimators, max_depth, min_samples_split, learning_rate, loss:
from sklearn.ensemble import GradientBoostingRegressor
regression_model = GradientBoostingRegressor(loss="ls", learning_rate=0.1, n_estimators=100, max_depth=3, min_samples_split=2)
5. Обучение модели регрессии и проверка качества предсказания

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

Вдаваться в детали процесса обучения мы не будем. Отдельно отметим важность способа сравнения результатов. Выбор способа для сравнения моделей зависит от решаемой задачи и существенно влияет на результаты обучения. В качестве примеров укажем средне-квадратичное отклонение (квадрат "евклидова расстояния") эталонного и предсказанного набора результатов, а также максимальное отклонение предсказанного результата от соответствующего эталона.
from sklearn.metrics import mean_squared_error, mean_absolute_error

regression_model.fit(X_train, y_train)
y_predicted = regression_model.predict(X_test)
print("mean squared error: ", mean_squared_error(y_test, y_predicted))
print("mean absolute error: ", mean_absolute_error(y_test, y_predicted))
print("max absolute distance: ", numpy.abs(y_test - y_predicted).max())
ПРИЛОЖЕНИЕ 1. Описание набора данных "Бостон"

Boston House Prices dataset
Notes

------
Data Set Characteristics:
:Number of Instances: 506
:Number of Attributes: 13 numeric/categorical predictive
:Median Value (attribute 14) is usually the target

:Attribute Information (in order):
- CRIM per capita crime rate by town
- ZN proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS proportion of non-retail business acres per town
- CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX nitric oxides concentration (parts per 10 million)
- RM average number of rooms per dwelling
- AGE proportion of owner-occupied units built prior to 1940
- DIS weighted distances to five Boston employment centres
- RAD index of accessibility to radial highways
- TAX full-value property-tax rate per $10,000
- PTRATIO pupil-teacher ratio by town
- B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town
- LSTAT % lower status of the population
- MEDV Median value of owner-occupied homes in $1000's

:Missing Attribute Values: None

:Creator: Harrison, D. and Rubinfeld, D.L. This is a copy of UCI ML housing dataset.

http://archive.ics.uci.edu/ml/datasets/Housing
This dataset was taken from the StatLib library which is maintained at Carnegie
Mellon University.

The Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic prices and the demand for clean air', J. Environ. Economics & Management, vol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics ...', Wiley, 1980. N.B. Various transformations are used in the table on pages 244-261 of the latter.

The Boston house-price data has been used in many machine learning papers that address regression problems.

References:
- Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.
- Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243,
University of Massachusetts, Amherst. Morgan Kaufmann.
ПРИЛОЖЕНИЕ 2. Алгоритм GradientBoosting

Алгоритм GradientBoosting состоит в использовании ансамбля классификаторов "Дерево" (см. ПРИЛОЖЕНИЕ 3), взаимодействующих по методу "Бустинг" (см. ПРИЛОЖЕНИЕ 4). Слово "Gradient" указывает на особенность обучения классификатора, его мы объяснять
не будем

Параметры, указанные в скрипте, имеют следующий смысл:
- n_estimators - количество классификаторов в ансамбле;
- max_depth - максимальная глубина дерева;
- min_samples_split - минимальное количество элементов обучающей выборки, приписанное листу дерева-классификатора;
- learning rate - связан с особенностями метода обучения;
- loss - описывает способ вычисления погрешности.
ПРИЛОЖЕНИЕ 3. Алгоритм "Дерево"

Классификатор "Дерево" (по-английски tree classifier) устроен следующим образом:
- во время обучения каждому внутреннему узлу дерева сопоставляется условие на набор признаков, а каждому листу - множество объектов обучающей выборки;
- по этому множеству строится доля представителей каждого класса (для задачи классификации) или среднее значение целевого признака (для задачи регрессии)

При анализе какого-либо объекта он двигается от корня к листьям в соответствии со значением своих признаков. Ответ выдается в соответствии с достигнутым листом (см. картинку снизу).

ПРИЛОЖЕНИЕ 4. Ансамбли моделей. Bagging и Boosting. Принцип "репки"

Есть два стандартных подхода для использования ансамблей моделей классификации или регрессии:
1. Bagging (бэгггинг);
2. И boosting (бустинг)

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

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

При бустинге классификаторы ансамбля работают "по очереди". Бустинг применяется, когда результатом работы классификатора (точнее - модели регрессии) является число. При этом результирующее число, выдаваемое ансамблем, - это сумма результатов отдельных классификаторов:

При этом только "нулевой" классификатор обучен решать исходную задачу. Следующий (первый) классификатор предсказывает погрешность результата первого классификатора (разность Y1 = Y0 - P0 между эталонным результатом Y и предсказанием P0 нулевого классификатора). Пусть P1 - это предсказание 1-го классификатора, а Y2 = Y1 - P1 = Y0-P0-P1 - его погрешность. Классификатор №2 предсказывает погрешность суммы 0-го и 1-го классификатора - величину Y2. Пусть P2 - его предсказание. Классификатор №3 предсказывает погрешность Y2-P2 = Y0-P0-P1-P2 и т.д. Окончательное предсказание значения величины Y0 получается, таким образом, как сумма предсказаний всех классификаторов P0+P1+P2+...


Этот принцип работы ансамбля классификаторов можно назвать принципом "Репки":
Мы обучаем первый классификатор ("дедка") и получаем какое-то предсказание. Оно неточное, потому подключается "бабка", которая помогает исправить ошибки предсказания. В сумме, они тоже ошибаются, поэтому подключается "жучка" и так далее.
Пишите нам в соцсети или на email:
study@bigdatateam.org