Апсемплинг набора данных с использованием pandas и sklearn — Python

У меня есть набор данных с одним классом, который очень несбалансирован (190 записей против 14810) на основе столбца «релевантность». Итак, я попытался повысить частоту дискретизации, и это сработало; но проблема в том, что у меня есть другая категория классов в другом столбце (1000 записей на каждый класс), и когда я просто повышаю выборку на основе столбца «релевантность», эти классы становятся несбалансированными. Есть ли способ увеличить «релевантность», сохраняя это соотношение классов в другом столбце?

# Creating a dataset with a class minority

df_minority = df[df['relevance'] == 1]

# Creating a dataset with the other class

df_rest = df[df['relevance'] != 1] 

# Upsample the minority class

df_1_upsampled = resample(df_minority,random_state=SEED,n_samples=14810,replace=True)

# Concatenate the upsampled dataframe

df_upsampled = pd.concat([df_1_upsampled,df_rest])

Пример набора данных:

  relevance   class   2   3   4   5  
          1       A  40  24  11  50
          1       A  60  20  19  60
          0       C  15  57  15  60
          0       B  12  50  15  43 
          0       B  90   8  32  80
          0       C  74   8  21  34

Таким образом, цель состоит в том, чтобы сделать количество классов «релевантности» равным, сохраняя соотношение 1:1:1 категории «класс».

Хорошо, в ваших реальных данных каждый класс имеет несколько строк с relevance = 1? в вашей игрушке сэмпла нет, поэтому будет сложно апсемплировать и сохранять соотношение между классами.

Ben.T 18.11.2022 15:28

Да, у всех из них есть несколько строк с «релевантностью 1». Количество этих строк варьируется для каждого из этих классов; но общее количество строк в классе постоянно и одинаково для каждого класса.

mariant 18.11.2022 15:33
Скраппинг поиска Apple App Store с помощью Python
Скраппинг поиска Apple App Store с помощью Python
📌Примечание: В этой статье я покажу вам, как скрапировать поиск Apple App Store и получить точно такой же результат, как на Apple iMac, потому что...
Редкие достижения на Github ✨
Редкие достижения на Github ✨
Редкая коллекция доступна в профиле на GitHub ✨
Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
1
2
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот способ сделать это для каждого класса. Обратите внимание, что я не уверен, что это не повлияет на какую-либо модель после этого, здесь недостаточно опыта. Сначала давайте создадим фиктивные данные, которые будут ближе к вашим реальным данным.

# dummy data
np.random.seed(0)
df = pd.DataFrame({
         'relevance':np.random.choice(a=[0]*14810+[1]*190,size=15000, replace=False), 
         'class':list('ABCDEFGHIKLMNOP')*1000,
         2 : np.random.randint(0,100, 15000), 3 : np.random.randint(0,100, 15000),
         4 : np.random.randint(0,100, 15000), 5 : np.random.randint(0,100, 15000),
})

Просто некоторая проверка релевантности класса, вам все равно понадобится эта информация. У вас есть весь класс с 1000 образцов, и каждый класс имеет разное количество relevance=1

ct = pd.crosstab(df['class'], df['relevance'])
print(ct.head())
# relevance    0   1
# class             
# A          983  17
# B          982  18
# C          990  10
# D          993   7
# E          993   7

Теперь вы можете рассчитать количество апсэмплов, необходимых для каждого класса. Обратите внимание, что мы можем определить это несколькими способами, и особенно изменить 1000 на любое число.

nb_upsample = (1000*ct[0].mean()/ct[0]).astype(int)
print(nb_upsample.head())
# class
# A    1004
# B    1005
# C     997
# D     994
# E     994
# Name: 0, dtype: int32

Теперь вы можете увеличить частоту дискретизации для каждого класса

df_1_upsampled = (
    df_minority.groupby(['class'])
      .apply(lambda x: resample(x, random_state=1, replace=True,
                                n_samples=nb_upsample[x.name]))
      .reset_index(drop=True)
)
print(df_1_upsampled['class'].value_counts().head())
# B    1005
# A    1004
# L    1004
# M    1003
# H    1001
# Name: class, dtype: int64

Наконец, concat и проверьте класс отношения и релевантность

df_upsampled = pd.concat([df_1_upsampled,df_rest])
print(df_upsampled['class'].value_counts().head()) #same ratio
# A    1987
# B    1987
# C    1987
# D    1987
# E    1987
# Name: class, dtype: int64
print(df_upsampled['relevance'].value_counts()) # almost same relevance number
# 1    14995 #this number is affected by the 1000 in nb_upsample
# 0    14810
# Name: relevance, dtype: int64

Вы можете видеть, что теперь релевантность = 1 больше. Что вы можете сделать, так это изменить 1000 в строке, определяющей nb_upsample, на любое число, которое вы хотите. Вы также можете использовать nb_upsample = (ct[0].mean()**2/ct[0]).astype(int), чтобы сбалансировать обе категории релевантности.

Вау, так круто! Именно то, что я хотел сделать; большое спасибо :) Почему вы думаете, что это может повлиять на последующее моделирование? Я не понимаю, почему это должно приводить к какой-либо предвзятости.

mariant 18.11.2022 17:08

@mariant, что я могу сказать, так это то, что до повышения частоты дискретизации соотношение relevance=1 между, скажем, классом A и классом D составляет 17 к 7, то есть более чем в два раза для класса A. точка передискретизации). это может повлиять на вашу модель, нет? это выбор между повторной выборкой только с учетом цели (релевантности) и вашим выбором сохранения соотношения между классами. просто открытый вопрос, я никогда не пробовал это раньше

Ben.T 18.11.2022 17:32

Другие вопросы по теме