点赞发Nature 关注中Science
by-product DEA模型取消了常用的DEA模型中的弱处置性(weak disposability),可以用来模拟副产品与主产品相关性不强的情景。
如,在电力生产中,若安装了APCD,则空气污染物的产生与电力生产量就不具有强的相关性,应当采用by-product模型。
import numpy as np
import pandas as pd
import pulp
class DEAProblem:
"""
Help on class DEAProblem
DEAProblem(inputs, outputs, bad_outs, weight_vector, directional_factor=None, returns='CRS',
in_weights=[0, None], out_weights=[0, None],badout_weights=[0, None])
DEAProblem solves DEA model using directional distance function.
Parameters:
inputs: input data, DataFrame data
outputs: output data, DataFrame data
bad_outs: undesirable output data, DataFrame data
weight_vector: weights for individual inputs and outputs. List data
"""
def __init__(
self,
n_inputs,
p_inputs,
outputs,
bad_outs,
weight_vector,
directional_factor=None,
returns="CRS",
in_weights=[0, None],
out_weights=[0, None],
badout_weights=[0, None],
):
self.n_inputs = n_inputs
self.p_inputs = p_inputs
self.outputs = outputs
self.bad_outs = bad_outs
self.returns = returns
self.weight_vector = (
weight_vector
)
self.J, self.nI = self.n_inputs.shape
_, self.pI = self.p_inputs.shape
_, self.R = self.outputs.shape
_, self.S = self.bad_outs.shape
self._ni = range(self.nI)
self._pi = range(self.pI)
self._r = range(self.R)
self._s = range(self.S)
self._j = range(self.J)
if directional_factor == None:
self.gx1 = self.n_inputs
self.gx2 = self.p_inputs
self.gy = self.outputs
self.gb = self.bad_outs
else:
self.gx1 = directional_factor[: self.nI]
self.gx2 = directional_factor[: (self.nI + self.pI)]
self.gy = directional_factor[
(self.nI + self.pI) : ((self.nI + self.pI) + self.J)
]
self.gy = directional_factor[((self.nI + self.pI) + self.J) :]
self._in_weights = in_weights
self._out_weights = out_weights
self._badout_weights = badout_weights
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 by-product technology model. Reference: doi.org/10.1111/deci.12421
"""
prob = pulp.LpProblem("".join(["DMU_", str(j0)]), pulp.LpMaximize)
self.weights_1 = pulp.LpVariable.dicts(
"Weight_non_polluting", (self._j), lowBound=self._in_weights[0]
)
self.weights_2 = pulp.LpVariable.dicts(
"Weight_polluting", (self._j), lowBound=self._in_weights[0]
)
self.beta = pulp.LpVariable("scalingFactor", lowBound=0)
prob += pulp.lpSum(self.beta)
for ni in self._ni:
prob += (
pulp.lpSum(
[
(self.weights_1[j0] * self.n_inputs.values[j0][ni])
for j0 in self._j
]
)
<= self.n_inputs.values[j0][ni]
)
for pi in self._pi:
prob += (
pulp.lpSum(
[
(self.weights_1[j0] * self.p_inputs.values[j0][pi])
for j0 in self._j
]
)
<= self.p_inputs.values[j0][pi]
)
for r in self._r:
prob += (
pulp.lpSum(
[
(self.weights_1[j0] * self.outputs.values[j0][r])
for j0 in self._j
]
)
>= self.outputs.values[j0][r] + self.beta * self.gy.values[j0][r]
)
for pi in self._pi:
prob += (
pulp.lpSum(
[
(self.weights_2[j0] * self.p_inputs.values[j0][pi])
for j0 in self._j
]
)
>= self.p_inputs.values[j0][pi]
)
for s in self._s:
prob += (
pulp.lpSum(
[
(self.weights_2[j0] * self.bad_outs.values[j0][s])
for j0 in self._j
]
)
<= self.bad_outs.values[j0][s] - self.beta * self.gb.values[j0][s]
)
if self.returns == "VRS":
prob += sum([self.weights_1[j] for j in self.weights_1]) == 1
prob += sum([self.weights_2[j] for j in self.weights_2]) == 1
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(pulp.PULP_CBC_CMD(msg=0))
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
使用的案例可以见我的Github
代码相关的文章工作还在进行中,代码有用的话,请考虑引用我的论文~
Cite my works
F. Yang, H. Lee. An innovative provincial CO2 emission quota allocation scheme for Chinese low-carbon transition. Technological forecast and social change. 2022. In press.
———————— 我目前奥尔堡大学做博士后(我的google scholar, 我的Github),关注能源转型过程中的环境、经济问题。
专注于分享利用python科研的技巧,欢迎一起交流、学习、合作。
关于我的博客内容、其他相关的研究问题,有问题可以下方👇评论、或私信我~
|