2011-07-15 19 views
10

私はMongoDBに大規模な銀行データベースを構築しました。私はこの情報を簡単に取り、whooshでインデックスを作成することができます。たとえば、私は銀行名の「Eagle Bank & Trust Co of Missouri」と「Eagle Bank and Trust Company of Missouri」を照合することができます。次のコードは、簡単なファジーなと動作しますが、上記の試合を達成することはできません。PythonでWhooshを使ったファジーストリングの検索

from whoosh.index import create_in 
from whoosh.fields import * 

schema = Schema(name=TEXT(stored=True)) 
ix = create_in("indexdir", schema) 
writer = ix.writer() 

test_items = [u"Eagle Bank and Trust Company of Missouri"] 

writer.add_document(name=item) 
writer.commit() 

from whoosh.qparser import QueryParser 
from whoosh.query import FuzzyTerm 

with ix.searcher() as s: 
    qp = QueryParser("name", schema=ix.schema, termclass=FuzzyTerm) 
    q = qp.parse(u"Eagle Bank & Trust Co of Missouri") 
    results = s.search(q) 
    print results 

は私を与える:

<Top 0 Results for And([FuzzyTerm('name', u'eagle', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'bank', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'trust', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'co', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'missouri', boost=1.000000, minsimilarity=0.500000, prefixlength=1)]) runtime=0.00166392326355> 

私はヒューという音で欲しいものを達成することが可能ですか?他のPythonベースのソリューションは何ですか?

答えて

7

あなたは一致する可能性Coヒューという音であいまい検索を使用しますがCoCompanyの差が大きいので、あなたがそうではないすべきCompanyと。 CoCompanyと似ています。Beast,~Companyと似ていますので、検索結果がどれくらい悪いのかがわかります。

あなたはCompanyCompanまたはcompaniまたはCompaneeを一致させたい場合は、デフォルト2以上のmaxdistFuzzyTermのパーソナライズされたクラスを使用することによってそれを行うことができます:

maxdist - 最大指定されたテキストからの距離を編集します。その後

class MyFuzzyTerm(FuzzyTerm): 
    def __init__(self, fieldname, text, boost=1.0, maxdist=2, prefixlength=1, constantscore=True): 
     super(MyFuzzyTerm, self).__init__(fieldname, text, boost, maxdist, prefixlength, constantscore) 

qp = QueryParser("name", schema=ix.schema, termclass=MyFuzzyTerm) 

あなたは5からmaxdistを設定することにより、CompanyCoに一致する可能性がありますが、これは私が悪いの検索結果を与える言ったように。 maxdist1から3に保つことをお勧めします。

単語の言語のバリエーションを探している場合は、whoosh.query.Variationsを使用することをお勧めします。

注:より古いバージョンのWhooshは、の代わりにminsimilarityです。

1

は、おそらくこのようなもののいくつかは、(文字列マッチングがseatgeekみんなでオープンソース化)に役立つかもしれない:今後の参考のため

https://github.com/seatgeek/fuzzywuzzy

+0

素晴らしいものを、ありがとう – cedbeu

3

、何とかこれを行うには良い方法がなければならないが、ここでのマイショット。

# -*- coding: utf-8 -*- 
import whoosh 
from whoosh.index import create_in 
from whoosh.fields import * 
from whoosh.query import * 
from whoosh.qparser import QueryParser 

schema = Schema(name=TEXT(stored=True)) 
idx = create_in("C:\\idx_name\\", schema, "idx_name") 

writer = idx.writer() 

writer.add_document(name=u"This is craaazy shit") 
writer.add_document(name=u"This is craaazy beer") 
writer.add_document(name=u"Raphaël rocks") 
writer.add_document(name=u"Rockies are mountains") 

writer.commit() 

s = idx.searcher() 
print "Fields: ", list(s.lexicon("name")) 
qp = QueryParser("name", schema=schema, termclass=FuzzyTerm) 

for i in range(1,40): 
    res = s.search(FuzzyTerm("name", "just rocks", maxdist=i, prefixlength=0)) 
    if len(res) > 0: 
     for r in res: 
      print "Potential match (%s): [ %s ]" % (i, r["name"]) 
     break 
    else: 
     print "Pass: %s" % i 

s.close() 
-2

フレーズに対する単語の集合検索ファズするために、次のこの機能を使用することができます。

def FuzzySearch(text, phrase): 
    """Check if word in phrase is contained in text""" 
    phrases = phrase.split(" ") 

    for x in range(len(phrases)): 
     if phrases[x] in text: 
      print("Match! Found " + phrases[x] + " in text") 
     else: 
      continue 
関連する問題