Apa perbedaan antara vektorizer hashing dan vektorizer tfidf

11

Saya mengubah kumpulan dokumen teks menjadi vektor kata untuk setiap dokumen. Saya sudah mencoba ini menggunakan TfidfVectorizer dan HashingVectorizer

Saya mengerti bahwa a HashingVectorizertidak mempertimbangkan IDFskor seperti halnya a TfidfVectorizer. Alasan saya masih bekerja dengan a HashingVectorizeradalah fleksibilitas yang diberikannya ketika berhadapan dengan dataset besar, seperti yang dijelaskan di sini dan di sini . (Kumpulan data asli saya memiliki 30 juta dokumen)

Saat ini, saya bekerja dengan sampel 45339 dokumen, jadi, saya memiliki kemampuan untuk bekerja dengan TfidfVectorizerjuga. Ketika saya menggunakan kedua vektorizers ini pada dokumen 45339 yang sama, matriks yang saya dapatkan berbeda.

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

bentuk matriks hashing (45339, 1048576)

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

bentuk matriks tfidf (45339, 663307)

Saya ingin lebih memahami perbedaan antara a HashingVectorizerdan a TfidfVectorizer, dan alasan mengapa matriks ini berbeda ukuran - terutama dalam jumlah kata / istilah.

Minu
sumber
Bisakah Anda berbagi dataset dengan saya? (respons akan dihapus)
nKarza

Jawaban:

7

Perbedaan utama adalah bahwa HashingVectorizermenerapkan fungsi hashing untuk menghitung jumlah frekuensi dalam setiap dokumen, di mana TfidfVectorizerskala istilah frekuensi tersebut dihitung dalam setiap dokumen dengan menghukum istilah yang muncul lebih luas di seluruh corpus. Ada ringkasan yang bagus di sini: https://spark.apache.org/docs/latest/mllib-feature-extraction.html

  • Fungsi hash adalah cara yang efisien untuk memetakan istilah ke fitur; itu tidak perlu diterapkan hanya untuk frekuensi istilah tapi begitulah cara HashingVectorizerdigunakan di sini. Bersama dengan 45339 dokumen, saya curiga vektor fitur memiliki panjang 1048576 karena standarnya adalah 2 ^ 20 n_features; Anda dapat mengurangi ini dan membuatnya lebih murah untuk diproses tetapi dengan peningkatan risiko tabrakan, di mana fungsi memetakan istilah yang berbeda untuk fitur yang sama: http://preshing.com/20110504/hash-collision-probabilities/

  • Bergantung pada use case untuk kata vektor, dimungkinkan untuk mengurangi panjang vektor fitur hash (dan dengan demikian kompleksitas) secara signifikan dengan hilangnya akurasi / keefektifan yang dapat diterima (karena peningkatan tabrakan). Scikit-learn memiliki beberapa parameter hashing yang dapat membantu, misalnya alternate_sign.

  • Jika matriks hashing lebih lebar dari kamus, itu berarti bahwa banyak entri kolom dalam matriks hashing akan kosong, dan bukan hanya karena dokumen yang diberikan tidak mengandung istilah tertentu tetapi karena mereka kosong di keseluruhan matriks. Jika tidak, mungkin mengirim beberapa istilah ke hash fitur yang sama - ini adalah 'tabrakan' yang telah kita bicarakan. HashingVectorizermemiliki pengaturan yang berfungsi untuk memitigasi hal ini alternate_signyang diaktifkan secara default, dijelaskan di sini: en.wikipedia.org/wiki/Feature_hashing#Properties

  • 'Frekuensi istilah - frekuensi dokumen terbalik' mengambil frekuensi istilah dalam setiap dokumen dan menimbangnya dengan menghukum kata-kata yang lebih sering muncul di seluruh korpus. Intinya adalah bahwa istilah yang ditemukan secara situasional lebih cenderung mewakili topik dokumen tertentu. Ini berbeda dengan fungsi hashing dalam hal ini diperlukan untuk memiliki kamus penuh kata-kata dalam korpus untuk menghitung frekuensi dokumen terbalik. Saya berharap dimensi matriks tf.idf Anda adalah 4.533 dokumen dengan 663307 kata dalam corpus; Manning dkk memberikan lebih detail dan contoh perhitungan: https://nlp.stanford.edu/IR-book/html/htmledition/term-frequency-and-weighting-1.html

