Я конвертирую корпус текстовых документов в векторы слов для каждого документа. Я пробовал это с помощью TfidfVectorizer и HashingVectorizer
Я понимаю, что HashingVectorizer
а не принимает во внимание IDF
оценки, как TfidfVectorizer
делает. Причина, по которой я все еще работаю с, HashingVectorizer
заключается в гибкости, которую он дает при работе с огромными наборами данных, как объяснено здесь и здесь . (Мой исходный набор данных содержит 30 миллионов документов)
В настоящее время я работаю с образцом 45339 документов, поэтому у меня есть возможность работать с ним TfidfVectorizer
. Когда я использую эти два векторизатора в одних и тех же 45339 документах, матрицы, которые я получаю, отличаются.
hashing = HashingVectorizer() with LSM('corpus.db')) as corpus: hashing_matrix = hashing.fit_transform(corpus) print(hashing_matrix.shape)
Форма матрицы хеширования (45339, 1048576)
tfidf = TfidfVectorizer() with LSM('corpus.db')) as corpus: tfidf_matrix = tfidf.fit_transform(corpus) print(tfidf_matrix.shape)
Форма матрицы tfidf (45339, 663307)
Я хочу лучше понять различия между a HashingVectorizer
и a TfidfVectorizer
, а также причину, по которой эти матрицы имеют разные размеры - особенно в количестве слов / терминов.
Ответы:
Основное отличие состоит в том, что
HashingVectorizer
функция хэширования применяется к счетчикам частот терминов в каждом документе, гдеTfidfVectorizer
масштабирует эти счетчики частот терминов в каждом документе, штрафуя термины, которые появляются более широко по всему корпусу. Здесь есть отличное резюме: https://spark.apache.org/docs/latest/mllib-feature-extraction.htmlХеш-функции - эффективный способ сопоставления терминов с функциями; это не обязательно должно применяться только к частотам термина, но именно так
HashingVectorizer
здесь используется. Я подозреваю, что наряду с документами 45339 вектор пространственных объектов имеет длину 1048576, поскольку по умолчанию он равен 2 ^ 20n_features
; Вы можете уменьшить это и сделать его менее затратным для обработки, но с повышенным риском столкновения, когда функция отображает разные термины в одну и ту же функцию: http://preshing.com/20110504/hash-collision-probabilities/В зависимости от варианта использования для векторов слов может быть возможно значительно уменьшить длину вектора хеш-функции (и, следовательно, сложность) с приемлемыми потерями в точности / эффективности (из-за увеличенного столкновения). Scikit-learn имеет некоторые параметры хеширования, которые могут помочь, например
alternate_sign
.Если матрица хеширования шире словаря, это будет означать, что многие записи столбцов в матрице хеширования будут пустыми, и не только потому, что данный документ не содержит определенного термина, но и потому, что они пусты во всем матрица. Если это не так, он может отправить несколько терминов в один и тот же хеш-объект - это «столкновение», о котором мы говорили.
HashingVectorizer
имеет настройку, которая работает, чтобы смягчить этот вызываемый,alternate_sign
который включен по умолчанию, описанный здесь: en.wikipedia.org/wiki/Feature_hashing#Properties«Термин частота - обратная частота документа» берет частоты термина в каждом документе и взвешивает их, штрафуя слова, которые встречаются чаще всего по всему корпусу. Интуиция заключается в том, что термины, найденные ситуативно, с большей вероятностью будут представлять тему конкретного документа. Это отличается от функции хеширования тем, что в корпусе необходимо иметь полный словарь слов, чтобы рассчитать частоту обратных документов. Я ожидаю, что ваши размеры матрицы tf.idf составляют 45339 документов на 663307 слов в корпусе; Мэннинг и др. Предоставляют более подробную информацию и примеры расчетов: https://nlp.stanford.edu/IR-book/html/htmledition/term-frequency-and-weighting-1.html
«Mining of Massive Datasets» Leskovec et al. Содержит массу деталей как по хешированию функций, так и по tf.idf, авторы сделали PDF доступным здесь: http://www.mmds.org/
источник
tfidf vectorizer
для вычислений idf требуется полный словарь слов, не должны ли термины в матрице tfidf быть больше, чем термины в матрице хеширования?n_features=1048576
, если у вас есть время, попробуйте 640k, 320k и посмотрите, сильно ли это повлияет на вашу точность. Это должно как минимум ускорить ваше тренировочное время. Смотрите @ ответ Натана заn_features=5
!HashingVectorizer
Имеет параметр ,n_features
который1048576
по умолчанию. При хешировании они фактически не вычисляют термины словаря, отображающие уникальный индекс для использования для каждого из них. Вместо этого, вы просто хэш каждого термина и использовать достаточно большой размер , что вы не ожидаете там быть слишком много столкновений:hash(term) mod table_size
. Вы можете сделать возвращаемую матрицу любого размера, установивn_features
. Вы должны настроить его так, чтобы он соответствовал вашему корпусу, если вы не думаете, что значение по умолчанию является разумным (его увеличение приведет к меньшему количеству столкновений, хотя и займет больше памяти).источник
HashingVectorizer и CountVectorizer (обратите внимание, не Tfidfvectorizer) предназначены для того же. Который должен преобразовать коллекцию текстовых документов в матрицу вхождений токенов.
Если вы хотите получить частоты терминов, взвешенные по их относительной важности (IDF), то вам следует использовать Tfidfvectorizer. Если вам нужны необработанные или нормализованные значения (периодичность), вам следует использовать CountVectorizer или HashingVectorizer.
Чтобы узнать о HashingVectorizer, см. Эту статью о HashingVectorizer против CountVectorizer .
Для получения дополнительной информации о Tfidfvectorizer см. Эту статью о том, как использовать Tfidftransformer и Tfidfvectorizer .
источник