web-dev-qa-db-ja.com

類似スコア-レーベンシュタイン

レーベンシュタインアルゴリズムをJavaに実装し、アルゴリズムによって行われた修正、つまりコストを取得しています。結果をパーセンテージで表示したいので、これは少しは役に立ちますが、あまり役に立ちません。

だから私はそれらの類似点を計算する方法を知りたいです。

また、皆さんがどのようにそれを行っているのか、そしてその理由も知りたいです。

22
N00programmer

Levenshtein 2つの文字列間の距離は、1つの文字列を別の文字列に変換するために必要な編集の最小数として定義され、許容される編集操作は1つの文字の挿入、削除、または置換です。 (ウィキペディア)

  • したがって、レーベンシュタイン距離が0の場合、両方の文字列が等しいことを意味します。
  • レーベンシュタインの最大距離(すべての文字が異なります)はmax(string1.length、string2.length)です。

したがって、パーセンテージが必要な場合は、これを使用してポイントをスケーリングする必要があります。例えば:

「ハロー」、「ハロー」->レーベンシュタイン距離1この2つの文字列の最大レーベンシュタイン距離は次のとおりです。5。したがって、文字の20%が一致しません。

String s1 = "Hallo";
String s2 = "Hello";
int lfd = calculateLevensteinDistance(s1, s2);
double ratio = ((double) lfd) / (Math.max(s1.length, s2.length));
33
Ralph

Apache Commons StringUtils をダウンロードして、レーベンシュタイン距離アルゴリズムの実装を調査(およびおそらく使用)できます。

17
Roman
 // Refer This: 100% working

public class demo 
{
public static void main(String[] args) 
{
    String str1, str2;

    str1="12345";
    str2="122345";


    int re=pecentageOfTextMatch(str1, str2);
    System.out.println("Matching Percent"+re);
}

public static int pecentageOfTextMatch(String s0, String s1) 
{                       // Trim and remove duplicate spaces
    int percentage = 0;
    s0 = s0.trim().replaceAll("\\s+", " ");
    s1 = s1.trim().replaceAll("\\s+", " ");
    percentage=(int) (100 - (float) LevenshteinDistance(s0, s1) * 100 / (float) (s0.length() + s1.length()));
    return percentage;
}

public static int LevenshteinDistance(String s0, String s1) {

    int len0 = s0.length() + 1;
    int len1 = s1.length() + 1;  
    // the array of distances
    int[] cost = new int[len0];
    int[] newcost = new int[len0];

    // initial cost of skipping prefix in String s0
    for (int i = 0; i < len0; i++)
        cost[i] = i;

    // dynamically computing the array of distances

    // transformation cost for each letter in s1
    for (int j = 1; j < len1; j++) {

        // initial cost of skipping prefix in String s1
        newcost[0] = j - 1;

        // transformation cost for each letter in s0
        for (int i = 1; i < len0; i++) {

            // matching current letters in both strings
            int match = (s0.charAt(i - 1) == s1.charAt(j - 1)) ? 0 : 1;

            // computing cost for each transformation
            int cost_replace = cost[i - 1] + match;
            int cost_insert = cost[i] + 1;
            int cost_delete = newcost[i - 1] + 1;

            // keep minimum cost
            newcost[i] = Math.min(Math.min(cost_insert, cost_delete),
                    cost_replace);
        }

        // swap cost/newcost arrays
        int[] swap = cost;
        cost = newcost;
        newcost = swap;
    }

    // the distance is the cost for transforming all letters in both strings
    return cost[len0 - 1];
}

}
3
Vishal Tathe

スコアを計算するには、可能な最大コスト(挿入+ドロップ+置換)が必要です。次に、以下の式を使用します-

score = 1 - actual_cost/max_possible_cost

参考までにこちらをご覧ください- レーベンシュタインスコア計算機能

0
userx

2つのストリング間のレーベンシュタイン差の最大値は、2つのストリングの長さの最大値になります。 (これは、短い文字列の長さまでの各文字の記号の変更に対応します。さらに、短い文字列から長い文字列へ、またはその逆に移動するかどうかに応じて、挿入または削除します。)文字列は、その最大値と、その最大値と実際のレーベンシュタイン差との差の比率である必要があります。

レーベンシュタインアルゴリズムの実装は、それらの編集がどうあるべきかを記録しない傾向がありますが、 ウィキペディアページ の抽象的なアルゴリズムを考えると、計算するのはそれほど難しいことではありません。

0
Donal Fellows

便利なリンクだと思います LevenshteinDistance

Mavenの依存関係を通じて使用できます

Maven依存関係

独自のコードを書くよりも、この実装を使用する方が良いと思います。

<dependency>
    <groupId>org.Apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.3</version>
</dependency>

例として、以下のコードを見てください

import org.Apache.commons.text.similarity.LevenshteinDistance;

public class MetricUtils {
    private static LevenshteinDistance lv = new LevenshteinDistance();

    public static void main(String[] args) {
        String s = "running";
        String s1 = "runninh";
        System.out.println(levensteinRatio(s, s1));
    }

    public static double levensteinRatio(String s, String s1) {
        return 1 - ((double) lv.apply(s, s1)) / Math.max(s.length(), s1.length());
    }
}
0
Alex