Levenshtein mesafesini hızlı bir şekilde hesaplamak


24

İzin verilen kelimelerin (alfabetik olarak sıralanmış) ve kelimelerin büyük bir veri tabanı göz önüne alındığında, verilen kelimeye en yakın olan veri tabanını Levenshtein mesafesi cinsinden bulun.

Doğal yaklaşım, elbette, verilen kelime ile sözlükteki tüm kelimeler arasındaki levenshtein mesafesini basitçe hesaplamaktır (mesafeleri hesaplamadan önce veritabanında ikili bir arama yapabiliriz).

Bu soruna daha etkili bir çözüm olup olmadığını merak ediyorum. Belki aranacak kelimelerin sayısını azaltmamıza ya da levenshtein uzaklık algoritmasında optimizasyon yapmamıza izin veren sezgisel.

Konuyla ilgili makalelere linkler kabul edilir.

Yanıtlar:


16

İstediğiniz şey, düzenleme mesafesinin altındaki komşu aramaların sorunu. Teorik sonuçlarla ya da sezgisel taramalarla ilgilenip ilgilenmediğinizi söylemediniz, bu yüzden eskisine cevap vereceğim.

Düzenleme mesafesi, komşu yakın arama yapılarının oluşturulması için uğraşılması biraz zor. Asıl sorun, bir ölçü olarak, boyutsallık azaltma ve yaklaştırma amacıyla, gibi diğer iyi bilinen kötü ölçütler gibi . Bu konuyla ilgili okumak için oldukça geniş bir çalışma alanı var ve en iyi kaynağınız Alex Andoni'nin bildiri dizileridir: işaretçileri geriye doğru izleyerek (örneğin, FOCS 2010 belgesinden) iyi bir kaynak kümesi elde edersiniz.1


1
Metrik uzaylar hakkında bildiğim tek şey anlambilimden geliyor, yani bir soru: Levenshtein metrikinin bir ultrametrik içine gömülü herhangi bir terbiyeli (terbiyeli değer için) var mı? Sonuç olarak, bu ikili-ağaç-ish algoritmasına yol açabilir.
Neel Krishnaswami

Tamamen emin değilim. Cevabın genel olmadığını düşünüyorum, ancak benim de işaret edecek hiçbir şeyim yok.
Suresh Venkat

Boytsov.info/pubs hakkındaki ikinci makale , Levenshtein ve Damereau-Levenshtein düzenleme mesafesi altındaki yakın komşu araştırmaları için olası çözümlerin iyi bir araştırmasıdır.
a3nm

@NeelKrishnaswami bir en az bozulma olmayacak olan, bir Ultrametrik içine gömmek d dizi uzunluğudur. Bu, daha az içine gömmek için bağlanmış bir bozulma izler L 1 nedeniyle Krauthgamer ve Rabani ultrametrics içine izometrik gömer Öklid boşluğa izometrik gömmek için, L 1 . Ω(logd)dL1L1
Sasho Nikolov


5

Hoşgörüleceğiniz az sayıda yanlış düzenleme varsa, noktalı bir sonek ağacı kullanmayı deneyebilirsiniz . Feragatname: Bu kağıdı ben yazdım, ancak istediğinizi çözdü: disk alanı maliyeti yüksek, ancak sorgular gerçekten hızlı.

Genel olarak, ona başka yollarla bakmak daha iyidir: sözlükteki tüm kelimelerin bir dizinine sahipsin. Şimdi, bir w kelimesi için, eğer sözlüğün içindeyse, dur. Aksi takdirde, 1. mesafedeki tüm varyasyonları oluşturun ve bunları arayın. Onlar orada değilse, mesafe 2'deki değişiklikleri arayın, vb.

Bu temel fikirde birkaç gelişme var.




4

Cs.stackexchange.com ( /cs//a/2096/1490 ) adresindeki benzer bir soruya cevap yazdım ve sonra bu soruyu buldum. Buradaki cevap düzenleme mesafesindeki yaklaşık yakın komşu aramaya yöneliktir (yani algoritma, sorgu dizesinin en yakın komşusu kadar sorgu dizesine yaklaşık olarak yakın olan bir dize verir). Ben burada gönderiyorum çünkü burada verilen cevaplarda verdiğim referansları bulamadım.



2

Kullanabilir mi demek istedin?

Ve sonra "Şunu mu demek istediniz" "ile verilen cevap ile Dinamik Programlamayı kullanarak giriş dizgisi arasındaki Levenshtein mesafesini bulun.


Bu cevabı anlamıyorum. Soru, Levenshtein mesafesini nasıl hesaplayacağınız ya da bir kara kutu yazım denetleyicisinin çıktısı ile karşılaştırmayla ilgili olarak değil, belirli bir girişe yakın bir Levenshtein mesafesine sahip büyük bir sözlükte bir kelimeyi nasıl etkili bir şekilde bulabileceğini soruyor ...
Huck Bennett

@Huck Bennett: @Grigory Javadyan'ın bina Did you mean?özelliği olduğunu düşündüm . Ayrıca Did you mean?verilen girdiye çok yakın olan kelimeyi döndürür ve oldukça verimli bir şekilde yapar. :)
Pratik Deoghare

Bence fikirlerin iyi, ama Grigory'nin daha derin ve daha spesifik bir şey istediği anlaşılıyor.
Huck Bennett

@Huck Bennett: Evet haklısınız! :)
Pratik Deoghare 9

