জাভাতে মিলের স্ট্রিং তুলনা


111

আমি একে অপরের সাথে কয়েকটি স্ট্রিং তুলনা করতে চাই এবং সর্বাধিক সাদৃশ্যযুক্তগুলি সন্ধান করতে চাই। আমি ভাবছিলাম যে কোনও লাইব্রেরি, পদ্ধতি বা সেরা অনুশীলন আছে যা আমাকে ফিরিয়ে দেবে যা অন্যান্য স্ট্রিংগুলির সাথে আরও বেশি সাদৃশ্যযুক্ত। উদাহরণ স্বরূপ:

  • "দ্রুত শিয়াল লাফিয়ে উঠল" -> "শিয়াল লাফিয়ে উঠল"
  • "দ্রুত শিয়াল লাফিয়ে উঠল" -> "শেয়াল"

এই তুলনাটি ফিরে আসবে যে প্রথমটির চেয়ে দ্বিতীয়টির চেয়ে বেশি মিল রয়েছে।

আমার ধারণা আমার কিছু পদ্ধতি দরকার যেমন:

double similarityIndex(String s1, String s2)

কোথাও কি এমন জিনিস আছে?

সম্পাদনা: আমি কেন এটি করছি? আমি একটি স্ক্রিপ্ট লিখছি যা কোনও এমএস প্রকল্প ফাইলের আউটপুটকে কিছু লিগ্যাসি সিস্টেমের ফলাফলের সাথে তুলনা করে যা কার্য পরিচালনা করে। কারণ লিগ্যাসি সিস্টেমটির ক্ষেত্রের প্রস্থ খুব সীমাবদ্ধ থাকে, যখন মান যুক্ত হয় তবে সংক্ষিপ্তসার হয়। আমি এমএস প্রকল্পের কোন এন্ট্রি সিস্টেমে প্রবেশের অনুরূপ তা সন্ধান করার জন্য কিছু আধা-স্বয়ংক্রিয় উপায় চাই যাতে আমি উত্পন্ন কীগুলি পেতে পারি। এটির ত্রুটিগুলি রয়েছে, কারণ এটি এখনও ম্যানুয়ালি পরীক্ষা করা দরকার, তবে এটি অনেক কাজ বাঁচাতে পারে

উত্তর:


82

হ্যাঁ, এখানে অনেকগুলি দলিলযুক্ত অ্যালগরিদম রয়েছে:

  • কোসিন মিল
  • জ্যাকার্ডের মিল
  • পাশা এর সহগ
  • মিল মিলছে
  • ওভারল্যাপের মিল
  • ইত্যাদি

একটি ভাল সংক্ষিপ্তসার ("স্যামের স্ট্রিং মেট্রিকস") এখানে পাওয়া যাবে (মূল লিঙ্কটি মৃত, সুতরাং এটি ইন্টারনেট সংরক্ষণাগারের সাথে লিঙ্ক করে)

এই প্রকল্পগুলিও দেখুন:


18
+1 সিমমেট্রিক্স সাইটটি আর সক্রিয় বলে মনে হচ্ছে না। যাইহোক, আমি সোর্সফোর্জে কোডটি পেয়েছি: পয়েন্টারটির জন্য সোর্সফোর্জন. नेट / প্রজেক্টস / সিমমেট্রিক্স ধন্যবাদ।
মাইকেল মার্চেন্ট

7
"আপনি এটি পরীক্ষা করতে পারেন" লিঙ্কটি নষ্ট হয়ে গেছে।
কিরিল

1
তাই মাইকেল বণিক উপরে সঠিক লিঙ্কটি পোস্ট করেছেন।
এমিলিক

2
সোর্সফোর্জে সিমিমেট্রিক্সের জারটি কিছুটা পুরানো, github.com/mpkorstanje/simmetics হ'ল maven নিদর্শনগুলির সাথে আপডেট গিথুব পাতা
tom91136

@ মিশেলমারচ্যান্টের মন্তব্যে যুক্ত করতে, প্রকল্পটি গিথুবেও উপলব্ধ । যদিও সেখানে খুব সক্রিয় নয় তবে সোর্সফোজের চেয়ে কিছুটা সাম্প্রতিক।
ঘুরডিল

163

0% -100% ফ্যাশনে দুটি স্ট্রিংয়ের মধ্যে সাদৃশ্য গণনার সাধারণ উপায় , যা অনেক লাইব্রেরিতে ব্যবহৃত হয় তা পরিমাপ করা হয় যে আপনি দীর্ঘতর স্ট্রিংটি সংক্ষিপ্ত করে তোলার জন্য কতটা পরিবর্তন করতে হবে:

