数据包络分析是评价多输入指标和多输出指标的较为有效的方法,将多投入与多产出进行比较,得到效率分析,可广泛使用于业绩评价。
代码
class DEA:
def CCR(self):
for k in self.DMUs:
MODEL=gurobipy.Model()
OE,lambdas,s_negitive,s_positive=MODEL.addVar(),MODEL.addVars(self.DMUs),MODEL.addVars(self.m1),MODEL.addVars(self.m2)
MODEL.update()
MODEL.setObjectiveN(OE,index=0,priority=1)
MODEL.setObjectiveN(-(sum(s_negitive)+sum(s_positive)),index=1,priority=0)
MODEL.addConstrs(
gurobipy.quicksum(lambdas[i] * self.X[i][j] for i in self.DMUs if i!=k or not self.AP)+
s_negitive[j]==OE*self.X[k][j] for j in range(self.m1))
MODEL.addConstrs(
gurobipy.quicksum(lambdas[i]*self.Y[i][j] for i in self.DMUs if i!=k or not self.AP)-
s_positive[j]==self.Y[k][j] for j in range(self.m2))
MODEL.setParam('OutputFlag',0)
MODEL.optimize()
self.Result.at[k,('效益分析','综合技术效益(CCR)')]=MODEL.objVal
self.Result.at[k,('效益分析','松弛变量S-')]=s_negitive[0].X
self.Result.at[k,('效益分析','松弛变量S+')]=s_positive[0].X
self.Result.at[k,('效益分析','有效性')]=('非DEA有效' if MODEL.objVal<1 else
'DEA弱有效' if s_negitive.sum().getValue()+s_positive.sum().getValue() else 'DEA强有效')
self.Result.at[k,('规模报酬分析','规模报酬系数')]=lambdas.sum().getValue()
self.Result.at[k,('规模报酬分析','类型')]=('规模报酬固定' if lambdas.sum().getValue() == 1 else
'规模报酬递增' if lambdas.sum().getValue()<1 else '规模报酬递减')
for m in range(self.m1):
self.Result.at[k,('差额变数分析',f'{self.m1_name[m]}')]=s_negitive[m].X
self.Result.at[k,('投入冗余率',f'{self.m1_name[m]}')]='N/A' if self.X[k][m]==0 else s_negitive[m].X/self.X[k][m]
for m in range(self.m2):
self.Result.at[k,('超额变数分析',f'{self.m2_name[m]}')]=s_positive[m].X
self.Result.at[k,('产出不足率',f'{self.m2_name[m]}')]='N/A' if self.Y[k][m]==0 else s_positive[m].X/self.Y[k][m]
return self.Result
def BCC(self):
for k in self.DMUs:
MODEL=gurobipy.Model()
TE,lambdas=MODEL.addVar(),MODEL.addVars(self.DMUs)
MODEL.update()
MODEL.setObjective(TE,sense=gurobipy.GRB.MINIMIZE)
MODEL.addConstrs(gurobipy.quicksum(lambdas[i]*self.X[i][j] for i in self.DMUs if i!=k or not self.AP)
<=TE*self.X[k][j] for j in range(self.m1))
MODEL.addConstrs(gurobipy.quicksum(lambdas[i]*self.Y[i][j] for i in self.DMUs if i!=k or not self.AP)
>=self.Y[k][j] for j in range(self.m2))
MODEL.addConstr(gurobipy.quicksum(lambdas[i] for i in self.DMUs if i!=k or not self.AP)==1)
MODEL.setParam('OutputFlag', 0)
MODEL.optimize()
self.Result.at[k,('效益分析','技术效益(BCC)')]=MODEL.objVal if MODEL.status==gurobipy.GRB.Status.OPTIMAL else 'N/A'
return self.Result
def dea(self):
columns_Page=(['效益分析']*6+['规模报酬分析']*2+['差额变数分析']*self.m1+['超额变数分析']*self.m2+
['投入冗余率']*self.m1+['产出不足率']*self.m2)
columns_Group=['技术效益(BCC)','规模效益(CCR/BCC)','综合技术效益(CCR)','松弛变量S-','松弛变量S+','有效性',
'规模报酬系数','类型']+(self.m1_name+self.m2_name)*2
self.Result=pd.DataFrame(index=self.DMUs,columns=[columns_Page,columns_Group])
self.CCR()
self.BCC()
self.Result.loc[:,('效益分析','规模效益(CCR/BCC)')]=(self.Result.loc[:,('效益分析','综合技术效益(CCR)')]/
self.Result.loc[:,('效益分析','技术效益(BCC)')])
return self.Result
def __init__(self,data:pd.DataFrame,inputs,outputs,AP=False):
DMUs_Name=data.index
inputs_data=data[inputs]
outputs_data=data[outputs]
self.m1=inputs_data.shape[1]
self.m1_name=inputs_data.columns.tolist()
self.m2=outputs_data.shape[1]
self.m2_name=outputs_data.columns.tolist()
self.AP=AP
self.DMUs,self.X,self.Y=gurobipy.multidict({DMU:[inputs_data.loc[DMU].tolist(),outputs_data.loc[DMU].tolist()] for DMU in DMUs_Name})
def show(self):
res=self.dea()
print('分析结果如下:')
display(res[['效益分析']])
print('''说明:
效益 S 的意义:
● 综合技术效益反映的是决策单元在最优规模时投入要素的生产效率,值等于1时,代表该决策单元的投入与产出结构合理,相对效益最优;
● 技术效益反映的是由于管理和技术等因素影响的生产效率,其值等于1时,代表投入要素得到了充分利用,在给定投入组合的情况下,实现了产出最大化;
● 规模效益反映的是由于规模因素影响的生产效率,其值等于1时,代表规模效率有效(规模报酬不变),也就是规模适宜,已达到最优的状态;
松弛变量的意义:
● 松驰变量S-指为达到目标效率可以减少的投入量,增加这些投入量就能达到更高的效率;
● 松驰变量S+指为达到目标效率可以增加的产出量,减少这些投入量就能达到更高的效率;
有效性的意义:
有效性分析结合综合效益指标,S-和S+共3个指标,可判断DEA有效性:
● 如果综合效益=1且S-与S+均为0,则为DEA强有效;
● 如果综合效益为1但S-或S+大于0,则为DEA弱有效;
● 如果综合效益<1则为非DEA有效。''')
print('效益有效性分析:')
plt.figure(figsize=(20,8),dpi=80)
x=self.DMUs
plt.plot(x,res[('效益分析','技术效益(BCC)')],x,res[('效益分析','规模效益(CCR/BCC)')],x,res[('效益分析','综合技术效益(CCR)')],marker='o')
plt.legend(labels=['技术效益(BCC)','规模效益(CCR/BCC)','综合技术效益(CCR)'],loc="lower right")
plt.show()
display(res[['规模报酬分析']])
print('''说明:
● 在不同的生产规模下,规模报酬将会随之改变:
● 规模报酬系数<1时,生产规模较小,投入产出比会随着规模增加而迅速提升,称为规模报酬递增(IRS)(规模过小可扩大规模增加效益);
● 规模报酬系数=1时,生产达到高峰期,产出与投入成正比而达到最适生产规模,称为规模报酬固定;
● 规模报酬系数>1时,生产规模过于庞大,导致产出减缓,则称为规模报酬递减(DRS),投入增加时,产出增加的比例会少于投入增加的比例(规模过大可减少规模增加效益)。''')
display(res[['差额变数分析','投入冗余率']])
print('''说明:
投入冗余分析(差额变数分析)主要用于分析各变量需要减少多少投入时才能达目标效率。
● 松驰变量 S-(差额变数)指为达到目标效率需要减少的投入量;
● 投入冗余率指‘过多投入’与已投入的比值,该值越大意味着‘过多投入’越多;''')
display(res[['超额变数分析','产出不足率']])
print('''说明:
产出不足分析(超额变数分析)主要用于分析各变量需要增加多少产出时达目标效率。
● 松驰变量 S-(超额变数)指为达到目标效率可以增加的产出量;
● 产品不足率指‘产出不足’与已产出的比值,该值越大意味着‘产出不足’越多;''')