# Why does downsampling leads classification to only predict one class?

I have a multi-class classification problem. It performs quite well but on the least represented classes it doesn't. Indeed, here is the distribution :

And here are the classification results of my former classification (I took the numbers off the labels):

.

Therefore I tried to improve classificationby downsampling the marjority classes

import os
from sklearn.utils import resample

# rebalance data
#df = resample_data(df)

if True:

count_class_A, count_class_B,count_class_C, count_class_D,count_class_E, count_class_F, count_class_G = df.grade.value_counts()
count_df = df.shape[0]
class_dict = {"A": count_class_A,"B" :count_class_B,"C": count_class_C,"D": count_class_D,"E": count_class_E, "F": count_class_F, "G": count_class_G}
counts = [count_class_A, count_class_B,count_class_C, count_class_D,count_class_E, count_class_F, count_class_G]
median = statistics.median(counts)

for key in class_dict:
if class_dict[key]>median:
print(key)
#replace=False,    # sample without replacement
#n_samples=int(count_df/7),     # to match minority class
#random_state=123)
# Divide the data set into training and test sets
x_train, x_test, y_train, y_test = split_data(df, APPLICANT_NUMERIC + CREDIT_NUMERIC,
APPLICANT_CATEGORICAL,
TARGET,
test_size = 0.2,
#row_limit = os.environ.get("sample"))
row_limit = 552160)


However it the results where catastrophic. The model accuracy and the model loss looked to have some issues :

And everything was classified in "A" on the test set.

• You sure you are really down sampling the data? Does df shape changes? This line df[df.grade == key] = df[df.grade == key].sample(int(count_df/7), replace = False) seems weird to me. – yoav_aaa Sep 19 '19 at 12:08
• I'm not sure anymore. I also tried with df.loc[df.grade == key] = df.loc[df.grade == key].sample(. How would you have done it ? – Revolucion for Monica Sep 19 '19 at 12:16

For the looks of it the sampling method you used isnt doing the trick. The way you use pandas slicing and assignment is a bit off.

Something like this might work:

dfs = []
for key in class_dict:

if class_dict[key] > median:
factor = int(count_df/7)
key_df = df[df.grade == key].sample(factor, replace=False)
else: