Контролируемое снижение размерности для текстовых данных в scikit-learn

Я пытаюсь использовать scikit-learn для обучения машинам по естественным языковым данным. У меня есть свой корпус, преобразованный в векторы мешков слов (которые принимают форму разреженной матрицы CSR), и мне интересно, существует ли в sklearn алгоритм сокращения размерности, способный принимать высокоразмерные, контролируемые данные и проецирование это в более низкое пространственное пространство, которое сохраняет дисперсию между этими классами.

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

В этом ядре это контролируемая, многозадачная, многоклассовая проблема, использующая разреженное представление векторов BoW. Есть ли способ уменьшения размерности в sklearn, который может обрабатывать такие данные? Существуют ли другие методы, которые люди использовали при работе с контролируемыми данными BoW в scikit-learn?

Спасибо!

Ответ 1

Я немного смущен вашим вопросом. По моему опыту, уменьшение размерности никогда не контролируется действительно... но кажется, что вы хотите, это какой-то осознанный выбор функций, который невозможно сделать, прежде чем классификация будет выполнена. Другими словами, вы не можете знать, какие функции более информативны, прежде чем ваш классификатор будет обучен и проверен.

Однако уменьшение размера и сложности ваших данных всегда хорошо, и у вас есть различные способы сделать это с текстовыми данными. Применимость и производительность зависят от типа векторов, которые у вас есть (частоты, tfidf), и вам всегда нужно будет определить количество измерений (компонентов), которые вы хотите в своем выходе. Реализации в scikit-learn главным образом находятся в модуле декомпозиции.

Наиболее популярным методом обработки естественного языка является "Различия в единичном значении" (SVD), который лежит в основе скрытого семантического анализа (LSA, также LSI). Оставаясь с помощью scikit-learn, вы можете просто применить TruncatedSVD() к своим данным. Аналогичный метод неотрицательная матричная факторизация, реализованная в scikit-learn как NMF().

Все более популярный подход использует преобразование случайными проекциями, Random Indexing. Вы можете сделать это в scikit-learn с помощью функций random_projection.

Как указывалось в другом ответе, Latent Dirichlet Allocation также является альтернативой, хотя она намного медленнее и вычислительно более требовательна, чем методы выше. Кроме того, на момент написания этой статьи он недоступен в scikit-learn.

Если вы хотите упростить свои данные, чтобы передать его в классификатор, я бы предложил SVD с n_компонентами от 100 до 500 или случайную проекцию с n_компонентами между 500 и 2000 (общие значения из литературы).

Если вы заинтересованы в том, чтобы использовать уменьшенные размеры как некоторую классификацию/кластеризацию уже (люди называют это извлечение тем, хотя вы действительно не извлекаете темы, а скорее скрытые размеры), тогда LDA может быть лучшим вариантом. Остерегайтесь, он медленный, и он принимает только чистые значения частоты (без tfidf). И количество компонентов - это параметр, который вы должны определить заранее (без возможности оценки).

Возвращаясь к вашей проблеме, я бы сделал конвейер sckit-learn с векторизатором, параметрами сокращения размерности и классификатором и выполнил массивный поиск параметров. Таким образом, вы увидите, что дает наилучшие результаты с набором ярлыков, который у вас есть.

Ответ 2

Вы можете использовать скрытое распределение дирихле (здесь wiki), чтобы открыть темы в ваших документах. Для присвоения метки документу вы можете использовать условное распределение вероятности для метки документа (учитывая распределение по темам в вашем документе). Если у вас уже есть ярлыки для ваших документов, вам просто нужно изучить CPD, что тривиально. К сожалению, scikit-learn не имеет реализации LDA, но gensim.

PS: Здесь другая бумага, которая может помочь. Если вы не очень хорошо разбираетесь в статистических выводах или обучении или машинах, я предлагаю вам начать здесь (обратите внимание: он все еще предполагает высокий уровень математической зрелости).

Ответ 3

Попробуйте ISOMAP. Там есть супер простая встроенная функция для scikits.learn. Даже если у него нет некоторых свойств сохранения, которые вы ищете, стоит попробовать.

Ответ 4

Используйте многослойную нейронную сеть для классификации. Если вы хотите увидеть, что представление ввода находится в уменьшенном измерении, посмотрите на активацию скрытого слоя. Роль скрытого слоя по определению оптимизирована для разграничения между классами, поскольку это то, что непосредственно оптимизируется при установке весов.

Нельзя использовать активацию softmax на выходном слое и нечто нелинейное на скрытом слое (tanh или sigmoid).

Ответ 5

Несколько существующих модулей scikit делают что-то похожее на то, что вы просили.

  • Линейный дискриминантный анализ, вероятно, ближе всего к тому, что вы просили. Он находит проекцию данных, которая максимизирует расстояние между центроидами класса относительно прогнозируемых дисперсий.

  • Кросс-декомпозиция включает в себя такие методы, как Partial Least Squares, которые соответствуют линейным регрессионным моделям для многомерных целей посредством проекции через нижнее промежуточное пространство, Это очень похоже на одну скрытую нейронную сеть без сигмоидов. Это методы линейной регрессии, но вы можете применить кодировку 0-1 к целевому сигналу и использовать эти модели в любом случае.

  • Вы можете использовать L1-регуляризованный классификатор типа LogisticRegression или SGDClassifier to do feature selection. RandomizedLogisticRegression`, который сочетает это с начальной загрузкой, чтобы получить более стабильный набор функций.