Я занимаюсь своими мозгами за последние 2-3 недели по этой проблеме. У меня проблема с несколькими метками (не многоклассы), где каждый образец может принадлежать нескольким ярлыкам.Масштабируемые или онлайн-классические многоэлементные классификаторы
У меня около 4,5 миллионов текстовых документов в качестве данных для обучения и около 1 миллиона в качестве тестовых данных. Этикетки составляют около 35K.
Я использую scikit-learn. Для извлечения функций я ранее использовал TfidfVectorizer, который вообще не масштабировался, теперь я использую HashVectorizer, который лучше, но не настолько масштабируемый, учитывая количество документов, которые у меня есть.
vect = HashingVectorizer(strip_accents='ascii', analyzer='word', stop_words='english', n_features=(2 ** 10))
SKlearn предоставляет OneVsRestClassifier, в который я могу подавать любую оценку. Для multi-label я нашел LinearSVC & SGDClassifier только для правильной работы. В соответствии с моими показателями SGD превосходит LinearSVC как в памяти & времени. Итак, у меня есть что-то вроде этого
clf = OneVsRestClassifier(SGDClassifier(loss='log', penalty='l2', n_jobs=-1), n_jobs=-1)
Но страдает от некоторых серьезных проблем:
- OneVsRest не метод partial_fit, что делает его невозможным вне-ядра обучения. Есть ли альтернативы для этого?
- HashingVectorizer/Tfidf работают на одном ядре и не имеют параметра n_jobs. Слишком много времени для хэширования документов. Любые альтернативы/предложения? Правильно ли значение n_features?
- Я проверил на 1 миллион документов. Хешинг занимает 15 минут, и когда дело доходит до clf.fit (X, y), я получаю MemoryError, потому что OvR внутренне использует LabelBinarizer и пытается выделить матрицу измерений (y x classes), которую довольно трудно выделить. Что мне делать?
- Любые другие библиотеки, которые имеют надежные масштабируемые алгоритмы с множеством меток &? Я знаю о гениальности & mahout, но у обоих из них нет ничего для многоэлементных ситуаций?
Просто замечание, когда вы говорите «HashVectorizer, который лучше, но не то, что масштабируемый»: ' HashVectorizer' отлично масштабируется: если вы выбросите в два раза больше вычислительного ресурса, вы будете обрабатывать данные в два раза быстрее (вы можете разделить данные и запустить обработку параллельно, благодаря ее безгражданству и ограниченному использованию памяти). Это точное определение масштабируемости. Я согласен с тем, что «HashVectorizer», вероятно, может быть более оптимизирован для более быстрой работы на одних и тех же вычислительных ресурсах, но это не имеет ничего общего с проблемой масштабируемости. – ogrisel
Спасибо за разъяснение. Я согласен с тем, что HV действительно выгодно по сравнению с Tfidf, я не был уверен в части разделения данных. Теперь я сделал небольшой POC для разделения данных и запуска HV на частях отдельно, а затем объединить результаты позже. Первоначально я имел в виду, что работа над частью алгоритма - большое достижение, но все же его можно сделать более масштабируемым, как вы предложили разделить и запустить параллельно. (После того, как я это сделал, я отправлю PR, чтобы HV также имел параметр n_jobs) –
К сожалению, в текущей реализации joblib, используемой в scikit-learn, мы используем многопроцессорность, поэтому входные данные должны быть скопированы для отправки к подпроцессам. Таким образом, такой параметр n_jobs добавит существенные накладные расходы и может быть не совсем полезен. Если у вас действительно есть большой набор данных, лучше обрабатывать множество параллельных сквозных циклов, которые имеют дело с доступом к данным (диск, БД, сеть ...), чтобы избежать копирования любой копии. Однако такой код котловой плиты, вероятно, никогда не будет включен в scikit-learn как слишком конкретный проект/каркас. – ogrisel