MLClass
Компания
33,15
рейтинг
13 января 2015 в 09:39

Разработка → Введение в машинное обучение с помощью Python и Scikit-Learn из песочницы

Привет, хабр!



Меня зовут Александр, я занимаюсь машинным обучением и анализом веб-графов (в основном — теоретическим), а также разработкой Big Data продуктов в одном из операторов Большой Тройки. Это мой первый пост — прошу, не судите строго!)

В последнее время ко мне все чаще стали обращаться люди, которые хотят научиться разрабатывать эффективные алгоритмы и участвовать в соревнованиях по машинному обучению с вопросом: «С чего начать?». Некоторое время назад я руководил разработкой инструментов Big Data для анализа медиа и социальных сетей в одном из учреждений Правительства РФ, и у меня остался некоторый материал, по которому обучалась моя команда и которым можно поделиться. Предполагается, что у читателя есть хорошее знание математики и машинного обучения (в команде были в основном выпускники МФТИ и студенты Школы Анализа Данных).

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

Наиболее распространенными инструментами Data Scientist'а на сегодняшний день являются R и Python. У каждого инструмента есть свои плюсы и минусы, однако, в последнее время по всем параметрам выигрывает Python (это исключительно мнение автора, к тому же пользующегося одновременно и тем и другим). Это стало после того, как появилась отлично документированная библиотека Scikit-Learn, в которой реализовано большое количество алгоритмов машинного обучения.

Сразу отметим, что в статье мы остановимся именно на алгоритмах Machine Learning. Первичный анализ данных лучше обычно проводится средствами пакета Pandas, разобраться с которым можно самостоятельно. Итак, сосредоточимся на реализации, для определенности полагая, что на входе у нас есть матрица обьект-признак, хранящаяюся в файле с расширением *.csv

Загрузка данных


В первую очередь данные необходимо загрузить в оперативную память, чтобы мы имели возможность работать с ними. Сама библиотека Scikit-Learn использует в своей реализации NumPy массивы, поэтому будем загружать *.csv файлы средствами NumPy. Загрузим один из датасетов из репозитория UCI Machine Learning Repository:

import numpy as np
import urllib
# url with dataset
url = "http://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"
# download the file
raw_data = urllib.urlopen(url)
# load the CSV file as a numpy matrix
dataset = np.loadtxt(raw_data, delimiter=",")
# separate the data from the target attributes
X = dataset[:,0:7]
y = dataset[:,8]

Далее во всех примерах будем работать с этим набором данных, а именно с матрицей обьект-признак X и значениями целевой переменной y.

Нормализация данных


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

from sklearn import preprocessing
# normalize the data attributes
normalized_X = preprocessing.normalize(X)
# standardize the data attributes
standardized_X = preprocessing.scale(X)


Отбор признаков


Не секрет, что зачастую самым важным при решении задачи является умение правильно отобрать и даже создать признаки. В англоязычной литературе это называется Feature Selection и Feature Engineering. В то время как Future Engineering довольно творческий процесс и полагается больше на интуицию и экспертные знания, для Feature Selection есть уже большое количество готовых алгоритмов. «Древесные» алгоритмы допускают расчета информативности признаков:

from sklearn import metrics
from sklearn.ensemble import ExtraTreesClassifier
model = ExtraTreesClassifier()
model.fit(X, y)
# display the relative importance of each attribute
print(model.feature_importances_)

Все остальные методы так или иначе основаны на эффективном переборе подмножеств признаков с целью найти наилучшее подмножество, на которых построенная модель дает наилучшее качество. Одним из таких алгоритмов перебора является Recursive Feature Elimination алгоритм, который также доступен в библиотеке Scikit-Learn:

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
# create the RFE model and select 3 attributes
rfe = RFE(model, 3)
rfe = rfe.fit(X, y)
# summarize the selection of the attributes
print(rfe.support_)
print(rfe.ranking_)


Построение алгоритма


