web-dev-qa-db-ja.com

複雑なレコードの重複排除/類似性の検出

私はかなり多数のフィールド(〜15-20)を持つレコードを含むプロジェクトに取り組んでおり、重複排除を実装するための適切な方法を見つけようとしています。基本的にレコードは、いくつかの追加データを含む人です。たとえば、レコードには名、姓、住所、電子メールアドレスなどの個人情報が含まれている可能性がありますが、すべてのレコードに同じ量のデータがあるわけではありません。

現在、レコードはRDBMS(MySQL)に保存されており、挿入時に重複を検出し、それでも挿入されたが重複としてフラグが付けられます。それがリアルタイムであるかどうかについてフィードバックを提供する必要があるので、それは高速である必要があります。データセットが大きい(何百万ものレコード)。

私は次のオプションを検討しましたが、どちらが最良であるか/それらがより良いオプションであるかどうかはわかりません:

  • MySQLに組み込まれている全文検索を使用し、あいまい検索を使用します。これの主な問題は遅いと思われ、最新バージョンのみがInnoDBでフルテキストインデックスをサポートし(代替エンジンはMyISAMであり、これは不適切であり、トランザクションをサポートしていません)、あいまい検索だけでは類似性検出に最適な方法とは思えません。
  • Simhashなどを使用します。これに関する問題は、simhashがこれをどのように処理するのかわからない同義語を検出できるようにしたいことです。たとえば、住所は「Some Road」や「Some Rd」のようになります。名前は「マイク」または「マイケル」のようになります。
  • Apache Lucene派生(elasticsearch/solr/etc)を使用してデータにインデックスを付け、多数の結果を返す可能性が高いクエリを実行します。

Apache Luceneの使用に関して、類似性の検出について読み、余弦の類似性を使用して、luceneが格納する頻度ベクトルから0〜1の値を生成しました。これをluceneクエリの結果に適用して、特定のしきい値を超える結果がないかどうかを確認できます。これに関する私の懸念は、コサインの類似性が、保存しているデータのタイプにどの程度関連するかです。 。

基本的に、私はこのタイプのデータを重複排除するための最良の方法は何ですか(または、代わりに、このタイプのデータとの類似性を検出します)?

5
Tomdarkness

重複除外に関する特効薬はありません。あなたは正規化に最初に集中する(3NFではなくパターンの意味から)および標準化です。これにより、比較を開始するためのある種の平等な競争条件が与えられます。

これを実現するには、各タイプのデータに有効な標準化手法を適用する必要があります。住所データの標準化は、指定された名前の標準化とはまったく異なる問題ドメインです。これらのデータ標準化問題のドメインのほとんどは、自分で解決しようとするには複雑すぎます。住所の検証と標準化を行うサードパーティ製ソフトウェアと、名前の標準化を行うサードパーティ製ソフトウェアの購入を検討してください。

電子メールアドレスや電話番号のようなものについては、それらを比較すると比較的単純なので、おそらく自分でロールすることができます。

データコンポーネントを適切に標準化したら、次にファジーマッチ、レーベンシュタイン距離、またはコサイン類似度(など)のどちらがより良いかについて心配することができます。

レコード全体を取得しようとするのではなく、サブ要素のようなマッチングを検討するのが最善です。次に、適切に一致するサブエレメントの数を確認します。メールアドレスとメールアドレスが異なる2つの同一名は非常に弱い一致です。 1つのレコードに電子メールアドレスが欠落している、ほぼ同一のメールアドレスと2つのほぼ同一の名前は、かなり強力な一致です。

2
Joel Brown

多くの重複排除手法では、Joel Brownが指摘したように、データの標準化が非常に重要です。しかし、minhashを使用すれば、それなしでうまくいくかもしれません。

それでも、できる限りデータを正規化する必要があります。大文字と小文字の正規化、アドレスの句読点の無視など。既知の同義語グループがある場合は、同義語を正規化することもできます。したがって、「マウントセントヘレンズストリート」は「mt st helens st」になります(このようなあいまいさを導入しても、通常、結果の精度は損なわれませんが、再現率は向上します)。

名前と住所は依然として異なる可能性が高く、スペルの間違い、順序の変更の可能性、そしておそらく余分なアイテムが含まれています。ミドルネーム、または異なる地域名。それは問題である必要はありません。

Minhashは、機能に基づいて、レコードごとに複数のハッシュを生成します。多くの実装では、人々はすべての機能を単一のminhashジェネレーターに投入するだけで、結果として50個のハッシュを取得します。しかし、あなたの場合、これを分割したいかもしれません。すべての名前フィールドを取得して、たとえば、それぞれに7文字の帯状疱疹を生成し、それらの帯状疱疹を1つのminhashジェネレーターに投げて、たとえば5つのハッシュを吐き出します。すべての郵便/物理アドレスフィールドを取得し、別のminhashジェネレーターを使用して同じことを行います。たとえば、メールアドレスから3つのハッシュを独自に導き出します。等々。

情報の種類ごとに保持するハッシュの数は、その情報が重複を判断する上でどれほど重要であるか、およびフィールドに入力されていない可能性がどの程度あるかに応じて調整できます。最も信頼性の高いデータには、最も多くのハッシュが割り当てられる必要がありますそれ。

近い重複を見つけることはそれからかなり簡単です。 simhashよりもかなり低速で、大量の結果をふるいにかけ、それぞれの共有ハッシュを数える必要があるため、メモリを少し消費する可能性があります。最悪の場合、「@ gmail」など、レコードの非常に一般的な部分からいくつかのminhashesが選択されることがあります。電子メールアドレスに含まれ、数十万または数百万もの他のレコードに存在する場合があります。しかし、minhashの優れた点は、4%や5%だけではなく、実際には20%、40%、または好きなだけ異なる結果を見つけられることです。

(類義語の置換と同じ手法を使用して、これらの「汎用」ミンハッシュをいくらか無効にして、「@ gmail.com」などの非常に一般的な汎用文字列を「@G!」などの短いエンコードされたプレースホルダーで置き換えることができます。これは、7より短いです。 -キャラクターの帯状疱疹なので、それ自体で帯状疱疹を形成することはありません。)

同じデータを表すために必要なハッシュを少なくして結果を改善するminhashのバリアントがいくつかあります( https://stackoverflow.com/questions/27712472/choosing-between-simhash-and-minhash-for-a-を参照)。 production-system )ですが、各レコードのサイズが小さい場合、大きなメリットは得られない可能性があります。レコードあたりのハッシュはすでに30または40になっている可能性があります(32ビットのハッシュで十分な場合があります)。 「一般的なminhashes」問題をまだ軽減していない場合は、局所性依存ハッシュ(LSH)が非常に役立ちます。ただし、これは類似性推定の精度を低下させます。

1
Ben Whitmore