www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Построение логистической регрессии в Python

Дата публикации Oct 16, 2018

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

Заметка:Я предлагаю вам прочитатьЛинейная регрессияпрежде чем идти вперед с этим блогом.

Оглавление

  • Что такое логистическая регрессия?
  • Визуализация набора данных
  • Гипотеза и функция стоимости
  • Обучение модели с нуля
  • Оценка модели
  • Scikit-Learn реализация

Что такое логистическая регрессия?

Если вы вызываете линейную регрессию, она используется для определения значения непрерывной зависимой переменной. Логистическая регрессия обычно используется для целей классификации. В отличие от линейной регрессии, зависимая переменная может принимать ограниченное количество значений только, т. Е. Зависимая переменнаякатегорический, Когда число возможных результатов только два, это называетсяБинарная логистическая регрессия,

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

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

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

Из рисунка ниже видно, что результат линейной регрессии проходит черезактивацияфункция, которая может отображать любое реальное значение между 0 и 1.

Используемая функция активации известна каксигмоидфункция. График сигмовидной функции выглядит так

сигмовидная функция

Мы можем видеть, что значение сигмоидной функции всегда лежит между 0 и 1. Значение точно равно 0,5 при X = 0. Мы можем использовать 0,5 в качестве порога вероятности для определения классов. Если вероятность больше 0,5, мы классифицируем ее какКласс-1 (Y = 1)или какКласс-0 (Y = 0),

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

  • Зависимая переменная должна быть категориальной
  • Независимые переменные (признаки) должны быть независимыми (чтобы избежать мультиколлинеарности).

Dataset

Данные, использованные в этом блоге, были взяты из работы Эндрю НгМашинное обучениеКонечно на Coursera. Данные можно скачать сВот, Данные состоят из оценок двух экзаменов для 100 претендентов. Целевое значение принимает двоичные значения 1,0. 1 означает, что заявитель был принят в университет, а 0 означает, что заявитель не получил зачисление. Цель состоит в том, чтобы создать классификатор, который может предсказать, будет ли заявка принята в университет или нет.

Давайте загрузим данные вpandasФрейм данных с использованиемread_csvфункция. Мы также разделим данные наadmittedа такжеnon-admittedвизуализировать данные.

Теперь, когда у нас есть четкое понимание проблемы и данных, давайте продолжим и построим нашу модель.

Гипотеза и функция стоимости

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

Модель линейной регрессии может быть представлена ​​уравнением.

Затем мы применяем сигмоидную функцию к выходу линейной регрессии

где сигмовидная функция представлена

Тогда гипотеза для логистической регрессии становится

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

Функция стоимости

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

Функция стоимости для одного примера обучения может быть задана как:

Интуиция функции стоимости

Если фактический класс равен 1, а модель предсказывает 0, мы должны строго оштрафовать его и наоборот. Как видно из рисунка ниже, для сюжета-log(h(x))когда h (x) приближается к 1, стоимость равна 0, а когда h (x) приближается к 0, стоимость равна бесконечности (то есть мы сильно наказываем модель). Аналогично для сюжета-log(1-h(x))когда фактическое значение равно 0, а модель прогнозирует 0, стоимость равна 0, а стоимость становится бесконечной, когда h (x) приближается к 1.

Мы можем объединить оба уравнения, используя:

Стоимость всех обучающих примеров обозначенаJ (θ)можно рассчитать, взяв среднее по стоимости всех обучающих образцов

гдемколичество обучающих образцов

Мы будем использовать градиентный спуск, чтобы минимизировать функцию стоимости. Градиент w.r.t любого параметра может быть задан

Уравнение аналогично тому, что мы достигли в линейной регрессии, только h (x) отличается в обоих случаях.

Обучение модели

Теперь у нас есть все, что нужно для построения нашей модели. Давайте реализуем это в коде.

Давайте сначала подготовим данные для нашей модели.

X = np.c_[np.ones((X.shape[0], 1)), X]
y = y[:, np.newaxis]
theta = np.zeros((X.shape[1], 1))

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