/**
 * Calculates the similarity (a number within 0 and 1) between two strings.
 */
public static double similarity(String s1, String s2) {
  String longer = s1, shorter = s2;
  if (s1.length() < s2.length()) { // longer should always have greater length
    longer = s2; shorter = s1;
  }
  int longerLength = longer.length();
  if (longerLength == 0) { return 1.0; /* both strings are zero length */ }
  return (longerLength - editDistance(longer, shorter)) / (double) longerLength;
}
// you can use StringUtils.getLevenshteinDistance() as the editDistance() function
// full copy-paste working code is below


গণনা editDistance():

editDistance()ফাংশন উপরে নিরূপণ বলে আশা করা হচ্ছে সম্পাদন করা দূরত্ব দুটি স্ট্রিং মধ্যে। আছে বিভিন্ন বাস্তবায়নের এই ধাপে, প্রতিটি ভাল একটি নির্দিষ্ট দৃশ্যকল্প অনুসারে হতে পারে। সর্বাধিক সাধারণ লেভেনস্টাইন দূরত্বের অ্যালগরিদম এবং আমরা নীচে এটি আমাদের উদাহরণে ব্যবহার করব (খুব বড় স্ট্রিংয়ের জন্য, অন্যান্য অ্যালগোরিদমগুলি আরও ভালভাবে সম্পাদন করতে পারে)।

সম্পাদনার দূরত্ব গণনা করার জন্য এখানে দুটি বিকল্প রয়েছে:


কাজের উদাহরণ:

অনলাইন ডেমো এখানে দেখুন।

public class StringSimilarity {

  /**
   * Calculates the similarity (a number within 0 and 1) between two strings.
   */
  public static double similarity(String s1, String s2) {
    String longer = s1, shorter = s2;
    if (s1.length() < s2.length()) { // longer should always have greater length
      longer = s2; shorter = s1;
    }
    int longerLength = longer.length();
    if (longerLength == 0) { return 1.0; /* both strings are zero length */ }
    /* // If you have Apache Commons Text, you can use it to calculate the edit distance:
    LevenshteinDistance levenshteinDistance = new LevenshteinDistance();
    return (longerLength - levenshteinDistance.apply(longer, shorter)) / (double) longerLength; */
    return (longerLength - editDistance(longer, shorter)) / (double) longerLength;

  }

  // Example implementation of the Levenshtein Edit Distance
  // See http://rosettacode.org/wiki/Levenshtein_distance#Java
  public static int editDistance(String s1, String s2) {
    s1 = s1.toLowerCase();
    s2 = s2.toLowerCase();

    int[] costs = new int[s2.length() + 1];
    for (int i = 0; i <= s1.length(); i++) {
      int lastValue = i;
      for (int j = 0; j <= s2.length(); j++) {
        if (i == 0)
          costs[j] = j;
        else {
          if (j > 0) {
            int newValue = costs[j - 1];
            if (s1.charAt(i - 1) != s2.charAt(j - 1))
              newValue = Math.min(Math.min(newValue, lastValue),
                  costs[j]) + 1;
            costs[j - 1] = lastValue;
            lastValue = newValue;
          }
        }
      }
      if (i > 0)
        costs[s2.length()] = lastValue;
    }
    return costs[s2.length()];
  }

  public static void printSimilarity(String s, String t) {
    System.out.println(String.format(
      "%.3f is the similarity between \"%s\" and \"%s\"", similarity(s, t), s, t));
  }

  public static void main(String[] args) {
    printSimilarity("", "");
    printSimilarity("1234567890", "1");
    printSimilarity("1234567890", "123");
    printSimilarity("1234567890", "1234567");
    printSimilarity("1234567890", "1234567890");
    printSimilarity("1234567890", "1234567980");
    printSimilarity("47/2010", "472010");
    printSimilarity("47/2010", "472011");
    printSimilarity("47/2010", "AB.CDEF");
    printSimilarity("47/2010", "4B.CDEFG");
    printSimilarity("47/2010", "AB.CDEFG");
    printSimilarity("The quick fox jumped", "The fox jumped");
    printSimilarity("The quick fox jumped", "The fox");
    printSimilarity("kitten", "sitting");
  }

}

আউটপুট:

