9

優れたパッケージ「stringdist」を発見し、それを使用して文字列の距離を計算したいと考えています。特に、一連の単語があり、「ほぼ一致」がレーベンシュタイン距離のようなアルゴリズムを介して行われるほぼ一致を出力したいと考えています。

シェル スクリプトのコードが非常に遅く、stringdist を読み込んでメトリックを含むマトリックスを生成することができました。ここで、そのマトリックスを、ほぼ一致するもののみを持つ小さなマトリックスに煮詰めたいと思います。たとえば、メトリックがゼロではなく、しきい値よりも小さい場合です。

kp <-  c('leaflet','leafletr','lego','levenshtein-distance','logo')
kpm <- stringdistmatrix(kp,useNames="strings",method="lv")
> kpm
                     leaflet leafletr lego levenshtein-distance
leafletr                   1                                   
lego                       5        6                          
levenshtein-distance      16       16   18                     
logo                       6        7    1                   19
m = as.matrix(kpm)
close = apply(m, 1, function(x) x>0 & x<5)
>  close
                     leaflet leafletr  lego levenshtein-distance  logo
 leaflet                FALSE     TRUE FALSE                FALSE FALSE
 leafletr                TRUE    FALSE FALSE                FALSE FALSE
 lego                   FALSE    FALSE FALSE                FALSE  TRUE
 levenshtein-distance   FALSE    FALSE FALSE                FALSE FALSE
 logo                   FALSE    FALSE  TRUE                FALSE FALSE

OK、これで (大きな) dist ができました。出力が次のようになるリストに戻すにはどうすればよいですか?

leafletr,leaflet,1
logo,lego,1

メトリックが非ゼロで n=5 未満の場合のみ? テストを実行できる「apply()」を見つけたので、その使用方法を整理する必要があります。

問題は stringdist と stringdistmatrix に固有のものではなく、非常に初歩的な R ですが、それでも行き詰まっています。答えにはsubset()が含まれていると思いますが、「dist」を別のものに変換する方法がわかりません。

4

2 に答える 2

6

あなたはこれを行うことができます:

library(reshape2)
d <- unique(melt(m))
out <- subset(d, value > 0 & value < 5)

ここでmeltm、長い形式 (文字列名を持つ 2 つの列と値を持つ 1 つの列) にします。ただし、対称マトリックスを融解したため、unique重複排除に使用します。

もう 1 つの方法は、次のように使用することdplyrです (クールな子供たちはdplyrパイプを使用しているため):

library(dlpyr)
library(reshape2)
library(magrittr)

out <- melt(m) %>% distinct() %>% filter(value > 0 & value < 5)

この 2 番目のオプションは、おそらくより高速ですが、実際に時間を計ったわけではありません。

于 2015-07-18T06:19:42.067 に答える
6

データを設定します。

library('stringdist')
library('dplyr')
kp <-  c('leaflet','leafletr','lego','levenshtein-distance','logo')
kpm <- stringdistmatrix(kp,useNames="strings",method="lv")

データフレームに変更できる場所はkpm次のとおりです。

kpm <- data.frame(as.matrix(kpm))

これは、単語が十分に近い場所を示す「1」を持つデータフレームを取得する方法です。

idx <- apply(kpm, 2, function(x) x >0 & x<5)
idx <- apply(idx, 1:2, function(x) if(isTRUE(x)) x<-1 else x<-NA)
#> idx
#                     leaflet leafletr lego levenshtein.distance logo
#  leaflet                   NA        1   NA                   NA   NA
#  leafletr                   1       NA   NA                   NA   NA
#  lego                      NA       NA   NA                   NA    1
#  levenshtein-distance      NA       NA   NA                   NA   NA
#  logo                      NA       NA    1                   NA   NA

簡単にするために、データフレームを溶かし、フィルタリングして、最後の列を取り除きます。

final <- melt(idx) %>%
        filter(value==1) %>%
        select(Var1, Var2)

すべてを要因ではなく文字に戻すことを忘れないでください! (R の壊れたレコードのようなものもあります...)

final[] <- lapply(final, as.character)
#> final
#      Var1     Var2
#  leafletr  leaflet
#   leaflet leafletr
#      logo     lego
#      lego     logo

次に、重複を取り除きます。

final <- final[!duplicated(data.frame(list(do.call(pmin,final),do.call(pmax,final)))),]

いくつかの良い名前を付けると、準備完了です。

names(final) <- c('string 1', 'string 2')
#> final
# string 1 string 2
# leafletr  leaflet
#     logo     lego

(リストを要求しましたが、これはデータフレームです。ここから、必要に応じて必要なものに変換するのは非常に簡単です。たとえば、csv に書き込むなどです。)

于 2015-07-18T05:04:53.543 に答える