0

私はfuzzywuzzyを試していましたが、かなりの数のケースで間違った結果が生成されていることに気付きました。デバッグしようとしましたが、説明が難しいget_matching_blocks()のシナリオに遭遇しました。

nget_matching_blocks()についての私の理解は、インデックスの最初の文字列の長さのサブ文字 列がインデックスの2番目の文字i列の長さのサブ文字列と正確に一致するトリプレットタプル(i、j、n)を返す必要があるということです。nj。

>>> hay = """"Find longest matching block in a[alo:ahi] and b[blo:bhi]. If isjunk was omitted or None, find_longest_match() returns (i, j, k) such that a[i:i+k] is equal to b[j:j+k], where alo <= i <= i+k <= ahi and blo <= j <= j+k <= bhi. For all (i', j', k') meeting those conditions, the additional conditions k >= k', i <= i', and if i == i', j <= j' are also met. In other words, of all maximal matching blocks, return one that starts earliest in a, and of all those maximal matching blocks that start earliest in a, return the one that starts earliest in b."""
>>> needle = "meeting those conditions"
>>> needle in hay
True
>>> sm = difflib.SequenceMatcher(None,needle,hay)
>>> sm.get_matching_blocks()
[Match(a=5, b=8, size=2), Match(a=24, b=550, size=0)]
>>> 

では、なぜ上記のコードが一致するブロックを見つけられないのでしょうか?

4

1 に答える 1

2

よく見えないかもしれませんが、あなたは一致hayしていませんneedle。あなたが得た

sm = difflib.SequenceMatcher(None,needle, sms)

あるべきではない

sm = difflib.SequenceMatcher(None, needle, hay)

?また、レコードの場合、によって返されるリストの最後の要素は、get_matching_blocks()形式(len(a)、len(b)、0)のダミーです。

貼り付けの間違いかもしれませんが、実際のコードで質問を更新してください(SequenceMatcher()方法を考えています)


SequenceMatcher「ジャンクヒューリスティック」が壊れています-2番目の文字列が少なくとも200文字の長さである場合、ジャンクは(count-1)が全長の1%を超えるすべての文字です。公式バグチケットからのコメント(つまり、このコメント):

バグの理由はヒューリスティックです。2番目のシーケンスが少なくとも200アイテムの長さである場合、2番目のシーケンスで1パーセントを超えて発生するアイテムはすべてジャンクとして扱われます。これは、「else:」や「return」などの繰り返しのコード行を対象としていましたが、一般的なアイテムが必要なコンテンツである小さなアルファベットでは致命的となる可能性があります。

また、上記の作成者から提供されたコード例を引用します。

ここで、len(a)== 200、len(b)== 199:

>>> print(SM(None, 'x' + 'y'*199, 'y'*199).ratio())
>>> 0.9975 #correct

ここで、len(a)== 199、len(b)== 200(切り替えab):

>>> print(SM(None, 'y'*199, 'x' + 'y'*199).ratio())
>>> 0 #wrong

明らかに両方の場合で同じ出力が得られるはずです。

バグは、私が言及したオプションのパラメータを追加することで修正autojunkされました。これは、ここで正しく動作させるために、手動でに設定する必要がありますFalse

于 2012-08-27T13:09:24.600 に答える