1.000 is the similarity between "" and ""
0.100 is the similarity between "1234567890" and "1"
0.300 is the similarity between "1234567890" and "123"
0.700 is the similarity between "1234567890" and "1234567"
1.000 is the similarity between "1234567890" and "1234567890"
0.800 is the similarity between "1234567890" and "1234567980"
0.857 is the similarity between "47/2010" and "472010"
0.714 is the similarity between "47/2010" and "472011"
0.000 is the similarity between "47/2010" and "AB.CDEF"
0.125 is the similarity between "47/2010" and "4B.CDEFG"
0.000 is the similarity between "47/2010" and "AB.CDEFG"
0.700 is the similarity between "The quick fox jumped" and "The fox jumped"
0.350 is the similarity between "The quick fox jumped" and "The fox"
0.571 is the similarity between "kitten" and "sitting"

11
Levenshtein দূরশিক্ষণ পদ্ধতিতে পাওয়া যায় org.apache.commons.lang3.StringUtils
ক্লিঙ্কোদ

@ ক্লেয়ানকোড এখন এটি কমন্স-পাঠ্যের অংশ: Commons.apache.org/proper/commons-text/javadocs/api-release/org/…
লুইজ

15

আমি লেভেনস্টাইন দূরত্বের অ্যালগরিদমটিকে জাভাস্ক্রিপ্টে অনুবাদ করেছি :

String.prototype.LevenshteinDistance = function (s2) {
    var array = new Array(this.length + 1);
    for (var i = 0; i < this.length + 1; i++)
        array[i] = new Array(s2.length + 1);

    for (var i = 0; i < this.length + 1; i++)
        array[i][0] = i;
    for (var j = 0; j < s2.length + 1; j++)
        array[0][j] = j;

    for (var i = 1; i < this.length + 1; i++) {
        for (var j = 1; j < s2.length + 1; j++) {
            if (this[i - 1] == s2[j - 1]) array[i][j] = array[i - 1][j - 1];
            else {
                array[i][j] = Math.min(array[i][j - 1] + 1, array[i - 1][j] + 1);
                array[i][j] = Math.min(array[i][j], array[i - 1][j - 1] + 1);
            }
        }
    }
    return array[this.length][s2.length];
};

11

দুটি স্ট্রিংয়ের মধ্যে পার্থক্য গণনা করতে আপনি লেভেনস্টাইন দূরত্ব ব্যবহার করতে পারেন। http://en.wikipedia.org/wiki/Levenshtein_distance


2
লেভেনস্টেইন কয়েকটি স্ট্রিংয়ের জন্য দুর্দান্ত তবে বড় সংখ্যক স্ট্রিংয়ের মধ্যে তুলনা করতে স্কেল করবে না।
ব্যয়কারী

আমি জাভাতে কিছু সাফল্যের সাথে লেভেনস্টাইন ব্যবহার করেছি। আমি বিশাল তালিকার তুলনায় তুলনা করি নি তাই পারফরম্যান্স হিট হতে পারে। এছাড়াও এটি কিছুটা সহজ এবং সংক্ষিপ্ত শব্দের জন্য প্রান্তিকতা বাড়াতে কিছু তাত্পর্যপূর্ণ ব্যবহার করতে পারে (3 বা 4 টি বর্ণের মতো) যা প্রবণতার চেয়ে বেশি অনুরূপ হিসাবে দেখা যায় (এটি বিড়াল থেকে কুকুরের মধ্যে কেবল 3 টি সম্পাদনা) নোট করুন যে সম্পাদনা দূরত্বগুলি নীচে প্রস্তাবিত বেশ একই জিনিস - লেভেনস্টাইন হ'ল সম্পাদনা দূরত্বের একটি বিশেষ প্রয়োগ।
রবিবার্ব

এখানে দক্ষ নিখরচায় এসকিউএল কোয়েরির সাথে লেভেনস্টেইনকে কীভাবে একত্রিত করা হবে তা নিবন্ধে এখানে দেখানো হয়েছে: litratejava.com/sql/fuzzy-string-search-sql
টমাস ডব্লিউ

10

প্রকৃতপক্ষে স্ট্রিং মিলের অনেকগুলি ব্যবস্থা রয়েছে:

  • লেভেনস্টাইন সম্পাদনা দূরত্ব;
  • ডামেরাউ-লেভেনস্টেইন দূরত্ব;
  • জারো-উইঙ্কলারের মিল;
  • দীর্ঘতম সাধারণ সাবসেক্সেন্স সম্পাদনার দূরত্ব;
  • কিউ-গ্রাম (উকোনেন);
  • এন-গ্রাম দূরত্ব (কনড্রাক);
  • জ্যাকার্ড সূচক;
  • সোরেনসেন-ডাইস সহগ;
  • কোসিন মিল;
  • ...

আপনি এখানে এর ব্যাখ্যা এবং জাভা বাস্তবায়ন পেতে পারেন: https://github.com/tdebatty/java-string-siversity


8

