我将 CCR 数据包络分析模型应用于股票数据之间的基准测试。为此,我正在运行此处发表的 DEA 论文中的 R 代码。本文档使用 lpSolve 解决线性问题。lpSolve 的文档在这里。
本文档附带有关如何在 R 中实现以下模型的分步说明。
背景资料:
数据包络分析 (=DEA) 是一种面向数据的方法,用于评估称为决策单元的一组实体的性能,这些实体将多个数据输入转换为多个数据输出。DEA 用于评估和比较决策单元 (DMU) 的性能通过考虑生产单位与效率边界的接近程度来确定生产单位的相对效率。
我们假设有 n 个 DMU 需要评估。每个 DMU 消耗不同数量的不同输入以产生不同的输出。具体来说就是消耗输入量,产生输出量。我们进一步假设 , ≥ 0 并且每个 DMU 至少有一个正输入和一个正输出值。在 CCR 模型中,目标是确定权重,使用线性规划来最大化每个决策单元的复合效率。这是由比率定义的:
然后变成这样的线性问题:
应用:
我将此效率模型应用于股票数据 CAPM 风险因素:
这是一个 5 个输入 - 1 个输出的案例
这里的目标是为分析的每个资产找到“最佳”权重集(1、1…5)。此处使用的术语“最佳”表示当这些权重分配给所有 DMU / Stocks (1...10) 的输入和输出时,上述比率相对于所有其他比率最大化。
这是经过标准化的原始样本 z 得分数据,所有值都介于 0 和 1 之间。
> dput(testdfst)
structure(list(Name = structure(1:10, .Label = c("Stock1", "Stock2",
"Stock3", "Stock4", "Stock5", "Stock6", "Stock7", "Stock8", "Stock9",
"Stock10"), class = "factor"), Date = structure(c(14917, 14917,
14917, 14917, 14917, 14917, 14917, 14917, 14917, 14917), class = "Date"),
`(Intercept)` = c(0.454991569278089, 1, 0, 0.459437188169979,
0.520523252955415, 0.827294243132907, 0.642696631099892,
0.166219881886161, 0.086341470900152, 0.882092217743293),
rmrf = c(0.373075150411683, 0.0349067218712968, 0.895550280607866,
1, 0.180151549474574, 0.28669170468735, 0.0939821798173586,
0, 0.269645291515763, 0.0900619760898984), smb = c(0.764987877309785,
0.509094491489323, 0.933653313048327, 0.355340700554647,
0.654000372286503, 1, 0, 0.221454091364611, 0.660571586102851,
0.545086931342479), hml = c(0.100608151187926, 0.155064872867367,
1, 0.464298576152336, 0.110803875258027, 0.0720803195598597,
0, 0.132407005239869, 0.059742053684015, 0.0661623383303703
), rmw = c(0.544512524466665, 0.0761995312858816, 1, 0, 0.507699534880555,
0.590607506295898, 0.460148690870041, 0.451871218073951,
0.801698199214685, 0.429094840372901), cma = c(0.671162426988512,
0.658898571758625, 0, 0.695830176886926, 0.567814542084284,
0.942862571603074, 1, 0.37571611336359, 0.72565234813082,
0.636762557753099), Returns = c(0.601347600017365, 0.806071701848376,
0.187500487065719, 0.602971876359073, 0.470386289298666,
0.655773224143057, 0.414258177255333, 0, 0.266112191477882,
1)), .Names = c("Name", "Date", "(Intercept)", "rmrf", "smb",
"hml", "rmw", "cma", "Returns"), row.names = c("Stock1.2010-11-04",
"Stock2.2010-11-04", "Stock3.2010-11-04", "Stock4.2010-11-04",
"Stock5.2010-11-04", "Stock6.2010-11-04", "Stock7.2010-11-04",
"Stock8.2010-11-04", "Stock9.2010-11-04", "Stock10.2010-11-04"
), class = "data.frame")
我现在通过从开头提到的论文中提取的 R 代码运行上述数据。请注意,testdfst
数据框中的截距变量被排除在计算之外。
require(lpSolve)
dea_results <- list()
namesDMU <- testdfst[1]
inputs <- testdfst[c(4,5,6,7,8)]
outputs <- testdfst[9]
N <- dim(testdfst)[1] # number of DMU
s <- dim(inputs)[2] # number of inputs
m <- dim(outputs)[2] # number of outputs
f.rhs <- c(rep(0,N),1) # RHS constraints
f.dir <- c(rep("<=",N),"=") # directions of the constraints
aux <- cbind(-1*inputs,outputs) # matrix of constraint coefficients in (6)
for (i in 1:N) {
f.obj <- c(0*rep(1,s),outputs[i,]) # objective function coefficients
f.con <- rbind(aux, c(as.matrix(inputs[i,]), rep(0, m))) # add LHS of bTz=1
results <-lp("max",f.obj,f.con,f.dir,f.rhs,scale=1,compute.sens=TRUE) # solve LPP
multipliers <- results$solution # input and output weights
efficiency <- results$objval # efficiency score
duals <- results$duals # shadow prices
if (i==1) {
weights <- multipliers
effcrs <- efficiency
lambdas <- duals [seq(1,N)]
} else {
weights <- rbind(weights,multipliers)
effcrs <- rbind(effcrs , efficiency)
lambdas <- rbind(lambdas,duals[seq(1,N)])
}
}
report <- as.data.frame(cbind(effcrs,weights))
colnames(report) <- c('efficiency',names(inputs),
names(outputs)) # header
rownames(report) <- namesDMU[,1]
代码说明:
可能与我的问题有关: 注意 z >= 0 部分?如果我错了,请纠正我,但 lpSolve 必须默认采用这个,因为这个限制不直接包含在代码中?如果我能正确识别这部分,我可以对其进行调整以解决我的问题。
问题:
这是最终结果:
> report
efficiency rmrf smb hml rmw cma Returns
Stock1 0.5674100 0 0.000000 0.1769187 0.0000000 1.4634319 0.9435640
Stock2 1.0000000 0 0.000000 0.0000000 0.7713486 1.4284803 1.2405844
Stock3 1.0000000 0 1.071061 0.0000000 0.0000000 7.4588210 5.3333195
Stock4 1.0000000 0 1.930968 0.0000000 0.7427269 0.4510419 1.6584521
Stock5 0.5218197 0 0.000000 0.2080023 0.0000000 1.7205486 1.1093429
Stock6 0.5498426 0 0.000000 9.3299443 0.0000000 0.3473408 0.8384645
Stock7 1.0000000 0 3.260381 0.0000000 0.0000000 1.0000000 2.4139536
Stock8 0.0000000 0 0.000000 0.0000000 2.2130199 0.0000000 0.0000000
Stock9 0.2756548 0 0.000000 11.5264372 0.0000000 0.4291132 1.0358592
Stock10 1.0000000 0 0.000000 0.1875005 0.0000000 1.5509620 1.0000000
在所有情况下,RMRF 输入的权重都被分配为 0。为了使这种效率措施与我应用它的上下文相关,有必要在每次计算中考虑所有 5 个输入。
我要解决的问题是进一步限制权重。我希望将所有 5 个输入合并到问题中,所以我想像这样限制“v”权重:
0.2 <= V(n) / V(n+1) <=5
这与
1/5 <= V(n) / V(n+1) <= 5/1
这样,所有权重都应限制为最大比任何其他权重大 5 倍,并且最小也小 5 倍。
我一直在检查模型中的每个变量,并尝试了一些不同的数据集。我还交换了数据帧中 rmrf 和 smb 的位置,试图查看是代码有问题还是数据有问题。
efficiency smb rmrf hml rmw cma Returns
Stock1 1.0000000 0.2540156 0.0000000 1.1812905 1.043781 0.03466956 1.000000
Stock2 1.0000000 1.2150960 0.0000000 0.5443910 2.854127 0.00000000 2.422061
Stock3 1.0000000 0.0000000 0.0000000 1.0000000 0.000000 1.48815164 1.104670
Stock4 1.0000000 1.2348830 0.0000000 0.0000000 4.088438 0.89216307 3.674087
Stock5 0.8151261 0.0000000 0.0000000 0.5921236 1.173539 0.61261329 1.231220
Stock6 0.1491688 0.0000000 0.0000000 2.8715984 1.262761 0.00000000 1.148347
Stock7 1.0000000 2.0599619 0.0000000 0.0000000 0.000000 1.03785902 1.520484
Stock8 1.0000000 0.8346388 0.1206426 0.0000000 1.862840 0.00000000 1.535768
Stock9 0.0000000 0.0000000 0.0000000 0.0000000 1.167498 0.00000000 0.000000
Stock10 0.8065724 0.0000000 0.6973118 2.9529776 1.318778 0.00000000 1.357774
在尝试了不同的数据集之后,似乎存在包含 RMRF 的例外情况(如上面的那个)。我开始相信我的问题的答案可能非常简单。该程序发现最好不将我的 RMRF 输入包含在计算中。对此的解决方案是对权重进行额外限制。
这是具有非标准化输入的解决方案示例(数据中的数字分布完全不同)
efficiency smb rmrf hml rmw cma Returns
Stock1 1 0 1.0775390 0 0 0 346.1943
Stock2 0 0 1.3576882 0 0 0 0.0000
Stock3 0 0 0.7443477 0 0 0 0.0000
Stock4 0 0 0.6879011 0 0 0 0.0000
Stock5 0 0 1.2115507 0 0 0 0.0000
Stock6 0 0 1.1305046 0 0 0 0.0000
Stock7 0 0 1.2472639 0 0 0 0.0000
Stock8 0 0 1.4552312 0 0 0 0.0000
Stock9 0 0 1.1937843 0 0 0 0.0000
Stock10 0 0 1.3569824 0 0 0 0.0000