lassogaussseidel.m

来自「lasso变量选择方法」· M 代码 · 共 114 行

M
114
字号
function [w,wp,iteration] = LassoGaussSeidel(X, y, gamma,varargin)% This function computes the Least Squares parameters% with a penalty on the L1-norm of the parameters%% Method used:%   The Gauss-Seidel method of [Shevade and Keerthi, 2003]%% Mode options:%   0 - Use bottom-up Method described in paper %       (start at 0 and introduce variables, faster if very sparse)%   1 - Use alternative top-down strategy %       (start at L2 and remove variables, faster if not very sparse)%% Modifications:%   The original paper derives the algorithm for Logistic Regression%   Here, we do the MUCH simpler Least Squares version%   Check out how much simpler the line minimizations are%   (1 closed form solution vs. 7 alternations to bracket a region before%   minimizing within the region)%%   Also, we precompute the Hessian values, since they do not change%   between iterations%%   Finally, we give the option to start at the Ridge Regression solution, %   since this seems to be a much more efficient strategy than introducing %   variables individually[maxIter,verbose,tau,threshold,mode] = process_options(varargin,'maxIter',10000,'verbose',2,'optTol',1e-5,'zeroThreshold',1e-4,'mode',0);[n p] = size(X);% initialize (set to L2 for top-down, set to 0 for bottom-up)if mode == 0    alpha = zeros(p,1);else    alpha = (X'*X + gamma*eye(p))\(X'*y);end% compute gradientXy = X'*y;XX = X'*X;g = XX*alpha-Xy;% compute violationviol = computeViol(p,alpha,threshold,gamma,g);% find the maximum violator nu in Iz[max_viol nu] = max(abs(viol));% start logif verbose==2    w_old = alpha;    fprintf('%10s %10s %15s %15s %15s %15s %5s\n','iter','line_mins','n(w)','n(step)','f(w)','max(viol)','free');    j=1;    wp = alpha;enditeration = 0;line_mins = 0;while max_viol > tau && line_mins < maxIter    while 1        line_mins = line_mins+1;        % optimize W wrt alpha(nu)        % compute slope        slope_nu = varSlope(alpha,nu,gamma/2,g,threshold);        alpha_original = alpha(nu);        % optimize alpha(nu)        % Here is the section that is much simpler for Least Squares!        % (changed from ~50 lines in the supplementary material for the paper to 4!)        alpha(nu) = alpha(nu) - slope_nu/XX(nu,nu);        if alpha_original ~= 0 && sign(alpha_original) ~= sign(alpha(nu))            alpha(nu)=0;        end        % find the maximum violator in the free set        g = XX*alpha-Xy;        viol = computeViol(p,alpha,threshold,gamma/2,g);        [max_viol nu] = max(viol.*(abs(alpha) >= threshold));        % stop if no violators in Inz        if max_viol < tau            break;        end    end    iteration = iteration+1;    % Update the log    if verbose==2        fprintf('%10d %10d %15.2e %15.2e %15.2e %15.2e %5d\n',iteration,line_mins,sum(abs(alpha)),sum(abs(alpha-w_old)),...            sum((X*alpha-y).^2)+gamma*sum(abs(alpha)),max(viol.*(abs(alpha) < threshold)),sum(abs(alpha) >= threshold));        w_old = alpha;        j=j+1;        wp(:,j) = alpha;    end    % find the maximum zero-valued violator    [max_viol nu] = max(viol.*(abs(alpha) < threshold));endif verbose && sum(viol <= tau*ones(p,1)) == p    fprintf('Solution Found\n');elseif verbose    fprintf('Solution Not Found\n');endif verbosefprintf('Number of iterations: %d\nNumber of line minimizations: %d\n',iteration,line_mins);endw = alpha;endfunction [slope_nu] = varSlope(alpha,nu,gamma,g,threshold,bias)% Computes the gradient for a single variableif alpha(nu) > 0 || ((abs(alpha(nu)) < threshold) && (gamma + g(nu) < 0))    slope_nu = gamma + g(nu);elseif alpha(nu) < 0 || ((abs(alpha(nu)) < threshold) && (-gamma + g(nu) > 0))    slope_nu = -gamma + g(nu);else    slope_nu = 0;endif nargin > 5 && bias == 1 && nu == 1    slope_nu = g(nu);endend

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?