আপনি অ্যাপাচি কমন্স জাভা লাইব্রেরি ব্যবহার করে এটি অর্জন করতে পারেন । এর মধ্যে এই দুটি ফাংশনটি একবার দেখুন:
- getLevenshteinDistance
- getFuzzyDistance


3
অক্টোবর 2017 হিসাবে, লিঙ্কযুক্ত পদ্ধতিগুলি হ্রাস করা হয়েছে। ক্লাস ব্যবহার করুন LevenshteinDistance এবং FuzzyScore থেকে কমন্স টেক্সট গ্রন্থাগার পরিবর্তে
vatbub



3

চৌর্যবৃত্তির সন্ধানকারীর মতো শোনাচ্ছেআপনার স্ট্রিংটি কোনও নথিতে রূপান্তরিত হলে আমার কাছে । সম্ভবত এই শব্দটির সাথে অনুসন্ধান করা ভাল কোনও বিষয়কে সরিয়ে দেবে।

"প্রোগ্রামিং কালেক্টিভ ইন্টেলিজেন্স" দুটি নথি অনুরূপ কিনা তা নির্ধারণের জন্য একটি অধ্যায় রয়েছে। কোডটি পাইথনে রয়েছে তবে এটি পরিষ্কার এবং পোর্ট করা সহজ।


3

প্রথম উত্তরদাতাকে ধন্যবাদ, আমি মনে করি 2 টি গণনা আছে গণনা সম্পাদনা দূরত্ব (এস 1, এস 2)। এটি বেশি সময় ব্যয় করার কারণে কোডটির কার্যকারিতা উন্নত করার সিদ্ধান্ত নিয়েছে। তাই:

public class LevenshteinDistance {

public static int computeEditDistance(String s1, String s2) {
    s1 = s1.toLowerCase();
    s2 = s2.toLowerCase();

    int[] costs = new int[s2.length() + 1];
    for (int i = 0; i <= s1.length(); i++) {
        int lastValue = i;
        for (int j = 0; j <= s2.length(); j++) {
            if (i == 0) {
                costs[j] = j;
            } else {
                if (j > 0) {
                    int newValue = costs[j - 1];
                    if (s1.charAt(i - 1) != s2.charAt(j - 1)) {
                        newValue = Math.min(Math.min(newValue, lastValue),
                                costs[j]) + 1;
                    }
                    costs[j - 1] = lastValue;
                    lastValue = newValue;
                }
            }
        }
        if (i > 0) {
            costs[s2.length()] = lastValue;
        }
    }
    return costs[s2.length()];
}

public static void printDistance(String s1, String s2) {
    double similarityOfStrings = 0.0;
    int editDistance = 0;
    if (s1.length() < s2.length()) { // s1 should always be bigger
        String swap = s1;
        s1 = s2;
        s2 = swap;
    }
    int bigLen = s1.length();
    editDistance = computeEditDistance(s1, s2);
    if (bigLen == 0) {
        similarityOfStrings = 1.0; /* both strings are zero length */
    } else {
        similarityOfStrings = (bigLen - editDistance) / (double) bigLen;
    }
    //////////////////////////
    //System.out.println(s1 + "-->" + s2 + ": " +
      //      editDistance + " (" + similarityOfStrings + ")");
    System.out.println(editDistance + " (" + similarityOfStrings + ")");
}

public static void main(String[] args) {
    printDistance("", "");
    printDistance("1234567890", "1");
    printDistance("1234567890", "12");
    printDistance("1234567890", "123");
    printDistance("1234567890", "1234");
    printDistance("1234567890", "12345");
    printDistance("1234567890", "123456");
    printDistance("1234567890", "1234567");
    printDistance("1234567890", "12345678");
    printDistance("1234567890", "123456789");
    printDistance("1234567890", "1234567890");
    printDistance("1234567890", "1234567980");

    printDistance("47/2010", "472010");
    printDistance("47/2010", "472011");

    printDistance("47/2010", "AB.CDEF");
    printDistance("47/2010", "4B.CDEFG");
    printDistance("47/2010", "AB.CDEFG");

    printDistance("The quick fox jumped", "The fox jumped");
    printDistance("The quick fox jumped", "The fox");
    printDistance("The quick fox jumped",
            "The quick fox jumped off the balcany");
    printDistance("kitten", "sitting");
    printDistance("rosettacode", "raisethysword");
    printDistance(new StringBuilder("rosettacode").reverse().toString(),
            new StringBuilder("raisethysword").reverse().toString());
    for (int i = 1; i < args.length; i += 2) {
        printDistance(args[i - 1], args[i]);
    }


 }
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.