दो तारों के बीच समानता मीट्रिक खोजें


284

पायथन में एक स्ट्रिंग के अन्य स्ट्रिंग के समान होने की संभावना कैसे प्राप्त करूं?

मैं एक दशमलव मान प्राप्त करना चाहता हूं जैसे 0.9 (मतलब 90%) आदि, मानक पायथन और लाइब्रेरी के साथ।

जैसे

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

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

6
मुझे नहीं लगता कि "संभावना" यहाँ सही शब्द है। किसी भी घटना में, stackoverflow.com/questions/682367/…
NPE

1
आप जिस शब्द की तलाश कर रहे हैं, वह अनुपात है, संभावना नहीं।
इबार रोज

1
हमिंग दूरी पर एक नज़र डालें ।
डायना

2
वाक्यांश 'समानता मीट्रिक' है , लेकिन कई समानताएं मैट्रिक्स हैं (जैकार्ड, कोसाइन, हेमिंग, लेवेन्शिन आदि) ने कहा कि आपको निर्दिष्ट करने की आवश्यकता है। विशेष रूप से आप तार के बीच एक समानता मीट्रिक चाहते हैं; @hbprotoss कई सूचीबद्ध हैं।
smci

जवाबों:


543

में निर्मित है।

from difflib import SequenceMatcher

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

उसका इस्तेमाल कर रहे हैं:

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

43
मॉड्यूल SequenceMatcherबनाम तुलना करने वाले इस शानदार उत्तर को देखें python-Levenshteinstackoverflow.com/questions/6690739/…
ssoler 13

1
दिलचस्प लेख और उपकरण: chairnerd.seatgeek.com/…
एंथोनी पेरोट

7
मैं अत्यधिक पूरे difflib डॉक बाहर की जाँच की सिफारिश करेंगे docs.python.org/2/library/difflib.html वहाँ एक है get_close_matchesमें बनाया गया है, हालांकि मैंने पाया sorted(... key=lambda x: difflib.SequenceMatcher(None, x, search).ratio(), ...)और अधिक विश्वसनीय, कस्टम के साथ sorted(... .get_matching_blocks())[-1] > min_matchजाँच करता है
ThorSummoner

2
@ थोरसुमोनर एक बहुत उपयोगी फ़ंक्शन ( get_closest_matches) पर ध्यान लाता है । यह एक सुविधा फ़ंक्शन है जिसे आप देख रहे हैं, AKA डॉक्स पढ़ सकता है! अपने विशेष एप्लिकेशन में मैं खराब इनपुट प्रदान करने वाले उपयोगकर्ता को कुछ बुनियादी त्रुटि की जाँच / रिपोर्टिंग कर रहा था, और यह उत्तर मुझे उनके संभावित मैचों और "समानता" क्या था, की । यदि आपको समानता प्रदर्शित करने की आवश्यकता नहीं है, हालांकि, निश्चित रूप से देखेंget_closest_matches
svenevs

यह पूरी तरह से काम किया। सरल और प्रभावी।
थैंक्यू

68

मुझे लगता है कि शायद आप स्ट्रिंग्स के बीच की दूरी का वर्णन करने वाले एल्गोरिदम की तलाश कर रहे हैं। यहाँ कुछ आप के लिए उल्लेख कर सकते हैं:

  1. हमिंग दूरी
  2. लेवेंसाइटिन दूरी
  3. दमेराऊ-लेवेनशीन दूरी
  4. यारो - विंकलर दूरी

46

समाधान # 1: पायथन बिल्डिन

SequenceMatcher को difflib से उपयोग करें

पेशेवरों : देशी अजगर पुस्तकालय, कोई अतिरिक्त पैकेज की जरूरत है।
विपक्ष : बहुत सीमित है, वहाँ स्ट्रिंग समानता के लिए कई अन्य अच्छे एल्गोरिदम हैं।

उदाहरण :
>>> from difflib import SequenceMatcher
>>> s = SequenceMatcher(None, "abcd", "bcde")
>>> s.ratio()
0.75

समाधान # 2: जेलीफ़िश लाइब्रेरी

अच्छा कवरेज और कुछ मुद्दों के साथ यह एक बहुत अच्छा पुस्तकालय है। यह समर्थन करता है:
-
लेवेंसहाइटिन दूरी - डेमारू-लेवेंसाइटिन दूरी
- जारो दूरी - जरो
-विंकलर दूरी
- मैच रेटिंग दृष्टिकोण तुलना
- हैमिंग दूरी

पेशेवरों : उपयोग करने में आसान, समर्थित एल्गोरिदम का सरगम, परीक्षण किया गया।
विपक्ष : देशी पुस्तकालय नहीं।

उदाहरण :