Как уже было отмечено, в Scikit-Learn реализованы все основные алгоритмы машинного обучения. Рассмотрим некоторые из них.

Логистическая регрессия


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

from sklearn import metrics
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
print(model)
# make predictions
expected = y
predicted = model.predict(X)
# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))


Наивный Байес


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

from sklearn import metrics
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(X, y)
print(model)
# make predictions
expected = y
predicted = model.predict(X)
# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))


K-ближайших соседей


Метод kNN (k-Nearest Neighbors) часто используется как составная часть более сложного алгоритма классификации. Например, его оценку можно использовать как признак для обьекта. А иногда, простой kNN на хорошо подобранных признаках дает отличное качество. При грамотной настройке параметров (в основном — метрики) алгоритм дает зачастую хорошее качество в задачах регрессии

from sklearn import metrics
from sklearn.neighbors import KNeighborsClassifier
# fit a k-nearest neighbor model to the data
model = KNeighborsClassifier()
model.fit(X, y)
print(model)
# make predictions
expected = y
predicted = model.predict(X)
# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))


Деревья решений


Classification and Regression Trees (CART) часто используются в задачах, в которых обьекты имеют категориальные признаки и используется для задач регресии и классификации. Очень хорошо деревья подходят для многоклассовой классификации

from sklearn import metrics
from sklearn.tree import DecisionTreeClassifier
# fit a CART model to the data
model = DecisionTreeClassifier()
model.fit(X, y)
print(model)
# make predictions
expected = y
predicted = model.predict(X)
# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))


Метод опорных векторов


SVM (Support Vector Machines) является одним из самых известных алгоритмов машинного обучения, применяемых в основном для задачи классификации. Также как и логистическая регрессия, SVM допускает многоклассовую классификацию методом one-vs-all.

from sklearn import metrics
from sklearn.svm import SVC
# fit a SVM model to the data
model = SVC()
model.fit(X, y)
print(model)
# make predictions
expected = y
predicted = model.predict(X)
# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))

Помимо алгоритмов классификации и регрессии, в Scikit-Learn имеется огромное количество более сложных алгоритмов, в том числе кластеризации, а также реализованные техники построения композиций алгоритмов, в том числе Bagging и Boosting.

Оптимизация параметров алгоритма


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

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

import numpy as np
from sklearn.linear_model import Ridge
from sklearn.grid_search import GridSearchCV
# prepare a range of alpha values to test
alphas = np.array([1,0.1,0.01,0.001,0.0001,0])
# create and fit a ridge regression model, testing each alpha
model = Ridge()
grid = GridSearchCV(estimator=model, param_grid=dict(alpha=alphas))
grid.fit(X, y)
print(grid)
# summarize the results of the grid search
print(grid.best_score_)
print(grid.best_estimator_.alpha)

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

import numpy as np
from scipy.stats import uniform as sp_rand
from sklearn.linear_model import Ridge
from sklearn.grid_search import RandomizedSearchCV
# prepare a uniform distribution to sample for the alpha parameter
param_grid = {'alpha': sp_rand()}
# create and fit a ridge regression model, testing random alpha values
model = Ridge()
rsearch = RandomizedSearchCV(estimator=model, param_distributions=param_grid, n_iter=100)
rsearch.fit(X, y)
print(rsearch)
# summarize the results of the random parameter search
print(rsearch.best_score_)
print(rsearch.best_estimator_.alpha)

Мы рассмотрели весь процесс работы с библиотекой Scikit-Learn за исключением вывода результатов обратно в файл, что предлагается сделать читателю в качестве упражнения, потому как одним из достоинств Python (и самой библиотеки Scikit-Learn) по-сравнению с R является отличная документация. В следующих частях мы рассмотрим подробно каждый из разделов, в частности, затронем такую важную вещь как Feauture Engineering.

