СОДЕРЖАНИЕ

В этом посте мы рассмотрим:

1. Введение в машинное обучение

2. Различные типы задач машинного обучения.

3. Функция затрат для линейной регрессии.

4. Алгоритм градиентного спуска.

5. Практическое руководство по задаче многомерной линейной регрессии на наборе данных Kaggle.

Что такое машинное обучение?

Помните первый код, который вы написали на компьютере? Большинство из нас начинают с программ «Hello World», но вспомните, когда вы написали что-то, что заставило вас гордиться собой. Для большинства энтузиастов информатики это может быть либо решение всего задания по программированию самостоятельно, либо решение вопросов по соревновательному программированию. Не будем забывать, что для большинства из нас это были первые шаги, которые помогли нам окунуться в мир информатики.

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

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

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

Контролируемое обучение

То, как люди учатся на примерах, можно сравнить с обучением с учителем. При контролируемом обучении мы предоставляем нашей машине помеченный набор данных, то есть мы предоставляем и ввод, и вывод, и, применяя один из различных алгоритмов (моделей) контролируемого машинного обучения, мы ожидаем, что наша модель машинного обучения изучит сопоставление между вводом и выход. Алгоритмы контролируемого обучения делятся на 2 большие категории:

(i) Алгоритмы классификации

(ii) Алгоритмы регрессии

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

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

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

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

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

(i) Алгоритмы кластеризации

(ii) Алгоритмы ассоциации

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

Ассоциация занимается установлением ассоциаций между объектами данных в больших базах данных. Одним из примеров является система рекомендаций Amazon, где после покупки определенного товара пользователю предлагается купить другие товары.

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

Один из самых простых методов машинного обучения с учителем - это линейная регрессия. Линейную регрессию можно легко реализовать на python с помощью библиотеки sci-kit learn с помощью pandas и numpy, но сначала давайте разберемся, как работает этот алгоритм.

Линейная регрессия

Рассмотрим прямую y = Wx + b. В терминах координатной геометрии x и y - переменные, W - наклон этой линии, а b - точка пересечения на оси y. Мы вводим различные значения x в это уравнение, и соответствующие значения y на графике дают прямую линию, учитывая значения W и b. В терминах машинного обучения 'x' - это 'входные данные', y - 'выход', а W и b - параметры, которые мы хотим, чтобы алгоритм линейной регрессии научился задавать 'правила', чтобы его можно было обобщить на новые входные данные.

Отдел тренировочных и тестовых наборов

Нам нужен хороший объем данных для наших обучающих алгоритмов, чтобы изучить отображения (правила) x - ›y, чтобы получить оптимальные значения W и b. Для наборов данных с менее 10 000 записей предпочтительно иметь разделение на 80–20 поездов и тестов, т.е. только 80% данных используется для обучения модели, а остальные 20% используются для оценки ее производительности. Кроме того, мы также можем использовать набор для разработки для настройки параметров модели, но проблема, которую мы решим позже в этом посте, - это небольшой набор данных, поэтому мы не будем использовать набор разработчиков на данный момент.

Как происходит обучение?

Для хорошей модели линейной регрессии мы хотим, чтобы значения W и b были оптимальными, то есть они учатся на входных данных и получают такие значения, чтобы они могли обобщить результаты на новые данные. Итак, главный вопрос, который возникает, - как получить оптимальные значения этих параметров. Для этого давайте посмотрим на функцию стоимости.

Функция стоимости для линейной регрессии

Обозначим прогнозируемые значения модели линейной регрессии через y_hat. Основная идея функции стоимости состоит в том, чтобы получить такие W и b, чтобы y_hat было близко к y для наших обучающих примеров, представленных парами (x, y). Другими словами, мы собираемся решить задачу минимизации W и b, и наша функция стоимости позволит нам это сделать. Обозначим нашу функцию стоимости буквой J. Функция стоимости поможет нам выбрать оптимальные значения W и b. Существует множество функций затрат, но та, которую мы будем использовать для линейной регрессии, очень интуитивно понятна.

Изображение выше является примером линейной регрессии (с одной переменной, например, y = Wx + b) в действии, где синие точки - это обучающие примеры, а красная линия - результат модели линейной регрессии. Эта линия проходит примерно между всеми синими точками. Другими словами, эта линия имеет минимальное общее расстояние от всех возможных линий, существующих в этой двумерной плоскости, что приводит нас к использованию «евклидова расстояния» в качестве функции потерь. Для примера обучения (x_i, y_i) и соответствующего прогноза (x_i, y_hat _i) евклидово расстояние определяется как:

L = (y_hat_i - y_i) ²

