Levenshtein Algoritması

Husamettin Elalmis

Levenshtein Algoritması

Merhaba arkadaşlar, bu yazıda sizlere Levenshtein algoritmasından bahsecedeğim.

Levenshtein Algoritması Nedir?

  • Levenshtein Distance algoritması olarak bilinir

  • Vladimir Levenshtein tarafından geliştirilmiştir

  • Kelimelerin birbirleri ile benzerlik oranını hesaplar

  • Temelinde kaynak ve hedef kelime için, İki boyutlu matris kullanarak uzaklık ölçümü yapar

  • Karşılaştırılan kelimelerin maliyetinin en küçük olanı "aradığımız kelimeye" yakın olacağı varsayılır

  • "Bunu mu demek istemiştiniz?" (Did you mean?) algoritmaları bunu kullanır

Algoritmanın Tatbik Edilmesi

  • Bir web sayfamız olduğunu varsayalım ve arama yaptırdığımızı varsayalım

  • Kullanıcının girdiği cümleyi bir havuza ekliyoruz (arama yapılanlar havuzu)

  • Kullanıcının girdiği cümleyi daha önce girilenler havuzunda benzerlik oranını en büyükten küçüğe doğru sıralayarak gösteriyoruz

  • Böylece, "Bunu mu demek istemiştiniz?" yaklaşım önermelerini listeliyoruz

Program

Program Kodu

using System;

using System.Collections.Generic;

using System.Linq;

namespace StringSimilarityArge

{

class Program

{

static void Main(string[] args)

{

Console.BackgroundColor = ConsoleColor.White;

Console.ForegroundColor = ConsoleColor.Black;

Console.Clear();

// havuzumuzdaki daha önce yapılmış olan aramalar bunlar olsun var list = new List<string>();

list.Add("ARKSOFT Bilişim Hizmetleri");

list.Add("GittiGidiyor Online Satış");

list.Add("HepsiBurada E-Ticaret");

list.Add("N11 E-Ticaret");

list.Add("Kendi E-Ticaret Sitenizi Yapın");

list.Add("Bilişim Hizmetleri Sektörü");

list.Add("Sektörel Piyasalar");

list.Add("Piyasalarda Son Durum");

list.Add("Hava Durumu");

list.Add("Online Satış İşlemleri");

list.Add("Bankacılık ve Denetleme Kurumu");

list.Add("Bağımsız Denetleme Kuruluşu");

list.Add("Bağımsız Yapı Denetim");

list.Add("Arkastra Casantra Problemi");

list.Add("Ark Signature");

list.Add("Finger Print İşlemleri ve Singer Dikiş Makinası");

list.Add("İş Makinaları Sempozyumu");

list.Add("Pazarda Satış İşlemleri");

// kullanıcının girdiği örnek arama kelimeleri var searchList = new string[] { "soft", "arksoft", "soft bilişim", "arksoft bilişim", "arksoft hizmet", "satış", "ark", "makina", "ticaret", "bilişim", "denetim", "yapı", "piyasa", "durum", "online" }; // simule ediyoruz foreach (var search in searchList)

{

Console.WriteLine($"== "{search.ToUpper()}" arama sonuçları (Bunu mu demek istediniz?) ==");

List<Tuple<double, string>> dic = new List<Tuple<double, string>>();

foreach (var item in list)

{

var res = GetBenzerlik(search, item);

dic.Add(Tuple.Create<double, string>(res, item));

}

var resList = dic.Where(x => x.Item1 > 10).OrderByDescending(x => x.Item1).ToList(); foreach (var item in resList)

{

Console.WriteLine($"{search.ToUpper()} => {item.Item2} => {item.Item1}%");

}

Console.WriteLine();

}

Console.WriteLine("ok");

Console.ReadLine();

}

public static int Hesapla(string source, string target)

{

int n = source.Length; int m = target.Length; int[,] d = new int[n + 1, m + 1]; // Adım 1 if (n == 0)

{

return m;

}

if (m == 0)

{

return n;

}

// Adım 2 for (int i = 0; i <= n; d[i, 0] = i++)

{

}

for (int j = 0; j <= m; d[0, j] = j++)

{

}

// Adım 3 for (int i = 1; i <= n; i++)

{

// Adım 4 for (int j = 1; j <= m; j++)

{

// Adım 5 int cost = (target[j - 1] == source[i - 1]) ? 0 : 1; // Adım 6

d[i, j] = Math.Min(Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost);

}

}

// Adım 7 return d[n, m];

}

static double GetBenzerlik(string fullString1, string fullString2)

{

double res = 0; string[] arr1 = fullString1.ToUpper().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string[] arr2 = fullString2.ToUpper().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr1.Length < arr2.Length)

{

string[] temp = arr2;

arr2 = arr1;

arr1 = temp;

}

int[,] scores = new int[arr1.Length, arr2.Length]; int[] bestWord = new int[arr1.Length]; for (int i = 0; i < arr1.Length; i++)

{

for (int j = 0; j < arr2.Length; j++) scores[i, j] = 1000;

bestWord[i] = -1;

}

int wordsMatched = 0; for (int i = 0; i < arr1.Length; i++)

{

string s1 = arr1[i]; for (int j = 0; j < arr2.Length; j++)

{

string s2 = arr2[j]; int levenshteinDistance = Hesapla(s1, s2);

scores[i, j] = levenshteinDistance;

if (bestWord[i] == -1 || scores[i, bestWord[i]] > levenshteinDistance) bestWord[i] = j;

}

}

for (int i = 0; i < arr1.Length; i++)

{

if (scores[i, bestWord[i]] == 1000) continue; for (int j = i + 1; j < arr1.Length; j++)

{

if (scores[j, bestWord[j]] == 1000) continue; if (bestWord[i] == bestWord[j])

{

if (scores[i, bestWord[i]] <= scores[j, bestWord[j]])

{

scores[j, bestWord[j]] = 1000;

int curBest = -1; int curScore = 1000; for (int k = 0; k < arr2.Length; k++)

{

if (curBest == -1 || curScore > scores[j, k])

{

curBest = k;

curScore = scores[j, k];

}

}

bestWord[j] = curBest;

}

else

{

scores[i, bestWord[i]] = 1000;

int curBest = -1; int curScore = 1000; for (int k = 0; k < arr2.Length; k++)

{

if (curBest == -1 || curScore > scores[i, k])

{

curBest = k;

curScore = scores[i, k];

}

}

bestWord[i] = curBest;

}

i = -1;

break;

}

}

}

for (int i = 0; i < arr1.Length; i++)

{

if (scores[i, bestWord[i]] == 1000)

{

res += arr1[i].Length;

}

else

{

res += scores[i, bestWord[i]];

if (scores[i, bestWord[i]] == 0) wordsMatched++;

}

}

int len = (fullString1.Replace(" ", "").Length > fullString2.Replace(" ", "").Length) ? fullString1.Replace(" ", "").Length : fullString2.Replace(" ", "").Length; if (res > len) res = len;

res = (1 - (res / len)) * 100;

// virgulden sonra 2 haneye yuvarla return Math.Round(res, 2);

}

}}

Sonuç

  • Bu dokumanda arama motorlarında kullanılan benzerlik algoritmasını uygulamalı görmüş olduk

Saygılarımla,

Hüsamettin ELALMIŞ – 11.06.2022

[email protected]

Last updated