简介:DEA的MATLAB程序包内含DEA-Solver工具箱,面向运筹学、管理学与经济学领域的研究者和实践者,用于评价企业、高校、医院等多投入多产出组织的相对效率。压缩包共21个文件,以xls数据表格、pdf理论文献、m脚本及mat数据文件为主,整体约2.54MB,其中包含CCR、BCC等经典DEA模型的定义、求解与结果分析组件,还有doc和txt说明便于查阅。已有442人学习,适合希望系统掌握DEA建模方法、快速开展效率评价实战的读者。借助这份资源,可以学习DEA原理,在MATLAB中快速构建和求解模型,还可基于示例数据与文档进行自定义扩展,或用作教学演示。需注意运行DEA-Solver可能需要安装MATLAB优化工具箱,合理设置参数能有效缩短大型数据集的计算时间。 先说结论:这个MATLAB工程干的事情,就是给你一套能直接跑的数据包络分析工具箱,里面那个dea solver不是那种带界面的商业软件,而是封装好了的求解函数。你只要把决策单元(DMU)的投入产出数据整理成矩阵,调用一下,就能得到效率值、松弛变量、投影值这些结果。DEA这个名字听起来学术,但实际应用场景非常广:高校院系绩效评估、银行网点运营效率、医院科室资源利用、物流分拨中心效率对比,甚至我自己还帮人做过连锁门店的坪效分析,用的都是这套逻辑。
这篇文章我打算从DEA的基本思路讲起,再结合这个MATLAB项目里的solver实际用法,把数据准备、模型选择、代码调用、结果解读、常见坑位一次说清楚。适合两类人看:一是运筹学、管理科学方向的学生或老师,论文需要跑DEA又不想从零写线性规划;二是工作中需要做效率评估的从业者,想在Excel手算之外找一个能批量处理、可复现的分析工具。
1. 项目概述与整体思路
1.1 DEA是什么,为什么用MATLAB
DEA全称Data Envelopment Analysis,中文叫数据包络分析,是一种基于线性规划的相对效率评价方法。它不需要预设生产函数,也不需要价格信息,只依赖投入产出数据,就能算出每个决策单元在“生产前沿面”上的相对效率。这个特性特别适合处理多投入、多产出的效率评价问题,比如教育、医疗、金融这些难以用单一利润指标衡量的领域。
为什么用MATLAB?因为DEA本质上是一堆线性规划问题。每个决策单元都要解一个优化模型,样本量一大,手动在Excel里排规划求解既不现实,又容易出错。MATLAB自带的linprog可以直接求解线性规划,但直接用linprog写DEA需要自己做模型转换、变量对齐、结果解析,代码量不小。这个项目里内置的dea solver就把这些事情封装好了,你提供数据,它负责求解,省掉中间一堆容易出错的环节。
1.2 内含的dea solver到底是个什么东西
根据项目标题来看,这个MATLAB工程里最重要的资产就是dea solver。我拿到类似项目后,第一件事就是打开函数目录,看看里面封装了什么。常见的实现方式是这样:一个主函数dea或deasolver.m,内部接收投入矩阵X、产出矩阵Y,以及模型选项(比如CCR还是BCC、投入导向还是产出导向),然后循环调用linprog计算每个DMU的效率值。
这里有一个容易忽略的点:DEA的线性规划模型往往是对偶模型,直接写原问题也可以,但求解效率和对偶变量的解释都会差一些。成熟的solver会自动处理好两件事:一是把效率模型转成标准线性规划形式;二是处理无穷小量epsilon,避免所有变量权重为零的退化情况。如果只看结果不看内部实现,这个问题不明显,一旦你自己尝试手写一个简单的DEA脚本,就会发现很容易卡在边界条件上。
1.3 这类项目适合什么人、能解决什么问题
我个人的判断是,这类“程序+内置solver”的组合,最适合三种情况:
- 学生写论文。管理科学与工程、应用经济学的论文里,DEA是常用实证工具,直接跑现成solver可以快速验证假设,把精力聚焦在模型解释上,而不是debug线性规划。
- 企业做效率评价。比如区域经理要评估几十家门店的运营效率,投入指标选人力成本、营业面积、库存,产出选销售额、客流量、利润,DEA能在没有标准成本数据的情况下给出一个相对效率排序。
- 研究者做方法对比。你可以在同一套数据上切换CCR、BCC、SBM模型,比较不同模型下的效率差异,这在方法类文章中是常见的敏感性分析。
但也有不适合的人:如果你需要的是带有友好图形界面的商业软件,比如DEA-Solver Pro,那么这个MATLAB脚本显然不是你的菜,它更偏向脚本化、批量化、可嵌入分析流程。
2. 核心原理与模型选型
2.1 CCR、BCC、SBM怎么选
DEA最基础的模型是CCR,由Charnes、Cooper和Rhodes在1978年提出,它假设规模报酬不变(CRS),也就是说投入翻倍、产出也翻倍。BCC模型由Banker、Charnes和Cooper在1984年扩展,放宽到规模报酬可变(VRS),区分了纯技术效率和规模效率。简单理解:CCR算出来的效率值是综合技术效率,BCC算出来的是纯技术效率,两者相除可以得到规模效率。
在solver的配置里,通常会有'model'参数,比如'CCR'或'BCC'。实际使用中,如果评价对象之间规模差异很大,比如既有几十人的小店,又有上千人的大厂,那用BCC更合理,否则可能把所有规模不经济都归到技术无效率里。如果规模差异不大,CCR往往够用。还有SBM模型,它属于非径向DEA,能处理投入产出同比例和非同比例变化的问题,对于存在零值、负值的数据,SBM通常更稳健,但计算复杂度高一些。
2.2 投入导向还是产出导向
这是个看似简单但非常影响结果的选择。投入导向(Input-Oriented)的意思是:在产出不变的前提下,测算投入能压缩多少比例。产出导向(Output-Oriented)是:在投入不变的前提下,测算产出能增长多少比例。
怎么选?核心看评价对象的控制能力。比如评价医院科室效率,科主任大多控制不了门诊量需求,但可以通过优化排班、耗材管理来控制成本,这更贴合投入导向。反过来,评价销售团队效率,团队可以努力增加销售额,但资源投入(比如广告预算)往往由公司统一调度,这种场景更适合产出导向。在dea solver的调用参数里,'orient'可以设置成'input'或'output',如果不确定,建议把两个都跑一遍,观察效率排名是否发生明显变化,这本身就是论文里不错的分析素材。
2.3 规模效率与松弛变量到底看什么
很多人跑完DEA只看效率值,结果发现自己浪费了大半信息。以BCC模型为例,输出结果里除了技术效率,还能得到规模效率和规模报酬状态(递增、递减、不变)。规模报酬递增意味着可以扩大规模,递减则意味着扩张要谨慎。这个信息对运营决策比效率值本身更有指导意义。
松弛变量同样重要。一个DMU效率为1,不一定就是“完美”。在非径向模型中,投入冗余或产出不足都会体现为松弛变量非零。比如某门店效率0.95,你去看松弛变量,发现人员投入松弛了15%,这意味着在不降低产出的情况下,理论上可以裁掉15%的人力。这些具体数值比一个单纯的0.95更能指导改进行动。
3. MATLAB实操:用dea solver跑通一个完整案例
3.1 数据准备:DMU、投入、产出的表格结构
这是整个流程里最花时间的一步,也是最多人出错的一步。DEA对数据格式要求很严格:每行是一个决策单元,每一列是一个指标。我通常习惯用Excel整理,再通过MATLAB的readmatrix或readtable导入。
一个典型的例子:评估12个物流配送中心的效率,投入指标选人工成本、车辆数、仓库面积,产出指标选日处理订单数、准时交付率。那么数据矩阵就是12行,投入矩阵X是12×3,产出矩阵Y是12×2。注意,指标的单位可以不一致,因为DEA的线性规划会自动处理权重,但指标的方向必须一致:投入越小越好,产出越大越好。
3.2 核心代码:调用dea solver计算效率
假如工程里的solver函数名是dea_solver,基本调用方式大概长这样:
% 加载数据,这里假设已经保存为xlsx文件 data = readmatrix('DMU_data.xlsx'); % 假设前3列是投入,后2列是产出 X = data(:, 1:3); Y = data(:, 4:5); % 调用solver,使用BCC模型,投入导向 options.model = 'BCC'; options.orient = 'input'; % 有些solver版本还会要求你指定是否计算超效率、是否汇总结果 options.super = false; result = dea_solver(X, Y, options); % 结果里一般包含 eff(效率值)、rank(排名)、lambda(同组权重)、slack、target eff = result.eff;这里有一点非常关键:linprog默认求解的是最小化问题,而DEA的效率模型通常表达为最大化或分式规划。成熟的solver内部会把效率值模型转化为线性规划的对偶形式,再调用linprog求解,具体方向由solver自己管理。你只需要明确你选择的是投入还是产出导向,不需要自己设定目标函数符号。
3.3 结果读取:效率值、排名、投影值
跑完solver之后,输出结果一般是一个结构体,我习惯逐个字段打印出来看:
% 效率值和排名 disp(table((1:size(X,1))', eff, rank)); % 查看松弛变量,判断投入冗余 disp(result.slack_input); disp(result.slack_output);投影值是我最常用来做决策建议的参数。投影的意思是:如果这个DMU要达到效率前沿,它的目标投入产出应该是多少。你可以简单理解成“最优状态下的指标值”。比如某个配送中心当前每日处理订单量是5000单,投影值是6500单,那说明产出不足,改进方向就是提升订单处理能力,而不是压缩车辆数。把投影值和当前值的差整理成表格,可以直接给业务部门做改进参考。
4. 常见问题与排查技巧实录
4.1 效率值全是1,是不是跑错了
这是最常见的困惑。我拿到一份结果,看到所有效率全是1,第一反应不是“样本都好棒”,而是“模型可能区分度不够”。产生这个现象的原因通常有三个:
- 决策单元数量太少,或者指标数量太多。DEA的经验法则是DMU数量至少是指标数量的两到三倍,最好达到三倍以上。如果只有10个DMU,却有6个指标,那么绝大多数DMU都容易被识别为有效。
- 投入产出指标之间高度相关。比如同时放入“营业面积”和“租金成本”,这两个指标高度相关,等于变相降低了指标维度的实际数量,也让DEA更容易把所有DMU都包络起来。
- 模型和数据范围不匹配。比如数据存在缺失或异常值,solver内部自动处理时把异常点当成前沿,导致结果整体偏高。
遇到这种情况,先检查数据量,再检查指标相关性,最后可以做一次相关系数矩阵看看有没有冗余指标。删除一个强相关指标往往就能让效率值分布拉开。
4.2 指标多、DMU少,怎么处理
学术论文里经常见到“样本只有十几个,指标选了七八个”的尴尬局面。解决办法有几个方向,但都不是很完美:
- 减少指标。用主成分分析先降维,把多个投入指标合成一个或两个综合指标,再跑DEA。不过这会让结果的物理含义变差,解释起来比较费劲。
- 扩大样本。如果研究对象可以细分到月别或区域别,尽量扩展DMU数量。
- 使用窗口DEA(Window DEA),把同一单位不同时期的数据当成多个DMU,变成面板形式的效率测算,这是学术论文里比较常用的妥协方案。
实测下来,我建议至少保证“DMU数量 ≥ 2 × 指标数量”,否则结果几乎不可用,落不了地。
4.3 solver结果和自己手写linprog对不上
这是一个很有代表性的debug问题。你拿自己手写的CCR脚本和这个项目里的solver跑同一份数据,结果差异明显。我遇到过的情况主要有两种:
第一,模型形式不一致。比如你手写的是产出导向,但dea solver默认是投入导向,结果当然对不上。第二,无穷小量的处理方式不同。很多DEA源代码里会设置一个很小的epsilon,比如1e-6,手动写代码时如果忽略它,或者epsilon取得太大,效率值会出现微小差异。
还有人会犯一个错误:以“让每个DMU的效率值在0到1之间”为理由,对计算后的效率值做归一化。这样做完全破坏了DEA的原理,DEA本身的效率值已经是相对比例,不需要额外归一化。如果你看到solver里有个normalize选项,除非你明确知道它在做什么,不然别乱开。
4.4 可视化与论文出图建议
DEA结果用表格呈现太枯燥,我一般做三类图:
- 效率分布直方图,展示整体效率形态。
- 效率值与规模报酬状态散点图,X轴是规模状态,Y轴是效率值,可以看到高效率单位集中在哪个规模区间。
- 投入产出投影对比图,可以用条形图把当前值和目标值并列显示,一眼看出改进空间。
MATLAB里画图有几个小技巧。用tiledlayout做多子图比subplot更整齐,尤其适合输出论文图。图例和字号建议统一用set(gca, 'FontSize', 12)固定,不然放到Word里会显得参差不齐。输出图片用exportgraphics函数,线宽和清晰度都比saveas好很多。
我在实际跑这个项目时,还有一个心得:dea solver返回的lambda权重矩阵值得多看一眼。它告诉你一个无效DMU是参考了哪些有效DMU的线性组合才得到的目标值。比如某门店的目标产出是参考了门店3和门店7的组合,这是很有说服力的对标信息,比单纯给个“改进方向”硬气得多。后面我把这个方法用在一个连锁零售项目上,就是通过这个参考集找出了几个标杆门店,把它们的运营参数整理成SOP,整个项目组的接受度非常高。
最后再分享一个小操作:如果你不想每次跑数据都打开MATLAB脚本改路径,可以在脚本开头加一段uigetfile选择Excel文件,把数据导入这个交互动作从“改代码”变成“选文件”,这样即使不会写MATLAB的同事,也能自己换数据跑结果。很多所谓的“DEA小工具”,说白了就是把这一步做顺了,用起来才显得高级。
本文还有配套的精品资源,点击获取