I am working on thousands of datasets. Many of them are "unbalanced"; either a multi-class list with highly skewed distribution (For example, three categories with the ratio of 3500:300:4 samples) or a continuous number with skewed distribution. I am looking for some metric that can say "How badly unbalanced" the dataset is. Is there such a metric?

Eventually, I want to score these datasets according to their balanced metric and provide a different balancing/ machine learning solution for each of them. I prefer a python solution if it exists.


You could use the Shannon entropy as a measure of balance.

On a data set of $n$ instances, if you have $k$ classes of size $c_i$ you can compute entropy as follows: $$ H = -\sum_{ i = 1}^k \frac{c_i}{n} \log{ \frac{c_i}{n}}. $$

This is equal to:

  • $0$ when there is one single class. In other words, it tends to $0$ when your data set is very unbalanced
  • $\log{k}$ when all your classes are balanced of the same size $\frac{n}{k}$

Therefore, you could use the following measure of Balance for a data set: $$ \mbox{Balance} = \frac{H}{\log{k}} = \frac{-\sum_{ i = 1}^k \frac{c_i}{n} \log{ \frac{c_i}{n}}. } {\log{k}} $$ which is equal to:

  • $0$ for a unbalanced data set
  • $1$ for a balanced data set
  • 2
    $\begingroup$ Note that any logarithm base is fine because the normalization makes the formula invariant to the base. $\endgroup$
    – Simone
    Oct 13 '16 at 11:36
  • $\begingroup$ @Simone, do you know if this balance equation is a standard balance measure in the literature? $\endgroup$ Feb 16 '17 at 20:44
  • $\begingroup$ Not in particular. I think I saw using entropy as measure of balance in literature. Other times I saw using $\min{\{c_i\}}/\max{\{c_i\}}$. I guess it does not really matter. They are usually just used as guidance to check the degree of balance of a data set. $\endgroup$
    – Simone
    Feb 17 '17 at 9:35
  • 1
    $\begingroup$ @Simone, interesting. Other two options can be using KL distance or cross entrpoy to measure the "distance" of {c_i}/n probabilities to 1/k. For KL distance this should be zero of the data-set is balanced and for cross entropy it should be come the log(k) for balanced dataset $\endgroup$
    – oak
    Oct 29 '18 at 14:19
  • 1
    $\begingroup$ Simone's suggestion is referred to as the "Shannon Diversity Index" and is common in ecology research. Here is some more information: itl.nist.gov/div898/software/dataplot/refman2/auxillar/… $\endgroup$ Nov 5 '20 at 23:21

Based on the answer of Simone, I wrote this short python code to calculate balance, which works very well for me.

def balance(seq):
    from collections import Counter
    from numpy import log
    n = len(seq)
    classes = [(clas,float(count)) for clas,count in Counter(seq).items()]
    k = len(classes)
    H = -sum([ (count/n) * log((count/n)) for clas,count in classes]) #shannon entropy
    return H/log(k)

Thank you very much!

  • $\begingroup$ for me, I had to change .iteritems() for .items() only, then it worked! thanks! $\endgroup$ Aug 13 '20 at 21:31

I had the same problem and looked for some metric to measure the degree of unbalance in my datasets, but I did not find any. Then, I created one that varies between 0 (perfectly balanced, the number of samples in all categories is the same) and 1 (extremely badly balanced, when the number of samples in all categories, except one, is 1 and the rest of samples belong to a single category)

The formula is:

unbalance= (max_nmb_of_samples - min_nmb_of_samples)/(total_nmb_of_samples - nclass)

Examples: For a balanced case max_nmb_of_samples=min_nmb_of_samples, then unbalance=0

For a three class case (nclass=3) having 500, 300 and 100 samples each, we have:

max_nmb_of_samples=500, min_nmb_of_samples=100, and total_nmb_of_samples = 900, then

unbalance = (500-100)/(900-3) = 0.446

In an extreme 3 classes case we have 500, 1 and 1 samples in each class, then max_nmb_of_samples=500, min_nmb_of_samples=1 and total_nmb_of_samples=502, then

unbalance = (500-1)/(502-3) = 1


Not the answer you're looking for? Browse other questions tagged or ask your own question.