CCR 모형을 이용한 효율성 계산
투입방향 CCR 모형

by SungYong


Posted on Aug. 3, 2017, 3:38 p.m.



투입방향 CCR 승수모형

투입방향 CCR 승수모형이라는 조건은 아래와 같은 제약조건으로 하는 것이다. 즉, 투입은 항상 1로 고정되어 있다고 보고 하는 방법이다.

$$\begin{array}{c} Max\,{E_k} = \sum\limits_{r = 1}^s {{y_{rk}}{u_{rk}}} \\ s.t.\,\sum\limits_{i = 1}^m {{x_{ik}}{v_{ik}}} = 1\\ \sum\limits_{r = 1}^s {{y_{rk}}{u_{rk}}} - \sum\limits_{i = 1}^m {{x_{ik}}{v_{ik}}} \le 0 & (j = 1,2, \cdots ,n)\\ {v_{ik}} \ge \varepsilon \\ {u_{rk}} \ge \varepsilon \end{array}$$

그럼 이 조건에서 아래와 같은 문제를 풀어보자. 교육비와 정교사 비율은 투입요소이고, 국어점수와 과학점수는 산출요소이다.

수식으로만 봐서는 이해가 어려우니까 실제 문제를 풀어보자. 아래 문제는 고길곤 교수의 효율성 분석이론42페이지에 있는 문제다. (교수님도 다른 논문인지 책인지에서 인용했다고 한다.)

학교 교육비(백만원) 정교사비율(%) 국어점수 과학점수
1 8.939 64.3 25.2 223
2 8.625 99 28.2 287
3 10.813 99.6 29.4 317
4 10.638 96 26.4 291
5 6.24 96.2 27.2 295
6 4.719 79.9 25.5 222

$k=1$인 경우, 즉 1번 학교부터 한번 해보자.

투입방향 CCR모형 첫번째 제약조건은

$$\begin{array}{c} \sum\limits_{i = 1}^m {{x_{i1}}{v_{i1}}} = 1\\ {x_{11}}{v_{11}} + {x_{11}}{v_{21}} = 1\\ 8.939 \cdot {v_{11}} + 64.3 \cdot {v_{21}} = 1 \end{array}$$

이 된다.

그리고 다른 제약조건을 실제 숫자로 쓰면 아래와 같다.

$$\begin{array}{l} \sum\limits_{r = 1}^s {{y_{r1}}{u_{r1}}} - \sum\limits_{i = 1}^m {{x_{i1}}{v_{i1}}} \le 0\\ 25.2 \cdot {u_{11}} + 223 \cdot {u_{21}} - 1 \le 0\\ 28.2 \cdot {u_{11}} + 287 \cdot {u_{21}} - 8.625 \cdot {v_{11}} - 99.0 \cdot {v_{21}} \le 0\\ 29.4 \cdot {u_{11}} + 317 \cdot {u_{21}} - 10.813 \cdot {v_{11}} - 99.6 \cdot {v_{21}} \le 0\\ 26.4 \cdot {u_{11}} + 291 \cdot {u_{21}} - 10.638 \cdot {v_{11}} - 96.0 \cdot {v_{21}} \le 0\\ 27.2 \cdot {u_{11}} + 295 \cdot {u_{21}} - 6.240 \cdot {v_{11}} - 96.2 \cdot {v_{21}} \le 0\\ 25.5 \cdot {u_{11}} + 222 \cdot {u_{21}} - 4.719 \cdot {v_{11}} - 79.9 \cdot {v_{21}} \le 0 \end{array}$$

$k=1$일 때,

$${v_{21}} = \frac{{1 - 8.939 \cdot {v_{11}}}}{{64.3}}$$

라는 제약조건을 알고 있으므로 $v_{21}$을 정리하면,

