2013-05-19 93 views
5

Giả sử tôi có dữ liệu huấn luyện dựa trên văn bản và dữ liệu thử nghiệm. Để cụ thể hơn, tôi có hai bộ dữ liệu - đào tạo và thử nghiệm - và cả hai đều có một cột chứa văn bản và được quan tâm cho công việc trong tầm tay.Cách tạo lại cùng một DocumentTermMatrix với dữ liệu mới (kiểm tra)

Tôi đã sử dụng gói tm trong R để xử lý cột văn bản trong tập dữ liệu đào tạo. Sau khi loại bỏ các khoảng trắng, dấu chấm câu và các từ dừng, tôi bắt đầu kho văn bản và cuối cùng tạo một ma trận thuật ngữ tài liệu là 1 gram chứa tần số/số lượng từ trong mỗi tài liệu. Sau đó, tôi đã cắt giảm được xác định trước, ví dụ: 50 và chỉ giữ những cụm từ có số lượng lớn hơn 50.

Sau này, tôi đào tạo mô hình GLMNET sử dụng DTM và phụ thuộc biến (đã có trong dữ liệu đào tạo). Tất cả mọi thứ chạy trơn tru và dễ dàng cho đến bây giờ.

Tuy nhiên, làm cách nào để tiếp tục khi tôi muốn ghi điểm/dự đoán mô hình trên dữ liệu thử nghiệm hoặc bất kỳ dữ liệu mới nào có thể đến trong tương lai?

Cụ thể, những gì tôi đang cố gắng tìm hiểu là làm cách nào để tạo DTM chính xác trên dữ liệu mới?

Nếu tập dữ liệu mới không có bất kỳ từ nào tương tự như dữ liệu đào tạo ban đầu thì tất cả các cụm từ phải có số không (điều này là tốt). Nhưng tôi muốn có thể sao chép chính xác cùng một DTM (về mặt cấu trúc) trên bất kỳ kho văn bản mới nào.

Bất kỳ ý tưởng/suy nghĩ nào?

+0

Nếu tôi hiểu câu hỏi của bạn một cách chính xác (và tôi không chắc là tôi có, mà không có một ví dụ tái sản xuất chứng minh những gì bạn đang cố gắng làm.), có vẻ cách đơn giản nhất để làm điều này là tạo ma trận thuật ngữ tài liệu bằng cách sử dụng tất cả dữ liệu của bạn và sau đó chia ma trận đó thành một bộ thử nghiệm và đào tạo. Bằng cách đó, bạn có tất cả các thuật ngữ được biểu diễn trong cả hai ma trận, ngay cả khi một ma trận chỉ có số không cho một số cụm từ. Bạn đang gặp rắc rối bởi vì bạn đang chia nhỏ dữ liệu trước khi tạo các ma trận tài liệu có kỳ hạn. – SchaunW

+1

Tôi đồng ý với Schaun, nhưng tôi chỉ có thể làm điều đó với dữ liệu thử nghiệm mà tôi hiện có. Tôi đang tìm một giải pháp sẽ hoạt động khi tôi nhận dữ liệu mới vào ngày mai. Khác nếu nó sẽ là một nỗi đau để luôn luôn thêm dữ liệu mới để thoát khỏi những người thân, tái tạo DTM và đào tạo lại mô hình mỗi lần. – Godel

+1

Một lần nữa, có dữ liệu ví dụ để làm việc với sẽ giúp bạn trả lời câu hỏi của mình dễ dàng hơn. Làm thế nào về điều này: biến dữ liệu mới của bạn thành ma trận thuật ngữ tài liệu, sau đó liên kết nó với dữ liệu cũ bằng cách sử dụng hàm 'rbind.fill' của gói' plyr', nó sẽ tạo một ma trận mới với tất cả các cột từ cả hai ma trận gốc. Dữ liệu đào tạo của bạn sẽ có các cột của NA cho bất kỳ điều khoản nào trong dữ liệu mới của bạn không có trong dữ liệu đào tạo của bạn. Sau đó, bạn có thể xóa các cột đó. Dữ liệu mới của bạn sẽ có các cột của NA cho bất kỳ điều khoản nào trong dữ liệu đào tạo của bạn nhưng không có trong dữ liệu mới của bạn, Bạn có thể thay thế các NA đó bằng số không. – SchaunW

Trả lời

7

Nếu tôi hiểu chính xác, bạn đã tạo dtm và bạn muốn tạo dtm mới từ các tài liệu mới có cùng cột (ví dụ: các thuật ngữ) làm dtm đầu tiên. Nếu đó là trường hợp, sau đó nó phải là một vấn đề của phụ thiết lập dtm thứ hai bởi các điều khoản trong lần đầu tiên, có lẽ một cái gì đó như thế này:

