【问题标题】:Fuzzy String Searching with Whoosh in Python在 Python 中使用 Whoosh 进行模糊字符串搜索
【发布时间】:2011-10-06 07:02:21
【问题描述】:

我在 MongoDB 中建立了一个大型银行数据库。我可以轻松地获取这些信息并用它创建索引。例如,我希望能够匹配银行名称“Eagle Bank & Trust Co of Missouri”和“Eagle Bank and Trust Company of Missouri”。以下代码适用于简单模糊之类,但无法实现上述匹配:

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>

是否可以通过 Whoosh 实现我想要的?如果没有,我还有什么其他基于 python 的解决方案?

【问题讨论】:

    标签: python information-retrieval fuzzy-search whoosh


    【解决方案1】:

    也许其中一些东西可能会有所帮助(字符串匹配由 seatgeek 家伙开源):

    https://github.com/seatgeek/fuzzywuzzy

    【讨论】:

      【解决方案2】:

      为了将来参考,必须有更好的方法来做到这一点,但这是我的想法。

      # -*- 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()
      

      【讨论】:

        【解决方案3】:

        您可以在 Whoosh 中使用模糊搜索将CoCompany 匹配,但您不应该这样做,因为CoCompany 之间的区别是大。 CoCompany 相似,BeBeast 相似,nyCompany 相似,您可以想象搜索结果会有多糟糕和有多大。

        但是,如果您想将CompancompaniCompaneeCompany 匹配,您可以使用FuzzyTerm 的个性化类来实现,默认maxdist 等于2 或更多:

        ma​​xdist – 与给定文本的最大编辑距离。

        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)
        

        您可以通过将maxdist 设置为5 来匹配CoCompany,但正如我所说的那样,搜索结果会很差。我建议将maxdist1 保留到3

        如果您正在寻找匹配单词的语言变体,您最好使用whoosh.query.Variations

        注意:较旧的 Whoosh 版本使用 minsimilarity 而不是 maxdist

        【讨论】:

          【解决方案4】:

          您可以使用下面的这个功能来模糊搜索一组词对一个短语:

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-04-23
            • 1970-01-01
            • 1970-01-01
            • 2020-09-02
            • 2020-05-06
            • 1970-01-01
            • 2016-11-20
            相关资源
            最近更新 更多