Могу ли я использовать pandas для создания смещенного образца? - PullRequest
0 голосов
/ 29 января 2020

В моем коде используется столбец с названием статуса бронирования, который равен 1 для «да» и 0 для «нет» (есть несколько других столбцов, из которых будет извлекаться информация, в зависимости от статуса бронирования) - есть много больше «нет», поэтому я хотел бы взять образец со всеми да и одинаковым количеством нет.

Когда я использую

samp = rslt_df.sample(n=298, random_state=1, weights='bookingstatus')

Я получаю ошибку:

ValueError: Меньше ненулевые записи в p, чем size

Есть ли способ сделать этот пример таким образом?

Ответы [ 2 ]

1 голос
/ 29 января 2020

Если весь наш набор данных выглядит следующим образом:

print(df)                                                                               
   c1  c2
0   1   1
1   0   2
2   0   3
3   0   4
4   0   5
5   0   6
6   0   7
7   1   8
8   0   9
9   0  10

Мы можем решить сэмплировать его, используя функцию DataFrame.sample. По умолчанию эта функция будет работать без замены. Это означает, что вы получите ошибку, указав число наблюдений, превышающее количество наблюдений в вашем начальном наборе данных:

df.sample(20)
ValueError: Cannot take a larger sample than population when 'replace=False'

В вашей ситуации ошибка ValueError происходит из параметра weights:

df.sample(3,weights='c1')
ValueError: Fewer non-zero entries in p than size

Перефразируя документы DataFrame.sample , используя столбец c1 в качестве нашего весового параметра, подразумевается, что строки с большим значением в c1 столбец с большей вероятностью будет выбран. В частности, функция sample не будет выбирать значения из этого столбца, которые являются нулевыми. Мы можем исправить эту ошибку, используя один из следующих методов:


Метод 1: Установите для параметра replace значение true:

m1 = df.sample(3,weights='c1', replace=True)
print(m1)                                                                               
   c1  c2
0   1   1
7   1   8
0   1   1

Метод 2: Убедитесь, что параметр n равен или меньше числа 1 в столбце c1 :

m2 = df.sample(2,weights='c1')
print(m2)                                                                               
   c1  c2
7   1   8
0   1   1

Если вы решили использовать этот метод, вы не будете на самом деле выборки. Вы действительно просто отфильтровываете все строки, где значение c1 равно 0.

0 голосов
/ 30 января 2020

В конце концов я смог это сделать, вот как я это сделал:

bookingstatus_count = df.bookingstatus.value_counts()
print('Class 0:', bookingstatus_count[0])
print('Class 1:', bookingstatus_count[1])
print('Proportion:', round(bookingstatus_count[0] / bookingstatus_count[1], 2), ': 1')
# Class count
count_class_0, count_class_1 = df.bookingstatus.value_counts()

# Divide by class
df_class_0 = df[df['bookingstatus'] == 0]

df_class_0_under = df_class_0.sample(count_class_1)
df_test_under = pd.concat([f_class_0_under, df_class_1], axis=0)
df_class_1 = df[df['bookingstatus'] == 1]

на основании этого https://www.kaggle.com/rafjaa/resampling-strategies-for-imbalanced-datasets

Спасибо всем

...