$$\begin{array}{l} \sum\limits_{r = 1}^s {{y_{r1}}{u_{r1}}} - \sum\limits_{i = 1}^m {{x_{i1}}{v_{i1}}} \le 0\\ 25.2 \cdot {u_{11}} + 223 \cdot {u_{21}} \le 1\\ 28.2 \cdot {u_{11}} + 287 \cdot {u_{21}} - \left( {8.625 - \frac{{99.0 \cdot 8.939}}{{64.3}}} \right) \cdot {v_{11}} \le \frac{{99.0}}{{64.3}}\\ 29.4 \cdot {u_{11}} + 317 \cdot {u_{21}} - \left( {10.813 - \frac{{99.6 \cdot 8.939}}{{64.3}}} \right) \cdot {v_{11}} \le \frac{{99.6}}{{64.3}}\\ 26.4 \cdot {u_{11}} + 291 \cdot {u_{21}} - \left( {10.638 - \frac{{96.0 \cdot 8.939}}{{64.3}}} \right) \cdot {v_{11}} \le \frac{{96.0}}{{64.3}}\\ 27.2 \cdot {u_{11}} + 295 \cdot {u_{21}} - \left( {6.240 - \frac{{96.2 \cdot 8.939}}{{64.3}}} \right) \cdot {v_{11}} \le \frac{{96.2}}{{64.3}}\\ 25.5 \cdot {u_{11}} + 222 \cdot {u_{21}} - \left( {4.719 - \frac{{79.1 \cdot 8.939}}{{64.3}}} \right) \cdot {v_{11}} \le \frac{{79.1}}{{64.3}} \end{array}$$

이 된다.

python scipy를 이용한 simplex method 해결

python 라이브러리 중에 scipy라는게 있다. 여러가지 계산을 용이하게 해주는 고마운 도구인데 이 문제도 scipy의 linprog라는 걸 이용해서 해결할 수 있다.

linprog는 주어진 식을 최소화 시켜주는 함수인데, 투입방향 CCR 승수모형은 투입은 1이라고 가정한 상태에서 산출을 최대화 시키는 것을 찾는 방법이므로, 맨 위의 식을 음수를 곱한 값을 최소화 하는 것으로 바꿔주면 된다.

$$Min\,{-E_k} = - \sum\limits_{r = 1}^s {{y_{rk}}{u_{rk}}} $$

위 식을 linprog에서 선호하는 형태로 식을 행렬과 벡터로 표현해보면,

$$Minimize:\left[ {\begin{array}{*{20}{c}} { - {y_{1k}}}&{ - {y_{2k}}} \end{array}} \right]\left\{ {\begin{array}{*{20}{c}} {{u_{1k}}}\\ {{u_{2k}}} \end{array}} \right\}$$

이 되고, $k=1$이니까

$$Minimize:\left[ {\begin{array}{*{20}{c}} { - 25.2}&{ - 223} \end{array}} \right]\left\{ {\begin{array}{*{20}{c}} {{u_{1k}}}\\ {{u_{2k}}} \end{array}} \right\}$$

이 된다.

위의 부등식을 행렬 형태로 표현해보면 아래와 같다.

$$\left[ {\begin{array}{*{20}{c}} {25.2}&{223}&0\\ {28.2}&{287}&{ - \left( {8.625 - \frac{{99.0 \cdot 8.939}}{{64.3}}} \right)}\\ {29.4}&{317}&{ - \left( {10.813 - \frac{{99.6 \cdot 8.939}}{{64.3}}} \right)}\\ {26.4}&{291}&{ - \left( {10.638 - \frac{{96.0 \cdot 8.939}}{{64.3}}} \right)}\\ {27.2}&{295}&{ - \left( {6.240 - \frac{{96.2 \cdot 8.939}}{{64.3}}} \right)}\\ {25.5}&{222}&{ - \left( {4.719 - \frac{{79.1 \cdot 8.939}}{{64.3}}} \right)} \end{array}} \right]\left\{ {\begin{array}{*{20}{c}} {{u_{11}}}\\ {{u_{21}}}\\ {{v_{11}}} \end{array}} \right\} \le \left\{ {\begin{array}{*{20}{c}} 1\\ {\frac{{99.0}}{{64.3}}}\\ {\frac{{99.6}}{{64.3}}}\\ {\frac{{96.0}}{{64.3}}}\\ {\frac{{96.2}}{{64.3}}}\\ {\frac{{79.1}}{{64.3}}} \end{array}} \right\}$$

