УДК 004
В. А. Трясучкин, М. М. Синцева
ИССЛЕДОВАНИЕ ОПТИМИЗАЦИИ ГИПЕРПАРАМЕТРОВ АЛГОРИТМА k-БЛИЖАИШИХ СОСЕДЕЙ
Аннотация. В машинном обучении при решении задач классификации каких-либо объектов с помощью алгоритма k-ближайших соседей становится очевидна задача автоматизации выбора гиперпараметра к, так как ручной подбор гиперпараметра занимает много времени и не всегда удается добиться максимальной точности. В связи с этим исследование методов оптимизации гиперпараметров является актуальной задачей. Научная новизна исследования состоит в применении в задаче классификации группы людей по гендерному признаку методов оптимизации gridsearch и randomsearch, которые позволяют повысить скорость и точность решения задачи, и сравнении результатов. Реализация данных методов оптимизации позволила значительно упросить и ускорить подбор гиперпараметра, однако каждый из методов имеет ряд особенностей, которые обусловливают выбор того или иного метода при решении конкретной задачи.
Ключевые слова: машинное обучение, классификация, гиперпараметры, оптимизация.
Машинное обучение активно применяется во многих сферах жизни людей. Одним из разделов машинного обучения является классификация. Она призвана решать задачи отнесения некоторого объекта к одному из заданных классов. Пусть задано конечное множество объектов, для которых определена принадлежность к тому или иному классу. Назовем это множество обучающей выборкой. Для остальных объектов неизвестно, к какому классу они относятся. Необходимо построить алгоритм, способный классифицировать произвольный объект, не относящийся к исходному множеству [1].
Одним из алгоритмов классификации в машинном обучении является алгоритм k-ближайших соседей. Этот алгоритм относит классифицируемый объект к тому классу, к которому принадлежат k ближайших к нему объектов из обучающей выборки, где k -это некоторое заранее заданное число.
Математическая формула данного метода выглядит следующим образом: а(и) = = arg1Ziii[xi-,u =y]w(.i,u), где w(i,u) — заданная весовая функция, которая оценивает степень важности i-го соседа для классификации объекта и. Естественно полагать, что эта функция неотрицательна и не возрастает по i. w(i,u) = [i <к] [2].
Для реализации данного алгоритма в ходе исследования была выбрана задача классификации группы людей по гендерному признаку. В качестве характеристик (признаков) классифицируемых объектов были выбраны рост и вес. Входные данные составляет множество из трехсот объектов. В ходе решения задачи данное множество было разбито на обучающую и тестовую выборку в соотношении 3:1. В качестве обучающей выборки было использовано множество из 225 объектов с известной классовой принадлежностью, в качестве тестовой - 75 объектов c неизвестным классом (рис. 1).
На рис. 1 черным цветом обозначены объекты мужского пола, белым - объекты женского пола. Кругами обозначена обучающая выборка, звездами - тестовая.
Для решения данной задачи использовался язык программирования Python 3.6 и редактор Spyder. Язык Python пользуется высокой популярностью среди разработчиков в области машинного обучения благодаря своей простоте и большому количеству библиотек [3].
© Трясучкин В. А., Синцева М. М., 2019.
130 МО 150 160 170 180 190 200 210 Рис. 1. Обучающая и тестовая выборки
В ходе решения задачи использовались встроенные библиотеки: библиотека numpy для работы с матрицами и массивами, библиотека matplotlib для визуализации графика с данными, библиотека sklearn для разделения данных на обучающую и тестовую выборку, а также для реализации метода k-ближайших соседей. Ниже представлено решение задачи на языке Python с соответствующими пояснениями.
import numpy as np # библиотека для работы с матрицами и массивами import matplotlib.pyplot as plt # для отрисовки графика
from sklearn.model_selection import train_test_split # для разделения данных на обучающую и тестовую выборки
from sklearn.neighbors import KNeighborsClassifier # для реализации алгоритма k-ближайших соседей
data = np.genfromtxt('..\\dat.csv', delimiter=',') # чтение файла с данными
classtrain_data: # класс для введения данных
response = np.array(range(0,300)) # пол
tag = np.array([range(0,600)], float)# признаки (рост и вес)
train_data.tag.shape = (300, 2) # преобразование одномерного массива в двумерный color = np.array(range(1000,1300), str) # массив с цветом, для удобства
for number in range(1,301): # запись данных в созданный объект train_data.response[number-1] = int(data[number][0]) if train_data.response[number-1] == 0:
color[number-1] = "w" if train_data.response[number-1] == 1: color[number-1] = "k" train_data.tag[number-1][0] = data[number][1] train_data.tag[number-1][1] = data[number][2] ""Импорт данных""
X_train, X_test, y_train, y_test, color_train, color_test = train_test_split(train_data.tag,
train_data.response,
color,
random_state=0) #разделение входных данных на обучающую выборку(75%) и те-стовую(25%)
for number in range(0,225): #отрисовка обучающей выборки plt.scatter(X_train[number][0], X_train[number][1],
c= color_train[number], edgecolors = "k") K = KNeighborsClassifier(n_neighbors=15) K.fit(X_train, y_train)#обучение модели predict = K.predict(X_test)
i = 0#переменная для подсчета верных прогнозов colorl = np.array(range(10000,10075), str)
for number in range(0,75): #присваивание цвета на основании прогнозов if predict[number] == 0: color1[number] = "w" else:
color1[number] = "k" if predict[number] == y_test[number]:#подсчет верных прогнозов i = i + 1 for number in range(0,75):
plt.scatter(X_test[number][0], X_test[number][1], c = color1 [number], marker = "*", edgecolors ="k") #отрисовка тестовой выборки print(i*100/75) #вывод точности
При реализации алгоритма k-ближайших соседей в решении данной задачи выбор гиперпараметра к осуществлялся путем ручного перебора и был равен 15. Точность составила 96 %.
Очевидна задача автоматизации выбора наиболее оптимального гиперпараметра к, так как подбор гиперпараметра вручную занимает большое количество времени.
Существует множество методов оптимизации гиперпараметров. К ним относятся такие методы, как gridsearch, randomsearch и некоторые другие.
Для оптимизации гиперпараметра при решении задачи было принято решение реализовать методы gridsearch и randomsearch и сравнить их.
Метод gridsearch осуществляет поиск оптимального гиперпараметра путем его полного перебора из заданного множества. Данный способ оптимизации наиболее точен, однако он сильно зависит от вычислительной мощности компьютера, и при больших объемах данных подбор гиперпараметра займет много времени [4].
Ниже представлен результат реализации метода оптимизации гиперпараметра gridsearch в алгоритме k-ближайших соседей на языке программирования Python с соответствующими пояснениями.
importnumpyasnp #библиотека для работы с матрицами и массивами import matplotlib.pyplot as plt #для отрисовки графика
from sklearn.model_selection import train_test_split #для разделения данных на обучающую и тестовую выборки
from sklearn.neighbors import KNeighborsClassifier #для реализации алгоритма k-ближайших соседей
from sklearn.model_selection import GridSearchCV
data = np.genfromtxt('C:\\Users\\sonik\\Downloads\\dat.csv',
delimiter=',') #чтение файла с данными
classtrain_data: #класс для введенных данных
response = np.array(range(0,300)) #пол
tag = np.array([range(0,600)], float)#признаки (рост и вес)
train_data.tag.shape = (300, 2) #преобразование одномерного массива в двумерный color = np.array(range(1000,1300), str)#массив с цветом, для удобства fornumberinrange(1,301): #запись данных в созданный объект
train_data.response[number-1] = int(data[number][0]) if train_data.response[number-1] == 0:
color[number-1] = "w" if train_data.response[number-1] == 1: color[number-1] = "k" train_data.tag[number-1][0] = data[number][1] train_data.tag[number-1][1] = data[number][2] ""Импорт данных""
X_train, X_test, y_train, y_test, color_train, color_test = train_test_split(train_data.tag,
train_data.response,
color,
random_state=0) #разделение входных данных на обучающую выборку(75%) и тесто-вую(25%)
for number in range(0,225): #отрисовка обучающей выборки plt.scatter(X_train[number][0], X_train[number][1], c= color_train[number], edgecolors ="k") params = {"n_neighbors":np.arange(1, 100)}
K = KNeighborsClassifier() #реализация метода k-ближайших соседей. Здесь берется 5 соседей
grid = GridSearchCV(K, params) grid.fit(X_train, y_train) #обучение модели predict = grid.predict(X_test) #прогноз i = 0 #переменная для подсчета верных прогнозов color1 = np.array(range(10000,10075), str)
for number in range(0,75): #присваивание цвета на основании прогнозов if predict[number] == 0: color1[number] = "w" else:
color1[number] = "k" if predict[number] == y_test[number]:#подсчет верных прогнозов i = i + 1 print (grid.best_params_) for number in range(0,75):
plt.scatter(X_test[number][0], X_test[number][1], c = color1 [number], marker = "*", edgecolors ="к")#отрисовка тестовой выборки print(i*100/75) #вывод точности
Точность gridsearch оказалась равна 96 %. При этом гиперпараметр k равен 39. Метод randomsearch, в отличие от gridsearch, осуществляет поиск оптимального гиперпараметра не путем полного перебора всех значений, а выбирая их случайным образом. Точность данного метода варьируется, но чаще всего она ниже, чем у gridsearch. Максимальной точности данный метод достигает при максимальном количестве итераций [5].
Ниже представлен результат реализации метода оптимизации гиперпараметра randomsearch в алгоритме k-ближайших соседей на языке программирования Python с соответствующими пояснениями.
importnumpyasnp #библиотека для работы с матрицами и массивами import matplotlib.pyplot as plt #для отрисовки графика
from sklearn.model_selection importtrain_test_split #для разделения данных наобуча-ющую и тестовуюв ыборки
from sklearn.neighbors import KNeighborsClassifier #для реализации алгоритма k-ближайших соседей
from sklearn.model_selection import RandomizedSearchCV
data = np.genfromtxt('C:\\Users\\sonik\\Downloads\\dat.csv', delimiter=',') #чтение файла с данными
classtrain_data: #класс для введенных данных response = np.array(range(0,300)) #пол
tag = np.array([range(0,600)], float) #признаки (рост и вес) train_data.tag.shape = (300, 2) #преобразование одномерного массива в двумерный color = np.array(range(1000,1300), str) #массив с цветом, для удобства fornumberinrange(1,301): #запись данных в созданный объект train_data.response[number-1] = int(data[number][0]) if train_data.response[number-1] == 0:
color[number-1] = "w" if train_data.response[number-1] == 1: color[number-1] = "k" train_data.tag[number-1][0] = data[number][1] train_data.tag[number-1][1] = data[number][2] ""Импорт данных""
X_train, X_test, y_train, y_test, color_train, color_test = train_test_split(train_data.tag,
train_data.response,
color,
random_state=0) #разделение входных данных на обучающую выборку(75%) и те-стовую(25%)
for number in range(0,225): #отрисовка обучающей выборки plt.scatter(X_train[number][0], X_train[number][1], c= color_train[number], edgecolors ="k") params = {"n_neighbors":np.arange(1, 150)}
K = KNeighborsClassifier() #реализация метода k-ближайших соседей. Здесь берется 5 соседей
grid = RandomizedSearchCV(K, params) grid.n_iter = 149
grid.fit(X_train, y_train) #обучение модели predict = grid.predict(X_test) #прогноз i = 0 #переменная для подсчета верных прогнозов color1 = np.array(range(10000,10075), str)
fornumberinrange(0,75): #присваивание цвета на основании прогнозов if predict[number] == 0: color1[number] = "w" else:
color1[number] = "k" if predict[number] == y_test[number]:#подсчет верных прогнозов i = i + 1 print (grid.best_params_) for number in range(0,75):
plt.scatter(X_test[number][0], X_test[number][1], c = color1 [number], marker = "*", edgecolors ="k") #отрисовка тестовой выборки print(i*100/75) #вывод точности
При числе итераций, равном 10, точность randomsearch менялась и была равна 94,6 % при к = 45 и 96 % при к = 39. При максимальном числе итераций точность была такой же, как и у gridsearch.
По результатам исследования можно сделать вывод, что реализованные методы оптимизации дают примерно одинаковые результаты, однако имеют ряд особенностей, от которых зависит выбор того или иного метода при решении конкретной задачи. В частности, gridsearch стоит применять только в том случае, когда имеется небольшой объем данных для обработки или требуется максимальная точность. Если же на первом месте стоит скорость обработки данных, то стоит использовать randomsearch.
Библиографический список
1. Müller, A. C. Introduction to Machine Learning with Python: A Guide for Data Scientists /
A. C. Müller, S. Guido. - O'Reilly, 2017. - P. 31.
2. Метод ближайших соседей. - URL: http://www.machinelearning.ru (дата обращения: 13.05.2019).
3. 3 самых важных сферы применения Python: возможности языка. - URL: https://proglib.io (дата обращения: 14.05.2019).
4. GridSearchCV. - URL: https://scikit-learn.org_(accessed on: 14 May 2019).
5. RandomizedSearchCV. - URL: https://scikit-learn.org (accessed on: 15 May 2019).
Трясучкин Владислав Алексеевич, студент, Пензенский государственный университет. E-mail: [email protected]
Синцева Марина Михайловна, студентка, Пензенский государственный университет. E-mail: [email protected]
Образец цитирования:
Трясучкин, В. А. Исследование оптимизации гиперпараметров алгоритма k ближайших соседей /
B. А. Трясучкин, М. М. Синцева // Вестник Пензенского государственного университета. - 2019. - № 2 (26). -
C. 63-68.