数据包络分析工具箱 EDA 算法分析

数据包络分析工具箱是MATLAB的新包,包括计算效率和生产率测量的功能。该软件包涵盖了径向,定向,添加,分配,Malmquist和Malmquist-Luenberger配方。


dea

function [ out ] = dea( X, Y, varargin)
%DEA Data envelopment analysis radial and directional model
%   Computes data envelopment analysis radial and directional model
%
%   out = DEA(X, Y, Name, Value) computes data envelopment analysis model
%   with inputs X and outputs Y. Model properties are specified using 
%   one or more Name ,Value pair arguments.
%
%   Additional properties:
%   - 'orient': orientation. Input oriented 'io', output oriented 'oo', 
%   directional distane function 'ddf'.
%   - 'rts': returns to scale. Constant returns to scale 'crs', variable
%   returns to scale 'vrs'.
%   - 'Gx': input directions for 'ddf' orientation. Default is Xeval.
%   - 'Gy': output directions for 'ddf' orientation. Default is Yeval.
%   - 'names': DMU names.
%   - 'secondstep': 1 to compute input and output slacks. Default is 1.
%
%   Advanced parameters:
%   - 'Xeval: inputs to evaluate if different from X.
%   - 'Yeval': outputs to evaluate if different from Y.
%
%   Example
%     
%      io = dea(X, Y, 'orient', 'io');
%      oo_vrs = dea(X, Y, 'orient', 'oo', 'rts', 'vrs');
%      ddf = dea(X, Y, 'ddf', 'Gx', X, 'Gy', Y);
%
%   See also DEAOUT, DEASCALE, DEAMALM, DEAADDIT, DEASUPER
%
%   Copyright 2016 Inmaculada C. 脕lvarez, Javier Barbero, Jos茅 L. Zof铆o
%   http://www.deatoolbox.com
%
%   Version: 1.0
%   LAST UPDATE: 1, August, 2017
%

    % Check size
    if size(X,1) ~= size(Y,1)
        error('Number of rows in X must be equal to number of rows in Y')
    end    
    
    % Get number of DMUs (n), inputs (m) and outputs (s)
    [n, m] = size(X);
    s = size(Y,2);
    
    % Get DEA options
    options = getDEAoptions(n, varargin{:});
    
    % Orientation
    switch(options.orient)
        case {'io','input'}
            orient = 'io';
        case {'oo','output'}
            orient = 'oo';
        case {'ddf'}
            orient = 'ddf';
        case {'none'}
            error('Radial Model is Oriented');
    end       
    
    % RETURNS TO SCALE
    rts = options.rts;
    switch(rts)
        case 'crs'
            AeqRTS1 = [];
            beqRTS1 = [];
            
            AeqRTS2 = [];
            beqRTS2 = [];
        case 'vrs'
            AeqRTS1 = [ones(1,n), 0];
            beqRTS1 = 1;
            
            AeqRTS2 = [ones(1,n), zeros(1,m), zeros(1,s)];
            beqRTS2 = 1;
    end
    
    % If evaluate DMU at different X or Y
    if ~isempty(options.Xeval)
        Xeval = options.Xeval;
    else
        Xeval = X;
    end
    
    if ~isempty(options.Yeval)
        Yeval = options.Yeval;
    else
        Yeval = Y;
    end
    
    if size(Xeval,1) ~= size(Yeval,1)
        % Check size: rows
        error('Number of rows in Xeval and Yeval must be equal')
    end
    
    if size(Xeval,2) ~= size(X,2)
        % Check columns Xref
        error('Number of columns in Xeval and X must be equal')
    end
    
    if size(Yeval,2) ~= size(Y,2)
        % Check columns Yref
        error('Number of columns in Yeval and Y must be equal')
    end
    
    neval = size(Xeval,1);

    % OPTIMIZATION OPTIONS:
    optimopts = options.optimopts;
    
    % Create variables to store results
    lambda = nan(neval, n);
    slackX = nan(neval, m);
    slackY = nan(neval, s);
    eff = nan(neval, 1);
    Eflag = nan(neval, 2);
    Xeff = nan(neval, m);
    Yeff = nan(neval, s);
    dualineqlin = nan(neval, m + s);
    dualeqlin = nan(neval, 1);
    
    % OPTIMIZE: SOLVE LINEAR PROGRAMMING MODEL
    switch(orient)
        case 'io'
            
            % For each DMU
            for j=1:neval
                
                % FIRST STEP:
                % Objective function
                f = [zeros(1,n), 1];
                
                % Constraints
                A = [ X', -Xeval(j,:)';
                     -Y', zeros(s,1)];
                b = [zeros(m,1);
                    -Yeval(j,:)'];
                Aeq = AeqRTS1;
                beq = beqRTS1;
                lb = zeros(1, n + 1);
                                
                % Optimize
                [z, ~, exitflag, ~, dual] = linprog(f, A, b, Aeq, beq, lb, [], [], optimopts);
                if exitflag ~= 1
                    if options.warning
                        warning('DMU %i. First Step. Optimization exit flag: %i', j, exitflag)
                    end
                end
                if isempty(z)
                    if options.warning
                        warning('DMU %i. First Step. Optimization doesn''t return a result. Efficiency set to NaN.', j)
                    end
                    z = nan(n + 1, 1);  
                    dual.ineqlin = nan(1, m + s);
                    dual.eqlin = nan(1, 1);
                end
                
                % Get efficiency
                theta = z(end);
                Eflag(j, 1) = exitflag;
                eff(j) = theta;
                
                % Get dual results
                dualineqlin(j, :) = dual.ineqlin;
                if ~isempty(beqRTS1)
                    dualeqlin(j, 1) = dual.eqlin;
                else
                    dualeqlin(j, 1) = NaN;
                end                
                
                % SECOND STEP
                
                if(options.secondstep) && ~isnan(theta)
                
                    % Objective function
                    f = [zeros(1, n), -ones(1, m + s)];

                    % Constraints
                    Aeq = [ X', eye(m,m)  , zeros(m,s);
                            Y', zeros(s,m), -eye(s,s);
                           AeqRTS2];
                    beq = [theta .* Xeval(j,:)';
                            Yeval(j,:)';
                            beqRTS2];
                    lb = zeros(n + s + m, 1);

                    % Optimize
                    [z, ~, exitflag] = linprog(f, [], [], Aeq, beq, lb, [], [], optimopts);
                    if exitflag ~= 1
                        if options.warning
                            warning('DMU %i. Second Step. Optimization exit flag: %i', j, exitflag)
                        end
                    end
                    if isempty(z)
                        if options.warning
                            warning('DMU %i. Second Step. Optimization doesn''t return a result. Results set to NaN.', j)
                        end
                        z = nan(n + m + s, 1);                   
                    end

                    % Get results
                    lambda(j,:) = z(1:n);
                    slackX(j,:) = z(n + 1 : n + m);
                    slackY(j,:) = z(n + m + 1 : n + m + s);                
                    Eflag(j, 2) = exitflag;

                    % Compute efficient inputs and outputs
                    Xeff(j,:) = repmat(eff(j), 1, m) .* Xeval(j,:) - slackX(j,:);
                    Yeff(j,:) = Yeval(j,:) + slackY(j,:);

                end
                
            end
            
            % Compute efficient inputs and outputs
            % Xeff = repmat(eff, 1, m) .* Xeval - slackX;
            % Yeff = Yeval + slackY;

            
        case 'oo'
                        
            % For each DMU
            for j=1:neval
                
                % FIRST STEP:
                % Objective function (maximize)
                f = -[zeros(1,n), 1];
                
                % Constraints
                A = [ X', zeros(m,1);
                     -Y', Yeval(j,:)'];
                b = [Xeval(j,:)';
                     zeros(s,1)];
                Aeq = AeqRTS1;
                beq = beqRTS1;
                lb = zeros(1, n + 1);

                % Optimize
                [z, ~, exitflag, ~, dual] = linprog(f, A, b, Aeq, beq, lb, [], [], optimopts);
                if exitflag ~= 1
                    if options.warning
                        warning('DMU %i. First Step. Optimization exit flag: %i', j, exitflag)
                    end
                end
                if isempty(z)
                    if options.warning
                        warning('DMU %i. First Step. Optimization doesn''t return a result. Efficiency set to NaN.', j)
                    end
                    z = nan(n + 1, 1);  
                    dual.ineqlin = nan(1, m + s);
                    dual.eqlin = nan(1, 1);
                end
                
                % Get efficiency
                phi = z(end);
                eff(j) = phi;
                Eflag(j, 1) = exitflag;
                
                % Get dual results
                dualineqlin(j, :) = dual.ineqlin;
                if ~isempty(beqRTS1)
                    dualeqlin(j, 1) = dual.eqlin;
                else
                    dualeqlin(j, 1) = NaN;
                end    
                
                % SECOND STEP
                
                if(options.secondstep)  && ~isnan(phi)
                                 
                    % Objective function
                    f = -[zeros(1, n), ones(1, m + s)];

                    % Constraints
                    Aeq = [ X', eye(m,m)  ,  zeros(m,s),  ;
                            Y', zeros(s,m), -eye(s,s)  ;                       
                           AeqRTS2];
                    beq = [Xeval(j,:)'
                           phi .* Yeval(j,:)';
                           beqRTS2];
                    lb = zeros(n + s + m, 1);

                    % Optimize
                    [z, ~, exitflag] = linprog(f, [], [], Aeq, beq, lb, [], [], optimopts);
                    if exitflag ~= 1
                        if options.warning
                            warning('DMU %i. Second Step. Optimization exit flag: %i', j, exitflag)
                        end
                    end
                    if isempty(z)
                        if options.warning
                            warning('DMU %i. Second Step. Optimization doesn''t return a result. Results set to NaN.', j)
                        end
                        z = nan(n + m + s, 1);                   
                    end

                    % Get results
                    lambda(j,:) = z(1:n);
                    slackX(j,:) = z(n + 1 : n + m);
                    slackY(j,:) = z(n + m + 1 : n + m + s);                
                    Eflag(j, 2) = exitflag;

                    % Compute efficient inputs and outputs
                    Xeff(j,:) = Xeval(j,:) - slackX(j,:);
                    Yeff(j,:) = repmat(eff(j), 1, s) .* Yeval(j,:) + slackY(j,:);

                end
                    
            end
            
            % Compute efficient inputs and outputs
            % Xeff = Xeval - slackX;
            % Yeff = repmat(eff, 1, s) .* Yeval + slackY;

            
        case 'ddf'
                        
            % Get directions
            Gx = options.Gx;
            Gy = options.Gy;
                        
            if length(Gx) == 1
                Gx = repmat(Gx, size(X,1), size(X,2));
            elseif size(Gx, 1) == 1
                Gx = repmat(Gx, size(X,1), 1);
            end
            
            if length(Gy) == 1
                Gy = repmat(Gy, size(Y,1), size(Y,2));
            elseif size(Gy, 1) == 1
                Gy = repmat(Gy, size(Y,1), 1);
            end
            
            if isempty(Gx)
                Gx = Xeval;
            end
            
            if isempty(Gy)
                Gy = Yeval;
            end
                        
            % For each DMU
            for j=1:neval
                
                % FIRST STEP:
                % Objective function (maximize)
                f = -[zeros(1,n), 1];
                
                % Constraints
                A = [ X', Gx(j,:)';
                     -Y', Gy(j,:)'];
                b = [ Xeval(j,:)';
                     -Yeval(j,:)'];
                Aeq = AeqRTS1;
                beq = beqRTS1;
                %lb = zeros(1, n + 1);
                lb = [zeros(1, n), -inf];
                
                % Optimize
                [z, ~, exitflag, ~, dual] = linprog(f, A, b, Aeq, beq, lb, [], [], optimopts);
                if exitflag ~= 1
                    if options.warning
                        warning('DMU %i. First Step. Optimization exit flag: %i', j, exitflag)
                    end
                end
                if isempty(z)
                    if options.warning
                        warning('DMU %i. First Step. Optimization doesn''t return a result. Efficiency set to NaN.', j)
                    end
                    z = nan(n + 1, 1);  
                    dual.ineqlin = nan(1, m + s);
                    dual.eqlin = nan(1, 1);
                end
                
                % Get efficiency
                beta = z(end);
                eff(j) = beta;
                Eflag(j, 1) = exitflag;
                
                % Get dual results
                dualineqlin(j, :) = dual.ineqlin;
                if ~isempty(beqRTS1)
                    dualeqlin(j, 1) = dual.eqlin;
                else
                    dualeqlin(j, 1) = NaN;
                end  
                
                % SECOND STEP
                
                if(options.secondstep) && ~isnan(beta)
                                 
                    % Objective function
                    f = -[zeros(1, n), ones(1, m + s)];

                    % Constraints
                    Aeq = [ X', eye(m,m)  ,  zeros(m,s),  ;
                            Y', zeros(s,m), -eye(s,s)  ;                       
                           AeqRTS2];
                    beq = [-beta .* Gx(j,:)' + Xeval(j,:)'
                            beta .* Gy(j,:)' + Yeval(j,:)';
                           beqRTS2];
                    lb = zeros(n + s + m, 1);

                    % Optimize
                    [z, ~, exitflag] = linprog(f, [], [], Aeq, beq, lb, [], [], optimopts);
                    if exitflag ~= 1
                        if options.warning
                            warning('DMU %i. Second Step. Optimization exit flag: %i', j, exitflag)
                        end
                    end
                    if isempty(z)
                        if options.warning
                            warning('DMU %i. Second Step. Optimization doesn''t return a result. Results set to NaN.', j)
                        end
                        z = nan(n + m + s, 1);                   
                    end

                    % Get results
                    lambda(j,:) = z(1:n);
                    slackX(j,:) = z(n + 1 : n + m);
                    slackY(j,:) = z(n + m + 1 : n + m + s);                
                    Eflag(j, 2) = exitflag;

                    % Compute efficient inputs and outputs
                    Xeff(j,:) = Xeval(j,:) - repmat(eff(j), 1, m) .* Gx(j,:) - slackX(j,:);
                    Yeff(j,:) = Yeval(j,:) + repmat(eff(j), 1, s) .* Gy(j,:) + slackY(j,:);
                end
                
            end

            
    end   
  
    % Slacks structure
    slack.X = slackX;
    slack.Y = slackY;  
    
    % Dual structure
    dual.X = dualineqlin(:, 1:m);
    dual.Y = dualineqlin(:, m+1: m+s);
    if ~isempty(beqRTS2)
        dual.rts = dualeqlin(:);
    else
        dual.rts = nan(neval,1);
    end
    
    % SAVE results and input data
    out = deaout('n', n, 'neval', neval', 's', s, 'm', m,...
        'X', X, 'Y', Y, 'names', options.names,...
        'model', 'radial', 'orient', orient, 'rts', rts,...
        'lambda', lambda, 'slack', slack,...
        'eff', eff, 'Xeff', Xeff, 'Yeff', Yeff,...
        'dual', dual,...
        'exitflag', Eflag,...
        'dispstr', 'names/X/Y/eff/slack.X/slack.Y');


end


dea2table

function [ T ] = ( out, dispstr )
%DEA2TABLE Convert 'deaodea2tableut' results into a table object
%   Convert data envelopment analysis results in a 'deaout' structure into
%   a MATLAB table object.
%
%   T = DEA2TABLE( out ) Converts 'deaout' structure into a MATLAB table
%   object.
%   T = DEA2TABLE( out, dispstr ) Converts 'deaout' structure into a MATLAB
%   table object using the specified 'dispstr' structure.
%
%   Example
%       
%       io = dea(X, Y, 'orient', 'io');
%       T = dea2table(io);
%
%       T2 = dea2table(io, 'names/lambda/eff');
%
%   See also DEAOUT, DEADISP
%
%   Copyright 2016 Inmaculada C. 羖varez, Javier Barbero, Jos� L. Zof韔
%   http://www.deatoolbox.com
%
%   Version: 1.0
%   LAST UPDATE: 9, May, 2017
%

    if nargin < 2
        dispstr = out.dispstr;
    end    
    
    % Convert to table
    dispstr = strsplit(dispstr, '/');
    
    % Create empty table
    T = table();
    
    % Build Header and Body
    for i=1:length(dispstr)  
            % Get param name
            paramstr = char(dispstr(i));
            
            % Get data
            dat = eval(sprintf('out.%s', paramstr));
            
            % Append to Table
            T = [T table(dat)];
            
            % Get variable name
            [name, ~] = getDEAformat(paramstr, out.orient);
            
            % If no name in output structure
            if isempty(name)
                disptext_field = sprintf('disptext_%s', strrep(paramstr,'.','_'));
                if isfield(out, disptext_field)
                    % If custom name exists in the output structure use it
                    name = eval(sprintf('out.%s',disptext_field));
                else
                    % If not, display paramstr name without eff.
                    name = strrep(paramstr, 'eff.', '');
                end
            end
            
            % Store variable name
            T.Properties.VariableNames(size(T,2)) = cellstr(name);
            
    end
    

end


你可能感兴趣的:(机器学习,Python)