Почему я получаю отрицательную функцию затрат для логистической регрессии с использованием градиентного спуска в python?

#python #pandas #numpy #logistic-regression #gradient-descent

#python #pandas #numpy #логистическая регрессия #градиентный спуск

Вопрос:

Я пытаюсь применить то, что я узнал из курса Coursera Эндрю Нга. Я успешно реализовал этот же алгоритм так же, как я делаю это здесь, в наборе данных Kaggle Titanic, но теперь с этими данными (бои UFC) Я получаю отрицательную стоимость. Я сократил набор данных только до двух функций (противник и раунд, в котором закончился бой), затем взял их zscore.

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

 array([[ 1.        , -0.50373455, -0.35651205],
   [ 1.        , -1.54975476,  0.84266484],
   [ 1.        ,  0.63737841, -1.55568894],
   [ 1.        ,  1.11284214,  0.84266484],
   [ 1.        , -1.07429103,  0.84266484],
   [ 1.        , -1.07429103, -1.55568894],
   [ 1.        ,  0.25700742,  0.84266484],
   [ 1.        , -1.83503301, -0.35651205],
   [ 1.        ,  1.20793489, -0.35651205],
   [ 1.        ,  1.58830588, -1.55568894],
   [ 1.        , -1.16938378,  0.84266484],
   [ 1.        , -0.78901279, -0.35651205],
   [ 1.        , -0.50373455, -1.55568894],
   [ 1.        ,  1.0177494 , -0.35651205],
   [ 1.        , -0.21845631,  0.84266484],
   [ 1.        ,  0.92265665, -1.55568894],
   [ 1.        ,  0.06682193,  0.84266484],
   [ 1.        ,  1.30302764, -0.35651205],
   [ 1.        ,  0.44719292, -0.35651205],
   [ 1.        , -0.69392004,  0.84266484],
   [ 1.        ,  1.39812038, -1.55568894],
   [ 1.        , -0.97919828,  0.84266484],
   [ 1.        ,  0.16191468,  0.84266484],
   [ 1.        , -1.54975476,  0.84266484],
   [ 1.        , -0.02827082,  0.84266484],
   [ 1.        ,  0.63737841, -0.35651205],
   [ 1.        , -0.88410554,  0.84266484],
   [ 1.        ,  0.06682193,  0.84266484],
   [ 1.        , -1.73994026,  0.84266484],
   [ 1.        , -0.12336356,  0.84266484],
   [ 1.        , -0.97919828,  0.84266484],
   [ 1.        ,  0.8275639 , -1.55568894],
   [ 1.        ,  0.73247116,  0.84266484],
   [ 1.        ,  1.68339863, -1.55568894],
   [ 1.        ,  0.35210017, -1.55568894],
   [ 1.        , -0.02827082,  0.84266484],
   [ 1.        ,  1.30302764,  0.84266484]])
 

Мой вектор весов инициализируется всеми нулями:

 array([[0.],
   [0.],
   [0.]])
 

Для полноты картины, вот вектор Y:

 array([[0],
       [0],
       [1],
       [1],
       [0],
       [0],
       [1],
       [0],
       [0],
       [1],
       [0],
       [0],
       [1],
       [0],
       [1],
       [0],
       [1],
       [0],
       [1],
       [1],
       [0],
       [1],
       [1],
       [0],
       [0],
       [1],
       [1],
       [1],
       [1],
       [0],
       [0],
       [1],
       [1],
       [1],
       [1],
       [0],
       [1]], dtype=uint8)
 

Это моя функция затрат и функции сигмоида / прогнозирования:

 def cost_function(X, Y, theta):
    m = len(Y)
    h = predict(X,theta)
    cost = (np.dot((-Y.T), np.log(h)) - np.dot((1-Y).T, np.log(1-h))) / m
    return cost

def sigmoid(z):
    return 1/(1 np.e**(-z))

def predict(X, theta):
    z = np.dot(X, theta)
    return sigmoid(z)
 

Вот функция градиентного спуска:

 def gradient_descent(X, Y, theta, rate):
    m = len(Y)
    h = predict(X, theta)

    gradient = rate * np.dot(X.T, (h-Y)) / m
    theta -= gradient
    return theta
 

Затем я использую эту train функцию для вызова обеих в течение n итераций.

 def train(X, Y, theta, rate, iters):
    cost_history = []

    for i in range(iters):
        theta = gradient_descent(X, Y, theta, rate)

        cost = cost_function(X, Y, theta)
        cost_history.append(cost)

        if i % 100 == 0:
            print("iter: "   str(i)   " cost: "   str(cost))
    return theta, cost_history
 

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

Это то, что мне трудно понять. Почему оно отрицательное? Это проблема с кодом или данными, или это то, как это должно работать, и я что-то упускаю? Я пытался в течение последнего дня разобраться в этом, но ничего не добился. Только с этими функциями он по-прежнему правильно предсказывает исход битвы примерно в 54% случаев в тестовом наборе, используя веса после того, как он был обучен с использованием вышеуказанных функций, но стоимость отрицательна.

Ответ №1:

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

Итак Y , вектор dtype есть uint8 , и это, по-видимому, вызывает проблемы где-то в будущем. Изменив его на int64 исправил все. Извините, я не знаю, почему это вызывает проблему, но если я узнаю, я отредактирую это в своем ответе.