이것을 파이썬으로 표현하면 아래 코드와 같다.

from scipy.optimize import linprog

c = [-25.2, -223, 0]
A = [
        [25.2, 223, 0],
        [28.2, 287, -(8.625-(99.0*8.939)/64.3)],
        [29.4, 317, -(10.813-(99.6*8.939)/64.3)],
        [26.4, 291, -(10.683-(96.0*8.939)/64.3)],
        [27.2, 295, -(6.240-(96.2*8.939)/64.3)],
        [25.5, 222, -(4.719-(79.1*8.939)/64.3)]
     ]


b = [1, 99.0/64.3, 99.6/64.3, 96.0/64.3, 96.2/64.3, 79.1/64.3]

ep = 0
u1_bnds = (ep, None)
u2_bnds = (ep, None)
v1_bnds = (ep, None)

res = linprog(c, A, b, bounds=(u1_bnds, u2_bnds, v1_bnds), options={"disp": True})
print(res)

결과는 아래와 같다.

Optimization terminated successfully.
         Current function value: -1.000000  
         Iterations: 1
     fun: -1.0
 message: 'Optimization terminated successfully.'
     nit: 1
   slack: array([ 0.        ,  0.25266234,  0.12746445,  0.18806882,  0.17324202,
        0.23465538])
  status: 0
 success: True
       x: array([ 0.       ,  0.0044843,  0.       ])

해석을 해보면, 효율성은 $1$이 나왔고, $u_1=0$, $u_2=0.0044843$, $v_1=0$이라는 뜻이다.

아직 다섯번 더 해야 한다. 따라서 일반화가 필요한 시점이다.

파이썬 코드 리팩토링하기

상수로 되어 있던 것 변수로 전환하기

천리길도 한걸음부터라고 했다. 일단 상수로 되어 있는 것을 변수로 선언해보자.

from scipy.optimize import linprog

x1 = [8.939, 8.625, 10.813, 10.638, 6.24, 4.719]
x2 = [64.3, 99, 99.6, 96, 96.2, 79.9]
y1 = [25.2, 28.2, 29.4, 26.4, 27.2, 25.5]
y2 = [223, 287, 317, 291, 295, 222]

n = len(x1)
k = 0

c = [-y1[k], -y2[k], 0]

A = []
for i in range(n):
    if i == k:
        A.append([y1[k], y2[k], 0])
    else:
        A.append([y1[i], y2[i], -(x1[i]-(x2[i]*x1[k])/x2[k])])


b = []
for i in range(n):
    if i == k:
        b.append(1)
    else:
        b.append(x2[i]/x2[k])

ep = 0
u1_bnds = (ep, None)
u2_bnds = (ep, None)
v1_bnds = (ep, None)

res = linprog(c, A, b, bounds=(u1_bnds, u2_bnds, v1_bnds), options={"disp": True})
print(res)

결과는 동일하게 나온다.

9번 라인의 k=0k=1로 수정해서 돌리면, 아래와 같이 효율성은 $0.909613$이 나왔고, $u_1=0$, $u_2=0.00316938$, $v_1=0.01716388$이라는 결과가 나왔다.

Optimization terminated successfully.
         Current function value: -0.909613  
         Iterations: 2
     fun: -0.90961320007888569
 message: 'Optimization terminated successfully.'
     nit: 2
   slack: array([ 0.        ,  0.0903868 ,  0.03802325,  0.08644313,  0.        ,
        0.06498631])
  status: 0
 success: True
       x: array([ 0.        ,  0.00316938,  0.01716388])

이렇게 k를 0~5로 변경하면서 p.55의 표 3.5와 같은 결과를 얻을 수 있다.


아직 댓글이 없습니다. 첫번째로 댓글을 남겨보세요.


Blog Search

Blog Categories

Side Widget Well

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero.