Jaka jest różnica między wektorem mieszającym a wektorem tfidf

11

Konwertuję korpus dokumentów tekstowych na wektory słów dla każdego dokumentu. Próbowałem tego za pomocą TfidfVectorizer i HashingVectorizer

Rozumiem, że a HashingVectorizernie uwzględnia IDFwyników tak, jak TfidfVectorizerrobi. Powodem, dla którego wciąż pracuję nad HashingVectorizerjest elastyczność, jaką daje podczas pracy z ogromnymi zbiorami danych, jak wyjaśniono tutaj i tutaj . (Mój oryginalny zestaw danych zawiera 30 milionów dokumentów)

Obecnie pracuję z próbką 45339 dokumentów, więc mam możliwość pracy z TfidfVectorizertakże. Kiedy używam tych dwóch wektoryzatorów na tych samych dokumentach 45339, otrzymane macierze są różne.

hashing = HashingVectorizer()
with LSM('corpus.db')) as corpus:
    hashing_matrix = hashing.fit_transform(corpus)
print(hashing_matrix.shape) 

kształt matrycy mieszającej (45339, 1048576)

tfidf = TfidfVectorizer()
with LSM('corpus.db')) as corpus:
    tfidf_matrix = tfidf.fit_transform(corpus)
print(tfidf_matrix.shape) 

Kształt matrycy TFIDF (45339, 663307)

Chcę lepiej zrozumieć różnice między a HashingVectorizeri a TfidfVectorizeroraz powód, dla którego te macierze mają różne rozmiary - szczególnie pod względem liczby słów / terminów.

Minu
źródło
Czy możesz udostępnić mi zestaw danych? (odpowiedź zostanie usunięta)
nKarza

Odpowiedzi:

7

Główną różnicą jest to, że HashingVectorizerstosuje funkcję haszującą do liczenia częstotliwości terminów w każdym dokumencie, przy czym TfidfVectorizerskaluje te częstotliwości w każdym dokumencie poprzez karanie terminów, które pojawiają się szerzej w korpusie. Tutaj jest świetne podsumowanie: https://spark.apache.org/docs/latest/mllib-feature-extraction.html

  • Funkcje skrótu to skuteczny sposób mapowania terminów na funkcje; niekoniecznie musi być stosowane tylko do częstotliwości terminowych, ale w ten sposób HashingVectorizersię tutaj stosuje. Podejrzewam, że wraz z dokumentami 45339 wektor cech ma długość 1048576, ponieważ jest to domyślna wartość 2 ^ 20 n_features; możesz to zmniejszyć i obniżyć koszty przetwarzania, ale ze zwiększonym ryzykiem kolizji, gdzie funkcja mapuje różne terminy na tę samą funkcję: http://preshing.com/20110504/hash-collision-probabilities/

  • W zależności od przypadku użycia wektorów słów może być możliwe znaczne zmniejszenie długości wektora cechy skrótu (a tym samym złożoności) przy akceptowalnej utracie dokładności / skuteczności (z powodu zwiększonej kolizji). Scikit-learn ma na przykład pewne parametry haszujące, które mogą pomóc alternate_sign.

  • Jeśli macierz skrótów jest szersza niż słownik, będzie to oznaczać, że wiele pozycji kolumn w macierzy skrótów będzie pustych, i to nie tylko dlatego, że dany dokument nie zawiera określonego terminu, ale dlatego, że są puste matryca. Jeśli tak nie jest, może wysłać wiele terminów do tego samego skrótu funkcji - jest to „kolizja”, o której mówiliśmy. HashingVectorizerma ustawienie, które działa w celu złagodzenia tego wywołania, alternate_signktóre jest domyślnie włączone, opisane tutaj: en.wikipedia.org/wiki/Feature_hashing#Properties

  • „Częstotliwość terminowa - odwrotna częstotliwość dokumentów” przyjmuje częstotliwości terminowe w każdym dokumencie i waży je poprzez karanie słów, które pojawiają się częściej w całym korpusie. Intuicja polega na tym, że warunki znalezione sytuacyjnie są bardziej reprezentatywne dla określonego tematu dokumentu. Różni się to od funkcji mieszającej, ponieważ konieczne jest posiadanie pełnego słownika słów w korpusie w celu obliczenia odwrotnej częstotliwości dokumentów. Oczekuję, że wymiary macierzy tf.idf to 45339 dokumentów na 663307 słów w korpusie; Manning i in. Podają więcej szczegółów i przykłady obliczeń: https://nlp.stanford.edu/IR-book/html/htmledition/term-frequency-and-weighting-1.html

