«ML — первые принципы» относится к идее о том, что для правильного понимания машинного обучения необходимо понимать основные принципы и концепции, которые заставляют его работать. Это означает выход за рамки простого использования готовых библиотек и алгоритмов машинного обучения и понимание математики, статистики и методов оптимизации, лежащих в их основе.

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

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

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

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

Обучение под наблюдением:

  • Линейная регрессия
  • Логистическая регрессия
  • Наивный Байес
  • k-ближайшие соседи (KNN)
  • Деревья решений
  • Случайные леса
  • Машины повышения градиента (GBM)
  • Методы опорных векторов (SVM)
  • Нейронные сети (многослойный персептрон)

Неконтролируемое обучение:

  • Кластеризация K-средних
  • Иерархическая кластеризация
  • Анализ главных компонентов (PCA)
  • Анализ независимых компонентов (ICA)
  • т-СНЭ
  • Автоэнкодеры
  • Генеративно-состязательные сети (GAN)

Обучение с подкреплением:

  • Q-обучение
  • САРСА
  • Глубокое обучение с подкреплением
  • Градиенты политики
  • Актер-критик
  1. Полуконтролируемое обучение:
  • Самообучение
  • Совместное обучение
  • Многопрофильное обучение
  • Графические методы

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

В этой серии статей мы рассмотрим некоторые алгоритмы, такие как KNN, регрессия, случайный лес, кластеризация k-средних, PCA, Q-Learning, методы на основе графов.

КНН

K-ближайшие соседи (KNN) — это простой и популярный алгоритм машинного обучения для классификации и регрессии. Алгоритм основан на том принципе, что точки данных, расположенные близко друг к другу в пространстве признаков, имеют тенденцию принадлежать к одному и тому же классу или иметь схожие целевые значения.

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

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

Я реализую KNN, используя чистый Python.

import numpy as np

class KNN:
    def __init__(self, k=3):
        self.k = k

    def fit(self, X, y):
        # Store training data and labels in class variables
        self.X_train = X
        self.y_train = y

    def predict(self, X):
        predictions = []
        for i in range(len(X)):
            # Compute distances between test point and all training points
            distances = np.sqrt(np.sum((self.X_train - X[i])**2, axis=1))
            
            # Get indices of k nearest neighbors
            indices = np.argsort(distances)[:self.k]
            
            # Get labels of k nearest neighbors
            labels = self.y_train[indices]
            
            # Get unique labels and their counts
            unique, counts = np.unique(labels, return_counts=True)
            
            # Determine the most common label among the k nearest neighbors
            pred_label = unique[np.argmax(counts)]
            
            # Add the predicted label to the list of predictions
            predictions.append(pred_label)
        
        # Return the list of predicted labels
        return predictions

Вот разбивка того, что делает каждая часть кода:

distances = np.sqrt(np.sum((self.X_train - X[i])**2, axis=1))
  • (self.X_train - X[i])**2: это вычитает контрольную точку X[i] из каждой точки обучения и возводит результат в квадрат по элементам. Результатом является матрица формы (n_train, n_features), где n_train — количество точек обучения, а n_features — количество признаков.
  • np.sum(..., axis=1): суммирует квадраты разностей по второй оси (т. е. размерность n_features), чтобы получить квадраты расстояний между тестовой и тренировочной точками. Результатом является одномерный массив длины. n_train.
  • np.sqrt(...): при этом извлекается квадратный корень из каждого элемента массива, чтобы получить фактические расстояния между контрольной точкой и каждой точкой обучения. Результатом является одномерный массив длиной n_train, где каждый элемент представляет собой евклидово расстояние между контрольной точкой X[i] и точкой обучения.
  • Таким образом, эта строка кода вычисляет евклидово расстояние между тестовой точкой и всеми обучающими точками, используя пустую широковещательную передачу и векторизованные операции. Результатом является одномерный массив расстояний, который можно использовать для поиска k ближайших соседей контрольной точки.

Вот разбивка того, что делает каждая часть кода:

            # Get indices of k nearest neighbors
            indices = np.argsort(distances)[:self.k]
            
            # Get labels of k nearest neighbors
            labels = self.y_train[indices]
            
            # Get unique labels and their counts
            unique, counts = np.unique(labels, return_counts=True)
  • np.argsort(distances)[:self.k]: возвращает индексы k ближайших соседей контрольной точки в обучающих данных. np.argsort Возвращает массив индексов, который будет сортировать входной массив в порядке возрастания. Разбивая отсортированные индексы до k элементов, мы получаем индексы k ближайших соседей.
  • self.y_train[indices]: это выбирает метки классов k ближайших соседей из обучающих меток self.y_train. Результирующий массив меток имеет длину k.
  • np.unique(labels, return_counts=True): Вычисляет уникальные метки классов и их количество среди k ближайших соседей. Аргумент return_counts=True говорит Numpy вернуть количество каждой уникальной метки и самих уникальных меток. Результирующие массивы уникальных меток и их счетчиков имеют одинаковую длину и поэлементно соответствуют друг другу.

Наконец, мы определяем прогнозируемую метку класса контрольной точки, выбирая метку с наибольшим количеством среди k ближайших соседей. Мы можем добиться этого, используя np.argmax(counts) для получения индекса наиболее распространенной метки, а затем используя этот индекс для выбора соответствующей метки из массива unique. Полученная метка является прогнозируемой меткой класса для контрольной точки.

Общий

В этой реализации мы определяем класс KNN с методами __init__, fit и predict. Метод __init__ устанавливает значение k (количество ближайших соседей для рассмотрения) равным 3 по умолчанию.

fit метод принимает данные обучения X и y и сохраняет их в классе как self.X_train и self.y_train.

predict метод принимает тестовые данные X и возвращает список предсказанных меток. Для каждой точки данных в X метод вычисляет расстояния между этой точкой и всеми точками обучающих данных, используя формулу евклидова расстояния. Затем он сортирует расстояния в порядке возрастания и выбирает k ближайших соседей. Затем метод определяет наиболее распространенную метку среди k ближайших соседей и возвращает эту метку в качестве прогноза.

Чтобы использовать этот класс, вы можете создать экземпляр класса KNN, вызвать метод fit для ваших обучающих данных, а затем вызвать метод predict для ваших тестовых данных. Вот пример:

# create a KNN classifier with k=5
clf = KNN(k=5)

# fit the model to the training data
clf.fit(X_train, y_train)

# make predictions on the test data
y_pred = clf.predict(X_test)

# print the accuracy score of the model
accuracy = sum(y_pred == y_test) / len(y_test)
print("Accuracy:", accuracy)

В этом примере X_train и y_train — это обучающие данные и метки, а X_test — тестовые данные. После подгонки модели к обучающим данным мы вызываем метод предсказания для X_test, чтобы получить предсказанные метки. Наконец, мы вычисляем показатель точности, сравнивая предсказанные метки с истинными метками y_test.