Эффективный способ вычисления косинусного сходства, игнорируя цикл
Я пытаюсь вычислить косинусное сходство, используя функцию stringdist из пакета stringdist в R. Я хочу получить среднее косинусное сходство для каждой строки в scoring_dt, вычислив косинусное сходство с каждой строкой baseline_dt и взяв среднее для всех значений. Я успешно получаю результаты, используя приведенный ниже код. Но я ищу очень эффективный код, потому что нижний цикл for очень медленный для большого набора данных.
baseline_dt <- read.table(text="id Product.Group.Code R1 R2 R3 R4 S1 S2 S3 U1 U2 U3 U4 U6
91 65418 164 0.68 0.70 0.50 0.59 NA NA 0.96 NA 0.68 NA NA NA
93 57142 164 NA 0.94 NA NA 0.83 NA NA 0.54 NA NA NA NA
99 66740 164 0.68 0.68 0.74 NA 0.63 0.68 0.72 NA NA NA NA NA
100 76712 164 0.54 0.54 0.40 NA 0.39 0.39 0.39 0.50 NA 0.50 NA NA
101 56463 164 0.67 0.67 0.76 NA NA 0.76 0.76 0.54 NA NA NA NA
125 11713 164 NA NA NA NA NA 0.88 NA NA NA NA NA NA",header=TRUE)
scoring_dt <- read.table(text="id Product.Group.Code R1 R2 R3 R4 S1 S2 S3 U1 U2 U3 U4 U6
11 999 164 0.68 0.70 0.50 0.59 0.7 NA 0.96 NA 0.68 NA NA NA
22 555 164 0 0.94 0 NA 0.83 0.6 NA 0.54 NA NA NA NA",header=TRUE)
Пожалуйста, найдите код R ниже.
dc <- setNames(data.frame(matrix(ncol = 3, nrow = 0)), c("baseline_id", "scoring_id", "cosine_score"))
dt <- setNames(data.frame(matrix(ncol = 2, nrow = 0)), c("scoring_id", "Avg_cosine_score"))
predictor <- c("R1" ,"R2" ,"R3" ,"R4", "S1", "S2", "S3", "U1", "U2" ,"U3", "U4" ,"U6")
id <-"id"
baseline_dt <- data.table::setDT(baseline_dt)
scoring_dt <- data.table::setDT(scoring_dt)
for(i in 1:length(scoring_dt[[id]])){
for(j in 1:length(baseline_dt[[id]])){
dc[j,1] <- baseline_dt[[id]][j]
dc[j,2] <- scoring_dt[[id]][i]
cos <- stringdist::stringdist(as.character(baseline_dt[ ,predictor ,with=F][j,]),as.character(scoring_dt[,predictor,with=F][i,]),
method=method,nthread=8)
cos[is.na(cos)] <- 0
dc[j,3] <- 1-mean(cos)
}
dt[i,1] <- scoring_dt[[id]][i]
dt[i,2] <- mean(dc[,3])
}
View(dt)
Я хочу преобразовать мой код в более эффективный код. Я пробовал foreach параллельные циклы, но, кажется, ничто не ускоряет мой код.
** Примечание. У меня есть смешанный символ данных и двоичный код (0 и 1), поэтому я использую функцию stringdist. Я не могу использовать функцию косинуса из пакета lsa.