Обратите внимание, что мы удалили квадратный корень без потери общности. Теперь нам нужно найти значения W и b, которые минимизируют эту функцию потерь. Здесь мы воспользуемся производными финансовыми инструментами.

Учитывая, что у нас есть m обучающих примеров, функция стоимости определяется как:

J = sum_over_all_training_examples ((y_hat_i - y_i) ²)

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

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

Градиентный спуск

Градиентный спуск - это термин, который не требует пояснений, и весь алгоритм заключается в значении этого термина. Градиент - это просто еще одно название наклона / производной, о котором мы говорили ранее, а спуск означает просто падение / падение. Итак, задача градиентного спуска состоит в том, чтобы взять начальную точку на кривой функции затрат и просто отбрасывать ее на каждом шаге, пока она не достигнет минимумов, и сообщать об оптимальных значениях параметров (здесь W и b). Давайте определим переменные «delta_W» и «delta_b», которые помогут нам завершить алгоритм при сходимости. Если изменение между двумя последовательными обновлениями W меньше, чем «delta_W», а изменение b равно «delta_b», мы можем завершить алгоритм градиентного спуска. Псевдокод для градиентного спуска выглядит следующим образом:

temp_W = temp_b = random_values
flag_W = flag_b = False
do
if ((abs(W — temp_W) > delta_W) and flag_W = False)
    temp_W = W — alpha * partial_derivate_wrt_W(J)
if ((abs(b — temp_b) > delta_b) and flag_b = False)
    temp_b = b — alpha * partial_derivative_wrt_b(J)
if(temp_W == W)
    flag_W = True
if(temp_b == b)
    flag_b = True
W = temp_W
b = temp_bwhile True

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

Формулу частных производных для функции стоимости (здесь Евклидово расстояние) можно найти здесь.

На этом мы подошли к концу этого раздела, где обсуждали линейную регрессию с 1 переменной (x). В случае более чем одной переменной наше уравнение линии слегка модифицируется следующим образом;

Y = W1x1 + W2x2 + W3x3 + ……… + Wnxn + b ………. (1)

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

J = sum_over_all_training_examples ((y_hat_i - y_i) ²)

Здесь мы поместим y_hat_i как уравнение (1) и y_i как исходное значение для обучающего примера i.

В алгоритме градиентного спуска мы вычислим частные производные функции стоимости для всех параметров (W1, W2,…. Wn, b), а затем обновим эти параметры до сходимости.

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

Постановка задачи

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

Y = W1x1 + W2x2 + W3x3 + W4x4 + W5x5 + W6x6 + W7x7 + W8x8 + b

Давайте посмотрим, как пакеты Python помогают нам в решении этой проблемы линейной регрессии.

import numpy as np
import pandas as pd
from sklearn import datasets, linear_model
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

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

df = pd.read_csv(‘/kaggle/input/graduate-admissions/Admission_Predict_Ver1.1.csv’)
df.head()

Мы читаем входной CSV-файл через pandas и отображаем первые 5 строк, чтобы изучить свойства данных. Здесь все значения либо целые, либо числа с плавающей запятой. Если бы у нас были строки или другие типы данных, нам пришлось бы проанализировать их и преобразовать в числовую форму, чтобы скормить их нашей модели линейной регрессии. В данных 500 записей, что довольно мало.

X = df.iloc[:, 1:-1].values
y = df.iloc[:, -1].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.15)

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

regressor = linear_model.LinearRegression()
regressor.fit(X_train, y_train)
y_pred = regressor.predict(X_test)

Теперь мы инициализируем объект LinearRegression из библиотеки scikit-learn и передаем ему наши обучающие данные для алгоритма линейной регрессии, чтобы он соответствовал наилучшей возможной строке для него. По умолчанию для обучения модели используется функция оценки mean_squared_error, поэтому нам не нужно явно упоминать ее здесь.

Давайте возьмем добычу для первых 5 прогнозируемых выходных значений.

print(y_pred[:5])

В заключение давайте посмотрим на параметры веса и оценку r².

print(‘Coefficients: \n’, regressor.coef_)
print(‘R2 Score: %.2f’ % r2_score(y_test, y_pred))

Оценка r² 0,83 говорит нам, что мы делаем прогнозы с достоверностью 83%, и является метрикой, используемой для оценки проблем регрессии. Подробнее о r² score можно прочитать здесь. Это хорошие результаты для небольшого набора данных, подобного этому. Мы можем применить методы выбора признаков, которые могут сделать нашу модель более точной. Но поскольку это очень маленький набор данных, это может привести к чрезмерной подгонке. Мы обсудим эти проблемы и методы в следующих статьях.

Код этого поста можно найти здесь.

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