Shapley-Shubik 指数是一种衡量投票权力的指标,它基于博弈论中的 Shapley 值的概念。Shapley-Shubik 指数可以用来分析在一个决策过程中,每个参与者对最终决策的贡献程度。
具体来说,Shapley-Shubik 指数反映了一个参与者在一个决策过程中成为“关键”参与者的概率。所谓“关键”参与者,是指如果该参与者不参与,原本可以通过的决议就无法通过。
Shapley-Shubik 指数的计算步骤如下:
列出所有可能的参与者排列组合。
对于每一种排列组合,计算该参与者是否为“关键”参与者。
统计每个参与者成为“关键”参与者的次数。
将每个参与者成为“关键”参与者的次数除以所有排列组合的总数,得到该参与者的 Shapley-Shubik 指数。
Shapley-Shubik 指数的取值范围是 [0, 1]。指数越大,表示该参与者在决策过程中的影响力越大。
在上市公司相关的研究中,Shapley-Shubik 指数可以用来衡量各股东的权力大小。本次课程中我们将以上市公司前 10 大股东份额数据为例,讲解如何在 Stata 中计算 Shapley-Shubik 指数。
一个简单的例子 考虑有四个团体,分别占据 40,39,11 和 11 个席位。总共是 101 个席位,决议通过的规则是 >= 51 票。计算每个团体的 Shapley-Shubik 权力指数。
一个简单的方法是借助这个在线应用:https://homepages.warwick.ac.uk/~ecaae/ssdirect.html
计算结果:
从 Shapley-Shubik 指数的计算过程中可以看到,如果增加一个团体,计算过程的耗时会增加 1 倍。
在 R 语言中可以使用 GameTheory 包的 ShapleyShubik() 函数计算 Shapley-Shubik 指数:
library( tidyverse) library( GameTheory) seats <- c ( 40 , 39 , 11 , 11 ) names <- c ( "A" , "B" , "C" , "D" ) SSI <- ShapleyShubik( 51 , seats, names ) summary( SSI)
#> #> Distribution of the agents #> #> A B C D #> 40 39 11 11 #> #> Minimum amount of votes to pass a vote: 51 #> #> Shapley-Shubik Power Index #> #> A B C D #> 0.5000000 0.1666667 0.1666667 0.1666667
我们也可以自己编程实现这一过程:
y <- c ( 40 , 39 , 11 , 11 ) quota <- 51 n <- length ( y) res1 <- permutations( n, n) res1
#> [,1] [,2] [,3] [,4] #> [1,] 1 2 3 4 #> [2,] 1 2 4 3 #> [3,] 1 3 2 4 #> [4,] 1 3 4 2 #> [5,] 1 4 2 3 #> [6,] 1 4 3 2 #> [7,] 2 1 3 4 #> [8,] 2 1 4 3 #> [9,] 2 3 1 4 #> [10,] 2 3 4 1 #> [11,] 2 4 1 3 #> [12,] 2 4 3 1 #> [13,] 3 1 2 4 #> [14,] 3 1 4 2 #> [15,] 3 2 1 4 #> [16,] 3 2 4 1 #> [17,] 3 4 1 2 #> [18,] 3 4 2 1 #> [19,] 4 1 2 3 #> [20,] 4 1 3 2 #> [21,] 4 2 1 3 #> [22,] 4 2 3 1 #> [23,] 4 3 1 2 #> [24,] 4 3 2 1
res2 <- apply( res1, 1 , function ( x) { x[ sum ( cumsum ( y[ x] ) < quota) + 1 ] } ) res2
#> [1] 2 2 3 3 4 4 1 1 1 4 1 3 1 1 1 4 1 2 1 1 1 3 1 2
Power <- matrix( NA , ncol = 1 , nrow = n) for ( i in 1 : n) { Power[ i, 1 ] <- sum ( res2 == i) } Power
#> [,1] #> [1,] 12 #> [2,] 4 #> [3,] 4 #> [4,] 4
#> [,1] #> [1,] 0.5000000 #> [2,] 0.1666667 #> [3,] 0.1666667 #> [4,] 0.1666667
计算上市公司前 5 大股东的权力指数 为了节约时间,这里我只计算了前 5 大股东的。data.dta 中存储了一些上市公司的前 10 大股东份额数据:
haven:: read_dta( "data.dta" ) -> df df
#> # A tibble: 100 × 12 #> stkcd year top1 top2 top3 top4 top5 top6 top7 #> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 600592 2013 0.379 0.0732 0.0600 0.0275 0.0250 0.0188 0.00740 #> 2 600692 2010 0.325 0.00960 0.00360 0.00340 0.00300 0.00270 0.00260 #> 3 603315 2018 0.577 0.0486 0.0444 0.0320 0.0188 0.0185 0.0185 #> 4 600580 2016 0.475 0.0592 0.0173 0.0173 0.0160 0.0142 0.0104 #> 5 600213 2020 0.510 0.00920 0.00840 0.00710 0.00590 0.00450 0.00450 #> 6 404 2011 0.299 0.0645 0.0396 0.0262 0.0208 0.0118 0.00930 #> 7 2559 2013 0.382 0.0590 0.0231 NA NA NA NA #> 8 895 2009 0.515 0.0397 0.0342 0.0206 0.0190 0.0169 0.0157 #> 9 300100 2012 0.642 0.0200 0.0112 0.00730 0.00510 0.00480 0.00460 #> 10 2120 2015 0.441 0.0349 0.0313 0.0134 0.0128 0.0117 0.00510 #> # ℹ 90 more rows #> # ℹ 3 more variables: top8 <dbl>, top9 <dbl>, top10 <dbl>
删除前 5 大股东份额小于 50% 的:
df %>% select( stkcd, year, paste0( "top" , 1 : 5 ) ) %>% rowwise( ) %>% mutate( total = sum ( c_across( contains( "top" ) ) , na.rm = T ) ) %>% ungroup( ) %>% filter( total >= 0.5 ) %>% mutate_at( vars( contains( "top" ) ) , ~ if_else( is.na ( .x) , 0 , .x) ) -> dfnew dfnew
#> # A tibble: 72 × 8 #> stkcd year top1 top2 top3 top4 top5 total #> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 600592 2013 0.379 0.0732 0.0600 0.0275 0.0250 0.564 #> 2 603315 2018 0.577 0.0486 0.0444 0.0320 0.0188 0.721 #> 3 600580 2016 0.475 0.0592 0.0173 0.0173 0.0160 0.584 #> 4 600213 2020 0.510 0.00920 0.00840 0.00710 0.00590 0.541 #> 5 895 2009 0.515 0.0397 0.0342 0.0206 0.0190 0.628 #> 6 300100 2012 0.642 0.0200 0.0112 0.00730 0.00510 0.685 #> 7 2120 2015 0.441 0.0349 0.0313 0.0134 0.0128 0.533 #> 8 688056 2020 0.368 0.241 0.0821 0.0553 0.00890 0.755 #> 9 2281 2015 0.454 0.0661 0.0192 0.0122 0.00960 0.561 #> 10 600481 2014 0.512 0.0119 0.00620 0.00590 0.00460 0.541 #> # ℹ 62 more rows
然后就可以计算了:
dfnew %>% select( - total) %>% nest( data = - c ( "stkcd" , "year" ) ) %>% mutate( res = map( data, function ( x) { ShapleyShubik( 0.5 , unlist( x) ) %>% summary( ) %>% as_tibble( ) %>% mutate( var = paste0( "Power" , 1 : 5 ) ) } ) ) -> dfb
dfb %>% unnest( data) %>% unnest( res) %>% spread( var, value)
#> # A tibble: 72 × 12 #> stkcd year top1 top2 top3 top4 top5 Power1 Power2 Power3 #> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 600592 2013 0.379 0.0732 0.0600 0.0275 0.0250 0.383 0.383 0.133 #> 2 603315 2018 0.577 0.0486 0.0444 0.0320 0.0188 1 0 0 #> 3 600580 2016 0.475 0.0592 0.0173 0.0173 0.0160 0.65 0.15 0.0667 #> 4 600213 2020 0.510 0.00920 0.00840 0.00710 0.00590 1 0 0 #> 5 895 2009 0.515 0.0397 0.0342 0.0206 0.0190 1 0 0 #> 6 300100 2012 0.642 0.0200 0.0112 0.00730 0.00510 1 0 0 #> 7 2120 2015 0.441 0.0349 0.0313 0.0134 0.0128 0.383 0.383 0.133 #> 8 688056 2020 0.368 0.241 0.0821 0.0553 0.00890 0.583 0.25 0.0833 #> 9 2281 2015 0.454 0.0661 0.0192 0.0122 0.00960 0.5 0.5 0 #> 10 600481 2014 0.512 0.0119 0.00620 0.00590 0.00460 1 0 0 #> # ℹ 62 more rows #> # ℹ 2 more variables: Power4 <dbl>, Power5 <dbl>
点击这里跳转到 RStata 短书平台获取附件:名师讲堂|使用 R 语言计算 Shapley-Shubik 权力指数:以上市公司前 10 大股东份额数据为例
评论