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

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

1. Загрузите библиотеки и данные

library(KernelKnn)
data(ionosphere, package = ‘KernelKnn’)

Библиотека KernelKnn загружается с помощью функции library(). В нем есть методы построения моделей k-NN. Этот пакет также содержит набор данных ионосферы, который мы загружаем с помощью функции данных, указав имя набора данных и пакет. Функция data() загружает набор данных «ионосфера» в фрейм данных с именем «ионосфера».

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

# Drop 2nd column because all values are 0
ionosphere = ionosphere[, -2]
# For the training attributes
X = scale(ionosphere[, -c(34)])
# For training labels
y = ionosphere[, c(34)]
# Convert factor(categorical) variable y to numeric 
# because factors cannot be used in KNN
y = as.numeric(y)

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

Мы хотим предсказать метку в 34-м столбце (Хорошо или Плохо, подробнее о наборе данных можно прочитать здесь). Итак, нам нужно дать нашей модели функции, оставляя метку. Поэтому мы разделим функции как X и метки как y.

3. Создайте обучающие наборы тестов

# Generate random indexes for train and test set rows
train.idx = sample(1:length(y), round(length(y) * 0.75))
test.idx = setdiff(1:length(y), train.idx)
train = X[train.idx, ]
test = X[test.idx, ]
train.labels = y[train.idx]
test.labels = y[test.idx]

Итак, здесь мы разделяем функции и метки на обучающие и тестовые наборы. Для этого мы генерируем обучающие и тестовые индексы. Индексы поезда состоят из случайной последовательности 75% чисел в диапазоне количества выборок. Остальные 25% чисел составляют тестовые индексы. Эти индексы используются для выбора строк из X и y для создания train, train.labels, test и test.labels.

Мы также определим функцию полезности для расчета точности:

accuracy = function (y_true, preds) {
 out = table(y_true,   # Confusion matrix
             max.col(preds, ties.method = “random”)) 
# max.col() Returns column which has highest value 
# and that corresponds to the class 0 or 1
 acc = sum(diag(out))/sum(out)
 acc
}

Здесь параметр preds является результатом функции KernelKnn(), которая имеет два столбца, соответствующих меткам 0 и 1. В каждой строке preds первый столбец содержит вероятность того, что точка данных принадлежит классу 0, а второй содержит вероятность того, что точка данных принадлежит классу 1. Это упрощается до одного столбца, содержащего метку, соответствующую самой высокой вероятности (прогнозируемая метка) в функции max.col(). Это используется в функции table(), которая создает матрицу путаницы.

4. Применение k-NN

Обычное ядро ​​k-NN

predictions = KernelKnn(train, test, train.labels, 
                  k = 5 ,             # number of nearest neighbors
                  method = 'euclidean',    # distance metric
                  weights_function = NULL, # kernel function
                  regression = F,          # classification problem
                  Levels = unique(y))# number of output classes (=2)
acc = accuracy(test.labels, predictions)
paste('Accuracy is ', acc)

Итак, здесь мы строим модель ядра k-NN. В ядре KNN мы используем функцию ядра (функцию весов), которая придает большее значение некоторым функциям. Для обычных k-ближайших соседей мы указываем weights_function = NULL с методом как евклидов. Вы можете экспериментировать с различными весовыми функциями, такими как «епанечников», «трикуб», «гауссов» и т. д. Параметр метода указывает метрику расстояния. Вы можете поэкспериментировать с различными показателями расстояния, такими как «канберра», «манхэттен».

predictions = KernelKnn(train, test, train.labels, 
                  k = 10,             # number of nearest neighbors
                  method = 'canberra',    # distance metric
                  weights_function = 'epanechnikov', # kernel function
                  regression = F,          # classification problem
                  Levels = unique(y))# number of output classes (=2)
acc = accuracy(test.labels, predictions)
paste('Accuracy is ', acc)

K-кратное ядро ​​перекрестной проверки k-NN

knn = KernelKnnCV(X, y, 
 k = 9 ,                            # number of nearest neighbors
 folds = 5,                         # number of folds in k-fold CV
 method = ‘canberra’,               # distance metric
 weights_function = ‘epanechnikov’, # kernel function
 regression = F,                    # classification problem
 Levels = unique(y),                # number of output classes (=2)
 threads = 5)             # number of threads for parallel execution
acc_cv = unlist(lapply(1:length(knn$preds), 
 function(x) accuracy(y[knn$folds[[x]]],knn$preds[[x]])))
paste(‘Accuracy is ‘, mean(acc_cv))

KernelKnnCV() использует метод перекрестной проверки, при котором весь набор признаков делится на k частей (сгибов). Одна из этих частей используется для тестирования, а остальные используются для обучения. Это продолжается до тех пор, пока каждая часть (складка) не будет использована хотя бы один раз для тестирования. Расчет точности здесь немного сложен. Возвращаемый кадр данных из KernelKnnCV() имеет два основных атрибута: складки и преды. Складки содержат индексы для каждой k-й итерации, а preds содержит соответствующие вероятности для метки 0 и 1. Мы вычисляем точность для каждой k-й итерации и находим ее среднее значение.

Здесь функция lapply() применяет ранее определенную функцию precision() к результату каждой k-й итерации. Здесь параметр x принимает значения 1:length(knn$preds). Функция unlist() преобразует список в вектор.

Вывод

Ядро k-NN — это усовершенствованная версия алгоритма k-NN, которая работает с пространством более высокой размерности для взвешивания точек данных. Но опять же, производительность зависит от выбора параметров и данных.