-1

Bir yol, kelimeleri vektörlerle eşlemek ve levenstein mesafesini öklid mesafesine eşlemek için bir makine öğrenme modelini eğitmektir. Daha sonra kullanmak istediğiniz sözlük için vektörlerden bir KDTree oluşturabilirsiniz. Bunu yapan bir jupyter notebooku yarattım: https://gist.github.com/MichaelSnowden/9b8b1e662c98c514d571f4d5c20c3a03

DW'nun yorumlarına göre:

  1. Eğitim prosedürü = adaptif gradyanlar ile stokastik gradyan inişi
  2. kayıp fonksiyonu = gerçek düzenleme mesafesi ile öklid mesafesi arasındaki ortalama kare hatası
  3. eğitim verileri = 1 - 32 karakter uzunluğunda rasgele dizeler (genel yazım hatalarının gerçek dağılımına uyan verilerle daha iyi olabilir)
  4. kantitatif sonuçlar: 2048 parti büyüklüğünde (duvar süresi = yaklaşık bir dakika) kabaca 150 dönem için eğitimden sonra, 512 boyutunda kelime eklemeleri kullanarak, bir gizli katmanı olan, gerçek düzenleme mesafesi ile öngörülen düzenleme mesafesi arasındaki ortalama mutlak hata Tahmin edilen düzenleme mesafesinin aşağı yukarı bir karakter olduğu anlamına gelir

Model yapısının özeti:

  1. Boş karakter dahil her karakter için öğrenilmiş bir gömme oluşturma (daha sonra karakter sınırının altındaki metni sağa kaydırmak için kullanılır)
  2. Metnin sağ tarafını boş karakter ile karakter sınırına gelinceye kadar boş bırakın (32)
  3. Bu yerleştirmeleri birleştir
  4. Daha düşük boyutlu bir kelime gömme (512 boyutlu) oluşturmak için yerleştirmeleri ileri beslemeli bir sinir ağından geçirin
  5. Bunu her iki kelime için de yap
  6. Vektörler arasındaki öklid mesafesini bulun
  7. Kaybı, gerçek Levenshtein mesafesi ile öklid mesafesi arasındaki ortalama kare hatası olarak ayarlayın.

Eğitim verilerim rastgele dizelerdir, ancak eğitim verilerinin (yazım hatası / doğru kelime) çift olması durumunda sonuçların gerçekten iyileşebileceğini düşünüyorum. /usr/share/dict/wordsYaygın olarak kullanılabildiğim için kullanmaya başladım .


2
Bir ML modelini, Levenshtein uzaklık haritasındaki yakın kelimelerdeki benzer vektörlere nasıl söylersiniz? Bunun için hangi eğitim prosedürünü ve kayıp fonksiyonunu kullanıyorsunuz? Cevabınızdaki yöntemi özetleyebilir misiniz, böylece bağlantı çalışmayı bıraksa bile cevabın hala yararlı olması ve kullandığınız yöntemi anlamak için not defterinizi incelememiz gerekmeyebilir mi? Ayrıca, nicel olarak ne kadar iyi çalıştığını değerlendirebilir misiniz? Bu alternatiflerden daha mı iyi?
DW

Olduğu gibi, bu (sanırım) CSTheory için kötü bir seçimdir. Yani, özellikle neyin önerildiği hakkında hiçbir fikriniz yok ve bunun için teorik bir gerekçe yok.
Clement C.

@DW Bunun için üzgünüm - bağlantının kopması durumunda kapsamlı olması gereken oldukça kapsamlı bir düzenleme yaptım. Bu gerçekten CS teorisi olmasa da araştırma olmadığı için pratik bir yaklaşım olduğunu düşünüyorum çünkü hem eğitim hem de çıkarım için hızlı ve kolay.
michaelsnowden

1
Rasgele dizelerde eğitim alıyorsunuz. Bu iki dizi arasındaki beklenen Levenshtein mesafesi, yaklaşık olarak daha uzun olan dizenin uzunluğu olacaktır. Bu nedenle, bu mesafeyi rastgele dizelerde tahmin etmek çok kolaydır, ancak bu gerçek dünya verileriyle başa çıkmak için kullanışlı değildir. Gömmelerinizin sadece dizenin uzunluğunu kodlayabileceğinden ve bu nedenle önemsiz ve işe yaramaz bir şey yapmanın lüks bir yolunu kurmuş olabileceğinden şüpheleniyorum. Bu ML kullanımı ile ilgili bir sorundur; kullandığınız kayıp fonksiyonuna karşı çok hassastır.
DW

@DW Dizüstü bilgisayardaki sonuçlara bakarsanız, geri alma işlemi sadece aynı uzunluktaki dizgelere değil, iyi sonuçlara yol açtı. Gerçekten yağmalaman için seni cesaretlendiririm. Buna önemsiz ve yararsız demezdim.
michaelsnowden
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.