私は、長年にわたって、わずかに異なる名前で多数の重複レコードを取得していたデータベースをクリーンアップしようとしています。たとえば、companysテーブルには、「Some Company Limited」や「SOME COMPANY LTD!」などの名前があります。
私の計画は、問題のあるテーブルをRにエクスポートし、名前を小文字に変換し、一般的な同義語( "limited"-> "ltd"など)を置き換え、アルファベット以外の文字を取り除き、agrep
を使用して似ています。
私の最初の問題は、agrep
が一致する単一のパターンのみを受け入れ、他の企業と一致するすべての会社名をループするのが遅いことです。 (クリーニングするテーブルによっては、数十、場合によっては数十万の名前をチェックする必要があります。)
私はtm
パッケージ( JSS記事 )を非常に簡潔に見てきましたが、それは非常に強力なようですが、名前だけでなく、テキストの大きなチャンクの分析に向けられています。
関連する質問がいくつかあります。
tm
パッケージはこの種のタスクに適していますか?
agrep
に代わる高速な方法はありますか? (Said関数は、突発的に遅いLevenshtein編集距離を使用します。)
Rには、agrep
とtm
以外の適切なツールはありますか?
私はこれをRで行うべきでしょうか、それともこの種のことはデータベースで直接行われるべきですか? (これはAccessデータベースなので、できれば触れないほうがいいです。)
比較的整形式の小さなバッチを実行しているだけの場合、 RecordLinkage
パッケージ のcompare.linkage()
またはcompare.dedup()
関数は、素晴らしい出発点になります。しかし、大きなバッチがある場合は、さらにいじくり回す必要があるかもしれません。
RecordLinkage
で関数jarowinkler()
、levenshteinSim()
、およびsoundex()
を使用して、独自の重み付けスキームを使用する独自の関数を記述します(また、つまり、RecordLinkage
を含むビッグデータセットに対してsoundex()
を使用することはできません。
一致させたい名前のリストが2つある場合( "レコードリンク")、通常は両方を小文字に変換し、句読点をすべて削除します。 「限定」対「LTD」を処理するために、私は通常、各リストから最初のワードの別のベクトルを作成します。これにより、最初のワードに追加の重みを付けることができます。 1つのリストに頭字語(多分ATTまたはIBM)が含まれていると思われる場合は、他のリストを頭字語化します。リストごとに、MySQLデータベースに個別のテーブルとして書き込む文字列のデータフレームを比較します。
候補が多すぎる候補にならないように、私はLEFT OUTER JOIN
2つのリスト間で一致するhasがあるものに関するこれらの2つのテーブル(おそらく、各リストの最初の3文字または最初の3文字と頭字語の最初の3文字)。次に、上記の関数を使用して一致スコアを計算します。
それでも多くの手動検査を行う必要がありますが、スコアをソートして、不一致をすばやく除外できます。
たぶん google精製 が役立つかもしれません。例外がたくさんあり、まだそれらすべてを知らない場合は、おそらくより適合しているように見えます。
あなたがしていることは レコードリンケージ と呼ばれ、すでに何十年にもわたって大きな研究分野となっています。幸いなことに、この種のものに対応した既製のツールがたくさんあります。基本的に、あなたはそれらをあなたのデータベースに向け、いくつかのクリーニングとコンパレーター(LevenshteinやJaro-Winklerなど)をセットアップすることができ、それらはあなたのために仕事をしてくれます。
これらのツールには通常、パフォーマンスの問題を解決する機能が備わっているため、レーベンシュタインが遅い場合でも、ほとんどのレコードペアがまったく比較されないため、高速に実行できます。
上記のWikipediaリンクには、使用できる多数のレコードリンケージツールへのリンクがあります。私は個人的にJavaで Duke と呼ばれるものを書きましたが、これを正確に使用しました。大きくて高価なものが必要な場合は、マスターデータ管理ツールを購入できます。
あなたのケースではおそらく編集距離の計算のようなものがうまくいきますが、大きなテキストベースのドキュメントでほぼ重複を見つける必要がある場合は、試すことができます http://www.softcorporation.com/products/neardup/ =