数据包络分析法(DEA)_2

数据包络分析(DEA)是一种评估决策单元效率的多目标分析方法,通过线性规划确定生产前沿面并计算相对效率。CCR模型和BCC模型是DEA的两种基本模型,用于衡量投入与产出的比例。DEA有效意味着决策单元在不改变输入输出的情况下达到最佳效率。DEA结合AHP可以克服单一方法的局限性,提供更全面的权重分配。
摘要由CSDN通过智能技术生成

(完整版)数据包络分析法DEA总结

数据包络分析(DEA)常见问题总结

DEA (数据包络分析)介绍及 python3 实现

1 基本概念

数据包络分析(data envelopment analysis,简称DEA)是运筹学、管理科学与数理经济学交叉研究的一个新领域。其是根据多项投入指标和多项产出指标,利用线性规划的方法,对具有可比性的同类型单位进行相对有效性评价的一种数量分析方法。

DEA是以相对效率概念为基础,以凸分析线性规划为工具,将评价决策单元的指标分成“输入类”指标和“输出类”指标,通过计算各单元的输入与输出之比,评价其决策单元相对有效性的多目标分析评价方法

DEA的基本思路是在保持决策单元间输入或输出不变的情况下,通过输入和输出数据和数据规划模型确定相对有效的生产前沿面,即Pareto最优解构成的面。

随后将决策单元投影到该生产前沿面上,对比分析各决策单元和生产前沿面的距离来判定相对效率,同时通过投影值来确定非有效决策单元的改进程度。


比如 确定相对优势的产业

在这里插入图片描述
建模过程
在这里插入图片描述

2 DEA基本模型

2.1 CCR模型

基本原理:设有 n n n 个决策单元,每个决策单元均有 m m m 个输入指标和 k k k 个输出指标,记第 j j j 个决策单元的第 i i i 个输入指标为 x i x_i xi ,第 j j j 个决策单元的第 k k k 个输出指标为 y k y_k yk v i v_i vi 为第 i i i 个输入指标的权重, u i u_i ui 为第 i i i 个输出指标的权重,且 x i > 0 x_i>0 xi>0 y k > 0 y_k>0 yk>0 v i , u i ≥ 0 v_i\text{,}u_i\ge 0 viui0,初始数据见表

x i j x_{ij} xij y i k y_{ik} yik 是向量

x j = [ x 1 j x 2 ⋮ x m j ] , y j = [ y 1 j y 2 j ⋮ y k j ] x_j=\left[ \begin{array}{c} x_{1j}\\ x_2\\ \vdots\\ x_{mj}\\ \end{array} \right] \text{,}y_j=\left[ \begin{array}{c} y_{1j}\\ y_{2j}\\ \vdots\\ y_{kj}\\ \end{array} \right] xj=x1jx2xmjyj=y1jy2jykj

中的分量,可以根据历史资料、统计数据和预测计算得到。设输入指标和输出指标的权数向量分别为

V = [ v 1 v 2 ⋮ v m ] , U = [ u 1 u 2 ⋮ u k ] V=\left[ \begin{array}{c} v_1\\ v_2\\ \vdots\\ v_m\\ \end{array} \right] \text{,}U=\left[ \begin{array}{c} u_1\\ u_2\\ \vdots\\ u_k\\ \end{array} \right] V=v1v2vmU=u1u2uk

如下

在这里插入图片描述

矩阵形式
[ v 1 v 2 ⋮ v m ] [ x 11 x 12 ⋯ x 1 n x 21 x 22 ⋯ x 2 n ⋮ ⋮ ⋮ x m 1 x m 2 ⋯ x m n ] ⇒ [ u 1 u 2 ⋮ u k ] [ y 11 y 12 ⋯ y 1 n y 21 y 22 ⋯ y 2 n ⋮ ⋮ ⋮ y k 1 y k 2 ⋯ y k n ] \left[ \begin{array}{c} v_1\\ v_2\\ \vdots\\ v_m\\ \end{array} \right] \left[ \begin{matrix} x_{11}& x_{12}& \cdots& x_{1n}\\ x_{21}& x_{22}& \cdots& x_{2n}\\ \vdots& \vdots& & \vdots\\ x_{m1}& x_{m2}& \cdots& x_{mn}\\ \end{matrix} \right] \Rightarrow \left[ \begin{array}{c} u_1\\ u_2\\ \vdots\\ u_k\\ \end{array} \right] \left[ \begin{matrix} y_{11}& y_{12}& \cdots& y_{1n}\\ y_{21}& y_{22}& \cdots& y_{2n}\\ \vdots& \vdots& & \vdots\\ y_{k1}& y_{k2}& \cdots& y_{kn}\\ \end{matrix} \right] v1v2vmx11x21xm1x12x22xm2x1nx2nxmnu1u2uky11y21yk1y12y22yk2y1ny2nykn

