Tôi đang làm việc trên một vấn đề cao (~ 4k điều khoản) và muốn lấy đầu k-tương tự (bằng sự tương tự cosin) và không thể đủ khả năng để làm một tính toán đôi khôn ngoan.Làm cách nào để truy xuất hiệu quả các vectơ K-tương tự bằng cách tương tự cosin bằng R?
Bộ đào tạo của tôi là ma trận 6million x 4k và tôi muốn đưa ra dự đoán cho ma trận 600k x 4k.
Cách hiệu quả nhất để truy xuất các mục tương tự k cho mỗi mục trong ma trận 600k x 4k của tôi là gì?
Lý tưởng nhất, tôi muốn có ma trận 600k x 10 (nghĩa là các mục 10 hàng tương tự cho mỗi mục 600k).
ps: Tôi đã nghiên cứu trang web SO và tìm thấy gần như tất cả các câu hỏi "tương tự cosin trong R" tham chiếu đến cosine_sim(vector1, vector2
). Nhưng câu hỏi này đề cập đến cosine_sim(matrix1, matrix2)
.
Cập nhật Các mã sau đây sử dụng một phương pháp ngây thơ để tìm ra sự tương đồng cosin giữa mỗi hàng trong testset và mỗi dòng trong tập huấn luyện.
set.seed(123)
train<-matrix(round(runif(30),0),nrow=6,ncol=5)
set.seed(987)
test<-matrix(round(runif(20),0),nrow=4,ncol=5)
train
[1,] 0 1 1 0 1
[2,] 1 1 1 1 1
[3,] 0 1 0 1 1
[4,] 1 0 1 1 1
[5,] 1 1 0 1 0
[6,] 0 0 0 1 0
test
[1,] 0 1 1 0 0
[2,] 1 0 1 0 1
[3,] 1 0 0 0 0
[4,] 1 0 0 1 1
coSim<-function(mat1, mat2, topK){
require(plyr)
#mat2: is the testset
#mat1: is the training set. We will find cosine similarity between each row in testset and every row in trainingset.
#topK: user-input. for each row in testset we will return 'topk' similar rows(index) from the testset
#set up an empty result matrix. nrow(result) will be the same as the cartesian product between mat1 & mat2.
result<-matrix(rep(NA, nrow(mat1)*nrow(mat2)), nrow=nrow(mat1)*nrow(mat2), ncol=3)
k=1
for(i in 1:nrow(mat2)){
for(j in 1:nrow(mat1)){
result[k,1]<-i
result[k,2]<-j
result[k,3]<-crossprod(mat1[j,], mat2[i,])/sqrt(crossprod(mat1[j,]) * crossprod(mat2[i,]))
k<-k+1
}
}
#sort the result matrix by cosine similarity found for each row in testset. not sure how to keep topK from each group so convert to df
result<-as.data.frame(result)
colnames(result)<-c("testRowId", "trainRowId","CosineSimilarity")
result<-ddply(result, "testRowId", function(x) head(x[order(x$CosineSimilarity, decreasing = TRUE) , ], topK))
resultMat<-matrix(result$trainRowId, nrow=nrow(mat2), ncol=topK,byrow=T)
finalResult<-list(similarity=result, index=resultMat)
}
system.time(cosineSim<-coSim(train, test, topK=2)) #0.12 secs
cosineSim
$similarity
testRowId trainRowId CosineSimilarity
1 1 1 0.8164966
2 1 2 0.6324555
3 2 4 0.8660254
4 2 2 0.7745967
5 3 5 0.5773503
6 3 4 0.5000000
7 4 4 0.8660254
8 4 2 0.7745967
$index
[,1] [,2]
[1,] 1 2
[2,] 4 2
[3,] 5 4
[4,] 4 2
set.seed(123)
train<-matrix(round(runif(1000000),0),nrow=5000,ncol=200)
set.seed(987)
test<-matrix(round(runif(400000),0),nrow=2000,ncol=200)
system.time(cosineSim<-coSim(train, test, topK=50)) #380secs
Khi tôi chạy cùng chức năng với ma trận 5000x200 để đào tạo và ma trận 2000x200 để thử nghiệm, nó mất hơn 380 giây.
Lý tưởng nhất, tôi muốn xem một số ý tưởng mà tôi không phải tính toán sự giống nhau giữa mỗi hàng. Nếu điều đó là không thể, một số gợi ý về cách vectơ mã trên sẽ hữu ích.
@cho người xuống bình chọn câu hỏi này: Nếu bạn định bỏ phiếu, có lẽ sẽ hữu ích nếu bạn có thể thêm nhận xét về lý do bạn làm như vậy. –
Tôi đã không downvote. Tuy nhiên, bạn nên đọc [this] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) trước khi đăng câu hỏi. – Metrics
@Metrics: cảm ơn, tôi đã cập nhật câu hỏi của mình với một số mã. Hy vọng rằng câu hỏi là rõ ràng ngay bây giờ. –