'Mining of Massive Datasets' oleh Leskovec et al memiliki banyak detail tentang hashing fitur dan tf.idf, penulis membuat pdf tersedia di sini: http://www.mmds.org/

redhqs
sumber
1
Jika tfidf vectorizerkebutuhan kamus lengkap kata-kata untuk perhitungan idf, bukankah istilah dalam matriks tfidf lebih dari istilah dalam matriks hashing?
Minu
2
Jika matriks hashing lebih lebar dari kamus, itu berarti bahwa banyak entri kolom dalam matriks hashing akan kosong, dan bukan hanya karena dokumen yang diberikan tidak mengandung istilah tertentu tetapi karena mereka kosong di keseluruhan matriks. Agak di luar topik, tetapi apakah Anda melakukan pemrosesan terhadap kata-kata dalam dokumen Anda sebelum membuat vektor? Stopwords, stemming, dll?
redhqs
Ya, saya sedang memproses. Saya menggunakan spacy.
Minu
1
Konfirmasi: Jadi, 1048576 adalah panjang default dari setiap matriks hashing jika n_features tidak disebutkan? Jika benar-benar hanya ada 663307 kata dalam corpus, 385269 fitur yang tersisa kosong. Bagaimana bisa membuat matriks hashing ini pas tanpa semua fitur kosong?
Minu
1
Itu benar - Anda dapat mengubah ukuran jumlah fitur dengan mengubah parameter n_features=1048576, jika Anda punya waktu, coba 640k, 320k dan lihat apakah ini berdampak besar pada keakuratan Anda. Setidaknya harus mempercepat waktu pelatihan Anda. Lihat jawaban @ Nathan untuk n_features=5!
redhqs
5

The HashingVectorizermemiliki parameter n_featuresyang 1048576secara default. Saat hashing, mereka tidak benar-benar menghitung istilah pemetaan kamus ke indeks unik untuk digunakan masing-masing. Sebaliknya, Anda hanya hash setiap istilah dan menggunakan ukuran yang cukup besar bahwa Anda tidak berharap ada menjadi terlalu banyak tabrakan: hash(term) mod table_size. Anda dapat membuat matriks yang dikembalikan menjadi ukuran apa pun yang Anda inginkan dengan mengatur n_features. Anda harus menyesuaikan ini agar berada di ballpark yang tepat untuk corpus Anda jika Anda tidak berpikir defaultnya masuk akal (memiliki ukuran yang lebih besar akan menyebabkan lebih sedikit tabrakan meskipun membutuhkan lebih banyak memori).

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
sumber
0

HashingVectorizer dan CountVectorizer (perhatikan bukan Tfidfvectorizer) dimaksudkan untuk melakukan hal yang sama. Yaitu untuk mengkonversi kumpulan dokumen teks ke matriks kejadian token.

Jika Anda mencari untuk mendapatkan frekuensi istilah yang ditimbang oleh kepentingan relatifnya (IDF) maka Tfidfvectorizer adalah apa yang harus Anda gunakan. Jika Anda memerlukan jumlah mentah atau jumlah normal (frekuensi istilah), maka Anda harus menggunakan CountVectorizer atau HashingVectorizer.

Untuk mempelajari tentang HashingVectorizer, lihat artikel ini di HashingVectorizer vs. CountVectorizer .

Untuk informasi lebih lanjut tentang Tfidfvectorizer, lihat artikel ini tentang Cara Menggunakan Tfidftransformer dan Tfidfvectorizer .

kavgan
sumber