2013-06-30 25 views
133

Làm thế nào để xác suất của một chuỗi tương tự với một chuỗi khác trong Python?Tìm phần trăm tương tự giữa hai chuỗi

Tôi muốn có được một giá trị thập phân như:

0.9 #means 90% 

, vv

Tốt với tiêu chuẩn Python và thư viện.

ví dụ:

similar("Apple","Appel") #would have a high prob. 

similar("Apple","Mango") #would have a lower prob. 
+4

Tôi không nghĩ rằng "khả năng" khá lâu ngay tại đây. Trong mọi trường hợp, hãy xem http://stackoverflow.com/questions/682367/good-python-modules-for-fuzzy-string-comparison – NPE

+1

Từ bạn đang tìm kiếm là tỷ lệ, không xác suất. –

+1

Hãy xem [Khoảng cách Hamming] (http://en.wikipedia.org/wiki/Hamming_distance). – Diana

Trả lời

313

Có được tích hợp sẵn trong

from difflib import SequenceMatcher 

def similar(a, b): 
    return SequenceMatcher(None, a, b).ratio() 

Sử dụng nó:

>>> similar("Apple","Appel") 
0.8 
>>> similar("Apple","Mango") 
0.0 
+15

Xem câu trả lời tuyệt vời này so sánh mô-đun 'SequenceMatcher' và' python-Levenshtein'. http://stackoverflow.com/questions/6690739/fuzzy-string-comparison-in-python-confused-with-which-library-to-use – ssoler

+1

Bài viết và công cụ thú vị: http://chairnerd.seatgeek.com/fuzzywuzzy -fuzzy-string-matching-in-python/ –

+2

Tôi rất muốn khuyên bạn nên kiểm tra toàn bộ tài liệu difflib https://docs.python.org/2/library/difflib.html có một 'get_close_matches' được xây dựng trong, mặc dù tôi tìm thấy 'được sắp xếp (... key = lambda x: difflib.SequenceMatcher (Không có, x, tìm kiếm) .ratio(), ...)' đáng tin cậy hơn, với tùy chỉnh 'được sắp xếp (... .get_matching_blocks()) [- 1]> min_match' kiểm tra – ThorSummoner

8

Bạn có thể tạo một chức năng như:.

def similar(w1, w2): 
    w1 = w1 + ' ' * (len(w2) - len(w1)) 
    w2 = w2 + ' ' * (len(w1) - len(w2)) 
    return sum(1 if i == j else 0 for i, j in zip(w1, w2))/float(len(w1)) 
+0

nhưng tương tự ('appel', 'apple') cao hơn tương tự ('appel', 'ape') – tenstar

+1

Chức năng của bạn sẽ so sánh một chuỗi nhất định so với các đốt khác. Tôi muốn một cách để trả về chuỗi có tỷ lệ tương tự cao nhất – answerSeeker

+1

@SaulloCastro, 'nếu self.similar (search_string, item.text())> 0,80:' hoạt động ngay bây giờ. Cảm ơn, – answerSeeker

14

Fuzzy Wuzzy là một package mà thực hiện khoảng cách levenshtein trong trăn, với một số chức năng helper để giúp trong một số tình huống mà bạn có thể muốn hai chuỗi riêng biệt được coi là giống nhau. Ví dụ:

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear") 
    91 
>>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear") 
    100 
6

Gói distance bao gồm khoảng cách levenshtein:

import distance 
distance.levenshtein("lenvestein", "levenshtein") 
# 3 
6

Giải pháp # 1: Python BUILTIN

sử dụng SequenceMatcher từ difflib

ưu: thư viện python bản địa, không cần gói thêm.
nhược điểm: quá hạn chế, có rất nhiều thuật toán tốt khác cho sự giống nhau về chuỗi trên mạng.

dụ:
>>> from difflib import SequenceMatcher 
>>> s = SequenceMatcher(None, "abcd", "bcde") 
>>> s.ratio() 
0.75 

Giải pháp # 2: jellyfish thư viện

mình một thư viện rất tốt với vùng phủ sóng tốt và vài vấn đề. nó hỗ trợ:
- Levenshtein cách
- Damerau-Levenshtein cách
- Jaro cách
- Jaro-Winkler cách
- Trận Đánh giá cách tiếp cận so sánh
- Hamming cách

ưu: dễ dàng để sử dụng, âm thanh của các thuật toán được hỗ trợ, được kiểm tra.
cons: không phải thư viện gốc.

dụ:

>>> import jellyfish 
>>> jellyfish.levenshtein_distance(u'jellyfish', u'smellyfish') 
2 
>>> jellyfish.jaro_distance(u'jellyfish', u'smellyfish') 
0.89629629629629637 
>>> jellyfish.damerau_levenshtein_distance(u'jellyfish', u'jellyfihs') 
1