Яка різниця між хеширующим векторизатором і векторизатором tfidf


11

Я перетворюю корпус текстових документів у слова векторів для кожного документа. Я спробував це за допомогою TfidfVectorizer та HashingVectorizer

Я розумію, що "a HashingVectorizer" не враховує IDFоцінок, як TfidfVectorizer"". Причина, по якій я все ще працюю з a, 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, і причину цих матриць різного розміру - особливо в кількості слів / термінів.


Чи можете ви поділитися набором даних зі мною? (відповідь буде видалена)
nKarza

Відповіді:


7

Основна відмінність полягає в тому, що HashingVectorizerзастосовується хешируюча функція до підрахунку частоти термінів у кожному документі, де TfidfVectorizerмасштабування підраховується частота термінів у кожному документі шляхом покарання термінів, які з'являються ширше у корпусі. Тут є чудовий підсумок: https://spark.apache.org/docs/latest/mllib-feature-extraction.html

  • Функції хешу - це ефективний спосіб відображення термінів до функцій; це не обов’язково потрібно застосовувати лише до термінальних частот, але саме так HashingVectorizerтут використовується. Поряд із документами 45339, я підозрюю, що вектор функції має довжину 1048576, оскільки це типовий 2 ^ 20 n_features; Ви можете зменшити це і зробити його дешевшим обробляти, але зі збільшенням ризику зіткнення, коли функція відображає різні терміни на одну і ту ж функцію: http://preshing.com/20110504/hash-collision-probables/

  • Залежно від випадку використання для слова векторів, можливо, можливо скоротити довжину вектора хеш-ознак (і, таким чином, складності), з прийнятною втратою точності / ефективності (через збільшення зіткнення). У 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

"Видобуток масивних наборів даних" від Leskovec та ін. Містить багато деталей як щодо хешування функцій, так і tf.idf, автори зробили pdf доступним тут: http://www.mmds.org/


1
Якщо вам tfidf vectorizerпотрібен повний словник слів для обчислення idf, чи не повинні терміни в матриці tfidf бути більше ніж терміни в матриці хешування?
Хвилина

2
Якщо матриця хешування ширша за словник, це буде означати, що багато записів стовпців у матриці хешування будуть порожніми, і не лише тому, що в даному документі немає конкретного терміна, а тому, що вони порожні в цілому матриця. Трохи поза темою, але чи робите ви будь-яку обробку слів у своїх документах перед векторизацією? Стоп-слова, стримування тощо?
redhqs

Так, я обробляю. Я використовую простори.
Хвилина

1
Підтвердження: Отже, 1048576 є довжиною за замовчуванням будь-якої матриці хешування, якщо n_features не згадується? Якщо в корпусі дійсно всього 663307 слів, решта 385269 функцій порожні. Як можна зробити цю матрицю хешування затиснутою без усіх порожніх функцій?
Хвилина

1
Правильно - ви можете змінити кількість функцій, змінивши параметр n_features=1048576, якщо встигнете спробувати 640k, 320k і побачити, чи може він сильно вплинути на вашу точність. Це має принаймні прискорити ваш час навчання. Дивіться відповідь @ Nathan для n_features=5!
redhqs

5

HashingVectorizerМає параметр , n_featuresякий 1048576за замовчуванням. Під час хешування вони фактично не обчислюють терміни зіставлення словника для унікального індексу, який слід використовувати для кожного. Замість цього, ви просто хеш кожного терміна і використовувати досить великий розмір , що ви не очікуєте там бути занадто багато зіткнень: hash(term) mod table_size. Ви можете зробити повернуту матрицю будь-якого потрібного вам розміру, встановивши n_features. Ви повинні налаштувати це так, щоб він був правильним для вашого корпусу, якщо ви не вважаєте, що дефолт є розумним (якщо його збільшити, це призведе до менших зіткнень, хоча це займе більше пам'яті).

from sklearn.feature_extraction.text import HashingVectorizer
vectorizer = HashingVectorizer()
print(vectorizer.transform(['a very small document']).shape)
(1, 1048576)

small_vectorizer = HashingVectorizer(n_features=5)
print(small_vectorizer.transform(['a very small document']).shape)    
(1, 5)

0

HashingVectorizer і CountVectorizer (зауважте, не Tfidfvectorizer) призначені для того ж, щоб зробити те саме. Що полягає в перетворенні колекції текстових документів у матрицю подій лексеми.

Якщо ви хочете отримати термінові частоти, зважені за їх відносною важливістю (IDF), то Tfidfvectorizer - це те, що вам слід використовувати. Якщо вам потрібні необроблені підрахунки або нормалізовані підрахунки (термінова частота), тоді вам слід використовувати CountVectorizer або HashingVectorizer.

Щоб дізнатися про HashingVectorizer, див. Цю статтю про HashingVectorizer vs. CountVectorizer .

Для отримання додаткової інформації про Tfidfvectorizer дивіться цю статтю про те, як користуватися Tfidftransformer та Tfidfvectorizer .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.