python DEA: 非径向距离函数(non-radial directional distance function)
日期: 2020-07-01 分类: 跨站数据测试 338次阅读
点赞发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()
该模块依据了这个公式:
文章是张宁老师13年发表在RESR上的综述,
该模块可以自行设定投入X, 产出Y, 方向向量g, 以及权重向量w
后续还得考虑把undesirable output也加入进去。
我在编程的时候发现产出扩张系数是有可能大于1的,我以前一直以为扩张系数就是无效率值,发现还是有些不一样的。
感兴趣的可以私信我交流DEA、能源、环境、生命周期分析等等的工作。
——————更新—————— 除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:DEA
精华推荐