Я написал небольшой скрипт, который выполняет полиномиальный градиент спуска, и я пытаюсь уменьшить размер кода, даже если это ухудшает читабельность.Этот фрагмент кода отлично работает для подгонки кривой к паре точек данных:
import numpy as np
import matplotlib.pyplot as plt
def descent(x, y, epochs, step, order):
ones = np.vstack(np.ones(len(x)))
x = np.vstack(x)
x2 = np.vstack(x ** 2)
features = np.concatenate((ones,x,x2), axis = 1)
print(features)
weights = np.zeros(order + 1)
for i in range(epochs):
est = 0
for i in range(order + 1):
est += weights[i] * x ** i
difference = est.T - y
weights = weights + (-step * (1/len(y)) * np.matmul(difference, features)[0])
cost = 0
for i in range(len(y)-1):
cost += ((y - (weights[i] * x ** i)) ** 2)
cost = ((1/(2*(len(y)))) * np.sum(cost ** 2))
plt.scatter(x,y)
u = np.linspace(0,3,100)
plt.plot(u, (u ** 2) * weights[2] + u * weights[1] + weights[0], 'r-')
plt.show()
descent(np.asarray([0,1,2,3]), np.asarray([1,2,0,3]), 5000, 0.05, 2)
И вот как выглядит кривая: Теперь я хочу создать своюПо-разному отображать матрицу-пустышку, так что я также могу построить многочлены более высокого порядка.Следовательно, в этом сценарии я просто изменил способ создания своей матрицы:
import numpy as np
import matplotlib.pyplot as plt
def descent(x, y, epochs, step, order):
features = np.vstack(np.ones(len(x)))
for i in range(1, order + 1):
features = np.concatenate((np.vstack(features), np.vstack(np.power(x,i))), axis = 1)
print(features)
weights = np.zeros(order + 1)
for i in range(epochs):
est = 0
for i in range(order + 1):
est += weights[i] * x ** i
difference = est.T - y
weights = weights + (-step * (1/len(y)) * np.matmul(difference, features)[0])
cost = 0
for i in range(len(y)-1):
cost += ((y - (weights[i] * x ** i)) ** 2)
cost = ((1/(2*(len(y)))) * np.sum(cost ** 2))
plt.scatter(x,y)
u = np.linspace(0,3,100)
plt.plot(u, (u ** 2) * weights[2] + u * weights[1] + weights[0], 'r-')
plt.show()
descent(np.asarray([0,1,2,3]), np.asarray([1,2,0,3]), 5000, 0.05, 2)
Но я получаю странную кривую, которая выглядит следующим образом: Даже если мойФункциональные матрицы идентичны в обоих случаях.Кроме того, я заметил, что мой массив весов сходится к разным значениям в двух сценариях.
Что я делаю неправильно, создавая матрицу numpy?
РЕДАКТИРОВАТЬ: преступник был этой строки:
np.matmul(difference, features)[0]
Для первого случая это будет работать правильно и получить массив из трех элементов, но во втором примере это будет тольковернуть единственное значение, в результате чего мой массив весов будет иметь 3 раза одинаковое значение.Я до сих пор не понимаю, почему есть разница.