Tần số kỳ hạn / tần số tài liệu nghịch đảo (TF / IDF): trọng số


12

Tôi đã có một bộ dữ liệu đại diện cho 1000 tài liệu và tất cả các từ xuất hiện trong đó. Vì vậy, các hàng đại diện cho các tài liệu và các cột đại diện cho các từ. Vì vậy, ví dụ, giá trị trong ô là viết tắt của số lần từ xảy ra trong tài liệu . Bây giờ, tôi phải tìm 'trọng số' của các từ, sử dụng phương thức tf / idf, nhưng tôi thực sự không biết làm thế nào để làm điều này. Ai đó có thể vui lòng giúp tôi không?(Tôi,j)jTôi


Thống kê tf-idf để trích xuất từ ​​khóa - joyofdata.de/blog/tf-idf-statistic-keyword-extraction
Raffael

Câu trả lời:


12

Wikipedia có một bài viết hay về chủ đề này, hoàn chỉnh với các công thức. Các giá trị trong ma trận của bạn là tần số hạn. Bạn chỉ cần tìm idf: (log((total documents)/(number of docs with the term))và nhiều 2 giá trị.

Trong R, bạn có thể làm như sau:

set.seed(42)
d <- data.frame(w=sample(LETTERS, 50, replace=TRUE))
d <- model.matrix(~0+w, data=d)

tf <- d
idf <- log(nrow(d)/colSums(d))
tfidf <- d

for(word in names(idf)){
  tfidf[,word] <- tf[,word] * idf[word]
}

Đây là bộ dữ liệu:

> colSums(d)
wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ 
 3  1  3  1  1  1  1  2  4  2  2  1  1  3  2  2  2  4  5  5  4 
> head(d)
  wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ
1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0
2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
3  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0
5  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
> head(round(tfidf, 2))
  wA wC wD wF wG   wH wJ wK wL wM   wN wO wP   wQ wR wS wT   wV  wX  wY wZ
1  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 2.3 0.0  0
2  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 2.3  0
3  0  0  0  0  0 3.91  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 0.0  0
4  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 2.53 0.0 0.0  0
5  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 2.81  0  0  0 0.00 0.0 0.0  0
6  0  0  0  0  0 0.00  0  0  0  0 3.22  0  0 0.00  0  0  0 0.00 0.0 0.0  0

Bạn cũng có thể xem idf của mỗi thuật ngữ:

> log(nrow(d)/colSums(d))
      wA       wC       wD       wF       wG       wH       wJ       wK       wL       wM       wN       wO       wP       wQ       wR       wS       wT       wV       wX       wY       wZ 
2.813411 3.912023 2.813411 3.912023 3.912023 3.912023 3.912023 3.218876 2.525729 3.218876 3.218876 3.912023 3.912023 2.813411 3.218876 3.218876 3.218876 2.525729 2.302585 2.302585 2.525729 

Cảm ơn bạn đã giúp đỡ! Nhưng có thể có được một số giá trị cho mỗi từ đại diện cho một số trọng số (thay vì toàn bộ ma trận) không? Bây giờ chúng ta có một ma trận toàn bộ trọng lượng. Tôi đang thực hiện một số lựa chọn tính năng và muốn sử dụng tf / idf làm phương thức lọc ...
ABC

@ABC tf-idf theo định nghĩa đề cập đến ma trận trọng số đầy đủ. Có lẽ bạn quan tâm đến trọng lượng idf một mình, mà bạn sẽ nhận được bằng log((number of docs)/(number of docs containing the term)). Bạn cũng có thể chỉ cần lọc ra các điều khoản không thường xuyên.
Zach

Rất rõ ràng! Rất cảm kích.
ABC

13

có gói tm (khai thác văn bản) http://cran.r-project.org/web/packages/tm/index.html sẽ làm chính xác những gì bạn cần:

#read 1000 txt articles from directory data/txt
corpus  <-Corpus(DirSource("data/txt"), readerControl = list(blank.lines.skip=TRUE));
#some preprocessing
corpus <- tm_map(corpus, removeWords, stopwords("english"))
corpus <- tm_map(corpus, stripWhitespace)
corpus <- tm_map(corpus, stemDocument, language="english")
#creating term matrix with TF-IDF weighting
terms <-DocumentTermMatrix(corpus,control = list(weighting = function(x) weightTfIdf(x, normalize = FALSE)))

#or compute cosine distance among documents
dissimilarity(tdm, method = "cosine")

R là một ngôn ngữ chức năng nên việc đọc mã có thể khó khăn (ví dụ x về thuật ngữ)


2

Mã của bạn có lỗi: colSums tính toán số lần xuất hiện trong kho văn bản, không phải số lượng văn bản có từ.

Một phiên bản điện toán như vậy sẽ là:

tfidf=function(mat){
  tf <- mat
  id=function(col){sum(!col==0)}
  idf <- log(nrow(mat)/apply(mat, 2, id))
  tfidf <- mat
  for(word in names(idf)){tfidf[,word] <- tf[,word] * idf[word]}
  return(tfidf)
  }


1

Tôi đến bữa tiệc muộn, nhưng tôi đã chơi với các khái niệm về tc-idf (tôi muốn nhấn mạnh từ 'khái niệm' vì tôi đã không theo dõi bất kỳ cuốn sách nào cho các tính toán thực tế; vì vậy chúng có thể bị tắt, và chắc chắn dễ dàng thực hiện hơn với các gói như {tm: Text Mining Package}, như đã đề cập), và tôi nghĩ những gì tôi nhận được có thể liên quan đến câu hỏi này, hoặc trong mọi trường hợp, đây có thể là một nơi tốt để đăng nó.


CÀI ĐẶT: Tôi có một tập các 5đoạn văn bản dài được lấy từ phương tiện truyền thông in, text 1thông qua 5như Thời báo New York . Bị cáo buộc, đó là một "cơ thể" rất nhỏ, một thư viện nhỏ, có thể nói, nhưng các mục trong thư viện "kỹ thuật số" này không phải là ngẫu nhiên: Các mục đầu tiênthứ năm liên quan đến bóng đá (hoặc "bóng đá" cho "câu lạc bộ xã hội" (?) quanh đây), và cụ thể hơn là về đội bóng vĩ đại nhất hiện nay. Vì vậy, ví dụ, text 1bắt đầu như ...

"Trong chín năm qua, Messi đã dẫn dắt FC Barcelona tới các danh hiệu quốc gia và quốc tế trong khi phá vỡ các kỷ lục cá nhân theo những cách có vẻ ngoài khác ..."

Rất đẹp! Mặt khác, bạn chắc chắn sẽ muốn bỏ qua nội dung trong ba mục ở giữa. Dưới đây là một ví dụ ( text 2):

"Trong khoảng vài giờ trên khắp Texas, ông Rubio cho rằng ông Trump đã đi tiểu trong quần và sử dụng người nhập cư bất hợp pháp để loại bỏ các tin nhắn Twitter không ngớt của mình ..."

Vậy phải làm gì để tránh bằng mọi giá "lướt" từ text 1đến text 2, trong khi tiếp tục vui mừng trong tài liệu về Barcelona FC toàn năng trong text 5?


TC-IDF: Tôi tách các từ textthành từng vectơ dài. Sau đó đếm tần số của mỗi từ, tạo ra năm vectơ (mỗi vectơ text) trong đó chỉ các từ gặp phải trong tương ứng textđược tính - tất cả các từ khác, thuộc về các texts khác , đều có giá trị bằng 0. text 1Ví dụ, trong đoạn đầu tiên , vectơ của nó sẽ có số 1 cho từ "Messi", trong khi "Trump" sẽ có 0. Đây là phần tc .

Phần idf cũng được tính riêng cho từng phần textvà tạo ra 5 "vectơ" (tôi nghĩ rằng tôi coi chúng là khung dữ liệu), chứa các phép biến đổi logarit của số lượng tài liệu (đáng buồn thay, chỉ từ 0 đến 5, cho thư viện nhỏ của chúng tôi ) có chứa một từ nhất định như trong:

đăng nhập(Số tài liệu1+Số tài liệu có chứa một từ)text01text

tc×idftext


SO SÁNH: Bây giờ chỉ còn là vấn đề thực hiện các sản phẩm chấm trong số các "vectơ quan trọng của từ" này.

Có thể đoán được, chấm sản phẩm của text 1với text 513.42645, trong khi text 1v. text2Chỉ là 2.511799.

Mã R clunky (không có gì để bắt chước) ở đây .

Một lần nữa, đây là một mô phỏng rất thô sơ, nhưng tôi nghĩ nó rất đồ họa.

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.