Вступление
Типичный процесс машинного обучения включает в себя обучение различных моделей в наборе данных и выбор наиболее производительной. Однако оценка производительности алгоритма не всегда является простой задачей. Есть несколько факторов, которые могут помочь вам определить, какой алгоритм работает лучше всего. Одним из таких факторов является производительность на множестве перекрестной проверки, а другим фактором является выбор параметров для алгоритма.
В этой статье мы подробно рассмотрим эти два фактора. Сначала мы изучим, что такое перекрестная проверка, почему она необходима и как ее выполнять с помощью библиотеки Python Scikit-Learn . Затем мы перейдем к алгоритму поиска по сетке и посмотрим, как его можно использовать для автоматического выбора лучших параметров алгоритма.
Перекрестная проверка
Обычно в процессе машинного обучения данные делятся на обучающие и тестовые наборы; затем обучающий набор используется для обучения модели, а набор тестов - для оценки производительности модели. Однако такой подход может привести к проблемам с отклонениями. Проще говоря, проблема дисперсии относится к сценарию, в котором наша точность, полученная в одном тесте, сильно отличается от точности, полученной в другом тестовом наборе с использованием того же алгоритма.
Решением этой проблемы является использование перекрестной проверки K-Fold для оценки производительности, где K - любое число. Процесс перекрестной проверки K-Fold прост. Вы делите данные на K складок. Из K складок наборы K-1 используются для обучения, а оставшийся набор используется для тестирования. Алгоритм обучается и тестируется K раз, каждый раз новый набор используется в качестве набора для тестирования, а оставшиеся наборы используются для обучения. Наконец, результат перекрестной проверки K-Fold - это среднее значение результатов, полученных на каждом наборе.
Предположим, мы хотим выполнить 5-кратную перекрестную проверку. Для этого данные делятся на 5 наборов, например, мы называем их SET A, SET B, SET C, SET D и SET E. Алгоритм обучается и тестируется K раз. В первом случае от SET A до SET D используются в качестве обучающего набора, а SET E используется как набор для тестирования, как показано на рисунке ниже:
{.ezlazyload .img-responsive}
Во втором случае SET A, SET B, SET C и SET E используются для обучения, а SET D используется для тестирования. Процесс продолжается до тех пор, пока каждый набор не будет использован хотя бы один раз для обучения и один раз для тестирования. Конечный результат - это среднее значение результатов, полученных с использованием всех складок. Таким образом мы можем избавиться от дисперсии. Используя стандартное отклонение результатов, полученных для каждого раза, мы можем фактически найти дисперсию в общем результате.
Перекрестная проверка с Scikit-Learn
В этом разделе мы будем использовать перекрестную проверку для оценки производительности алгоритма случайного леса для классификации. Задача, которую мы собираемся решить, - спрогнозировать качество вина по 12 признакам. Подробная информация о наборе данных доступна по следующей ссылке:
https://archive.ics.uci.edu/ml/datasets/wine+quality
В этой статье мы используем данные только для красного вина.
Выполните следующие шаги, чтобы реализовать перекрестную проверку с помощью Scikit-Learn:
1. Импорт необходимых библиотек
Следующий код импортирует несколько необходимых библиотек:
import pandas as pd
import numpy as np
2. Импорт набора данных
Загрузите набор данных, который доступен в Интернете по этой ссылке:
https://www.kaggle.com/piyushgoyal443/red-wine-dataset
После того, как мы его загрузили, мы поместили файл в папку «Datasets» на нашем диске «D» для этой статьи. Название набора данных - winequality-red.csv. Обратите внимание, что вам нужно изменить путь к файлу, чтобы он соответствовал местоположению, в котором вы сохранили файл на своем компьютере.
Выполните следующую команду, чтобы импортировать набор данных:
dataset = pd.read_csv(r"D:/Datasets/winequality-red.csv", sep=';')
Набор данных был разделен точкой с запятой, поэтому мы передали ";" атрибут для параметра "sep", чтобы pandas мог правильно проанализировать файл.
3. Анализ данных
Выполните следующий сценарий, чтобы получить обзор данных:
dataset.head()
Результат выглядит так:
фиксированная кислотность летучая кислотность лимонная кислота остаточный сахар хлориды свободный диоксид серы общий диоксид серы плотность pH сульфаты алкоголь качество
0 7,4 0,70 0,00 1.9 0,076 11.0 34,0 0,9978 3,51 0,56 9,4 5 1 7,8 0,88 0,00 2,6 0,098 25,0 67,0 0,9968 3.20 0,68 9,8 5 2 7,8 0,76 0,04 2.3 0,092 15.0 54,0 0,9970 3,26 0,65 9,8 5 3 11.2 0,28 0,56 1.9 0,075 17.0 60,0 0,9980 3,16 0,58 9,8 6 4 7,4 0,70 0,00 1.9 0,076 11.0 34,0 0,9978 3,51 0,56 9,4 5
4. Предварительная обработка данных
Выполните следующий сценарий, чтобы разделить данные на наборы меток и функций.
X = dataset.iloc[:, 0:11].values
y = dataset.iloc[:, 11].values
Поскольку мы используем перекрестную проверку, нам не нужно разделять
наши данные на обучающие и тестовые наборы. Нам нужны все данные в
обучающем наборе, чтобы мы могли применить к ним перекрестную проверку.
Самый простой способ сделать это - установить для test_size
значение
0. Это вернет все данные в обучающем наборе следующим образом:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0, random_state=0)
5. Масштабирование данных
Если вы посмотрите на набор данных, вы заметите, что он плохо масштабируется. Например, столбцы «летучая кислотность» и «лимонная кислота» имеют значения от 0 до 1, в то время как большинство остальных столбцов имеют более высокие значения. Следовательно, перед обучением алгоритма нам нужно будет уменьшить масштаб наших данных.
Здесь мы будем использовать класс StandardScalar
from sklearn.preprocessing import StandardScaler
feature_scaler = StandardScaler()
X_train = feature_scaler.fit_transform(X_train)
X_test = feature_scaler.transform(X_test)
6. Обучение и перекрестная проверка
Первый шаг на этапе обучения и перекрестной проверки прост. Вам просто
нужно импортировать класс алгоритма из sklearn
как показано ниже:
from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators=300, random_state=0)
Далее, для реализации перекрестной проверки, то cross_val_score
метод
sklearn.model_selection
можно использовать библиотеку.
cross_val_score
возвращает точность для всех складок. Значения 4
параметров необходимо передать в класс cross_val_score
Первый параметр
-
это оценщик, который в основном определяет алгоритм, который вы хотите использовать для перекрестной проверки. Второй и третий параметры,
X
иy
, содержат данныеX_train
иy_train
то есть функции и метки.cv
передается количество складок, как показано в следующем коде:from sklearn.model_selection import cross_val_score all_accuracies = cross_val_score(estimator=classifier, X=X_train, y=y_train, cv=5)
Выполнив это, давайте просто напечатаем точности, возвращенные для пяти
сгибов методом cross_val_score
, вызвав print
для all_accuracies
.
print(all_accuracies)
Выход:
[ 0.72360248 0.68535826 0.70716511 0.68553459 0.68454259 ]
Чтобы найти среднее значение для всех значений точности, просто
используйте метод mean()
объекта, возвращаемого методом
cross_val_score
как показано ниже:
print(all_accuracies.mean())
Среднее значение 0,6972 или 69,72%.
Наконец, давайте найдем стандартное отклонение данных, чтобы увидеть
степень дисперсии результатов, полученных с помощью нашей модели. Для
этого вызовите метод std()
для объекта all_accuracies
print(all_accuracies.std())
Результат: 0,01572, что составляет 1,57%. Это чрезвычайно мало, что означает, что наша модель имеет очень низкую дисперсию, что на самом деле очень хорошо, поскольку это означает, что прогноз, который мы получили на одном наборе тестов, не случаен. Скорее, модель будет работать более или менее одинаково на всех тестовых наборах.
Поиск по сетке для выбора параметра
Модель машинного обучения имеет два типа параметров. Первый тип параметров - это параметры, которые изучаются с помощью модели машинного обучения, а второй тип параметров - это гиперпараметры, которые мы передаем в модель машинного обучения.
В последнем разделе при прогнозировании качества вина мы использовали алгоритм случайного леса. Количество оценок, которые мы использовали для алгоритма, было 300. Аналогично в алгоритме KNN мы должны указать значение K, а для алгоритма SVM мы должны указать тип ядра. Эти оценки - значение K и ядро - все типы гиперпараметров.
Обычно мы случайным образом устанавливаем значение для этих гиперпараметров и смотрим, какие параметры дают наилучшую производительность. Однако случайный выбор параметров для алгоритма может оказаться исчерпывающим.
Кроме того, нелегко сравнивать производительность разных алгоритмов путем случайной установки гиперпараметров, потому что один алгоритм может работать лучше, чем другой, с другим набором параметров. И если параметры изменить, алгоритм может работать хуже, чем другие алгоритмы.
Поэтому, вместо случайного выбора значений параметров, лучшим подходом было бы разработать алгоритм, который автоматически находит наилучшие параметры для конкретной модели. Grid Search - один из таких алгоритмов.
Поиск по сетке с помощью Scikit-Learn
Реализуем алгоритм поиска по сетке на примере. Сценарий в этом разделе должен запускаться после сценария, который мы создали в последнем разделе.
Для реализации алгоритма поиска по сетке нам необходимо импортировать
класс GridSearchCV
из библиотеки sklearn.model_selection
Первый шаг, который вам нужно выполнить, - это создать словарь всех параметров и соответствующего им набора значений, которые вы хотите протестировать на лучшую производительность. Имя элементов словаря соответствует имени параметра, а значение соответствует списку значений параметра.
Давайте создадим словарь параметров и их соответствующих значений для нашего алгоритма случайного леса. Подробная информация обо всех параметрах алгоритма случайного леса доступна в документации Scikit-Learn .
Для этого выполните следующий код:
grid_param = {
'n_estimators': [100, 300, 500, 800, 1000],
'criterion': ['gini', 'entropy'],
'bootstrap': [True, False]
}
Внимательно посмотрите на приведенный выше код. Здесь мы создаем
grid_param
с тремя параметрами: n_estimators
, criterion
и
bootstrap
загрузкой. Значения параметров, которые мы хотим опробовать,
передаются в списке. Например, в приведенном выше сценарии мы хотим
найти, какое значение (из 100, 300, 500, 800 и 1000) обеспечивает
наивысшую точность.
Точно так же мы хотим найти, какое значение приводит к наивысшей
производительности для criterion
: «Джини» или «энтропия»? Алгоритм
поиска по сетке в основном перебирает все возможные комбинации значений
параметров и возвращает комбинацию с максимальной точностью. Например, в
приведенном выше случае алгоритм проверит 20 комбинаций (5 x 2 x 2 =
20).
Алгоритм поиска по сетке может быть очень медленным из-за потенциально огромного количества тестируемых комбинаций. Кроме того, перекрестная проверка еще больше увеличивает время выполнения и сложность.
После создания словаря параметров следующим шагом будет создание
экземпляра класса GridSearchCV
Вам необходимо передать значения для
estimator
, который в основном является алгоритмом, который вы хотите
выполнить. Параметр param_grid
принимает словарь параметров, который
мы только что создали, в качестве параметра, параметр scoring
принимает метрики производительности, cv
соответствует количеству
сверток, которое в нашем случае равно 5, и, наконец, n_jobs
относится
к количеству процессоров, которые вы хотите использовать для исполнения.
Значение -1 для n_jobs
означает использование всей доступной
вычислительной мощности. Это может быть удобно, если у вас большой объем
данных.
Взгляните на следующий код:
gd_sr = GridSearchCV(estimator=classifier,
param_grid=grid_param,
scoring='accuracy',
cv=5,
n_jobs=-1)
После того , как GridSearchCV
класс инициализируется, последний шаг
заключается в вызове fit
метод класса и передать его на обучение и
набор тестов, как показано в следующем коде:
gd_sr.fit(X_train, y_train)
Выполнение этого метода может занять некоторое время, потому что у нас есть 20 комбинаций параметров и пятикратная перекрестная проверка. Таким образом, алгоритм выполнится всего 100 раз.
После того, как метод завершит выполнение, следующим шагом будет
проверка параметров, которые возвращают наивысшую точность. Для этого
распечатайте sr.best_params_
атрибут GridSearchCV
объекта, как
показано ниже:
best_parameters = gd_sr.best_params_
print(best_parameters)
Выход:
{'bootstrap': True, 'criterion': 'gini', 'n_estimators': 1000}
Результат показывает, что наивысшая точность достигается, когда
n_estimators
равны 1000, bootstrap
имеет значение True
и
criterion
- «gini».
Примечание . Было бы неплохо добавить больше оценщиков и посмотреть,
увеличится ли производительность дальше, поскольку было выбрано
n_estimators
Последний и последний шаг алгоритма поиска по сетке - найти точность,
полученную с использованием лучших параметров. Ранее у нас была средняя
точность 69,72% с 300 n_estimators
.
Чтобы добиться максимальной точности, выполните следующий код:
best_result = gd_sr.best_score_
print(best_result)
Достигнутая точность составляет: 0,6985 из 69,85%, что лишь немного
лучше 69,72%. Чтобы улучшить это, было бы хорошо проверить значения для
других параметров алгоритма случайного леса, таких как max_features
,
max_depth
, max_leaf_nodes
и т. Д., Чтобы увидеть, улучшится ли
точность в дальнейшем или нет.
Заключение
В этой статье мы изучили два очень часто используемых метода оценки производительности и выбора модели алгоритма. Перекрестная проверка методом K-Fold может использоваться для оценки производительности модели путем решения проблемы дисперсии набора результатов. Кроме того, чтобы определить лучший алгоритм и лучшие параметры, мы можем использовать алгоритм поиска по сетке.