Tính toán khoảng cách Levenshtein một cách nhanh chóng


24

Đưa ra một cơ sở dữ liệu khổng lồ gồm các từ được phép (sắp xếp theo thứ tự abc) và một từ, tìm từ từ cơ sở dữ liệu gần nhất với từ đã cho theo khoảng cách Levenshtein.

Tất nhiên, cách tiếp cận ngây thơ chỉ đơn giản là tính khoảng cách levenshtein giữa từ đã cho và tất cả các từ trong từ điển (chúng ta có thể thực hiện tìm kiếm nhị phân trong cơ sở dữ liệu trước khi thực sự tính khoảng cách).

Tôi tự hỏi nếu có một giải pháp hiệu quả hơn cho vấn đề này. Có thể một số heuristic cho phép chúng ta giảm số lượng từ để tìm kiếm hoặc tối ưu hóa cho thuật toán khoảng cách levenshtein.

Liên kết đến các giấy tờ về chủ đề chào mừng.

Câu trả lời:


16

Những gì bạn đang hỏi là vấn đề tìm kiếm gần hàng xóm trong khoảng cách chỉnh sửa. Bạn đã không đề cập đến việc bạn quan tâm đến kết quả lý thuyết hay chẩn đoán, vì vậy tôi sẽ trả lời trước.

Khoảng cách chỉnh sửa là hơi khó chịu để đối phó với việc xây dựng các cấu trúc tìm kiếm gần hàng xóm. Vấn đề chính là ở dạng số liệu, nó hoạt động (sắp xếp) giống như các số liệu xấu nổi tiếng khác như với mục đích giảm kích thước và xấp xỉ. Có rất nhiều công việc để đọc về chủ đề này và nguồn tốt nhất của bạn là tập hợp các bài báo của Alex Andoni : bằng cách làm ngược con trỏ (ví dụ từ bài báo FOCS 2010 của anh ấy), bạn sẽ có được một bộ nguồn tốt.1


1
Tất cả những gì tôi biết về không gian số liệu là từ ngữ nghĩa, vì vậy một câu hỏi: có bất kỳ giá trị nào (đối với bất kỳ giá trị nào của số liệu đàng hoàng) của số liệu Levenshtein vào một siêu dữ liệu không? Chính thức, điều đó có thể làm tăng thuật toán nhị phân cây-ish.
Neel Krishnaswami

Tôi không hoàn toàn chắc chắn. Tôi nghi ngờ câu trả lời là không nói chung, nhưng tôi không có gì để chỉ ra.
Suresh Venkat

Bài viết thứ hai trên boytsov.info/pub là một cuộc khảo sát tốt về các giải pháp khả thi cho tìm kiếm hàng xóm gần theo khoảng cách chỉnh sửa Levenshtein và Damereau-Levenshtein.
a3nm

@NeelKrishnaswami Việc nhúng vào một siêu ma trận sẽ có biến dạng ít nhất là trong đó là độ dài chuỗi. Điều này xuất phát từ một biến dạng bị ràng buộc thấp hơn khi nhúng vào do Krauthgamer và Rabani , do siêu âm nhúng phương pháp đo lường vào không gian Euclide, nhúng vào phương pháp đo vào . d L 1 L 1Ω(logd)dL1L1
Sasho Nikolov


5

Nếu bạn có một số lượng nhỏ các chỉnh sửa sai mà bạn sẽ dung thứ, thì bạn có thể thử sử dụng một cây hậu tố chấm . Tuyên bố miễn trừ trách nhiệm: Tôi đã viết bài báo đó, nhưng nó giải quyết những gì bạn muốn: nó có chi phí không gian đĩa cao, nhưng các truy vấn thực sự nhanh.

Nói chung, tốt hơn là nhìn nó theo cách khác: bạn có một chỉ mục của tất cả các từ trong từ điển. Bây giờ, đối với một từ đầu vào w, nếu nó có trong từ điển, hãy dừng lại. Nếu không, tạo tất cả các biến thể ở khoảng cách 1 và tìm kiếm các biến thể. Nếu chúng không có ở đó, hãy tìm các biến thể ở khoảng cách 2, v.v.