„Mining of Massive Datasets” autorstwa Leskovec i in. Ma mnóstwo szczegółów zarówno na temat haszowania funkcji, jak i tf.idf, autorzy udostępnili pdf tutaj: http://www.mmds.org/

redhqs
źródło
1
Jeśli tfidf vectorizerpotrzebuje pełnego słownika słów do obliczeń idf, to czy terminy w macierzy tfidf nie powinny być więcej niż terminy w macierzy haszującej?
Minu
2
Jeśli macierz skrótów jest szersza niż słownik, będzie to oznaczać, że wiele pozycji kolumn w macierzy skrótów będzie pustych, i to nie tylko dlatego, że dany dokument nie zawiera określonego terminu, ale dlatego, że są puste matryca. Nie na temat, ale czy przetwarzasz słowa w dokumentach przed wektoryzacją? Stopery, porzucanie itp.?
redhqs
Tak, przetwarzam. Używam spacy.
Minu
1
Potwierdzenie: Zatem 1048576 jest domyślną długością dowolnej macierzy haszującej, jeśli n_features nie jest wymienione? Jeśli naprawdę w korpusie jest tylko 663307 słów, pozostałe 385269 funkcji są puste. Jak sprawić, by ta macierz mieszania była wygodna bez wszystkich pustych funkcji?
Minu
1
Zgadza się - możesz zmienić rozmiar funkcji, zmieniając parametr n_features=1048576, jeśli masz czas, wypróbuj 640k, 320k i sprawdź, czy ma to duży wpływ na twoją dokładność. Powinno to przynajmniej przyspieszyć twój trening. Zobacz odpowiedź @ Nathana na n_features=5!
redhqs
5

HashingVectorizerMa parametr n_features, który jest 1048576domyślnie. Podczas mieszania w rzeczywistości nie obliczają terminów mapowania słownika na unikalny indeks, który można zastosować dla każdego z nich. Zamiast tego, po prostu hash każdy termin i korzystać wystarczająco duże rozmiary, że nie oczekują tam być zbyt wiele kolizji: hash(term) mod table_size. Możesz ustawić zwracaną macierz na dowolny rozmiar, ustawiając n_features. Powinieneś dostosować to, aby znaleźć się w odpowiednim polu dla swojego korpusu, jeśli nie uważasz, że domyślna wartość jest rozsądna (zwiększenie jej spowoduje mniej kolizji, choć zajmie więcej pamięci).

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)
Nathan
źródło
0

HashingVectorizer i CountVectorizer (zauważ, że nie Tfidfvectorizer) mają robić to samo. Który polega na przekonwertowaniu zbioru dokumentów tekstowych na macierz wystąpień tokenów.

Jeśli szukasz częstotliwości ważonych według ich względnej ważności (IDF), powinieneś użyć Tfidfvectorizer. Jeśli potrzebujesz liczby surowej lub liczby znormalizowanej (częstotliwość terminów), powinieneś użyć CountVectorizer lub HashingVectorizer.

Aby dowiedzieć się więcej o HashingVectorizer, zobacz ten artykuł o HashingVectorizer vs. CountVectorizer .

Aby uzyskać więcej informacji na temat Tfidfvectorizer, zobacz ten artykuł na temat korzystania z Tfidftransformer i Tfidfvectorizer .

kavgan
źródło