#python #machine-learning #scikit-learn #data-analysis #imbalanced-data
#python #машинное обучение #scikit-learn #анализ данных #несбалансированные данные
Вопрос:
Я работаю над классификацией изображений с несколькими метками. Это мой фрейм данных:
Как вы можете видеть изображения, помеченные 26 функциями. «1» означает, что существует, «0» означает, что не существует.
Моя проблема во многих ярлыках имеет несбалансированные данные. Например:
[1] train_df.value_counts('Eyeglasses')
Output:
Eyeglasses
0 54735
1 1265
dtype: int64
[2] train_df.value_counts('Double_Chin')
Output:
Double_Chin
0 55464
1 536
dtype: int64
Как я могу разделить его как для обучения, так и для проверки данных как сбалансированный?
[ОБНОВЛЕНИЕ]
Я пытался
from imblearn.over_sampling import SMOTE
smote = SMOTE()
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=42)
X_train_smote, y_train_smote = smote.fit_sample(X_train, y_train)
Ошибка ValueError: несбалансированный -learn в настоящее время поддерживает двоичные, многоклассовые и
двоично закодированные цели мультиклассов. Цели с несколькими метками и несколькими
выводами не поддерживаются.
Ответ №1:
В вашем вопросе смешиваются две концепции: разделение многоклассового набора данных изображений с несколькими метками на подмножества, которые имеют пропорциональное представление, и методы повторной выборки для устранения дисбаланса классов. Я собираюсь сосредоточиться только на разделении части проблемы, поскольку именно об этом идет речь в названии.
Я бы использовал стратифицированное разделение в случайном порядке, чтобы убедиться, что каждое подмножество имеет одинаковую повторяемость. Вот удобный визуальный пример для стратифицированной выборки из Википедии:
Для этого я рекомендую skmultilearn
IterativeStratification
метод. Он поддерживает наборы данных с несколькими метками.
from skmultilearn.model_selection.iterative_stratification import IterativeStratification
stratifier = IterativeStratification(
n_splits=2, order=2, sample_distribution_per_fold=[1.0 - train_fraction, train_fraction],
)
# this class is a generator that produces k-folds. we just want to iterate it once to make a single static split
# NOTE: needs to be computed on hard labels.
train_indexes, everything_else_indexes = next(stratifier.split(X=img_urls, y=labels))
# s3url array shape (N_samp,)
x_train, x_else = img_urls[train_indexes], img_urls[everything_else_indexes]
# labels array shape (N_samp, n_classes)
Y_train, Y_else = labels[train_indexes, :], labels[everything_else_indexes, :]
Я написал более полное решение, включая модульные тесты, в сообщении в блоге.
Одним из недостатков skmultilearn
является то, что он не очень хорошо поддерживается и имеет некоторую нарушенную функциональность. Я задокументировал некоторые из этих острых углов и ошибок в своем сообщении в блоге. Также обратите внимание, что эта процедура стратификации выполняется мучительно медленно, когда вы получаете несколько миллионов изображений, потому что стратификатор использует только один процессор.
Комментарии:
1. Я пытался использовать ваш код, но это приводит к нехватке оперативной памяти, даже с формой everything_else_indexes (500,26) и img_urls (500,). Я обновил свой вопрос, который заключается в том, что вы можете видеть мой фрейм данных. Также ваше визуальное объяснение не имеет смысла, потому что я не могу разделить значения, например, если метка x несбалансирована, а метка y сбалансирована, я не могу их стратифицировать, потому что они влияют на другие метки. Если я ошибаюсь, пожалуйста, поправьте меня.
2. @claymorehack Я не уверен, что значит иметь сбалансированные метки x, но несбалансированные метки y.
3. У меня всего 26 функций. Как вы можете видеть в df.png, где идет речь, каждое изображение обладает этими функциями, и у меня всего 15000 изображений. В целом, большинство функций несбалансированы, например, функция «Big_Nose» имеет {0: 14234, 1: 766}, а функция «Doubly_Chin» имеет {0: 7800, 1: 7200}. Проблема в том, что каждая функция связана друг с другом, поэтому не имеет смысла их стратифицировать. Если я попытаюсь стратифицировать положительные функции «Big_Nose», возможно, теперь я смогу столкнуться с несбалансированным «Doubly_Chin». Если я ошибаюсь, пожалуйста, поправьте меня.
4. Итак, ваши
x
изображения — это сами изображения, аy
остальные столбцы (ваши функции). Проблема, которую вы описываете со связанными функциями, является распространенной ситуацией в наборах данных с несколькими метками, и при использованииIterativeStratification
withorder=2
при стратификации будет учитываться несколько меток. В документах есть более подробная информация и видеоролики с лекциямиskmultilearn
: scikit.ml/api /…5. Хорошо, теперь я понимаю, но сложная сторона — моей оперативной памяти (16 ГБ) недостаточно, даже если небольшие данные.