nunosempere.github.io/ea/ShapleyValueCode.R

81 lines
2.7 KiB
R
Raw Normal View History

2019-10-10 08:49:38 +00:00
## Code in R, for the Addendum of [Shapley Values: Better than Counterfactuals](https://forum.effectivealtruism.org/posts/XHZJ9i7QBtAJZ6byW/shapley-values-better-than-counterfactuals)
```
AMV <-function(foundations, roomforfoundingfoundations, roomforfoundingOP, projects, numprojects){
avm = ValueOfFunded((foundations*roomforfoundingfoundations + roomforfoundingOP), projects, numprojects) - ValueOfFunded(foundations*roomforfoundingfoundations, projects, numprojects)
# Note that the code could easily be optimized by computing both calls to ValueOfFunded at the same time. However, this loses clarity.
return(avm)
}
ValueOfFunded <-function(room, projects, numprojects){
value = 0
for(k in c(1:numprojects)){
#print(c("k=",k))
value = value + ProbabilityThatKwillBeAmongTheRSmallestNumbers(k,room,projects, numprojects)*Impact(k)
}
#print(c("value=", value))
return(value)
}
ProbabilityThatKwillBeAmongTheRSmallestNumbers <-function(k,r,q,n){
#print(c("k=",k,"r=", r,"q=",q,"n=",n))
## Probability that K is the i-th smallest number =
## = choose(k-1,i-1)*choose(n-1,p-i-1)/choose(n,p)
p=0
for(i in c(0:r)){
# we notice that all of the terms contain the factor choose(n,p), so we can leave it at the end.
p=p+(choose(k-1,i-1)*choose(n-k,q-i))
}
p = p/ choose(n,q)
return(p)
}
ComputeShapleyValue <-function(numfoundations, roomforfoundingfoundations, roomforfoundingOP, numprojects){
ShapleyValue = 0
for(Foundations in c(0:numfoundations)){
for(Projects in c(0:numprojects)){
print(paste("We're at: (",Foundations,"/", Projects, ") of (", numfoundations,",", numprojects, ")" , sep=""))
ShapleyValue = ShapleyValue+choose(numfoundations,Foundations)*choose(numprojects,Projects)*AMV(Foundations, roomforfoundingfoundations, roomforfoundingOP, Projects, numprojects)/choose(numprojects+numfoundations, Foundations+Projects)
}
}
return(ShapleyValue/(numfoundations+numprojects+1))
}
ComputeShapleyValue(1, 1, 1, 3)
ComputeShapleyValue(1, 1, 2, 3)
ComputeShapleyValue(numfoundations=1, roomforfoundingfoundations=1, roomforfoundingOP=1, numprojects=3)
Impact <- function(k){
#return(0.99^k)
return(2/(k^2))
}
## IT WORKS!!!!
start <- Sys.time()
ComputeShapleyValue(numfoundations=10, roomforfoundingfoundations=10, roomforfoundingOP=10, numprojects=500)
end <- Sys.time()
end-start
sum(0.99^c(1:500))
start <- Sys.time()
ComputeShapleyValue(numfoundations=10, roomforfoundingfoundations=20, roomforfoundingOP=250, numprojects=500)
end <- Sys.time()
end-start
sum(0.99^c(1:500))
# With a different impact measure.
start <- Sys.time()
ComputeShapleyValue(numfoundations=10, roomforfoundingfoundations=20, roomforfoundingOP=250, numprojects=500)
end <- Sys.time()
end-start
sum(2/(c(1:1000))^2)```
```