Có một số cải tiến cho ý tưởng cơ bản này.


1
Bạn nên bao gồm một liên kết đến kho lưu trữ nghiên cứu tái sản xuất của bạn cho bài báo .
Dan D.

4

Một giải pháp đơn giản là lưu trữ các từ như một trie. Sau đó, bạn có thể tính khoảng cách Levenshtein của từ truy vấn so với trie bằng thuật toán lập trình động tiêu chuẩn, thay vì tính toán nó với từng từ riêng biệt. Độ phức tạp thời gian trong trường hợp xấu nhất không được cải thiện một cách không có triệu chứng, nhưng nếu bạn mở rộng các nhánh có triển vọng nhất trước tiên, bạn sẽ nhận được thời gian như cho độ dài truy vấn , kích thước bảng chữ cái và chỉnh sửa khoảng cách .m σ kO(mk+1σk)mσk


4

Tôi đã viết một câu trả lời cho một câu hỏi rất giống nhau tại cs.stackexchange.com ( /cs//a/2096/1490 ) và sau đó tôi tìm thấy câu hỏi này. Câu trả lời dành cho tìm kiếm hàng xóm gần đúng trong khoảng cách chỉnh sửa (tức là thuật toán xuất ra một chuỗi gần với chuỗi truy vấn như là hàng xóm gần nhất của chuỗi truy vấn). Tôi đang đăng ở đây vì tôi không tìm thấy bất kỳ tài liệu tham khảo nào tôi đã đưa ra trong các câu trả lời ở đây.


3

Tôi nghĩ những gì bạn muốn là thuật toán Wagner-Fischer: https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_alacticm Cái nhìn sâu sắc quan trọng là, vì từ điển bạn đang duyệt qua được sắp xếp, hai từ liên tiếp rất có khả năng chia sẻ một tiền tố dài, do đó bạn không cần cập nhật toàn bộ ma trận cho mỗi phép tính khoảng cách.


2

Bạn có thể sử dụng Ý của bạn là gì?

Và sau đó tìm khoảng cách Levenshtein giữa câu trả lời được trả về bởi "Ý của bạn là" "và chuỗi đầu vào bằng Lập trình động.


Tôi không hiểu câu trả lời này. Câu hỏi hỏi làm thế nào người ta có thể tìm thấy một từ trong từ điển lớn với khoảng cách Levenshtein gần với một đầu vào nhất định, không phải về cách tính khoảng cách Levenshtein hoặc về so sánh với đầu ra của trình kiểm tra chính tả hộp đen ...
Huck Bennett

@Huck Bennett: Tôi nghĩ @Grigory Javadyan đang xây dựng Did you mean?tính năng. Bên cạnh đó Did you mean?trả về từ rất gần với đầu vào đã cho và nó khá hiệu quả. :)
Pratik Deoghare

Tôi nghĩ ý tưởng của bạn là tốt, nhưng có vẻ như Grigory đang yêu cầu một cái gì đó sâu sắc và cụ thể hơn.
Huck Bennett

@ Huck Bennett: Có bạn đúng! :)
Pratik Deoghare

-1

Một cách là đào tạo một mô hình học máy để ánh xạ các từ thành vectơ và ánh xạ khoảng cách levenshtein đến khoảng cách euclide. Sau đó, bạn có thể xây dựng một KDTree từ các vectơ cho từ điển bạn muốn sử dụng. Tôi đã tạo một sổ ghi chép jupyter thực hiện việc này tại đây: https://gist.github.com/MichaelSnowden/9b8b1e662c98c514d571f4d5c20c3a03

Theo nhận xét của DW:

  1. quy trình đào tạo = giảm độ dốc ngẫu nhiên với độ dốc thích nghi
  2. hàm mất = lỗi bình phương trung bình giữa khoảng cách chỉnh sửa thực và khoảng cách euclide
  3. dữ liệu huấn luyện = chuỗi ngẫu nhiên dài từ 1 đến 32 ký tự (có thể được cải thiện với dữ liệu khớp với phân phối thực tế của các lỗi chính tả)
  4. kết quả định lượng: Sau khi đào tạo khoảng 150 epoch với kích thước lô 2048 (thời gian treo tường = khoảng một phút), sử dụng nhúng từ 512 kích thước, với một lớp ẩn, lỗi tuyệt đối trung bình giữa khoảng cách chỉnh sửa thực và khoảng cách chỉnh sửa dự đoán nằm ở khoảng 0,75, có nghĩa là khoảng cách chỉnh sửa dự đoán là khoảng một ký tự

