Bir hashing vectorizer ve bir tfidf vectorizer arasındaki fark nedir


11

Her bir belge için bir metin belgeleri grubunu kelime vektörlerine dönüştürüyorum. Ben bir TfidfVectorizer ve bir HashingVectorizer kullanarak denedim

A'nın yaptığı gibi puanları HashingVectorizerdikkate almadığını anlıyorum . Hala çalışmamın nedeni , burada ve burada açıklandığı gibi, büyük veri kümeleriyle uğraşırken sağladığı esneklik . (Orijinal veri kümemde 30 milyon belge var)IDFTfidfVectorizerHashingVectorizer

Şu anda, 45339 belgeden oluşan bir örnekle çalışıyorum, bu yüzden bir ile TfidfVectorizerde çalışabiliyorum . Bu iki vectorizeri aynı 45339 dokümanda kullandığımda, aldığım matrisler farklı.

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

karma matris şekli (45339, 1048576)

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

tfidf matris şekli (45339, 663307)

A HashingVectorizerve a arasındaki farkları ve TfidfVectorizerbu matrislerin neden farklı boyutlarda olduğunu, özellikle de kelime / terim sayısında daha iyi anlamak istiyorum .


Veri kümesini benimle paylaşabilir misiniz? (kaldırılacak yanıt)
nKarza

Yanıtlar:


7

Temel fark, HashingVectorizerher belgedeki terim sıklık sayılarına bir hash fonksiyonu uygulamaktır; burada, TfidfVectorizerbu belgede, terim sıklığı sayılarını her belgede korpus genelinde daha yaygın görünen terimleri cezalandırarak ölçeklendirir. Burada harika bir özet var: https://spark.apache.org/docs/latest/mllib-feature-extraction.html

  • Karma işlevleri, terimleri özelliklere eşlemenin etkili bir yoludur; sadece terim frekanslarına uygulanması gerekmez, ancak HashingVectorizerburada bu şekilde kullanılır. 45339 belgelerle birlikte, özellik vektörünün 1048576 uzunluğunda olduğundan şüpheleniyorum çünkü varsayılan 2 ^ 20 n_features; bunu azaltabilir ve işlenmesini daha ucuz hale getirebilirsiniz, ancak işlevin farklı terimleri aynı özellikle eşleştirdiği çarpışma riski artar: http://preshing.com/20110504/hash-collision-probability/

  • Kelime vektörleri için kullanım durumuna bağlı olarak, hash özellik vektörünün uzunluğunu (ve dolayısıyla karmaşıklığını), doğruluk / etkililikte kabul edilebilir kayıp (artan çarpışma nedeniyle) ile önemli ölçüde azaltmak mümkün olabilir. Scikit-learn, örneğin yardımcı olabilecek bazı karma parametrelere sahiptir alternate_sign.

  • Karma matris sözlükten daha genişse, yalnızca belirli bir belgenin belirli bir terimi içermediği için değil, tümünde boş oldukları için karma matristeki sütun girişlerinin çoğunun boş olacağı anlamına gelir. matris. Değilse, aynı özellik karmasına birden fazla terim gönderebilir - bu bahsettiğimiz 'çarpışma'. burada açıklanan varsayılan HashingVectorizerolarak açık alternate_signolan bu ayarı hafifletmek için çalışan bir ayar vardır : en.wikipedia.org/wiki/Feature_hashing#Properties

  • 'Terim sıklığı - ters belge sıklığı' her belgede terim sıklıklarını alır ve tüm toplulukta daha sık görünen kelimeleri cezalandırarak ağırlaştırır. Sezgi, durumsal olarak bulunan terimlerin belirli bir belgenin konusunu temsil etme olasılığının daha yüksek olmasıdır. Bu, ters belge sıklığını hesaplamak için bir tam kelime sözlüğünün olması gerektiğinden bir karma işlevinden farklıdır. Ben senin tf.idf matris boyutlarının corpus'ta 663307 kelime ile 45339 belge olmasını bekliyorum; Manning ve diğerleri daha fazla ayrıntı ve hesaplama örnekleri sağlar: https://nlp.stanford.edu/IR-book/html/htmledition/term-frequency-and-weighting-1.html

Leskovec ve arkadaşlarının 'Devasa Veri Kümelerinin Madenciliği' hem hash hem de tf.idf özellikleri hakkında bir ton ayrıntıya sahip, yazarlar pdf'yi burada kullanılabilir hale getirdiler: http://www.mmds.org/


1
Eğer tfidf vectorizeridf hesaplamaları için tam bir sözlük sözlüğü gerekiyorsa, tfidf matrisindeki terimler karma matrisindeki terimlerden daha fazla olmamalı mı?
Minu

2
Karma matris sözlükten daha genişse, yalnızca belirli bir belgenin belirli bir terimi içermediği için değil, tümünde boş oldukları için karma matristeki sütun girişlerinin çoğunun boş olacağı anlamına gelir. matris. Biraz konu dışı, ancak vektörleştirmeden önce belgelerinizdeki kelimelere herhangi bir işlem yapıyor musunuz? Engellenecek kelimeler, stemming, vb.
redhqs

Evet, işliyorum. Boşluk kullanıyorum.
Minu

1
Onaylama: Eğer n_features belirtilmemişse, 1048576 herhangi bir karma matrisin varsayılan uzunluğudur? Eğer toplulukta gerçekten sadece 663307 kelime varsa, geri kalan 385269 özellikler boştur. Bu hash matrisini tüm boş özellikler olmadan nasıl sağlam hale getirebiliriz?
Minu

1
Bu doğru - parametreyi değiştirerek özellik sayısını yeniden boyutlandırabilirsiniz n_features=1048576, eğer zamanınız varsa 640k, 320k'yi deneyin ve doğruluğunuz üzerinde çok fazla etkisi olup olmadığını görün. En azından eğitim sürenizi hızlandırmalıdır. @ Nathan'ın cevabına bakın n_features=5!
redhqs

5

HashingVectorizerBir parametresi vardır n_featuresolduğunu 1048576varsayılan olarak. Karma yaparken, aslında her biri için kullanılacak benzersiz bir dizine sözlük eşleme terimleri hesaplamazlar. Bunun yerine, sadece her dönem karma ve çok fazla çarpışmalar orada bekliyor kalmamasıdır yeterince büyük bir boyutu kullanın: hash(term) mod table_size. Döndürülen matrisi ayarlayarak istediğiniz boyutta yapabilirsiniz n_features. Eğer varsayılanın makul olduğunu düşünmüyorsanız (daha fazla hafızaya sahip olmak daha az çarpışmaya neden olacaktır) bunu corpus için doğru basketbol sahası olarak ayarlamanız gerekir.

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 ve CountVectorizer (Tfidfvectorizer değil not) aynı şeyi yapmak içindir. Hangi metin belgeleri bir koleksiyon belirteç oluşumları matrisine dönüştürmek için.

Terim frekanslarını göreceli önemleri (IDF) ile ağırlıklandırmak istiyorsanız, Tfidfvectorizer kullanmanız gereken şeydir. Ham sayılara veya normalleştirilmiş sayılara (terim sıklığı) ihtiyacınız varsa, CountVectorizer veya HashingVectorizer'ı kullanmalısınız.

HashingVectorizer hakkında bilgi edinmek için HashingVectorizer vs. CountVectorizer hakkındaki bu makaleye bakın .

Tfidfvectorizer hakkında daha fazla bilgi için, Tfidftransformer ve Tfidfvectorizer Kullanımı hakkında bu makaleye bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.