我试图实现Logistic回归算法,部分Matlab代码如下。
for i = 1 : MAX_ITR
% Calculate mu
mu = 1.0 ./ (1.0 + exp(-(X * w)));
% Calculate h to check for convergence
h(i) = sum(-y .* log(mu) - (1 - y) .* log(1 - mu)) + (lambda / 2) * norm(w([2:end]))^2;
% Calculate gradient and hessian.
G = lambda .* w;
G(1) = 0; % Set extra term for gradient to 0
L = lambda .* eye(D + 1);
L(1) = 0; % Set extra term for Hessian to 0
grad = (X' * (mu - y)) + G;
S = diag((mu .* (1 - mu)));
H = (X' * S * X) + L;
% Update w
w = w - H\grad;
end
显然mu
的值不能为1,因为指数不能为0.但是,有一些值,其中指数的计算值非常小,例如1.6629e-05
。这导致该实例的mu
值非常接近1,即0.999983371689452。
我通过迭代运行代码迭代,前4次迭代很好,因为mu
不包含任何此类"接近1"值。但是,第五次迭代确实如此,因此,我得到NaN
的{{1}},算法不会收敛。
我已运行h
命令,其值为32,因此我不知道导致此问题的原因。
ETA :
在@ rayryeng的建议之后更新了代码:
digits
是D
中的功能数量,X
是培训样本的数量m
X
我不再感到 for i = 1 : MAX_ITR
% Initialize arrays
grad = zeros(D+1,1);
h(i) = 0;
H = zeros(D+1,D+1);
for j = 1 : m
% Calculate mu
mu = sigmoid(X(j,:) * w);
% Calculate h (to check for convergence)
h(i) = h(i) - (1/m)*(y(j) * log(mu) + (1 - y(j)) * log(1 - mu)) + (lambda / (2 * m)) * norm(w(2:end))^2;
% Calculate gradient and Hessian
G = lambda * w;
G(1) = 0; % Set extra term for gradient to 0
L = lambda * eye(numFeatures + 1);
L(1) = 0; % Set extra term for Hessian to 0
grad = grad - (1/m) * ((X(j,:)' * (mu - y(j))) + G);
S = diag((mu .* (1 - mu)));
H = H - (1/m) * ((X(j,:)' * S * X(j,:)) + L);
end
%fprintf('h(%d) = %0.5f\n', i, h(i));
% Update w
w = w - H\grad;
end
错误,并且NaN
值似乎在几次迭代后收敛。
答案 0 :(得分:1)
在我的实施中,
X
是输入数据m x n
(1
的列已添加到
初始数据X = [ones(m, 1) X];
)
y
是输出数据。
sigmoid函数定义如下:
function g = sigmoid(z)
g = 1./(1+exp(-z));
end
成本函数定义如下:
function [J, grad] = costFunction(theta, X, y)
m = length(y);
J = (1/m)*sum(-y .* log(sigmoid(X*theta)) - (1-y) .* log(1-sigmoid(X*theta)));
grad = (X'*(sigmoid(X*theta)-y))/m;
end
在主代码中,我使用fminunc
函数来找到最佳theta。
options = optimset('GradObj', 'on', 'MaxIter', 400);
[theta, cost] = fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);
最后它与您的实现不同,但找到问题的解决方案可能会有用。