Я очень надеюсь, что данный материал поможет начинающим Data Scientist'ам как можно скорее приступить к решению задач машинного обучения на практике. В заключение хочу пожелать успехов и терпения тем, кто только начинает участвовать в соревнованиях по машинному обучению!
Автор: @akrot
MLClass
рейтинг 33,15
Компания прекратила активность на сайте

Комментарии (11)

  • 0
    Спасибо автору — интересная выжимка и приятно удивлен уровню госслужащих))
    Некоторое время назад я руководил разработкой инструментов Big Data… в одном из учреждений Правительства РФ

    Если не секрет, почему и куда ушли?
    • 0
      глянул профиль автора — вопрос снят. Недостаточно кармы чтобы плюсануть статью — примите благодарность на словах.
    • 0
      Спасибо!)
      Ушел, потому что всю работу сделал, там было всего несколько продуктов, основной упор которых был именно на анализ соц. сетей и медиа. И это было как раз в то время, когда еще стек hadoop только появлялся, дистрибутивов не было и все приходилось настраивать и администрировать своими руками. Собрали кластер из десятка довольно мощных машин, настроили HDFS. Кластер в основном использовался для хранения данных и простых ETL-операций, обучение классификаторов было в основном на локальных машинах (отсюда и статья про Scikit-Learn), запуск самих алгоритмов был на кластере — как правило, все переписывалось потом под map-reduce. Наверное, мы были одни из первых, кто делал весь процесс целиком своими руками — хороший эксперимент получился) Команда там была действительно сильная — почти все с Физтеха/ШАДа. К сожалению, что сейчас происходит внутри этой организации с данным кластером — мне неизвестно
  • 0
    А как насчет Scala, насколько часто её используют? Что думаете вобще про Scala. Интересно :). За пост спасибо!
  • +1
    Scala стала популярна в машинном обучении после того, как появился Apache Spark и используется, когда нужно обучаться на больших выборках (хотя также есть Python и чистая Java). Тут наверное имеет смысл перечислить все преимущества спарка — но это уже, наверное, будет отдельная статья) Основная идея такая: на Scala пишут код, когда нужно обучаться на огромных выборках, или делать online-обучение или real-time аналитику (для этого используется Spark Streaming или Apache Storm — у них одна принципиальная разница, об этом также наверное расскажу подробнее позже). Проблема также в том, что в полноценной коммерческой эксплуатации Spark пока еще сырой, как следствие — довольно мало организаций его используют

    • 0
      Спасибо!
    • +1
      Мы в Retail Rocket используем Apache Spark. Возможно, кому-нибудь будет полезен рассказ про наш путь от Hadoop к Spark Scala:
      www.slideshare.net/rzykov/retail-rocket-sparkrzykov
  • +1
    Отличная статья! Её можно использовать в учебном процессе (давать этот материал студентам)?
    • +1
      Да, конечно, в будущем будут еще статьи. Вы могли бы написать пожелания, какие темы вам интересны и я обязательно при наличии времени что-нибудь напишу
  • +1
    Немного не уловил сути, обычно, такие ребята — «Предполагается, что у читателя есть хорошее знание математики и машинного обучения (в команде были в основном выпускники МФТИ и студенты Школы Анализа Данных)» уже знают про различные «классные» пакеты, а sklearn так уж точно.

    Просто дело в том, что начать лучше с лекций Воронцова, а то создавать python классы по инструкции, может каждый, но проблема в понимании сути, границ применимости и некотором опыте.
    • +3
      Суть немного в другом: ребята отлично знали алгоритмы, и многие прочитали курс Воронцова, но все из них использовали разные инстурменты (на тот момент Weka или R). Это отчасти связано с тем, что, например, в ШАДе несколько лет назад в курсе машинного обучения в основном показывался R, и только с прошлого года стал более популярен Python. Конечно, реализацию всего, что тут написано — можно найти просто в доках scikit-learn. Поэтому в то время целью этого мануала было — дать быстрое введение в Scikit-Learn, показать, убедить, что его в целом достаточно, и избавить от «гугления»

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

Самое читаемое Разработка