哈希向量化器和tfidf向量化器有什么区别


11

我正在将文本文档的语料库转换为每个文档的单词向量。我已经尝试过使用TfidfVectorizerHashingVectorizer

我了解a 不像a 那样HashingVectorizer考虑IDF分数TfidfVectorizer。我仍然使用a的原因HashingVectorizer是它在处理庞大数据集时具有的灵活性,如此此处所述。(我的原始数据集有3000万个文档)

目前,我正在处理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

Answers:


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-probabilities/

  • 取决于单词向量的使用情况,有可能显着减少散列特征向量的长度(并因此减少复杂性),而准确性/有效性的可接受损失(由于增加的冲突)。例如,Scikit-learn具有一些可以帮助使用的哈希参数alternate_sign

  • 如果散列矩阵比字典宽,则意味着散列矩阵中的许多列条目将为空,这不仅是因为给定的文档不包含特定术语,还因为它们在整个范围内都是空的矩阵。如果不是,它可能会向同一要素哈希发送多个术语-这就是我们一直在谈论的“冲突”。HashingVectorizer有一个设置可以缓解这种alternate_sign情况,默认情况下处于启用状态,具体说明如下:en.wikipedia.org/wiki/Feature_hashing#Properties

  • “术语频率-反向文档频率”采用每个文档中的术语频率,并通过惩罚整个语料库中出现频率更高的单词来对其加权。直觉是,情境中找到的术语更有可能代表特定文档的主题。这与散列函数的不同之处在于,必须在语料库中具有完整的单词词典才能计算逆文档频率。我希望您的tf.idf矩阵维数是语料库中663307个单词的45339个文档;Manning等人提供了更多详细信息和计算示例: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

是的,我正在处理。我正在使用spacy。
分钟

1
确认:如果没有提到n_features,那么1048576是任何哈希矩阵的默认长度吗?如果语料库中确实只有663307个单词,则其余385269个特征为空。如何在没有所有空白功能的情况下使此哈希矩阵紧贴?
分钟

1
没错-您可以通过更改参数来调整功能部件的数量n_features=1048576,如果您有时间尝试640k,320k,看看它是否对精度有很大影响。它至少可以加快您的培训时间。请参阅@Nathan的答案n_features=5
redhqs

5

HashingVectorizer有一个参数n_features1048576默认。散列时,它们实际上并没有计算将术语映射到用于每个索引的唯一索引的字典。相反,你只是哈希每学期并使用足够大的尺寸,你不认为会有太多的冲突: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与CountVectorizer的相关文章。

有关Tfidfvectorizer的更多信息,请参见有关如何使用Tfidftransformer和Tfidfvectorizer的文章

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.