3

レーベンシュタイン文字列距離を計算するための関数を含む R で名前が付けられたパッケージがあります。stringdistこのパッケージには 2 つの問題があります。

1st大きな文字列では機能しません。例:

set.seed(1)
a.str <- paste(sample(0:9, 100000, replace = T), collapse="")

set.seed(2)
b.str <- paste(sample(0:9, 100000, replace = T), collapse="")

stringdist(a.str, b.str, method = "lv")
# THE LAST COMMAND RESTARTS R SESSION

ベクトルの2 番目の距離は、ベクトル全体ではなく、ベクトル要素の文字ごとに計算されます。

a.vec <- c(1, 2, 3, 4, 5, 666)
b.vec <- c(1, 2, 4, 3, 6, 777)
stringdist(a.vec, b.vec, method = "lv")
# [1] 0 0 1 1 1 3

最後のコマンド 4 の結果が必要です: 4 つの置換が必要なためです (対応する位置の 4 つのベクトル要素が異なります)。この場合、0 以外の値を取得してカウントできますr <- stringdist(a.vec, b.vec, method = "lv"); length(r[r!=0])。ただし、次の例では機能しません。

a.vec <- c(1, 2, 3)
b.vec <- c(1, 2, 2, 3)
stringdist(a.vec, b.vec, method = "lv")
# [1] 0 0 1 1
# Warning message:
# In stringdist(a.vec, b.vec, method = "lv") :
#   longer object length is not a multiple of shorter object length

最後のコマンド 1 の結果が必要です (1 番目のベクトルの 1 番目の位置に 2 を挿入します)。

PS実装も組み込まれていますが、大きな文字列では機能しません(正直なところ、出力が理解できないため、ベクトルでどのように機能するのかわかりません):

adist(a.str,b.str, counts = T)
# Error in adist(a.str, b.str, counts = T) : 
#   'Calloc' could not allocate memory (1410265409 of 8 bytes)

私の要件を満たす実装 (できれば python、perl、または R) はありますか? どうもありがとうございました。

PPS各行に1〜500の数字が含まれる複数のファイルがあります(これが、たとえば347を3、4、7で構成される文字列としてではなく、1つの要素として扱う必要がある理由です。3、4、7は別の別の数字だからです)。これらのファイルには ~ 250000 行あります。そして、これらのファイルが互いにどの程度類似しているかを知りたいです。10k*10k サイズが問題だと思います。ただし、ここでは、2*10k サイズのみを使用するレーベンシュタイン アルゴリズムについて説明します (両方の文字列の長さが 10k の場合)。トリックは、結果のみを計算し、結果がどのように計算されたかを忘れることだと思いますが、これは私にとっては問題ありません。挿入、削除、置換を考慮する必要があるため、ハミング距離では十分ではありません。ハミングではこれら 2 つの文字列1234567890 0123456789は完全に異なりますが、レーベンシュタインでは類似しています。

4

1 に答える 1

1

メモリの問題の解決策は次のとおりです。

library(RecordLinkage)

set.seed(1)
a.str <- paste(sample(0:9, 100000, replace = T), collapse="")
set.seed(2)
b.str <- paste(sample(0:9, 100000, replace = T), collapse="")
levenshteinDist(a.str, b.str)
[1] 73969

pasteパッケージによって自動的に想定されないため、使用してベクトルを文字列に変換する必要があります。ほとんどのユースケースでは、ベクトル化された操作が必要です。

代わりにそれらを文字列として扱う方法については、以下を参照してください。

a.vec <- c(1, 2, 3, 4, 5, 666)
b.vec <- c(1, 2, 4, 3, 6, 777)
levenshteinDist(paste(a.vec, collapse = ''), paste(b.vec, collapse = ''))
[1] 5
于 2016-04-26T13:04:56.183 に答える