数百万のレコードでの部分的な名前の一致


10

私たちは、名前を照合するためのWebベースのアプリケーションを開発しました。名前をパーツに分割することで動作し、各パーツのSoundex値はデータベースに格納されます。レーベンシュタイン距離メトリックは、与えられた名前に対するパーセンテージ音のマッチングだけでなく、スペルを適用するために使用されます。

実行時に、すべてのレコードをメモリに読み込み、すべてのSoundex値とすべての名前のすべての部分のスペルにレーベンシュタイン距離を適用します。

最大で2万の名前があったため、これは最初は問題なく機能していましたが、現在、当社のクライアントの1つに3,000万の名前があります。リクエストごとにこの巨大なリストをメモリにロードし、このタイプのマッチングを適用することは、大量のメモリと実行時間を使用する悲惨なアプローチです。

サウンドとスペリングのパーセンテージマッチングを使用して、近い将来に3000万件以上のレコードのデータベースを検索するための提案を探しています。

コア機能

エンドユーザーは、照合する名前と最小パーセンテージを入力します。名前の任意の部分が指定された名前の指定されたパーセンテージまでの任意の部分と一致するすべての名前をデータベースに表示することになっています。完全な名前を一致させる必要はありません。割合までの一致が成功した場合は、どの部分でも成功します。例えば。

Given Name: Helen Hunt
Name in DB: Holly Hunter 

両方の名前の両方の部分は正確には一致していませんが、ある程度までは一致します。80%と想定します。したがって、ユーザーが80%と入力した場合、DB内の名前は一致する名前として表示される必要があります。


1
SQL Serverを使用していますか?asp.netでタグ付けしたようです。ネットワークトラフィックを防止し、SQLサーバーにメモリを管理させるCLRアセンブリの可能性を考えます。
RubberChickenLeader

@WindRavenはSQL ServerとOracleの両方を使用しています
bjan

1
これは、Googleが解決するWebクロールの問題と同じではありませんか?
candied_orange

@bjan名前はどこに保存されていますか?それらはSQL Serverに保存されますか?
RubberChickenLeader

何を探していますか?特定のクエリに最も一致する上位100の名前はどれですか。
Doc Brown

回答:


6

あなたが必要なものの詳細を知らなくても、あなたはおそらく、次のいずれかを実行します:

私はスフィンクスのインストールと構成に何が関係しているのか完全には知りません。しかし、私はあなたがそれをデータベースに向け、どのフィールドにインデックスを付けるか、どのように結果に重みを付けるかを伝えることができるという印象の下にあります。これにより、一致するレコードの順序付きリストが返されます。

ユーザー向けまたはミッションクリティカルなものについては、既存の検索ツールを使用してください。

あなたが学問的であると感じているなら... ngramsで遊んでください:

ngramsルックアップテーブルは、潜在的な一致の最初のセットとして機能し、レーベンシュタイン距離を使用して結果をプルーニングおよびソートできます。

peopleあなたが検索したいと仮定すると、あなたは次のようなことをするかもしれません:

_ people _________
personId: int
name: varchar
soundex_name: varchar

_ people_ngrams __
personId: int
ngramId: int

_ ngrams _________
ngramId: int
ngram: char(3)
count: int

ngramを定期的に再構築することも、オンザフライで構築することもできます。どちらの場合も、単純で単純な検索アルゴリズムは次のようになります。

search_ngrams = ngrammify(soundex(search_string));

notable_ngrams = select top 10 *
  from ngrams
  where ngram in (search_ngrams)
  order by count asc;

possible_matches = select top 1000 distinct people.*
  from people_ngrams, people
  where ngramId in (notable_ngrams);

best_matches = top 100 possible_matches
  ordered by Levenshtein_distance(match, soundex(search_string));

これとかなり似たもの(ただし、ngramの「人気」の調整、ブラックリスト、ホワイトリストなど)を使用して、この種のアルゴリズムはデータセット間でレコードをあいまいにマージし、カスタムファジー検索を容易にしました。ユーティリティおよび進行中のレコードの重複除外の取り組み。

さて、私の場合、数百万のレコードを照合するのではなく、2つのデータセット間でそれぞれ数十万のレコードのオーダーで可能な限り最適なマージを選択しようとしていました。そして、数分以内に、それをかなり迅速に機能させたいと考えました。(クイック、100,000 * 100,000とは何ですか?)そして、成功しました。

したがって、適切なチューニングを行うことで、この種のことは迅速かつ効果的になる可能性があります。私たちは最終的に、数分で、日付の古い控えめなデュアルコアマシンでマージされたセットを作成できました。しかし、ngramの人気/関連性のスイートスポット、適切な文字列距離のしきい値、ブラックリスト、ホワイトリストなどを見つけるには、かなりの時間がかかりました。

それは言った、あなたは本当にこのようなものに取り組んでいる穴に吸い込まれることができます。実際のプロダクションレベルのものについては、通常、この種の検索用に既に作成および最適化されている、確立されたツールを使用する必要があります。

同様にスフィンクスLuceneを


Sphinx 2.2.11リリースのリファレンスマニュアルでファジーを検索したところ、単語を部分的に一致させる必要があるのに、完全に一致するようです。私がこれについて間違っているなら、私を訂正してください。
bjan

@bjanええ。さらにドキュメントを見ると、Sphinxのあいまい検索がまさにあなたが探しているものかどうかわかりません。これは、soundex形態を使用できます。ただし、最近の編集に基づいて、独自のngram +文字列距離検索をロールバックすることできます。また、上で述べたように、アルゴリズムとしきい値を調整して適切に調整するには、しばらく時間がかかる場合があります。しかし、それは実行不可能ではありません。そして、もしあなたがそのレベルの柔軟性を必要とするなら...
svidgen

@bjanああ、私もLuceneについて完全に忘れていました。私はそれがあなたが必要とすることのどちらかをしているのかわかりません。しかし、それはかなり人気があるので、自分でロールする前に一見の価値があります。Luceneのドキュメントでは、レーベンシュタイン文字列距離を使用したあいまい検索とランキングについて言及しています。
svidgen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.