您现在的位置是:首页 >其他 >绿色全要素生产率,python,采用全局生产技术的弱可处置性非径向方向距离函数(NDDF),可调方向权重,DDF,DEA网站首页其他

绿色全要素生产率,python,采用全局生产技术的弱可处置性非径向方向距离函数(NDDF),可调方向权重,DDF,DEA

JOJO_zzzz 2024-10-04 00:01:04
简介绿色全要素生产率,python,采用全局生产技术的弱可处置性非径向方向距离函数(NDDF),可调方向权重,DDF,DEA


一、NDDF是什么?

1. 采用方法

一文详细说明SBM、SBM-DDF、DDF、NDDF、ML指数是什么
利用python的pulp库进行CCR、BCC、超效率模型的数学建模
在本文使用的公式是采用全局生产技术的弱可处置性非径向方向距离函数
李江龙(2018)
在这里插入图片描述
由上图可知,存在 ω 、 λ 、 β 、 g omega、lambda、eta、g ωλβg 这三个变量
其中 λ lambda λ 计算前沿面,可以理解为测算投入产出权重以获得一个前沿面
β eta β 为各个投入产出缩放比例
ω omega ω 为权重向量(denotes the normalized weight vector that is relevant to the numbers of inputs and outputs)
g g g为方向向量,当 g x = x t , g y = y t g^x = x^t, g^y = y^t gx=xt,gy=yt则为(DDF)。特例如上文 , g = ( 0 , 0 , − E , Y , − D , − S , − W ) g=(0,0,-E,Y,-D,-S,-W) g=(0,0,E,Y,D,S,W)
N D ⃗ vec{ND} ND 得出的是无效率程度,值越大越无效率

2.具体参数解释

问题:上文公式问题,投入应该是减少而到达前沿面, ∑ i = 1 N ∑ t = 1 T λ i , t E i , t sum_{i=1}^{N}sum_{t=1}^{T}lambda_{i,t}E_{i,t} i=1Nt=1Tλi,tEi,t为前沿面, E − β E g E E-eta_E g_E EβEgE当期减少多少投入能达到前沿面,于是带入方向向量后解释不通。
文中方向向量定义为: g = ( 0 , 0 , − E , Y , − D , − S , − W ) 但公式中出现: ∑ i = 1 N ∑ t = 1 T λ i , t E i , t ≤ E − β E g E 将方向向量带入得: ∑ i = 1 N ∑ t = 1 T λ i , t E i , t ≤ E + β E E 文中方向向量定义为:g=(0,0,-E,Y,-D,-S,-W) \但公式中出现:sum_{i=1}^{N}sum_{t=1}^{T}lambda_{i,t}E_{i,t} leq E-eta_E g_E \ 将方向向量带入得:sum_{i=1}^{N}sum_{t=1}^{T}lambda_{i,t}E_{i,t} leq E+eta_E E 文中方向向量定义为:g=(0,0,E,Y,D,S,W)但公式中出现:i=1Nt=1Tλi,tEi,tEβEgE将方向向量带入得:i=1Nt=1Tλi,tEi,tE+βEE

Zhou(2012)提到得公式更好理解,此公式中所有约束条件都为“+”,因此带入方向向量时候是正确的。
在这里插入图片描述
文中提到 “If the direction vector is set equal to (-F, 0, 0), Eq. (7) is essentially equivalent to an input-oriented DEA model with undesirable outputs.”
g 1 = ( − F , 0 , 0 ) D 1 ⃗ ( F , E , C ; g 1 ) = m a x w 1 F β 1 F s . t . ∑ n = 1 N z 1 n F 1 n ≤ ( 1 − β 1 F ) F s . t . ∑ n = 1 N z 1 n E 1 n ≤ E s . t . ∑ n = 1 N z 1 n C 1 n = C z 1 n ≥ 0 , n = 1 , 2 , . . . , N , β 1 F ≥ 0 g_1=(-F,0,0) \vec{D_1}(F,E,C;g_1) = maxw_{1F}eta_{1F} \ s.t. sum_{n=1}^{N}z_{1n}F_{1n} leq (1-eta_{1F})F \ s.t. sum_{n=1}^{N}z_{1n}E_{1n} leq E \ s.t. sum_{n=1}^{N}z_{1n}C_{1n} = C \ z_{1n} geq 0, n=1,2,...,N, eta_{1F} geq 0 g1=(F,0,0)D1 (F,E,C;g1)=maxw1Fβ1Fs.t.n=1Nz1nF1n(1β1F)Fs.t.n=1Nz1nE1nEs.t.n=1Nz1nC1n=Cz1n0,n=1,2,...,N,β1F0
在这里插入图片描述
由此可见当有方向向量时,公式中应都设为“+”号。若公式设好,则方向向量应取值为 0 或 1 0 或 1 01而没有 − 1 -1 1,再乘以原本的投入产出值。

