Регуляризованный градиентный спуск Python для логистической регрессии

Я пытаюсь реализовать Gradient Descent (GD) (не стохастический) для логистической регрессии в Python 3x. И есть некоторые проблемы.

Логистическая регрессия определяется следующим образом (1): формула логистической регрессии

Формулы для градиентов определяются следующим образом (2): градиентный спуск для логистической регрессии

Описание данных:

  • X является (Nx2)-матрицей объектов (состоит из положительных и отрицательных чисел с плавающей точкой)
  • y является (Nx1)-вектором меток класса (-1 или +1)

Задача: реализовать градиентный спуск 1) с L2-регуляризацией; и 2) без регуляризации. Желаемые результаты: векторы весов. Параметры: норма регуляризации C=10 для регуляризованной регрессии и C=0 для нерегулярной регрессии; шаг градиента k= 0,1; максимальное число итераций = 10000; допуск =1е-5. Примечание: GD сходится, если расстояние между векторами весов от текущего и предыдущего шагов меньше допуска (1e-5).

Вот моя реализация:k - шаг градиента;С - нормализация уровня.

import numpy as np

def sigmoid(z):
    result = 1./(1. + np.exp(-z))
    return result

def distance(vector1, vector2):
    vector1 = np.array(vector1, dtype='f')    
    vector2 = np.array(vector2, dtype='f')
    return np.linalg.norm(vector1-vector2)

def GD(X, y, C, k=0.1, tolerance=1e-5, max_iter=10000):

    X = np.matrix(X)
    y = np.matrix(y)
    l=len(X)
    w1, w2 = 0., 0.  # weights (look formula (2) in the beginning of question)
    difference = 1.
    iteration = 1

    while(difference > tolerance):

        hypothesis = y*(X*np.matrix([w1, w2]).T)

        w1_updated = w1 + (k/l)*np.sum(y*X[:,0]*(1.-(sigmoid(hypothesis)))) - k*C*w1
        w2_updated = w2 + (k/l)*np.sum(y*X[:,1]*(1.-(sigmoid(hypothesis)))) - k*C*w2

        difference = distance([w1, w2], [w1_updated, w2_updated])
        w1, w2 = w1_updated, w2_updated
        if(iteration >= max_iter):
            break;

        iteration = iteration + 1

    return [w1_updated, w2_updated]  #vector of weights

Соответственно:

# call for UNregularized GD: C=0
w = GD(X, y, C=0., k=0.1) 

а также

# call for regularized GD: C=10
w_reg = GD(X, y, C=10., k=0.1)

Вот результаты (весовые векторы):

# UNregularized GD
[0.035736331265589463, 0.032464572442830832]

# regularized GD
[5.0979561973044096e-06, 4.6312243707352652e-06]

Тем не менее, это должно быть (правильные ответы для самоконтроля):

# UNregularized GD
[0.28801877, 0.09179177]

# regularized GD
[0.02855938, 0.02478083]

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

Заранее спасибо.

1 ответ

Прежде всего, сигмоидальные функции должны быть

def sigmoid(Z):
   A=1/(1+np.exp(-Z))
   return A

Попробуйте запустить его снова с этой формулой. Тогда что такое L?

Другие вопросы по тегам