Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >跨站数据测试

python DEA: 非径向距离函数(non-radial directional distance function)

点赞发Nature
关注中Science

最近在想怎么用python实现非径向距离函数

之前用了pyDEA包https://pypi.org/project/pyDEA/,那个包比较简陋,只有普通的CCR BCC模型。

另一方面,MaxDEA因为是打包好的嘛,所以不够灵活。所以想自己做一个NDDF的模型出来。

所以用pyDEA的初始代码进行了一些改造,直接上代码:

import numpy as np
import pandas as pd
import pulp

class DEAProblem:
    def __init__(self, inputs, outputs, weight_vector, directional_factor=None, returns='CRS',
                 in_weights=[0, None], out_weights=[0, None]):
        self.inputs = inputs
        self.outputs = outputs
        self.returns = returns
        self.weight_vector = weight_vector # weight vector in directional distance function      
        
        self.J, self.I = self.inputs.shape  # no of DMUs, inputs
        _, self.R = self.outputs.shape  # no of outputs
        self._i = range(self.I)  # inputs
        self._r = range(self.R)  # outputs
        self._j = range(self.J)  # DMUs
        if directional_factor == None:
            self.gx = self.inputs
            self.gy = self.outputs
        else:
            self.gx = directional_factor[:self.I]
            self.gy = directional_factor[-self.J:]

        
        self._in_weights = in_weights  # input weight restrictions
        self._out_weights = out_weights  # output weight restrictions

        # creates dictionary of pulp.LpProblem objects for the DMUs
        self.dmus = self._create_problems()
    
    def _create_problems(self):
        """
        Iterate over the DMU and create a dictionary of LP problems, one
        for each DMU.
        """

        dmu_dict = {}
        for j0 in self._j:
            dmu_dict[j0] = self._make_problem(j0)
        return dmu_dict
    
    def _make_problem(self, j0):
        """
        Create a pulp.LpProblem for a DMU.
        """

        # Set up pulp
        prob = pulp.LpProblem("".join(["DMU_", str(j0)]), pulp.LpMaximize)
        self.weights = pulp.LpVariable.dicts("Weight", (self._j),
                                                  lowBound=self._in_weights[0])
        self.betax = pulp.LpVariable.dicts("scalingFactor_x", (self._i),
                                                  lowBound=0)

        self.betay = pulp.LpVariable.dicts("scalingFacotr_y", (self._r),
                                                  lowBound=0)
        
        
        # Set returns to scale
        if self.returns == "VRS":
            prob += pulp.lpSum([weight for weight in self.weights]) == 1

        # Set up objective function      
        prob += pulp.lpSum([(self.weight_vector[i]*self.betax[i]) for i in self._i]+[(self.weight_vector[self.I+r]*self.betay[r]) for r in self._r])

        # Set up constraints
        for i in self._i:
            prob += pulp.lpSum([(self.weights[j0]*
                                              self.inputs.values[j0][i]) for j0 in self._j]) <= self.inputs.values[j0][i]-self.betax[i]*self.gx.values[j0][i]
        for r in self._r:
            prob += pulp.lpSum([(self.weights[j0]*
                                              self.outputs.values[j0][r]) for j0 in self._j]) >= self.outputs.values[j0][r]+self.betay[r]*self.gy.values[j0][r]
        
        return prob
    
    def solve(self):
        """
        Iterate over the dictionary of DMUs' problems, solve them, and collate
        the results into a pandas dataframe.
        """

        sol_status = {}
        sol_weights = {}
        sol_efficiency = {}

        for ind, problem in list(self.dmus.items()):
            problem.solve()
            sol_status[ind] = pulp.LpStatus[problem.status]
            sol_weights[ind] = {}
            for v in problem.variables():
                sol_weights[ind][v.name] = v.varValue
            sol_efficiency[ind] = pulp.value(problem.objective)
        return sol_status, sol_efficiency, sol_weights

solve = DEAProblem(X, y, weight).solve()

计算结果
该模块依据了这个公式:
NDDF公式
文章是张宁老师13年发表在RESR上的综述,

该模块可以自行设定投入X, 产出Y, 方向向量g, 以及权重向量w

后续还得考虑把undesirable output也加入进去。

我在编程的时候发现产出扩张系数是有可能大于1的,我以前一直以为扩张系数就是无效率值,发现还是有些不一样的。

感兴趣的可以私信我交流DEA、能源、环境、生命周期分析等等的工作。

——————更新——————

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: 比特币协会年度报告(2019):BSV生态迅猛发展

下一篇: 国产数据库操作系统强强联合,巨杉与银河麒麟完成兼容认证

精华推荐