>>> 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

26

Fuzzy Wuzzyएक पैकेज है जो अजगर में लेवेन्सेटिन दूरी को लागू करता है, कुछ सहायक कार्यों में मदद करने के लिए कुछ स्थितियों में जहां आप दो अलग-अलग तारों को समान मान सकते हैं। उदाहरण के लिए:

>>> 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

9

आप एक समारोह बना सकते हैं जैसे:

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))

लेकिन समान ('एपेल', 'सेब') समान ('एपेल', 'एप') से अधिक है
टेनस्टार

1
आपका कार्य अन्य स्टिंग के खिलाफ दिए गए स्ट्रिंग की तुलना करेगा। मैं उच्चतम समानता अनुपात के साथ स्ट्रिंग को वापस करने का एक तरीका चाहता हूं
उत्तरशिक्षक

1
@SaulloCastro, if self.similar(search_string, item.text()) > 0.80:अभी के लिए काम करता है। धन्यवाद,
उत्तर १२


6

SequenceMatcherबड़े इनपुट पर बिल्टिन बहुत धीमा है, यहां बताया जा सकता है कि यह अलग -अलग मैच पैच के साथ कैसे किया जा सकता है :

from diff_match_patch import diff_match_patch

def compute_similarity_and_diff(text1, text2):
    dmp = diff_match_patch()
    dmp.Diff_Timeout = 0.0
    diff = dmp.diff_main(text1, text2, False)

    # similarity
    common_text = sum([len(txt) for op, txt in diff if op == 0])
    text_length = max(len(text1), len(text2))
    sim = common_text / text_length

    return sim, diff

5

नोट, difflib.SequenceMatcher केवल सबसे लंबे समय तक सन्निहित मिलान का पता लगाता है, यह अक्सर वांछित नहीं होता है, उदाहरण के लिए:

>>> a1 = "Apple"
>>> a2 = "Appel"
>>> a1 *= 50
>>> a2 *= 50
>>> SequenceMatcher(None, a1, a2).ratio()
0.012  # very low
>>> SequenceMatcher(None, a1, a2).get_matching_blocks()
[Match(a=0, b=0, size=3), Match(a=250, b=250, size=0)]  # only the first block is recorded

दो तारों के बीच समानता का पता लगाना जैव सूचना विज्ञान में युग्म अनुक्रम अनुक्रम संरेखण की अवधारणा से निकटता से संबंधित है। इसके लिए कई समर्पित पुस्तकालय हैं जिनमें बायोपथॉन भी शामिल है । यह उदाहरण नीडलमैन वून्श एल्गोरिथ्म को लागू करता है :

>>> from Bio.Align import PairwiseAligner
>>> aligner = PairwiseAligner()
>>> aligner.score(a1, a2)
200.0
>>> aligner.algorithm
'Needleman-Wunsch'

कई अलग-अलग स्कोरिंग योजनाओं और एल्गोरिदम उपलब्ध होने के बाद से बायोपथॉन या किसी अन्य जैव सूचना विज्ञान पैकेज का उपयोग करना अजगर मानक पुस्तकालय के किसी भी हिस्से की तुलना में अधिक लचीला है। इसके अलावा, आप वास्तव में क्या हो रहा है, इसकी कल्पना करने के लिए मिलान अनुक्रम प्राप्त कर सकते हैं:

>>> alignment = next(aligner.align(a1, a2))
>>> alignment.score
200.0
>>> print(alignment)
Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-
|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-
App-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-el

0

आप अधिकांश पाठ समानता विधियों को पा सकते हैं और इस लिंक के तहत उनकी गणना कैसे की जाती है: https://github.com/luozhouyang/python-string-similarity#python-string-similarity यहाँ कुछ उदाहरण हैं;

  • सामान्यीकृत, मीट्रिक, समानता और दूरी

  • (सामान्यीकृत) समानता और दूरी

  • मीट्रिक दूरी

  • शिंगल्स (एन-ग्राम) समानता और दूरी पर आधारित है
  • Levenshtein
  • सामान्यीकृत लेवेंसाइटिन
  • भारित लेवेंसाइटिन
  • Damerau-Levenshtein
  • इष्टतम स्ट्रिंग संरेखण
  • Jaro-विंकलर
  • सबसे लंबा सामान्य परिणाम
  • मैट्रिक सबसे लंबा सामान्य परिणाम
  • एन-ग्राम
  • शिंगल (एन-ग्राम) आधारित एल्गोरिदम
  • क्यू ग्राम
  • कोसाइन समानता
  • जैकार्ड सूचकांक
  • सोरेंसन-पासा गुणांक
  • ओवरलैप गुणांक (यानी, Szymkiewicz-Simpson)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.