Sự khác biệt giữa vectorizer băm và vectorizer tfidf là gì


11

Tôi đang chuyển đổi một tập hợp các tài liệu văn bản thành các vectơ từ cho mỗi tài liệu. Tôi đã thử điều này bằng TfidfVectorizerHashingVectorizer

Tôi hiểu rằng HashingVectorizerkhông xem xét IDFđiểm số như thế TfidfVectorizernào. Lý do tôi vẫn làm việc với một HashingVectorizersự linh hoạt mà nó mang lại trong khi xử lý các bộ dữ liệu khổng lồ, như được giải thích ở đâyđây . (Tập dữ liệu gốc của tôi có 30 triệu tài liệu)

Hiện tại, tôi đang làm việc với một mẫu gồm 4539 tài liệu, vì vậy, tôi có khả năng làm việc với một tài liệu TfidfVectorizer. Khi tôi sử dụng hai vectơ này trên cùng một tài liệu 45339, các ma trận mà tôi nhận được là khác nhau.

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

hình dạng ma trận băm (45339, 1048576)

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

hình dạng ma trận tfidf (45339, 663307)

Tôi muốn hiểu rõ hơn về sự khác biệt giữa a HashingVectorizervà a TfidfVectorizer, và lý do tại sao các ma trận này có kích thước khác nhau - đặc biệt là về số lượng từ / thuật ngữ.


Bạn có thể vui lòng chia sẻ dữ liệu với tôi? (phản hồi sẽ bị xóa)
nKarza

Câu trả lời:


7

Sự khác biệt chính là HashingVectorizeráp dụng chức năng băm cho số lượng tần số trong mỗi tài liệu, trong đó chia TfidfVectorizertỷ lệ số lượng thuật ngữ đó trong mỗi tài liệu bằng cách xử phạt các thuật ngữ xuất hiện rộng rãi hơn trên toàn văn bản. Có một bản tóm tắt tuyệt vời ở đây: https://spark.apache.org/docs/latest/mllib-feature-extraction.html

  • Các hàm băm là một cách hiệu quả để ánh xạ các thuật ngữ đến các tính năng; nó không nhất thiết chỉ cần được áp dụng cho các tần số hạn nhưng đó là cách HashingVectorizerđược sử dụng ở đây. Cùng với các tài liệu 45339, tôi nghi ngờ vectơ đặc trưng có độ dài 1048576 vì đó là mặc định 2 ^ 20 n_features; bạn có thể giảm điều này và làm cho nó ít tốn kém hơn khi xử lý nhưng với nguy cơ va chạm tăng lên, trong đó chức năng ánh xạ các thuật ngữ khác nhau vào cùng một tính năng: http://preshing.com/20110504/hash-collision-probabilities/

  • Tùy thuộc vào trường hợp sử dụng cho vectơ từ, có thể giảm độ dài của vectơ tính năng băm (và do đó độ phức tạp) đáng kể với tổn thất chấp nhận được đối với độ chính xác / hiệu quả (do va chạm tăng). Scikit-learn có một số tham số băm có thể hỗ trợ, ví dụ alternate_sign.

  • Nếu ma trận băm rộng hơn từ điển, điều đó có nghĩa là nhiều mục trong cột trong ma trận băm sẽ trống và không chỉ vì một tài liệu đã cho không chứa một thuật ngữ cụ thể mà vì chúng trống toàn bộ ma trận. Nếu không, nó có thể gửi nhiều thuật ngữ cho cùng một hàm băm - đây là 'sự va chạm' mà chúng ta đã nói đến. HashingVectorizercó một cài đặt hoạt động để giảm thiểu cái gọi là alternate_signtheo mặc định, được mô tả ở đây: en.wikipedia.org/wiki/Feature_hashing#Properies

  • 'Tần số thuật ngữ - tần số tài liệu nghịch đảo' lấy tần số kỳ hạn trong mỗi tài liệu và đánh giá chúng bằng cách xử phạt các từ xuất hiện thường xuyên hơn trên toàn bộ văn bản. Trực giác là các thuật ngữ được tìm thấy theo tình huống có nhiều khả năng là đại diện cho chủ đề của một tài liệu cụ thể. Điều này khác với chức năng băm ở chỗ cần phải có một từ điển đầy đủ các từ trong kho để tính tần số tài liệu nghịch đảo. Tôi hy vọng kích thước ma trận tf.idf của bạn là 45339 tài liệu với 663307 từ trong kho; Manning et al cung cấp thêm chi tiết và ví dụ về tính toán: https://nlp.stanford.edu/IR-book/html/htmledition/term-frequency-and- weighting-1.html

'Khai thác dữ liệu khổng lồ' của Leskovec et al có rất nhiều chi tiết về cả tính năng băm và tf.idf, các tác giả đã cung cấp bản pdf có sẵn tại đây: http://www.mmds.org/


1
Nếu tfidf vectorizercần một từ điển đầy đủ các từ để tính toán idf, thì các thuật ngữ trong ma trận tfidf có nên nhiều hơn các thuật ngữ trong ma trận băm không?
Minu

2
Nếu ma trận băm rộng hơn từ điển, điều đó có nghĩa là nhiều mục trong cột trong ma trận băm sẽ trống và không chỉ vì một tài liệu đã cho không chứa một thuật ngữ cụ thể mà vì chúng trống toàn bộ ma trận. Hơi lạc đề, nhưng bạn có đang xử lý các từ trong tài liệu của mình trước khi véc tơ không? Mật khẩu, xuất phát, vv?
redhqs

Vâng, tôi đang xử lý. Tôi đang sử dụng spacy.
Minu

1
Xác nhận: Vậy, 1048576 là độ dài mặc định của bất kỳ ma trận băm nào nếu n_features không được đề cập? Nếu thực sự chỉ có 663307 từ trong kho văn bản, thì các tính năng 385269 còn lại đều trống. Làm thế nào có thể làm cho ma trận băm này không có tất cả các tính năng trống?
Minu

1
Điều đó đúng - bạn có thể thay đổi kích thước số lượng tính năng bằng cách thay đổi tham số n_features=1048576, nếu bạn có thời gian hãy thử 640k, 320k và xem liệu nó có ảnh hưởng nhiều đến độ chính xác của bạn không. Nó sẽ tăng tốc thời gian đào tạo của bạn ít nhất. Xem câu trả lời của @ cho n_features=5!
redhqs

5

Các HashingVectorizercó một tham số n_featuresmà là 1048576theo mặc định. Khi băm, họ không thực sự tính toán một thuật ngữ ánh xạ từ điển thành một chỉ mục duy nhất để sử dụng cho mỗi từ. Thay vào đó, bạn chỉ cần băm từng thuật ngữ và sử dụng kích thước đủ lớn mà bạn không mong muốn có quá nhiều va chạm : hash(term) mod table_size. Bạn có thể đặt ma trận trả về là bất kỳ kích thước nào bạn muốn bằng cách đặt n_features. Bạn nên điều chỉnh điều này để ở trong sân bóng phù hợp với kho của bạn nếu bạn không nghĩ mặc định là hợp lý (nếu nó lớn hơn sẽ gây ra ít va chạm hơn mặc dù phải mất nhiều bộ nhớ hơn).

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.