Одномерная линейная регрессия с выводом NaN

В настоящее время я пишу реализацию одномерной линейной регрессии на Python:

# implementation of univariate linear regression
import numpy as np


def cost_function(hypothesis, y, m):
  return (1 / (2 * m)) * ((hypothesis - y) ** 2).sum()


def hypothesis(X, theta):
  return X.dot(theta)


def gradient_descent(X, y, theta, m, alpha):
  for i in range(1500):
    temp1 = theta[0][0] - alpha * (1 / m) * (hypothesis(X, theta) - y).sum()
    temp2 = theta[1][0] - alpha * (1 / m) * ((hypothesis(X, theta) - y) * X[:, 1]).sum()
    theta[0][0] = temp1
    theta[1][0] = temp2

  return theta

if __name__ == '__main__':
  data = np.loadtxt('data.txt', delimiter=',')

  y = data[:, 1]
  m = y.size
  X = np.ones(shape=(m, 2))
  X[:, 1] = data[:, 0]
  theta = np.zeros(shape=(2, 1))
  alpha = 0.01

  print(gradient_descent(X, y, theta, m, alpha))

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

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

Может кто-то указать мне верное направление?

1 ответ

Решение

Проблема, которую вы видите в том, что когда вы делаете X[:,1] или же data[:,1]Вы получаете объекты формы (м,). Когда вы умножаете объект формы (m,) на матрицу формы (m,1), вы получаете матрицу размера (m, m)

a = np.array([1,2,3])
b = np.array([[4],[5],[6]])
(a*b).shape #prints (3,3)

Если вы делаете y=y.reshape((m,1)) в вашем if __name__ блок и внутри вашей градиентной функции вы делаете

X_1 = X[:,1].reshape((m,1))

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

((hypothesis(X, theta) - y) * X[:, 1])

Вы получаете матрицу 100 на 100, а это не то, что вам нужно.

Полный код, который я использовал для тестирования:

# implementation of univariate linear regression
import numpy as np


def cost_function(hypothesis, y, m):
  return (1 / (2 * m)) * ((hypothesis - y) ** 2).sum()


def hypothesis(X, theta):
  return X.dot(theta)


def gradient_descent(X, y, theta, m, alpha):
  X_1 = X[:,1]
  X_1 = X_1.reshape((m,1))
  for i in range(1500):
    temp1 = theta[0][0] - alpha * (1 / m) * (hypothesis(X, theta) - y).sum()
    temp2 = theta[1][0] - alpha * (1 / m) * ((hypothesis(X, theta) - y) * X_1).sum()
    theta[0][0] = temp1
    theta[1][0] = temp2

  return theta

if __name__ == '__main__':
  data= np.random.normal(size=(100,2))

  y = 30*data[:,0] + data[:, 1]
  m = y.size
  X = np.ones(shape=(m, 2))
  y = y.reshape((m,1))
  X[:, 1] = data[:, 0]
  theta = np.zeros(shape=(2, 1))
  alpha = 0.01

  print(gradient_descent(X, y, theta, m, alpha))
Другие вопросы по тегам