Что такое Scikit Learn - гайд по популярной библиотеке Python для начинающих

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

Scikit-Learn поддерживает:

  • предварительную обработку данных;
  • уменьшение размерности;
  • выбор модели;
  • регрессии;
  • классификации;
  • кластерный анализ.

Он также предоставляет несколько наборов данных, которые вы можете использовать для тестирования ваших моделей.

Scikit-learn не реализует все, что связано с машинным обучением. Например, он не имеет комплексной поддержки для:

  • нейронных сетей;
  • самоорганизующихся карт (сетей Кохонена);
  • обучения ассоциативным правилам;
  • обучения с подкреплением (reinforcement learning).

Scikit-learn основан на NumPy и SciPy, поэтому необходимо понять хотя бы азы этих двух библиотек, чтобы эффективно применять Scikit-learn.

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

В этой статье кратко представим некоторые возможности scikit-learn. 

Предварительная обработка данных

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

Давайте сначала определим массив NumPy, с которым будем работать:

>>> import numpy as np
>>> x = np.array([[0.1, 1.0, 22.8],
...               [0.5, 5.0, 41.2],
...               [1.2, 12.0, 2.8],
...               [0.8, 8.0, 14.0]])
>>> x
array([[ 0.1,  1. , 22.8],
       [ 0.5,  5. , 41.2],
       [ 1.2, 12. ,  2.8],
       [ 0.8,  8. , 14. ]])

Вам часто нужно преобразовывать данные таким образом, чтобы среднее значение каждого столбца (элемента) было равно нулю, а стандартное отклонение - единице. В этом случае, можно использовать sklearn.preprocessing.StandardScaler:

>>> from sklearn.preprocessing import StandardScaler
>>> scaler = StandardScaler()
>>> scaled_x = scaler.fit_transform(x)
>>> scaler.scale_
array([ 0.40311289,  4.03112887, 14.04421589])
>>> scaler.mean_
array([ 0.65,  6.5 , 20.2 ])
>>> scaler.var_
array([1.6250e-01, 1.6250e+01, 1.9724e+02])
>>> scaled_x
array([[-1.36438208, -1.36438208,  0.18512959],
       [-0.3721042 , -0.3721042 ,  1.4952775 ],
       [ 1.36438208,  1.36438208, -1.23894421],
       [ 0.3721042 ,  0.3721042 , -0.44146288]])
>>> scaled_x.mean().round(decimals=4)
0.0
>>> scaled_x.mean(axis=0)
array([ 1.66533454e-16, -1.38777878e-17,  1.52655666e-16])
>>> scaled_x.std(axis=0)
array([1., 1., 1.])
>>> scaler.inverse_transform(scaled_x)
array([[ 0.1,  1. , 22.8],
       [ 0.5,  5. , 41.2],
       [ 1.2, 12. ,  2.8],
       [ 0.8,  8. , 14. ]])

Бывает, что у вас есть некоторые категориальные данные, и вам нужно преобразовать их в числа. Один из способов сделать это - использовать класс sklearn.preprocessing.OneHotEncoder. Рассмотрим следующий пример с массивами ролей в компании:

>>> from sklearn.preprocessing import OneHotEncoder
>>> roles = np.array([('Tom', 'manager'),
...                   ('Mary', 'developer'),
...                   ('Ann', 'recruiter'),
...                   ('Jim', 'developer')])
>>> roles
array([['Tom', 'manager'],
       ['Mary', 'developer'],
       ['Ann', 'recruiter'],
       ['Jim', 'developer']], dtype='<u9')>>> encoder = OneHotEncoder()
>>> encoded_roles = encoder.fit_transform(roles[:, [1]])
>>> encoded_roles.toarray()
array([[0., 1., 0.],
       [1., 0., 0.],
       [0., 0., 1.],
       [1., 0., 0.]])</u9')>

В приведенном выше примере первый столбец объекта encoded_roles указывает, является ли каждый сотрудник разработчиком. Второй и четвертый сотрудник (Мэри и Джим) - разработчики. Второй столбец связан с должностью менеджера. Только первый сотрудник (Том) имеет эту должность. Наконец, третий столбец соответствует должности рекрутера, и им является третий сотрудник (Энн).

Уменьшение размерности

Уменьшение размерности включает в себя выбор или извлечение наиболее важных компонентов (признаков) многомерного набора данных. Scikit-learn предлагает несколько подходов к уменьшению размерности. Одним из них является анализ основных компонентов (PCA).

Выбор модели

Для обучения и тестирования моделей машинного обучения, вам необходимо случайным образом разбивать данные на подмножества. Это включает как входы, так и их соответствующие выходы. Функция sklearn.model_selection.train_test_split () полезна в таких случаях:

>>> import numpy as np
>>> from sklearn.model_selection import train_test_split
>>> x, y = np.arange(1, 21).reshape(-1, 2), np.arange(3, 40, 4)
>>> x
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10],
       [11, 12],
       [13, 14],
       [15, 16],
       [17, 18],
       [19, 20]])
>>> y
array([ 3,  7, 11, 15, 19, 23, 27, 31, 35, 39])
>>> x_train, x_test, y_train, y_test =\
...     train_test_split(x, y, test_size=0.4, random_state=0)
>>> x_train
array([[ 3,  4],
       [13, 14],
       [15, 16],
       [ 7,  8],
       [ 1,  2],
       [11, 12]])
>>> y_train
array([ 7, 27, 31, 15,  3, 23])
>>> x_test
array([[ 5,  6],
       [17, 18],
       [ 9, 10],
       [19, 20]])
>>> y_test
array([11, 35, 19, 39])

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

