0

R の stringdist パッケージの stringdist 関数を使用してコサイン類似度を計算しようとしています。以下のコードを使用して結果を取得しています。しかし、以下のネストされた 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 パッケージのコサイン関数を使用できません。

4

0 に答える 0