Быстрый рост объемов данных способствует все большему распространению методов машинного обучения, однако эффективность их применения зависит от выбора алгоритмов и библиотек, адекватных конкретной задаче. На выбор влияет множество факторов: класс проблемы (классификация, регрессия и т. д.); исходные данные; требуемая производительность; точность предсказания; возможность интерпретации модели. Какие критерии можно использовать для выбора подходящих алгоритмов? Для ответа попробуем проанализировать три разных решения задачи классификации растений по форме листьев и задачи анализа катастрофы «Титаника». В решениях используются библиотека Scikit-learn для языка Python, язык R и библиотека Intel DAAL (Intel Data Analytics Acceleration Library — библиотека, предоставляющая оптимизированные строительные блоки для анализа данных и машинного обучения на платформе Intel). Все эти программные инструменты имеются в открытом доступе, загружаются бесплатно, а исходный код библиотеки DAAL распространяется под лицензией Apache 2.0.
Задачу классификации растений будем решать методом K-ближайших соседей, а для анализа набора данных «Титаник» применим метод опорных векторов (SVM) [1] на базе популярной платформы Kaggle. Эта платформа используется для работы с алгоритмами машинного обучения и проведения соревнований по анализу данных: компании и исследователи выкладывают свои данные в общий доступ, а специалисты по математической статистике и анализу данных соревнуются в создании самых лучших моделей описания какой-либо проблемы. Сообщество Kaggle объединяет более 500 тыс. пользователей из 194 стран и с момента своего основания в 2010 году провело свыше 200 соревнований по анализу и обработке данных. Качество модели оценивается путем определения точности ее предсказания на тестовом наборе данных: можно оценить свою модель, предоставив свое предсказание на тестовом наборе данных, либо сравнить свой результат с результатами лидеров соревнования.
Классификация растений по форме листьев
Во всем мире существует почти полмиллиона видов растений, от качества классификации которых зависят, например, точность их идентификации и исключение повторов. В задаче требуется определить 99 видов растений по изображениям их листьев и свойствам (форма, край листа и текстура) для обучения классификатора. Обучающие данные включают в себя 990 изображений листьев, а тестовые — 594 изображения. Для каждого изображения предоставляются три набора признаков: описание формы листа, гистограмма внутренней текстуры и гистограмма края листа мелкого масштаба. Каждый набор признаков представлен вектором из 64 атрибутов для каждого изображения (рис. 1).
Рис. 1. Описание признаков |
Один из подходов к решению данной задачи заключается в применении списка алгоритмов машинного обучения на тренировочных данных, а затем в оценке их точности с помощью тестовых данных для нахождения оптимальных алгоритмов и их параметров. В исследовании, опубликованном на Kaggle, проанализирована точность предсказания для десяти алгоритмов. Наилучшую точность на тестовых данных показали линейный дискриминантный анализ и метод K-ближайших соседей.
Линейный дискриминантный анализ основан на простой вероятностной модели, которая вычисляет условную вероятность принадлежности классифицируемого объекта X к классу К. Результат предсказания может быть получен по формуле Байеса. В качестве результата предсказания выбирается класс, для которого условная вероятность максимальна [2].
Метод К-ближайших соседей — один из самых простых алгоритмов классификации. Классифицируемый объект X относится к тому классу L, к которому принадлежит большинство из его соседей K, ближайших к нему объектов тренировочного набора данных.
Реализация линейного дискриминантного анализа на языке Python с использованием пакета Scikit-learn выглядит следующим образом:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # Создание объекта алгоритма линейного дискриминантного анализа clf = LinearDiscriminantAnalysis() # Тренировка модели линейного дискриминантного анализа clf.fit(X_train, y_train) # Вычисление предсказаний для тестовых данных test_predictions = favorite_clf.predict(X_test),
где X_train — это двумерный массив типа numpy.ndarray размером 990х192, содержащий тренировочный набор данных; y_train — массив из 990 значений классов для каждого изображения в тренировочном наборе данных; X_test — массив размером 594х192, содержащий тестовый набор данных.
Реализация метода К-ближайших соседей на языке Python с использованием пакета Scikit-learn выглядит следующим образом:
from sklearn.neighbors import KNeighborsClassifier # Создание объекта метода К-ближайших соседей для K = 4 clf = KNeighborsClassifier(k = 4) # Тренировка модели метода К-ближайших соседей clf.fit(X_train, y_train) # Вычисление предсказаний для тестовых данных test_predictions = favorite_clf.predict(X_test)
Популярным языком для анализа данных является R, в котором также можно применить линейный дискриминантный анализ из пакета MASS и метод K-ближайших соседей из пакета class:
library(MASS) # Тренировка модели линейного дискриминантного анализа r <- lda(y_train ~ X_train) # Вычисление предсказаний для тестовых данных test_predictions <- predict(object = r, newdata = X_test)$class
Алгоритм K-ближайших соседей в R:
library(class) # Вычисление предсказаний для тестовых данных на базе тренировочных данных test_predictions <- knn(train = X_train, test = X_test, cl = y_train, k=4).
Здесь X_train — матрица, содержащая тренировочный набор данных; y_train — вектор значений классов для каждого изображения в тренировочном наборе данных; X_test — матрица, содержащая тестовый набор данных.
Библиотека Intel DAAL предоставляет масштабируемую версию метода K-ближайших соседей, которая использует дерево размерностью K и низкоуровневую оптимизацию для обеспечения высокой скорости на архитектурах Intel при обеспечении хорошей точности:
from daal.algorithms.kdtree_knn_classification import training, prediction from daal.algorithms import classifier, kdtree_knn_classification # Создание алгоритма для тренировки модели методом К-ближайших соседей trainAlg = kdtree_knn_classification.training.Batch() # Передача входных данных алгоритму trainAlg.input.set(classifier.training.data, X_train) trainAlg.input.set(classifier.training.labels, y_train) # Задание параметра K = 4 trainAlg.parameter.k = 4 # Получение результата тренировки алгоритма trainingResult = trainAlg.compute()
Этап предсказания метода K-ближайших соседей:
# Создание алгоритма для вычисления предсказаний predictAlg = kdtree_knn_classification.prediction.Batch() # Передача входных данных алгоритму predictAlg.input.setTable(classifier.prediction.data, X_test) predictAlg.input.setModel(classifier.prediction.model, trainingResult.get( classifier.training.model)) # Вычисление предсказаний для тестовых данных predictionResult = predictAlg.compute() test_predictions = predictionResult.get(classifier.prediction.prediction)
Тренировочный набор данных X_train и значения классов для него y_train представлены в виде числовых таблиц типа NumericTable.
На рис. 2 приведены графики сравнения производительности для стадии тренировки и вычисления предсказаний. Видно, что на процессоре Intel Xeon Phi можно получить 36-кратное ускорение при использовании Intel DAAL по сравнению с R и 4-кратное по сравнению с Scikit-learn (конфигурация системы, использованная для тестирования: Intel Xeon E5-2699 v4 @ 2.20GHz, память 256 Гбайт; Intel Xeon Phi 000A @ 1.40GHz, память 16 Гбайт).
Рис. 2. Сравнение производительности Intel DAAL 2017 Beta Update 2, Scikit-learn 0.19.2 и R 3.3.2 |
Точность для Intel DAAL — 7,91%, для Scikit-learn — 10,27%, а для R — 11,72%.
Можно улучшить точность метода К-ближайших соседей, если применять его к данным с меньшим количеством признаков. Применим предварительную обработку изначальных данных с использованием линейного дискриминантного анализа для числа компонентов, равного 40. Далее обучим модель метода К-ближайших соседей на обработанных данных.
На рис. 3 показано сравнение производительности Intel DAAL, Scikit-learn и R для метода К-ближайших соседей, запущенного на предварительно обработанных данных. График показывает, что на процессоре Intel Xeon Phi можно получить 40-кратное ускорение при использовании Intel DAAL по сравнению с R и 2-кратное по сравнению с Scikit-learn.
Рис. 3. Сравнение производительности Intel DAAL 2017 Beta Update 2, Scikit-learn 0.19.2 и R 3.3.2 на предварительно обработанных данных |
Благодаря предварительной обработке данных также значительно уменьшилась ошибка классификации.
Конструирование признаков играет ключевую роль в машинном обучении, а выбор качественных признаков имеет решающее значение для получения точных предсказаний.
«Титаник»: машинное обучение для анализа катастрофы
Еще одно соревнование Kaggle основывается на анализе катастрофы «Титаника», в результате которой погибло 1502 из 2224 пассажиров и членов экипажа. Задача состоит в анализе различных классов пассажиров и членов экипажа с целью предсказания выживших в трагедии. Исходные данные включают в себя следующие свойства (рис. 4): класс пассажира, ФИО, пол, возраст, количество братьев и сестер/супругов на борту, количество родителей/детей на борту, номер билета, плата за проезд, каюта и порт посадки.
Рис. 4. Исходные признаки набора данных «Титаник» |
Предварительная обработка данных позволяет повысить точность. Поэтому требуется выбрать наиболее информативные признаки, которые можно использовать для тренировки моделей машинного обучения, а затем натренировать несколько классификаторов на данных, прошедших предварительную обработку, чтобы выяснить, какие алгоритмы показывают самую лучшую точность. В этом ядре Kaggle выполняется конструирование признаков. Набор данных после предварительной обработки включает уже лишь семь признаков: класс пассажира, пол, возраст (преобразован с помощью дискретизации), плата за проезд (преобразована с помощью дискретизации), порт посадки, путешествует в одиночку (верно, если у человека нет братьев и сестер/супруга/детей/родителей на «Титанике»), форма обращения (г-жа/мисс/г-н/мастер). Из десяти алгоритмов набора Scikit-learn самую высокую точность показала машина опорных векторов.
Машина опорных векторов — это двухклассовый классификатор, строящий разделяющую гиперплоскость таким образом, чтобы расстояние от этой плоскости до ближайших наблюдений из разных классов в тренировочной выборке было наибольшим. Машина опорных векторов также может разделять классы, которые не являются линейно разделимыми в конечно-мерном пространстве исходной задачи. Для этого используются так называемые ядра, которые могут переводить исходные данные в пространство более высокой и даже бесконечной размерности, тем самым упрощая проблему разделения классов в новом пространстве.
Реализация алгоритма SVM на языке Python с использованием пакета Scikit-learn выглядит следующим образом:
from sklearn.svm import SVC # Создание объекта алгоритма с заданным параметром для гауссова ядра gamma # и ограничением задачи квадратичной оптимизации С clf = SVC(C = 5, gamma = 1.5) # Тренировка модели SVM clf.fit(X_train, y_train) # Вычисление предсказаний для тестовых данных test_predictions = favorite_clf.predict(X_test)
Здесь X_train — двумерный массив типа numpy.ndarray размером 891х7, содержащий тренировочный набор данных; y_train — массив из 891 значения классов для каждого изображения в тренировочном наборе данных; X_test — массив размером 418х7, содержащий тестовый набор данных.
Алгоритм SVM в R выглядит следующим образом:
library(e1071) # Тренировка модели SVM model <- svm(X_train, y_train, gamma=1.5, cost=5) # Вычисление предсказаний для тестовых данных test_predictions <- predict(model, X_test)
Использование SVM с гауссовым ядром требует многочисленных вычислений экспоненциальной функции и сопряжено с большими затратами времени. В библиотеке Intel DAAL такие вычисления оптимизированы для архитектуры Intel, что позволяет быстро тренировать модель SVM.
Реализация этого алгоритма на языке Python выглядит следующим образом:
Этап обучения SVM в Python:
from daal.algorithms.svm import prediction, training from daal.algorithms import kernel_function, classifier import daal.algorithms.kernel_function.rbf # Создание алгоритма для тренировки модели SVM trainAlg = svm.training.Batch() # Передача входных данных алгоритму SVM trainAlg.input.set(classifier.training.data, X_train) trainAlg.input.set(classifier.training.labels, y_train) # Создание алгоритма гауссова ядра с параметром gamma = 1.5 kernel = kernel_function.rbf.Batch() kernel.parameter.sigma = 1.5 # Передача параметров алгоритму SVM trainAlg.parameter.C = 5 trainAlg.parameter.kernel = kernel # Получение результата тренировки алгоритма trainingResult = trainAlg.compute()
Тренировочный набор данных X_train и значения классов для него, y_train, представлены в виде числовых таблиц типа NumericTable.
Этап предсказания SVM в Python:
# Создание алгоритма для вычисления предсказаний SVM predictAlg = svm.prediction.Batch() # Передача входных данных алгоритму предсказания SVM predictAlg.input.setTable(classifier.prediction.data, X_test) predictAlg.input.setModel(classifier.prediction.model, trainingResult.get(classifier.training.model)) # Передача параметров алгоритму предсказания SVM predictAlg.parameter.kernel = kernel # Вычисление предсказаний для тестового набора данных predictionResult = predictAlg.compute() test_predictions = predictionResult.get(classifier.prediction.prediction)
На рис. 5 приведен график сравнения производительности. Видно, что на процессоре Intel Xeon Phi при использовании Intel DAAL можно получить 3,5-кратное ускорение по сравнению с R и 1,5-кратное по сравнению с Scikit-learn.
Рис. 5. Сравнение производительности Intel DAAL 2017 Beta Update 2, Scikit-learn 0.19.2 и R 3.3.2 для задачи «Титаник» |
Точность для Intel DAAL и Scikit-learn составила 21,5%, а для R — 22,49%.
***
Выбор алгоритма для задач, решаемых методами машинного обучения, требует глубокого анализа. Такие библиотеки, как Intel DAAL и Scikit-learn, предоставляют широкий спектр алгоритмов машинного обучения, и пользователь может выбрать наиболее подходящий. Применение библиотеки Intel DAAL дает возможность наиболее эффективно использовать ресурсы платформ от Intel для быстрого обучения моделей и вычисления предсказаний, позволяя получать высокую производительность по сравнению с Scikit-learn и R, а также тренировать самые точные модели.
Литература
- Виктор Китов. Практические аспекты машинного обучения // Открытые системы.СУБД. — 2016. — №1. — С. 14–17. URL: https://www.osp.ru/os/2016/01/13048648 (дата обращения: 18.09.2017).
- Trevor Hastie, Robert Tibshirani, Jerome Friedman. The Elements of Statistical Learning, Second edition.
Олег Кремнев (oleg.kremnyov@intel.com) — инженер по разработке ПО, Иван Кузьмин (ivan.kuzmin@intel.com) — менеджер по разработке ПО, Геннадий Федоров (gennady.fedorov@intel.com) — инженер по техническим консультациям по ПО, Виктория Федотова (victoriya.s.fedotova@intel.com) — старший инженер по разработке ПО, Intel (Нижний Новгород).