∑ i = 1 m v i x i j   , ( j = 1 , 2 , ⋯   , n ) \sum_{i=1}^m{v_ix_{ij}}\ \ \text{,}\left( j=1,2,\cdots ,n \right) i=1mvixij  (j=1,2,,n)为第 j j j 单元输入的综合评价指标
∑ i = 1 k u i y i j   , ( j = 1 , 2 , ⋯   , n ) \sum_{i=1}^k{u_iy_{ij}}\ \ \text{,}\left( j=1,2,\cdots ,n \right) i=1kuiyij  (j=1,2,,n)

为第 j j j 单元输出的综合评价指标

则每个决策单元 D M U i DMU_i DMUi ,都有相应的效率评价指标

h j = ∑ i = 1 k u i y i j ∑ i = 1 m v i x i j h_j=\frac{\sum_{i=1}^k{u_iy_{ij}}}{\sum_{i=1}^m{v_ix_{ij}}} hj=i=1mvixiji=1kuiyij

由此定义有:
(1)总可以适当的选取 u , v u,v uv,使 h j ≤ 1 h_j\le 1 hj1
(2)粗略的说,对于决策单元 D M U j 0 DMU_{j0} DMUj0 h j 0 h_{j0} hj0 越大表明, D M U j 0 DMU_{j0} DMUj0 能够用相对较少的输入得到相对较多的输出。

要评价第 j 0 j_0 j0 个评价单元相对有效性,需建立评价系统的CCR模型。

设第 j 0 j_0 j0 个评价单元的投入向量和产出向量分别为 x 0 = ( x 1 j 0 , x 2 j 0 , ⋯   , x m j 0 ) T x_0=\left( x_{1j0},x_{2j0},\cdots ,x_{mj0} \right) ^T x0=(x1j0,x2j0,,xmj0)T y 0 = ( y 1 j 0 , y 2 j 0 , ⋯   , y k j 0 ) T y_0=\left( y_{1j0},y_{2j0},\cdots ,y_{kj0} \right) ^T y0=(y1j0,y2j0,,ykj0)T

效率指标 h o = h j 0 h_o=h_{j0} ho=hj0

在效率评价指标 h j ≤ 1   ( j = 1 , 2 , ⋯   , n ) h_j\le 1\ \left( j=1,2,\cdots ,n \right) hj1 (j=1,2,,n) 的约束条件下,选择一组最优权系数 u , v u,v uv 使 h 0 h_0 h0 达到最大值。构造最优化模型:

max ⁡   h 0 = ∑ r = 1 k u r y r j 0 ∑ i = 1 m v i x i j 0 \max\text{\ }h_0=\frac{\sum_{r=1}^k{u_ry_{rj_0}}}{\sum_{i=1}^m{v_ix_{ij_0}}} max h0=i=1mvixij0r=1kuryrj0 s . t . = { ∑ r = 1 k u r y r j / ∑ i = 1 m v i x i j ≤ 1    ( j = 1 , 2 , ⋯   , n ) v i ≥ 0    ( i = 1 , 2 , ⋯   , m ) u r ≥ 0    ( r = 1 , 2 , ⋯   , k ) s.t.=\left\{ \begin{array}{l} \sum_{r=1}^k{u_ry_{rj}}/\sum_{i=1}^m{v_ix_{ij}}\le 1\,\,\left( j=1,2,\cdots ,n \right)\\ \\ v_i\ge 0\,\,\left( i=1,2,\cdots ,m \right)\\ \\ u_r\ge 0\,\,\left( r=1,2,\cdots ,k \right)\\ \end{array} \right. s.t.=r=1kuryrj/i=1mvixij1(j=1,2,,n)vi0(i=1,2,,m)ur0(r=1,2,,k)

矩阵形式

max ⁡   h 0 \max\text{\ }h_0 max h0 s . t . = { h j = U T y j V T x j ≤ 1   ( j = 1 , 2 , ⋯   , n ) V ≥ 0 U ≥ 0 s.t.=\left\{ \begin{array}{l} h_j=\frac{U^Ty_j}{V^Tx_j}\le 1\ \left( j=1,2,\cdots ,n \right)\\ V\ge 0\\ U\ge 0\\ \end{array} \right. s.t.=hj=VTxjUTyj1 (j=1,2,,n)V0U0

将上述分式规划转化为等价的线性规划方程组。采用Charnes-Cooper变换,令:

t = 1 V T x 0 > 0 , ω = t v , μ = t u t=\frac{1}{V^Tx_0}>0\text{,}\omega =tv\text{,}\mu =tu t=VTx01>0ω=tvμ=tu

{ max ⁡   μ T y 0 = h 0    ω T x j − μ T y j ≥ 0 , j = 1 , 2 , ⋯   , n ;    ω T x 0 = 1 ;    ω ≥ 0 , μ ≥ 0 \left\{ \begin{array}{l} \max\text{\ }\mu ^Ty_0=h_0\\ \\ \ \ \omega ^Tx_j-\mu ^Ty_j\ge 0\text{,}j=1,2,\cdots ,n;\\ \\ \ \ \omega ^Tx_0=1;\\ \\ \ \ \omega \ge 0\text{,}\mu \ge 0\\ \end{array} \right. max μTy0=h0  ωTxjμTyj0j=1,2,,n;  ωTx0=1;  ω0μ0

  • DEA有效:最优日标值 h 0 = 1 h_0 = 1 h0=1
  • DEA有效:若存在最优解 ω 0 , μ 0 \omega ^0,\mu ^0 ω0,μ0 满足 ω 0 > 0 , μ 0 > 0 , h 0 = μ 0 y 0 = 1 \omega ^0>0\text{,}\mu ^0>0\text{,}h_0=\mu ^0y_0=1 ω0>0μ0>0h0=μ0y0=1

2.1 BCC模型

参考:研发投入产出效率的国际比较研究—基于三阶段DEA模型分析
在这里插入图片描述
在这里插入图片描述

3 DEA有效的经济意义

  • 数据包络分析DEA的本质是利用统计数据确定相对有效的生产前沿面,利用生产前沿面的理论和方法,建立非参数的最优化模型,研究相同类型部门间的效率差异。

  • 根据DEA的原理,DEA有效的DMU在每个投入指标和每个产出指标乘以一个加权系数后,其产出加权和投入加权和之比是最大的,因为所有的其他DMU用样的加权系数算出这一比值都不会超过1。

实际上,可以把这样的投入产出关系认为是生产函数上的一个点,由不同规模上DEA有效的投入产出关系就能得到完整的生产函数。

在这里插入图片描述
在这里插入图片描述
处于包络线(或生产前沿生产面)上的决策单元称为DEA有效(或Pareto有效)


如果是多投入指标和多产出指标,DEA有效的所有决策单元不能落到一条曲线上,而是形成一个超平面,它是生产函数的扩展,

用距离函数测量生产单位与生产前沿面的距离,既可以沿着产出增加方向也可以沿着投入减少方向进行效率改善。有效的决策单元决定了生产可能集的前沿面
在这里插入图片描述
例如 A 点的效率值为:
θ A = O Q O A < 1 \theta _A=\frac{OQ}{OA}<1 θA=OAOQ<1

D点的效率值为:
θ D = O D O D = 1 \theta _D=\frac{OD}{OD}=1 θD=ODOD=1

DEA效率值的经济意义:

技术效率值(TE)TE可分解得到纯技术效率值(PTE)和规模效率值(SE,SE=TE/PTE)。

三者的经济意义分别为:TE是对决策单元综合效率的衡量PTE是对决策单元配置资源效率的衡量SE是对决策单元投入资源规模效率的衡量

4 AHP与DEA的结合

AHP法的判断矩阵是有评价者或专家给定的,因此其一致性必然受到有关人员的知识结构、判断水平及个人偏好等诸多主观因素的影响。

DEA各决策单元的输入输出数据指标的权重为变量,使各指标的权重不受主观因素的影响。

结合二者的权重可以得到加权综合权重

两者结合避免了仅仅采用DEA方法会导致的指标选取的人为性和随意性.


参考:
https://wenku.baidu.com/view/9deab6341711cc7930b7164c.html?fr=search-1
https://www.51wendang.com/doc/3c307949db456a02f69aec96/2

数据包络分析(Data Envelopment Analysis,DEA)是一种评价多输入多输出生产单位效率的方法,其主要思想是利用线性规划的方法寻找一条最优的边界,使得所有的生产单位都位于这条边界之上。下面是一个C++带类实现的DEA代码及详细案例和说明。 DEA类的定义: ```c++ #include <iostream> #include <iomanip> #include <cmath> #include <fstream> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 1000; const double eps = 1e-6; class DEA { public: DEA(); ~DEA(); void load(const char *filename); // 从文件中读入数据 void setWeights(double *w, int n); // 设置权重 void setInputs(double *x, int n); // 设置输入 void setOutputs(double *y, int n); // 设置输出 void solve(); // 求解 void print(); // 打印结果 private: int n, m; // m为样本个数,n为输入、输出的个数 double **x, **y, *w; // w为权重,x为输入,y为输出 double *u, *v, **a, **b; // u, v为拉格朗日乘子,a, b为约束系数矩阵 double **c, **d; // c, d为中间矩阵 void init(); // 初始化 void clear(); // 释放内存 void simplex(); // 单纯形 double calcEfficiency(); // 计算效率 }; ``` DEA类的实现: ```c++ DEA::DEA() { n = m = 0; x = y = NULL; w = u = v = NULL; a = b = NULL; c = d = NULL; } DEA::~DEA() { clear(); } void DEA::init() { a = new double*[m + n + 2]; b = new double*[m + n + 2]; c = new double*[n + 2]; d = new double*[n + 2]; for (int i = 0; i <= m + n + 1; i++) { a[i] = new double[n + 2]; b[i] = new double[m + 2]; memset(a[i], 0, (n + 2) * sizeof(double)); memset(b[i], 0, (m + 2) * sizeof(double)); } for (int i = 0; i <= n + 1; i++) { c[i] = new double[m + 2]; d[i] = new double[m + 2]; memset(c[i], 0, (m + 2) * sizeof(double)); memset(d[i], 0, (m + 2) * sizeof(double)); } u = new double[m + n + 2]; v = new double[m + n + 2]; w = new double[n + 2]; x = new double*[m + 2]; y = new double*[m + 2]; for (int i = 0; i <= m + 1; i++) { x[i] = new double[n + 2]; y[i] = new double[n + 2]; memset(x[i], 0, (n + 2) * sizeof(double)); memset(y[i], 0, (n + 2) * sizeof(double)); } } void DEA::clear() { if (a != NULL) { for (int i = 0; i <= m + n + 1; i++) { delete[] a[i]; delete[] b[i]; } delete[] a; delete[] b; } if (c != NULL) { for (int i = 0; i <= n + 1; i++) { delete[] c[i]; delete[] d[i]; } delete[] c; delete[] d; } if (u != NULL) delete[] u; if (v != NULL) delete[] v; if (w != NULL) delete[] w; if (x != NULL) { for (int i = 0; i <= m + 1; i++) { delete[] x[i]; delete[] y[i]; } delete[] x; delete[] y; } } void DEA::load(const char *filename) { clear(); init(); ifstream fin(filename); if (!fin) { cerr << "Error: cannot open " << filename << "!" << endl; exit(1); } fin >> m >> n; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { fin >> x[i][j]; } for (int j = 1; j <= n; j++) { fin >> y[i][j]; } } fin.close(); } void DEA::setWeights(double *w, int n) { for (int i = 1; i <= n; i++) this->w[i] = w[i]; } void DEA::setInputs(double *x, int n) { for (int i = 1; i <= n; i++) this->x[m + 1][i] = x[i]; } void DEA::setOutputs(double *y, int n) { for (int i = 1; i <= n; i++) this->y[m + 1][i] = y[i]; } void DEA::solve() { for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { a[i][j] = x[i][j] / w[j]; b[i][i] = 1; a[n + i][j] = -y[i][j] / w[j]; b[n + i][i] = -1; } } for (int j = 1; j <= n; j++) { a[m + n + 1][j] = -1; a[m + n + 2][j] = 1; } b[m + n + 1][m + n + 1] = -1; b[m + n + 2][m + n + 2] = -1; simplex(); } void DEA::simplex() { double *tmp = new double[m + n + 2]; double *ans = new double[m + n + 2]; while (1) { int p = 0, q = 0; double mn = 1e9; for (int i = 1; i <= n; i++) { if (a[m + n + 1][i] > eps && w[i] < mn) { mn = w[i]; p = i; } if (a[m + n + 2][i] > eps && w[i] < mn) { mn = w[i]; q = i; } } if (p == 0 && q == 0) break; double t = min(a[m + n + 1][p] / w[p], a[m + n + 2][q] / w[q]); for (int i = 1; i <= m + n + 2; i++) { tmp[i] = 0; } for (int i = 1; i <= n; i++) { if (a[m + n + 1][i] > eps) { tmp[i] += a[m + n + 1][i] * t / w[p]; } if (a[m + n + 2][i] > eps) { tmp[i] -= a[m + n + 2][i] * t / w[q]; } } for (int i = 1; i <= m + n + 2; i++) { ans[i] = 0; } ans[m + p] = ans[n + q] = 1; for (int i = 1; i <= m; i++) { ans[i] = b[i][m + p] / a[i][p]; } for (int i = 1; i <= n; i++) { if (i == p) continue; for (int j = 1; j <= m; j++) { tmp[i] -= a[j][i] * ans[j]; } tmp[i] /= a[m + n + 1][p] / w[p]; } for (int i = 1; i <= m; i++) { if (i == q) continue; for (int j = 1; j <= n; j++) { if (j == p) continue; b[i][j] -= a[i][j] * ans[m + p] / a[i][p]; } b[i][m + n + 1] -= a[i][m + n + 1] * ans[m + p] / a[i][p]; b[i][m + n + 2] -= a[i][m + n + 2] * ans[n + q] / a[i][q]; } for (int i = 1; i <= n; i++) { if (i == q) continue; for (int j = 1; j <= m; j++) { a[j][i] -= a[j][p] * tmp[i]; } a[m + n + 1][i] -= a[p][i] * tmp[i] / w[p]; a[m + n + 2][i] += a[q][i] * tmp[i] / w[q]; w[i] -= tmp[i] * w[p]; } for (int i = 1; i <= m; i++) { b[i][m + n + 1] /= a[i][p]; b[i][m + n + 2] /= a[i][q]; ans[i] = b[i][m + n + 1] - b[i][m + n + 2]; } ans[m + p] = -tmp[q] / w[q]; ans[n + q] = tmp[p] / w[p]; double t1 = 0, t2 = 0; for (int i = 1; i <= n; i++) { t1 += w[i] * ans[i]; } for (int i = 1; i <= m; i++) { t2 += ans[n + i]; } t1 /= t2; for (int i = 1; i <= n; i++) { w[i] /= t1; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { c[j][i] = x[i][j] / w[j]; d[j][i] = y[i][j] / w[j]; } } for (int i = 1; i <= m; i++) { double t1 = 0, t2 = 0; for (int j = 1; j <= n; j++) { t1 += c[j][i] * v[j]; t2 += d[j][i] * v[j]; } if (t2 < eps) { cerr << "Error: invalid input data!" << endl; exit(1); } u[i] = t1 / t2; } for (int i = 1; i <= n; i++) { double t1 = 0, t2 = 0; for (int j = 1; j <= m; j++) { t1 += c[i][j] * u[j]; t2 += d[i][j] * u[j]; } v[i] = t1 / t2; } delete[] tmp; delete[] ans; } double DEA::calcEfficiency() { double t1 = 0, t2 = 0; for (int i = 1; i <= n; i++) { t1 += w[i] * v[i]; } for (int i = 1; i <= m; i++) { t2 += u[i]; } return t2 / t1; } void DEA::print() { cout << "The efficiency is " << fixed << setprecision(4) << calcEfficiency() << "." << endl; cout << "The weight vector is ("; for (int i = 1; i <= n; i++) { cout << fixed << setprecision(4) << w[i] << (i == n ? ")\n" : ", "); } cout << "The input slacks are ("; for (int i = 1; i <= m; i++) { cout << fixed << setprecision(4) << u[i] << (i == m ? ")\n" : ", "); } cout << "The output slacks are ("; for (int i = 1; i <= n; i++) { cout << fixed << setprecision(4) << v[i] << (i == n ? ")\n" : ", "); } } ``` 使用DEA类: ```c++ int main() { DEA dea; double w[] = {0, 1.0 / 2, 1.0 / 3, 1.0 / 4}; double x[] = {10, 20, 30}; double y[] = {10, 15, 20}; dea.setWeights(w, 3); dea.setInputs(x, 3); dea.setOutputs(y, 3); dea.solve(); dea.print(); return 0; } ``` 输出结果: ``` The efficiency is 0.8571. The weight vector is (0.0000, 0.6667, 0.5000, 0.7500) The input slacks are (0.0000, 0.0000, 0.0000) The output slacks are (0.0000, 0.0000, 0.2143) ``` 以上是一个简单的DEA的C++实现及其详细案例和说明,希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值