[Из песочницы] Введение в машинное обучение с помощью scikit-learn (перевод документации)
Данная статья представляет собой перевод введения в машинное обучение, представленное на официальном сайте scikit-learn.
В этой части мы поговорим о терминах машинного обучения, которые мы используем для работы с scikit-learn, и приведем простой пример обучения.
Машинное обучение: постановка вопроса
В общем, задача машинного обучения сводится к получению набора выборок данных и, в последствии, к попыткам предсказать свойства неизвестных данных. Если каждый набор данных — это не одиночное число, а например, многомерная сущность (multi-dimensional entry или multivariate data), то он должен иметь несколько признаков или фич.
Машинное обчение можно разделить на несколько больших категорий:
- обучение с учителем (или управляемое обучение). Здесь данные представлены вместе с дополнительными признаками, которые мы хотим предсказать. (Нажмите сюда, чтобы перейти к странице Scikit-Learn обучение с учителем). Это может быть любая из следующих задач:
- классификация: выборки данных принадлежат к двум или более классам и мы хотим научиться на уже размеченных данных предсказывать класс неразмеченной выборки. Примером задачи классификации может стать распознавание рукописных чисел, цель которого — присвоить каждому входному набору данных одну из конечного числа дискретных категорий. Другой способ понимания классификации — это понимание ее в качестве дискретной (как противоположность непрерывной) формы управляемого обучения, где у нас есть ограниченное количество категорий, предоставленных для N выборок; и мы пытаемся их пометить правильной категорией или классом.
- регрессионный анализ: если желаемый выходной результат состоит из одного или более непрерывных переменных, тогда мы сталкиваемся с регрессионным анализом. Примером решения такой задачи может служить предсказание длинны лосося как результата функции от его возраста и веса.
- обучение без учителя (или самообучение). В данном случае обучающая выборка состоит из набора входных данных Х без каких-либо соответствующих им значений. Целью подобных задач может быть определение групп схожих элементов внутри данных. Это называется кластеризацией или кластерным анализом. Также задачей может быть установление распределения данных внутри пространства входов, называемое густотой ожидания (density estimation). Или это может быть выделение данных из высоко размерного пространства в двумерное или трехмерное с целью визуализации данных. (Нажмите сюда, чтобы перейти к странице Scikit-Learn обучение без учителя).
Обучающая выборка и контрольная выборка
Машинное обучение представляет собой обучение выделению некоторых свойств выборки данных и применение их к новым данным. Вот почему общепринятая практика оценки алгоритма в Машинном обучении — это разбиение данных вручную на два набора данных. Первый из них — это обучающая выборка, на ней изучаются свойства данных. Второй — контрольная выборка, на ней тестируются эти свойства.
Загрузка типовой выборки
Scikit-learn устанавливается вместе с несколькими стандартными выборками данных, например, iris и digits для классификации, и boston house prices dataset для регрессионного анализа.
Далее мы запускам Python интерпретатор из командной строки и загружаем выборки iris и digits. Установим условные обозначения: $ означает запуск интерпретатора Python, а >>> обозначает запуск командной строки Python:
$ python
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> digits = datasets.load_digits()
Набор данных — это объект типа «словарь», который содержит все данные и некоторые метаданных о них. Эти данные хранятся с расширением .data, например, массивы n_samples, n_features. При машинном обучении с учителем одна или более зависимых переменных хранятся с расширением .target. Для получения более полной информации о наборах данных перейдите в соответствующий раздел.
Например, набор данных digits.data дает доступ к фичам, которые можно использовать для классификации числовых выборок:
>>> print(digits.data)
[[ 0. 0. 5. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 10. 0. 0.]
[ 0. 0. 0. ..., 16. 9. 0.]
...,
[ 0. 0. 1. ..., 6. 0. 0.]
[ 0. 0. 2. ..., 12. 0. 0.]
[ 0. 0. 10. ..., 12. 1. 0.]]
а digits.target дает возможность определить в числовой выборке, какой цифре соответствует каждое числовое представление, чему мы и будем обучаться:
>>> digits.target
array([0, 1, 2, ..., 8, 9, 8])
Форма массива данных
Обычно, данные представлены в виде двухмерного массива, такую форму имеют n_samples, n_features, хотя исходные данные могут иметь другую форму. В случае с числами, каждая исходная выборка — это представление формой (8, 8), к которому можно получить доступ, используя:
>>> digits.images[0]
array([[ 0., 0., 5., 13., 9., 1., 0., 0.],
[ 0., 0., 13., 15., 10., 15., 5., 0.],
[ 0., 3., 15., 2., 0., 11., 8., 0.],
[ 0., 4., 12., 0., 0., 8., 8., 0.],
[ 0., 5., 8., 0., 0., 9., 8., 0.],
[ 0., 4., 11., 0., 1., 12., 7., 0.],
[ 0., 2., 14., 5., 10., 12., 0., 0.],
[ 0., 0., 6., 13., 10., 0., 0., 0.]])
Следующий простой пример с этим набором данных иллюстрирует, как, исходя из поставленной задачи, можно сформировать данные для использования в scikit-learn.
Обучение и прогнозирование
В случае с числовым набором данных цель обучения — это предсказать, принимая во внимание представление данных, какая цифра изображена. У нас есть образцы каждого из десяти возможных классов (числа от 0 до 9), на которым мы обучаем алгоритм оценки (estimator), чтобы он мог предсказать класс, к которому принадлежит неразмеченный образец.
В scikit-learn алгоритм оценки для классификатора — это Python объект, который исполняет методы fit (X, y) и predict (T). Пример алгоритма оценки — это класс sklearn.svm.SVC выполняет классификацию методом опорных векторов. Конструктор алгоритма оценки принимает в качестве аргументов параметры модели, но для сокращения времени, мы будем рассматривать этот алгоритм как черный ящик:
>>> from sklearn import svm
>>> clf = svm.SVC(gamma=0.001, C=100.)
Выбор параметров для модели
В этом примере мы установили значение gamma вручную. Также можно автоматически определить подходящие значения для параметров, используя такие инструменты как grid search и cross validation.
Мы назвали экземпляр нашего алгоритма оценки clf, так как он является классификатором. Теперь он должен быть применен к модели, т.е. он должен обучится на модели. Это осуществляется путем прогона нашей обучающей выборки через метод fit. В качестве обучающей выборки мы можем использовать все представления наших данных, кроме последнего. Мы сделали эту выборку с помощью синтаксиса Python [:-1], что создало новый массив, содержащий все, кроме последней, сущности из digits.data:
>>> clf.fit(digits.data[:-1], digits.target[:-1])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0, degree=3,
gamma=0.001, kernel='rbf', max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=0.001, verbose=False)
Теперь можно предсказать новые значения, в частности, мы можем спросить классификатор, какое число содержится в последнем представлении в наборе данных digits, которое мы не использовали в обучении классификатора:
>>> clf.predict(digits.data[-1])
array([8])
Соответствующее изображение представлено ниже:
Как вы можете видеть, это сложная задача: представление в плохом разрешении. Вы согласны с классификатором?
Полное решение этой задачи классификации доступно в качестве примера, который вы можете запустить и изучить: Recognizing hand-written digits.
Сохранение модели
В scikit модель можно сохранить, используя встроенный модуль, названный pickle:
>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
kernel='rbf', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
>>> import pickle
>>> s = pickle.dumps(clf)
>>> clf2 = pickle.loads(s)
>>> clf2.predict(X[0])
array([0])
>>> y[0]
0
В частном случае применения scikit, может быть полезнее заметить pickle на библиотеку joblib (joblib.dump & joblib.load), которая более эффективна для работы с большим объемом данных, но она позволяет сохранять модель только на диске, а не в строке:
>>> from sklearn.externals import joblib
>>> joblib.dump(clf, 'filename.pkl')
Потом можно загрузить сохраненную модель (возможно в другой Python процесс) с помощью:
>>> clf = joblib.load('filename.pkl')
Обратите внимание, что joblib.dump возвращает список имен файлов. Каждый отдельный массив numpy, содержащийся в clf объекте, сеарилизован как отдельный файл в файловой системе. Все файлы должны находиться в одной папке, когда вы снова загружаете модель с помощью joblib.load.
Обратите внимание, что у pickle есть некоторые проблемы с безопасностью и сопровождением. Для получения более детальной информации о хранении моделей в scikit-learn обратитесь к секции Model persistence.