我想在Python中实现Coordinate Descent,并将结果与Gradient Descent进行比较。我写了代码。但是它不能很好地工作。 GD可能还可以,但是CD不好。
这是对坐标下降的引用。 --- LINK
我期望这个结果 Gradient Descent vs Coordinate Descent
HttpHeaders headers = new HttpHeaders();
headers.setContentDisposition(ContentDisposition.builder("inline; filename=\"" + resource.getFilename() + "\"").build());
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setContentLength(resource.contentLength());
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
谢谢。
答案 0 :(得分:0)
我不是优化专家。这只是一些建议。
您的代码对我来说看起来很不错
1。以下两行似乎不正确
loss = h - y
param[i] = np.dot(X[:,i].T, (y - dele))/np.sum(np.square(X[:,i]))
您用(n_samples, 1)
将y重塑为z = z.reshape(-1, 1)
,而h
和dele
的形状为(n_samples,)
。这将产生一个(n_samples, n_samples)
矩阵,我认为这不是您想要的。
2。您的数据可能无法满足测试目的。这并不意味着它不起作用,但是您可能需要一些提取工作来调整学习率/迭代次数。
我在波士顿数据集上尝试了您的代码,输出看起来像这样。
代码
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScaler
# boston house-prices dataset
data = load_boston()
X, y = data.data, data.target
X = StandardScaler().fit_transform(X) # for easy convergence
X = np.hstack([X, np.ones((X.shape[0], 1))])
param = np.zeros(X.shape[1])
def gradient_descent(X, y, param, eta=0.01, iter=300):
cost_history = [0] * (iter+1)
cost_history[0] = costf(X, y, param) # you may want to save initial cost
for iteration in range(iter):
h = X.dot(param)
loss = h - y.ravel()
gradient = X.T.dot(loss)/(2 * len(y))
param = param - eta * gradient
cost = costf(X, y, param)
#print(cost)
cost_history[iteration+1] = cost
return param, cost_history
def coordinate_descent(X, y, param, iter=300):
cost_history = [0] * (iter+1)
cost_history[0] = costf(X, y, param)
for iteration in range(iter):
for i in range(len(param)):
dele = np.dot(np.delete(X, i, axis=1), np.delete(param, i, axis=0))
param[i] = np.dot(X[:,i].T, (y.ravel() - dele))/np.sum(np.square(X[:,i]))
cost = costf(X, y, param)
cost_history[iteration+1] = cost
return param, cost_history
ret, xret = gradient_descent(X, y, param)
cret, cxret = coordinate_descent(X, y, param.copy())
plt.plot(range(len(xret)), xret, label="GD")
plt.plot(range(len(cxret)), cxret, label="CD")
plt.legend()
如果这是您想要的,则可以尝试对其他一些数据进行测试。请注意,即使实现正确,也仍然需要调整超参数以获得良好的收敛性。