Chung(1997)
在这里插入图片描述
k = 1 , m = 1 , t = 1 ; y k ′ m t k=1, m=1, t=1; y_{k'm}^t k=1,m=1,t=1;ykmt 意味着第一个时期的第一个DMU的第一个期望产出。

3.强弱可处置性

参考
Y. H. Chung, R. F ̈ are and S. Grosskopf.Productivity and Undesirable Outputs: A Directional Distance Function Approach.*Journal of Environmental Management * (1997) 51, 229–240
成刚. 数据包络分析方法与MaxDEA软件[M].北京:知识产权出版社,2014.5

二、代码

1.参考与改进

参考代码:
python DEA:强/弱处置性假设下的考虑非期望产出的非径向距离函数
改变部分

        else:			# 每一个方向应该要乘以原本变量
            self.gx = directional_factor[:self.I] * self.inputs
            self.gy = directional_factor[self.I:(self.I+self.R):1] * self.outputs
            self.gb = directional_factor[(self.I+self.R):(self.I+self.R+self.S):1] * self.bad_outs

按照上文参考文献,在约束条件中已确定了方向
那么方向向量部分得到的应该是 [ 0 × L , 0 × K , 1 × E , 1 × D , 1 × S , 1 × W ] [0 imes L,0 imes K,1 imes E,1 imes D,1 imes S,1 imes W] [0×L,0×K,1×E,1×D,1×S,1×W]


import numpy as np
import pandas as pd
import pulp

class DEAProblem:
    def __init__(
        self,
        inputs,
        outputs,
        bad_outs,
        weight_vector,
        directional_factor=None,
        returns="CRS",
        disp="weak disposability",
        in_weights=[0, None],
        out_weights=[0, None],
        badout_weights=[0, None],
    ):
        self.inputs = inputs
        self.outputs = outputs
        self.bad_outs = bad_outs
        self.returns = returns
        self.weight_vector = (
            weight_vector  # weight vector in directional distance function
        )
        self.disp = disp
        self.directional_factor = directional_factor
        
        # directional_factor 方向向量需要输入列表形式,并且若不等于0,则用1,公式方向已给定。
        # 投入产出传入数据皆为DataFrame,权重和方向向量为列表形式
        
        self.J, self.I = self.inputs.shape  # no of DMUs, inputs
        _, self.R = self.outputs.shape  # no of outputs
        _, self.S = self.bad_outs.shape  # no of bad outputs
        self._i = range(self.I)  # inputs
        self._r = range(self.R)  # outputs
        self._s = range(self.S)  # bad_output
        self._j = range(self.J)  # DMUs
        if directional_factor == None:  #(方向向量未定义则与原本投入产出相同)
            self.gx = self.inputs
            self.gy = self.outputs
            self.gb = self.bad_outs
        else:			# 每一个方向应该要乘以原本变量
            self.gx = directional_factor[:self.I] * self.inputs
            self.gy = directional_factor[self.I:(self.I+self.R):1] * self.outputs
            self.gb = directional_factor[(self.I+self.R):(self.I+self.R+self.S):1] * self.bad_outs


        self._in_weights = in_weights  # input weight restrictions
        self._out_weights = out_weights  # output weight restrictions
        self._badout_weights = badout_weights  # bad 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, upBound=1
        )

        self.betay = pulp.LpVariable.dicts(
            "scalingFactor_y", (self._r), lowBound=0
        )

        self.betab = pulp.LpVariable.dicts(
            "scalingFactor_b", (self._s), lowBound=0, upBound=1
        )

        # Set returns to scale
        if self.returns == "VRS":
            prob += pulp.lpSum([self.weights[j] for j 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]
            + [
                (self.weight_vector[self.I + self.R + s] * self.betab[s])
                for s in self._s
            ]
        )
