Начало работы

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

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

Обучение и прогнозирование: основы оценок

Scikit-learn предоставляет десятки встроенных алгоритмов и моделей машинного обучения, называемых estimators. Каждый модель может быть обучена к некоторым данным с помощью своего метода fit.

Вот простой пример, в котором мы обучаем RandomForestClassifier к некоторым очень базовым данным:

>>> from sklearn.ensemble import RandomForestClassifier
>>> clf = RandomForestClassifier(random_state=0)
>>> X = [[ 1,  2,  3],  # 2 samples, 3 features
...      [11, 12, 13]]
>>> y = [0, 1]  # classes of each sample
>>> clf.fit(X, y)
RandomForestClassifier(random_state=0)

Метод fit обычно принимает 2 входных сигнала:

  • Матрица образцов (или матрица проектирования) X. Размер X обычно составляет (n_samples, n_features), что означает, что образцы представлены в виде строк, а признаки - в виде столбцов.

  • Целевые значения y, которые являются вещественными числами для задач регрессии, или целыми числами для классификации (или любым другим дискретным набором значений). Для задач обучения без контроля y задавать не нужно. Обычно y представляет собой 1d массив, в котором i запись соответствует цели i выборки (строки) X.

Обычно предполагается, что и X, и y являются массивами numpy или эквивалентными array-like типами данных, хотя некоторые модели работают с другими форматами, например, с разреженными матрицами.

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

>>> clf.predict(X)  # predict classes of the training data
array([0, 1])
>>> clf.predict([[4, 5, 6], [14, 15, 16]])  # predict classes of new data
array([0, 1])

Преобразователи и препроцессоры

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

В scikit-learn препроцессоры и трансформаторы работают по тому же API, что и объекты моделей (фактически все они наследуются от одного класса BaseEstimator). У объектов transformer нет метода predict, а есть метод transform, который выводит новую преобразованную матрицу выборки X:

>>> from sklearn.preprocessing import StandardScaler
>>> X = [[0, 15],
...      [1, -10]]
>>> # scale data according to computed scaling values
>>> StandardScaler().fit(X).transform(X)
array([[-1.,  1.],
       [ 1., -1.]])

Иногда требуется применить различные преобразования к различным характеристикам: ColumnTransformer предназначен для таких случаев использования.

Конвейеры: цепочка препроцессоров и моделей

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

В следующем примере мы загружаем набор данных Iris, разбиваем его на обучающий и тестовый наборы и вычисляем оценку точности конвейера на тестовых данных:

>>> from sklearn.preprocessing import StandardScaler
>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.pipeline import make_pipeline
>>> from sklearn.datasets import load_iris
>>> from sklearn.model_selection import train_test_split
>>> from sklearn.metrics import accuracy_score
...
>>> # create a pipeline object
>>> pipe = make_pipeline(
...     StandardScaler(),
...     LogisticRegression()
... )
...
>>> # load the iris dataset and split it into train and test sets
>>> X, y = load_iris(return_X_y=True)
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
...
>>> # fit the whole pipeline
>>> pipe.fit(X_train, y_train)
Pipeline(steps=[('standardscaler', StandardScaler()),
                ('logisticregression', LogisticRegression())])
>>> # we can now use it like any other estimator
>>> accuracy_score(pipe.predict(X_test), y_test)
0.97...

Оценка модели

Обучение модели под некоторые данные не означает, что она будет хорошо предсказывать на невидимых данных. Это нужно оценивать напрямую. Мы только что рассмотрели вспомогательный метод train_test_split, который разбивает набор данных на обучающий и тестовый наборы, но scikit-learn предоставляет множество других инструментов для оценки моделей, в частности cross-validation.

Здесь мы кратко покажем, как выполнить 5-кратную процедуру кросс-валидации, используя метод cross_validate. Обратите внимание, что можно также вручную итерировать по разбитым частям (фолдам), использовать различные стратегии разбиения данных и применять собственные функции оценки. Более подробная информация содержится в нашем Руководстве пользователя:

>>> from sklearn.datasets import make_regression
>>> from sklearn.linear_model import LinearRegression
>>> from sklearn.model_selection import cross_validate
...
>>> X, y = make_regression(n_samples=1000, random_state=0)
>>> lr = LinearRegression()
...
>>> result = cross_validate(lr, X, y)  # defaults to 5-fold CV
>>> result['test_score']  # r_squared score is high because dataset is easy
array([1., 1., 1., 1., 1.])

Автоматический поиск параметров

У всех моделей есть параметры (часто называемые в литературе гиперпараметрами), которые можно настраивать. Часто обобщающая способность модели критически зависит от нескольких параметров. Например, у RandomForestRegressor есть параметр n_estimators, определяющий количество деревьев в лесу, и параметр max_depth, определяющий максимальную глубину каждого дерева. Часто бывает так, что точные значения этих параметров не ясны, поскольку они зависят от имеющихся данных.

Scikit-learn предоставляет инструменты для автоматического поиска наилучших комбинаций параметров (через кросс-валидацию). В следующем примере мы случайным образом перебираем пространство параметров случайного леса с помощью объекта RandomizedSearchCV. По окончании поиска RandomizedSearchCV ведет себя как RandomForestRegressor, который был обучен с наилучшим набором параметров. Подробнее читайте в Руководство пользователя:

>>> from sklearn.datasets import fetch_california_housing
>>> from sklearn.ensemble import RandomForestRegressor
>>> from sklearn.model_selection import RandomizedSearchCV
>>> from sklearn.model_selection import train_test_split
>>> from scipy.stats import randint
...
>>> X, y = fetch_california_housing(return_X_y=True)
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
...
>>> # define the parameter space that will be searched over
>>> param_distributions = {'n_estimators': randint(1, 5),
...                        'max_depth': randint(5, 10)}
...
>>> # now create a searchCV object and fit it to the data
>>> search = RandomizedSearchCV(estimator=RandomForestRegressor(random_state=0),
...                             n_iter=5,
...                             param_distributions=param_distributions,
...                             random_state=0)
>>> search.fit(X_train, y_train)
RandomizedSearchCV(estimator=RandomForestRegressor(random_state=0), n_iter=5,
                   param_distributions={'max_depth': ...,
                                        'n_estimators': ...},
                   random_state=0)
>>> search.best_params_
{'max_depth': 9, 'n_estimators': 4}

>>> # the search object now acts like a normal random forest estimator
>>> # with max_depth=9 and n_estimators=4
>>> search.score(X_test, y_test)
0.73...

Примечание

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

Использование конвейера для кросс-валидации и поиска в значительной степени убережет вас от этого распространенного подводного камня.

Следующие шаги

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

Пожалуйста, обратитесь к нашему Содержание для получения подробной информации обо всех инструментах, которые мы предоставляем. Вы также можете найти исчерпывающий список публичных API в API Reference.

Вы также можете посмотреть на наши многочисленные примеры, которые иллюстрируют использование scikit-learn в различных контекстах.

В учебники также содержатся дополнительные обучающие ресурсы.