Tóm tắt cấu trúc mô hình:

  1. Tạo một nhúng nhúng đã học cho mỗi ký tự, bao gồm ký tự null (được sử dụng sau này cho văn bản đệm bên phải dưới giới hạn ký tự)
  2. Di chuyển bên phải của văn bản với ký tự null cho đến khi nó ở giới hạn ký tự (32)
  3. Nối các phần nhúng này
  4. Chạy các nhúng thông qua một mạng lưới thần kinh chuyển tiếp thức ăn để tạo ra một từ nhúng chiều thấp hơn (512 chiều)
  5. Làm điều này cho cả hai từ
  6. Tìm khoảng cách euclide giữa các vectơ
  7. Đặt tổn thất là sai số bình phương trung bình giữa khoảng cách Levenshtein thực và khoảng cách euclide

Dữ liệu đào tạo của tôi chỉ là các chuỗi ngẫu nhiên, nhưng tôi nghĩ rằng kết quả thực sự có thể cải thiện nếu dữ liệu đào tạo là các cặp (lỗi chính tả / từ đúng). Tôi đã kết thúc việc sử dụng /usr/share/dict/wordsbởi vì nó thường có sẵn.


2
Làm thế nào để bạn đào tạo một mô hình ML sao cho các từ ở gần trong bản đồ khoảng cách Levenshtein với các vectơ tương tự? Quy trình đào tạo và chức năng mất nào bạn sử dụng cho điều đó? Bạn có thể tóm tắt phương pháp trong câu trả lời của mình để câu trả lời vẫn hữu ích ngay cả khi liên kết ngừng hoạt động và để chúng tôi không phải tìm hiểu về sổ ghi chép của bạn để hiểu phương pháp bạn đang sử dụng? Ngoài ra, bạn có thể đánh giá nó hoạt động tốt như thế nào theo một số lượng? Điều này là tốt hơn so với các lựa chọn thay thế?
DW

Như hiện tại, đây là (tôi nghĩ) không phù hợp với CSTheory. Đó là, không có ý tưởng về những gì được đề xuất cụ thể, và không có lời biện minh lý thuyết cho nó.
Clement C.

@DW Xin lỗi về điều đó - Tôi đã thực hiện một chỉnh sửa khá đáng kể, toàn diện khi liên kết bị hỏng (hoặc trong trường hợp bạn không muốn chọc vào sổ ghi chép). Mặc dù đây không thực sự là lý thuyết CS vì nó không phải là nghiên cứu, nhưng tôi nghĩ đó là một cách tiếp cận thực tế bởi vì nó nhanh chóng và dễ dàng cho cả đào tạo và suy luận.
michaelsnowden

1
Bạn đang đào tạo trên chuỗi ngẫu nhiên. Khoảng cách Levenshtein dự kiến ​​giữa hai chuỗi như vậy sẽ xấp xỉ chiều dài của chuỗi dài hơn. Do đó, rất dễ dàng để ước tính khoảng cách này trên các chuỗi ngẫu nhiên, nhưng điều đó không hữu ích để xử lý dữ liệu trong thế giới thực. Tôi nghi ngờ các nhúng của bạn có thể chỉ mã hóa độ dài của chuỗi, và do đó bạn có thể đã xây dựng một cách lạ mắt để làm một cái gì đó tầm thường và vô dụng. Đây là một vấn đề với việc sử dụng ML; nó rất nhạy cảm với chức năng mất bạn sử dụng.
DW

@DW Nếu bạn nhìn vào kết quả trong sổ ghi chép, việc truy xuất cuối cùng sẽ trả về kết quả tốt - không chỉ các chuỗi có cùng độ dài. Tôi thực sự sẽ khuyến khích bạn lướt qua nó. Tôi sẽ không gọi nó là tầm thường và vô dụng.
michaelsnowden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.