def sigmoid(x):
# Activation function used to map any real value between 0 and 1
return 1 / (1 + np.exp(-x))

def net_input(theta, x):
# Computes the weighted sum of inputs
return np.dot(x, theta)

def probability(theta, x):
# Returns the probability after passing through sigmoid
return sigmoid(net_input(theta, x))

Далее мы определяемcostиgradientфункция.

def cost_function(self, theta, x, y):
# Computes the cost function for all the training samples
m = x.shape[0]
total_cost = -(1 / m) * np.sum(
y * np.log(probability(theta, x)) + (1 - y) * np.log(
1 - probability(theta, x)))
return total_cost

def gradient(self, theta, x, y):
# Computes the gradient of the cost function at the point theta
m = x.shape[0]
return (1 / m) * np.dot(x.T, sigmoid(net_input(theta, x)) - y)

Давайте также определимfitфункция, которая будет использоваться для поиска параметров модели, которая минимизирует функцию стоимости. ВэтоВ блоге мы кодировали подход градиентного спуска для вычисления параметров модели. Здесь мы будем использоватьfmin_tncфункция отscipyбиблиотека. Он может быть использован для вычисления минимума для любой функции. Принимает аргументы как

  • func: функция для минимизации
  • x0: начальные значения параметров, которые мы хотим найти
  • fprime: градиент для функции, определенной как «func»
  • args: аргументы, которые необходимо передать функциям.
def fit(self, x, y, theta):
opt_weights = fmin_tnc(func=cost_function, x0=theta,
fprime=gradient,args=(x, y.flatten()))
return opt_weights[0]parameters = fit(X, y, theta)

Параметры модели[-25.16131856 0.20623159 0.20147149]

Чтобы увидеть, насколько хорошо работает наша модель, мы нарисуем границу решения.

Построение границы решения

Поскольку в нашем наборе данных есть две особенности, линейное уравнение может быть представлено как

Как обсуждалось ранее, граница решения может быть найдена путем установки взвешенной суммы входных данных равной 0. Приравнивание h (x) к 0 дает нам,

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

x_values = [np.min(X[:, 1] - 5), np.max(X[:, 2] + 5)]
y_values = - (parameters[0] + np.dot(parameters[1], x_values)) / parameters[2]

plt.plot(x_values, y_values, label='Decision Boundary')
plt.xlabel('Marks in 1st Exam')
plt.ylabel('Marks in 2nd Exam')
plt.legend()
plt.show()

Похоже, наша модель проделала приличную работу по прогнозированию классов. Но насколько это точно? Давайте разберемся.

Точность модели

def predict(self, x):
theta = parameters[:, np.newaxis]
return probability(theta, x)def accuracy(self, x, actual_classes, probab_threshold=0.5):
predicted_classes = (predict(x) >=
probab_threshold).astype(int)
predicted_classes = predicted_classes.flatten()
accuracy = np.mean(predicted_classes == actual_classes)
return accuracy * 100accuracy(X, y.flatten())

Точность модели составляет 89%.

Давайте реализуем наш классификатор с помощью scikit-learn и сравним его с моделью, которую мы создали с нуля.

научная реализация

from sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score model = LogisticRegression()
model.fit(X, y)
predicted_classes = model.predict(X)
accuracy = accuracy_score(y.flatten(),predicted_classes)
parameters = model.coef_

Параметры модели[[-2.85831439, 0.05214733, 0.04531467]]и точность составляет 91%.

Почему параметры модели существенно отличаются от модели, которую мы реализовали с нуля?Если вы посмотрите надокументацияВ реализации логистической регрессии sk-Learn она учитывает регуляризацию. По сути, регуляризация используется для предотвращения перегрузки модели данными. Я не буду вдаваться в подробности регуляризации в этом блоге. Но пока это все. Спасибо за чтение !!

Полный код, используемый в этом блоге, можно найти в этом GitHubСделки рЕПО,

Пожалуйста, напишите мне сообщение, если вы застряли в любом месте или если у вас есть какие-либо отзывы.

Что дальше?

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

Посмотрите это место для большего.

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map