Đầu tiên thiết lập một số dữ liệu tái sản xuất ...

Đây là của bạn đào tạo dữ liệu ...

library(tm) 
# make corpus for text mining (data comes from package, for reproducibility) 
data("crude") 
corpus1 <- Corpus(VectorSource(crude[1:10]))  
# process text (your methods may differ) 
skipWords <- function(x) removeWords(x, stopwords("english")) 
funcs <- list(tolower, removePunctuation, removeNumbers, 
       stripWhitespace, skipWords) 
crude1 <- tm_map(corpus1, FUN = tm_reduce, tmFuns = funcs) 
crude1.dtm <- DocumentTermMatrix(crude1, control = list(wordLengths = c(3,10))) 

Và đây là dữ liệu thử nghiệm của bạn ...

corpus2 <- Corpus(VectorSource(crude[15:20])) 
# process text (your methods may differ) 
skipWords <- function(x) removeWords(x, stopwords("english")) 
funcs <- list(tolower, removePunctuation, removeNumbers, 
       stripWhitespace, skipWords) 
crude2 <- tm_map(corpus2, FUN = tm_reduce, tmFuns = funcs) 
crude2.dtm <- DocumentTermMatrix(crude2, control = list(wordLengths = c(3,10))) 

Dưới đây là bit mà những gì bạn muốn:

Bây giờ chúng ta tiếp tục chỉ các điều khoản trong các dữ liệu thử nghiệm có mặt trong các dữ liệu đào tạo ...

# convert to matrices for subsetting 
crude1.dtm.mat <- as.matrix(crude1.dtm) # training 
crude2.dtm.mat <- as.matrix(crude2.dtm) # testing 

# subset testing data by colnames (ie. terms) or training data 
xx <- data.frame(crude2.dtm.mat[,intersect(colnames(crude2.dtm.mat), 
              colnames(crude1.dtm.mat))]) 

Cuối cùng thêm vào các dữ liệu thử nghiệm tất cả các cột trống với các điều kiện trong các dữ liệu đào tạo mà không có trong dữ liệu thử nghiệm ...

# make an empty data frame with the colnames of the training data 
yy <- read.table(textConnection(""), col.names = colnames(crude1.dtm.mat), 
       colClasses = "integer") 

# add incols of NAs for terms absent in the 
# testing data but present # in the training data 
# following SchaunW's suggestion in the comments above 
library(plyr) 
zz <- rbind.fill(xx, yy) 

vì vậy zz là một khung dữ liệu của các tài liệu thử nghiệm, nhưng có cấu trúc tương tự như các tài liệu đào tạo (ví dụ. cùng một cột, mặc dù nhiều cột chứa NA, như SchaunW ghi chú).

Đó có phải là những gì bạn muốn không?

+0

Có Bến. Điều này giúp khá nhiều. Cảm ơn rất nhiều. :) – Godel

+0

Không phải lo lắng! Và bây giờ bạn biết cách tạo dữ liệu mẫu để bao gồm trong bất kỳ câu hỏi liên quan nào bạn có thể muốn hỏi. – Ben

+0

Tôi đã tìm kiếm một giải pháp cho điều này một thời gian, cảm ơn, mặc dù sẽ cố gắng cũng một trong những prowided dưới đây bởi Dmitriy – Tetlanesh

12

tm có rất nhiều cạm bẫy ... Xem hiệu quả hơn text2vecvectorization vignette có câu trả lời đầy đủ cho câu hỏi.

Đối tm đây có lẽ là một trong nhiều cách đơn giản để tái tạo lại ma trận DTM cho corpus thứ hai:

crude2.dtm <- DocumentTermMatrix(crude2, control = list 
       (dictionary=Terms(crude1.dtm), wordLengths = c(3,10))) 
+3

Điều đó cũng hoạt động tốt, nhưng 'Dictionary()' không còn được hỗ trợ và bạn phải sử dụng 'Terms()' để thay thế. – Khozzy

+0

Ví dụ tuyệt vời, chắc chắn sẽ cung cấp cho nó một thử, đã được tìm kiếm một cách bản địa của việc này. Tôi đoán tôi thực sự nên đọc vingietes của gói tôi sử dụng :) – Tetlanesh

+1

Tôi nghĩ rằng giải pháp này là tốt hơn nhiều vì nó không chuyển đổi từ ma trận thưa thớt – elactic