2020-07-26 17:09:05 +08:00
|
|
|
package mathx
|
|
|
|
|
|
|
|
import "math"
|
|
|
|
|
2020-08-07 15:28:40 +08:00
|
|
|
const epsilon = 1e-6
|
|
|
|
|
2021-02-21 20:47:01 +08:00
|
|
|
// CalcEntropy calculates the entropy of m.
|
2020-08-06 23:06:26 +08:00
|
|
|
func CalcEntropy(m map[interface{}]int) float64 {
|
2020-08-07 15:28:40 +08:00
|
|
|
if len(m) == 0 || len(m) == 1 {
|
|
|
|
return 1
|
|
|
|
}
|
2020-07-26 17:09:05 +08:00
|
|
|
|
2020-08-07 15:28:40 +08:00
|
|
|
var entropy float64
|
2020-08-06 23:06:26 +08:00
|
|
|
var total int
|
|
|
|
for _, v := range m {
|
|
|
|
total += v
|
|
|
|
}
|
|
|
|
|
2020-07-26 17:09:05 +08:00
|
|
|
for _, v := range m {
|
|
|
|
proba := float64(v) / float64(total)
|
2020-08-07 15:28:40 +08:00
|
|
|
if proba < epsilon {
|
|
|
|
proba = epsilon
|
|
|
|
}
|
2020-07-26 17:09:05 +08:00
|
|
|
entropy -= proba * math.Log2(proba)
|
|
|
|
}
|
|
|
|
|
|
|
|
return entropy / math.Log2(float64(len(m)))
|
|
|
|
}
|