Apache Lucene 和通过候选词列表在文本文档中进行模糊搜索

Apache Lucene and fuzzy search in text document by list of candidate words

我有经过 OCR 处理后的文本文件。由于原始文档的图像质量不佳,此文本经常包含损坏的文字。

我还有一个有效公司名称的列表,可以出现在上述文本文件中。

根据这个公司名称列表,我想确定拥有扫描文档的公司名称(即使公司名称在文本文件中略有损坏)。

我想对扫描的文档进行类似模糊搜索的操作,以便尝试从那里的列表中找到公司名称。获胜者将是匹配分数最高的公司名称。

我想我可以为此目的使用 Apache Lucene 功能。您能否提出建议,或者可以使用 Apache Lucene 来实现,如果可以,请给出示例。

提出的想法如下。您可以为每个公司名称(甚至描述和任何有用的信息)创建一个 Lucene 文档

Document doc = new Document();
        doc.add(new TextField("text", "BlueCross BlueShield", Field.Store.YES));
        writer.addDocument(doc);

添加所有公司后,您可以将获得的文本用作 MoreLikeThis 查询。 MLT背后的想法如下,它试图找到相似的文本。

可以创建如下:

MoreLikeThis mlt = new MoreLikeThis(reader);
        mlt.setAnalyzer(analyzer);
        mlt.setMinDocFreq(0);
        mlt.setMinTermFreq(0);
        mlt.setMinWordLen(0);
        final Query query = mlt.like("text", new StringReader("BlueCros BlueShield              Customer Service \n" +
                "   1-800-521-2227           \n" +
                "                        of Texas                          Preauth-Medical              1-800-441-9188           \n" +
                "                                                          Preauth-MH/CD                1-800-528-7264           \n" +
                "                                                          Blue Card Access             1-800-810-2583           "));
        System.out.println(query);

        TopDocs results = searcher.search(query, 5);

总的来说,我们正在做反向匹配,它应该对你有帮助,我在那里做了一些测试。棘手的部分是模糊匹配,因为 MLT 不提供它,所以在这种情况下,可以重写 MLT 查询以将其包装到 FuzzyQuery 中。

BooleanQuery.Builder builder = new BooleanQuery.Builder();
        if (query instanceof BooleanQuery) {
            final List<BooleanClause> clauses = ((BooleanQuery) query).clauses();
            for (BooleanClause bc : clauses) {
                Query q = bc.getQuery();
                if (q instanceof TermQuery) {
                    builder.add(new FuzzyQuery(((TermQuery) q).getTerm(), 2), bc.getOccur());
                } else {
                    builder.add(bc);
                }
            }
        }

此外,使用适当的分析器非常重要 - 在 BlueCross 的简单情况下,我提供了一个在大写更改时拆分标记的分析器。在此处添加同义词可能会有所帮助

完整代码示例位于here