# Set up constraints  # 括号外j0为该函数传入的j0
        # 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]
            )

        if self.disp == "weak disposability":
            for s in self._s:  # weak disposability
                prob += (
                    pulp.lpSum(
                        [
                            (self.weights[j0] * self.bad_outs.values[j0][s])
                            for j0 in self._j
                        ]
                    )
                    == self.bad_outs.values[j0][s]
                    - self.betab[s] * self.gb.values[j0][s]
                )

        elif self.disp == "strong disposability":
            for s in self._s:  # strong disposability
                prob += (
                    pulp.lpSum(
                        [
                            (self.weights[j0] * self.bad_outs.values[j0][s])
                            for j0 in self._j
                        ]
                    )
                    >= self.bad_outs.values[j0][s]
                    - self.betab[s] * self.gb.values[j0][s]
                )

        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 = {}
        sol_objective = {}
        sol_directional ={}
        if self.directional_factor == None:
            for ind, problem in list(self.dmus.items()):
                problem.solve()
                sol_status[ind] = pulp.LpStatus[problem.status]
                sol_weights[ind] = {}
                sol_objective[ind] = problem.objective
                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, sol_objective
        else:
            for ind, problem in list(self.dmus.items()):
                problem.solve()
                sol_status[ind] = pulp.LpStatus[problem.status]
                sol_weights[ind] = {}
                sol_objective[ind] = problem.objective
                sol_directional[ind] = self.directional_factor
                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, sol_objective, sol_directional

sol_status 每个DMU是否计算成功
sol_efficiency 得出方程的解,测量的是无效率值
sol_weights Weight求得是 λ lambda λ ; scalingFactor_x、 scalingFactor_y、 scalingFactor_b求的是目标函数中的 β eta β
sol_objective 目标函数的设定情况
sol_directional方向向量的设定情况

1.1约束条件关键代码解释

        for i in self._i:
            prob += (
            pulp.lpSum([(self.weights[j0] * self.inputs.values[j0][i]) for j0 in self._j]) #不要求设定时间,遍历所有时期的所有dmu,将所有变量都累加。i是第i个投入变量。
            <= self.inputs.values[j0][i] - self.betax[i] * self.gx.values[j0][i]) #这里 j0 是函数_make_problem参数中的j0,是上面函数第j0个变量。

2.示例

X = pd.DataFrame(
    np.array(
        [
            [20, 300,20],
            [30, 200,30],
            [40, 100,40],
            [20, 200,20],
            [10, 400,10],
            [11, 222,11],
            [12, 321,12],
            [14, 231,14],
        ]
    )
)
y = pd.DataFrame(np.array([[20], [30], [40], [30], [50], [21], [32], [42]]))
b = pd.DataFrame(np.array([[10], [20], [10], [10], [10], [12], [-2], [-1]]))
weight = [1 / 9, 1 / 9,1 / 9 ,1 / 3, 1 / 3]
directional = [0,0,1,1,1]
solve1 = DEAProblem(X, y, b, weight, directional_factor=directional, disp="weak disposability").solve()

需要说明一点是该代码得出的为单个dmu在全局生产技术下所得到的非效率值。在结果中看不出时期和第几个dmu,因此若有分时期和dmu位数可以后期手动加上。因为得出的结果是根据输入投入产出的顺序得到的,所以按输入时的时期和dmu在结果前添加两列即可
后续会根据该模型继续改进

三、绿色指标

邵帅(2022)利用Luenberger 生产率进行定义t+1 期的碳排放绩效(TFCEP)为
在这里插入图片描述
若前一期的无效率值大于后一期,则说明全要素碳排放生产率得到了改善
杨翔(2015)利用全域GMalmquist-Luenberger测算碳生产率
在这里插入图片描述
李江龙(2018)
在这里插入图片描述

四、非全局生产技术的弱可处置性非径向方向距离函数(NDDF)

张宁(2022)采用两期模型,同样利用两期非径向Luenberger生产率指数定义碳要素生产率。
在这里插入图片描述


参考文献

  1. 李江龙,徐斌. 诅咒”还是“福音”:资源丰裕程度如何影响 中国绿色经济增长?[J]. 经济研究,2018(9)
  2. 邵帅,范美婷,杨莉莉. 经济结构调整、绿色技术进步 与中国低碳转型发展 ——基于总体技术前沿和空间溢出效应视角的经验考察[J].管理世界, 2022(2)
  3. 杨翔,李小平,周大川. 中国制造业碳生产率的差异与收敛性研究[J]. 数量经济技术经济研究,2015(12)
  4. 张宁. 碳全要素生产率、低碳技术创新和节能 减排效率追赶* ———来自中国火力发电企业的证据[J]. 经济研究,2022(2)
  5. P. Zhou, B.W. Ang, H. Wang., 2012. Energy and CO2 emission performance in electricity generation: A non-radial directional distance function approach. European Journal of Operational Research 221, 625-635
  6. Y. H. Chung, R. F ̈ are and S.,1997. Grosskopf.Productivity and Undesirable Outputs: A Directional Distance Function Approach.Journal of Environmental Management 51, 229–240
  7. 成刚. 数据包络分析方法与MaxDEA软件[M].北京:知识产权出版社,2014.5
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。