Набор данных

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

Например, функция sklearn.datasets.load_boston () отображает данные о ценах на дома в районе Бостона (цены не обновляются!). Есть 506 наблюдений, а входная матрица имеет 13 столбцов (признаков):

>>> from sklearn.datasets import load_boston
>>> x, y = load_boston(return_X_y=True)
>>> x.shape, y.shape
((506, 13), (506,))

Этот набор данных подходит для многовариантной регрессии.

Другой пример - набор данных, связанный с вином. Его можно получить с помощью функции sklearn.datasets.load_wine ():

>>> from sklearn.datasets import load_wine
>>> x, y = load_wine(return_X_y=True)
>>> x.shape, y.shape
((178, 13), (178,))
>>> np.unique(y)
array([0, 1, 2])

Этот набор данных подходит для классификации. Он содержит 13 функций, связанных с тремя различными винодельческими компаниями из Италии, и 178 наблюдений.

Регрессия

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

Ниже покажем регрессию random forest.

Обычно мы начинаем наше регрессионное путешествие с импорта необходимых нам пакетов, классов и функций:

>>> import numpy as np
>>> from sklearn.datasets import load_boston
>>> from sklearn.ensemble import RandomForestRegressor
>>> from sklearn.model_selection import train_test_split

Следующим шагом является получение данных для работы и разделение этих данных на обучающее и тестовое подмножества. Мы будем использовать набор данных Бостона:

>>> x, y = load_boston(return_X_y=True)
>>> x_train, x_test, y_train, y_test =\
...     train_test_split(x, y, test_size=0.33, random_state=0)

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

Теперь нам нужно создать наш регрессор и обучить его с помощью подмножества данных, выбранного для обучения:

>>> regressor = RandomForestRegressor(n_estimators=10, random_state=0)
>>> regressor.fit(x_train, y_train)
RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,
                      max_features='auto', max_leaf_nodes=None,
                      min_impurity_decrease=0.0, min_impurity_split=None,
                      min_samples_leaf=1, min_samples_split=2,
                      min_weight_fraction_leaf=0.0, n_estimators=10,
                      n_jobs=None, oob_score=False, random_state=0, verbose=0,
                      warm_start=False)

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

>>> regressor.score(x_train, y_train)
0.9680930547240916
>>> regressor.score(x_test, y_test)
0.8219576562705848

Модель, обученная достаточно хорошо, может использоваться для прогнозирования выходных данных при других новых входных данных x_new. В данном случае, используется команда .predict(): regressor.predict(x_new).

Классификация

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

В этой статье показано, как использовать метод random forest для классификации. Этот подход весьма аналогичен подходу, применяемому в случае регрессии. Но теперь мы будем использовать набор данных, связанных с вином, определять классификатор и оценивать его с точностью классификации вместо коэффициента детерминации. 

>>> import numpy as np
>>> from sklearn.datasets import load_wine
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.model_selection import train_test_split
>>> x, y = load_wine(return_X_y=True)
>>> x_train, x_test, y_train, y_test =\
...     train_test_split(x, y, test_size=0.33, random_state=0)
>>> classifier = RandomForestClassifier(n_estimators=10, random_state=0)
>>> classifier.fit(x_train, y_train)
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
                       max_depth=None, max_features='auto', max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=10,
                       n_jobs=None, oob_score=False, random_state=0, verbose=0,
                       warm_start=False)
>>> classifier.score(x_train, y_train)
1.0
>>> classifier.score(x_test, y_test)
1.0

Модель, обученная достаточно хорошо, может использоваться для прогнозирования выходных данных при других новых входных данных. В данном случае, используется команда .predict(): regressor.predict(x_new).

Кластерный анализ

Кластеризация - это ветвь неконтролируемого обучения, широко поддерживаемая в scikit-learn. В дополнение к методу k-средних, есть возможность применять метод распространения близости, спектральную кластеризацию, агломеративную кластеризацию и т.д.

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

Опять же, мы начинаем с импорта и получения данных. На этот раз мы возьмем NumPy и sklearn.cluster.KMeans:

>>> import numpy as np
>>> from sklearn.cluster import KMeans
>>> x = np.array([(0.0, 0.0),
...               (9.9, 8.1),
...               (-1.0, 1.0),
...               (7.1, 5.6),
...               (-5.0, -5.5),
...               (8.0, 9.8),
...               (0.5, 0.5)])
>>> x
array([[ 0. ,  0. ],
       [ 9.9,  8.1],
       [-1. ,  1. ],
       [ 7.1,  5.6],
       [-5. , -5.5],
       [ 8. ,  9.8],
       [ 0.5,  0.5]])

Следующим шагом является масштабирование данных, но это не всегда обязательно. Однако во многих случаях это действительно хорошая идея. Как только предварительная обработка данных завершена, мы создаем копию KMeans и подгоняем ее под наши данные:

>>> cluster_analyzer = KMeans(n_clusters=3, init='k-means++')
>>> cluster_analyzer.fit()
>>> cluster_analyzer.fit(x)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
       n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto',
       random_state=None, tol=0.0001, verbose=0)

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

>>> cluster_analyzer.cluster_centers_
array([[ 8.33333333,  7.83333333],
       [-0.16666667,  0.5       ],
       [-5.        , -5.5       ]])
>>> cluster_analyzer.labels_
array([1, 0, 1, 0, 2, 0, 1], dtype=int32)

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

Заключение

В этой статье представлены только основы Scikit-Learn, очень популярного пакета Python по data science и machine learning. Это одна из основных библиотек Python для этих целей. 

Спасибо за чтение!

Источник

Поделиться записью
Вверх