axh>(i)(x), где i – номер класса. Другими словами, объект принадлежит к тому классу, функция гипотезы которого максимальна.

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



Интересно, что производная функции стоимости логистической регрессии ровно такая же, как и производная функции стоимости линейной регрессии (вывод см., например, в [[38]]). Следовательно, алгоритм градиентного спуска будет работать так же, как и для линейной регрессии (формула 1.5), с тем отличием, что значение функции гипотезы будет вычисляться по формуле 2.8.

Пример. Построим линейный классификатор на основе логистической регрессии. Вначале сгенерируем набор данных и разделим его на тренировочное и тестовое множества:


from sklearn.datasets import make_moons, make_circles, make_classification

from sklearn.model_selection import train_test_split

dataset = make_circles(noise=0.2, factor=0.5, random_state=1)

X_D2, y_D2 = dataset

plt.figure(figsize=(9,9))

plt.scatter(X_D2[:,0],X_D2[:,1],c=y_D2,marker='o',

      s=50,cmap=ListedColormap(['#FF0000','#00FF00']))

X_train, X_test, y_train, y_test = train_test_split(X_D2, y_D2, test_size=.4, random_state=42)


В результате получим распределение данных, показанное на рисунке 1.3.

Вызовем необходимые библиотеки и методы:


>import matplotlib.pyplot as plt

>import numpy as np

>from sklearn.metrics import confusion_matrix, classification_report

>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score


Последние две строки необходимы для оценки точности работы классификатора (см. раздел «Оценка качества методов ML»).

Разработаем логистическую функцию logisticFunction(X,theta) и функцию, обеспечивающую оценку объекта на основе предсказанного значения гипотезы, – logRegPredictMatrix(h,threshold). Как показано выше, функция гипотезы принимает значение от 0 до 1. Для того чтобы получить оценку принадлежности объекта к классу (1 – «положительный», 0 – «отрицательный»), необходимо для каждого значения гипотезы вычислить номер класса («предсказать») по правилу predicted = 0 If h = threshold. Обычное значение порога threshold=0.5.

Функция, вычисляющая значения коэффициентов логистической регрессии первого порядка:


>def logisticRegressionByNumpy(X,y):

>   m=y.size

>   X=np.concatenate((np.ones([m,1]),X), axis=1)

>   theta=np.array(np.random.rand(X.shape[1]))

>   h=logisticFunction(X,theta)

>   alpha=0.05

>   iterations=1500

>   lambda_reg=0.01

>   for i in range(iterations):

>   theta=theta – alpha*(1/m) *np.dot(X.T,(h-y))-(lambda_reg/m)*theta

>      h=logisticFunction(X,theta)

>   return theta,h


Вызов функции и вывод показателей качества можно выполнить:


>theta,h=logisticRegressionByNumpy(X_train,y_train)

>predicted_train=logRegPredictMatrix(h,threshold=0.50)

>matrix_train = confusion_matrix(y_train, predicted_train)#,labels)

>print('Logistic regression')

>print('Results on train set')

>print('Accuracy on train set: {:.2f}'.format(accuracy_score(y_train, predicted_train)))

>print('Conf. matrix on the train \n', matrix_train)

>print('Classification report at train set\n',

>    classification_report(y_train, predicted_train, target_names = ['not 1', '1']))


В результате получим на тренировочном множестве значение accuracy = 0.57, а на тестовом 0.4. Другими словами, точность предсказания нашей функции хуже, чем при случайном выборе классов! Подобный результат вполне предсказуем, поскольку мы попытались использовать прямую там, где требуется как минимум окружность.