一般的なアプローチ(少なくとも私には一般的です)は、ビット文字列をいくつかのチャンクに分割し、これらのチャンクをクエリして、フィルター前の手順として完全に一致するようにすることです。ファイルを操作する場合は、チャンクと同じ数のファイル(たとえば、ここでは4つ)を作成し、各チャンクを前に並べ替えてから、ファイルを並べ替えます。バイナリ検索を使用でき、ボーナスのために一致するチャンクの上下で検索を拡張することもできます。
次に、返された結果に対してビット単位のハミング距離の計算を実行できます。これは、データセット全体のより小さなサブセットにすぎないはずです。これは、データファイルまたはSQLテーブルを使用して実行できます。
要約すると、DBまたはファイルに32ビットの文字列がたくさんあり、「クエリ」ビット文字列から3ビット以下のハミング距離内にあるすべてのハッシュを検索するとします。
4つの列を持つテーブルを作成します。それぞれに32ビットハッシュの8ビット(文字列または整数として)スライス、islice 1〜4が含まれます。または、ファイルを使用する場合は、4つのファイルを作成します。各「行」の前に1つの「islice」
qslice1から4と同じ方法でクエリビット文字列をスライスします。
のいずれかになるようにこのテーブルをクエリしますqslice1=islice1 or qslice2=islice2 or qslice3=islice3 or qslice4=islice4
。8 - 1
これにより、クエリ文字列から7ビット()以内にあるすべての文字列が得られます。ファイルを使用する場合は、4つの並べ替えられたファイルのそれぞれでバイナリ検索を実行して、同じ結果を取得します。
返されたビット文字列ごとに、クエリビット文字列を使用してペアごとに正確なハミング距離を計算します(DBまたは並べ替えられたファイルのいずれかからの4つのスライスからインデックス側のビット文字列を再構築します)
ステップ4の操作の数は、テーブル全体の完全なペアワイズハミング計算よりもはるかに少なく、実際には非常に効率的です。さらに、並列処理を使用してより高速にする必要があるため、ファイルを小さなファイルに簡単に分割できます。
もちろん、あなたの場合は、ある種の自己結合、つまり、互いにある程度の距離内にあるすべての値を探しています。同じアプローチがIMHOでも機能しますが、開始チャンクを共有し、結果のクラスターのハミング距離を計算する順列(ファイルまたはリストを使用)の開始点から上下に拡張する必要があります。
ファイルではなくメモリで実行している場合、100M32ビット文字列データセットは4GBの範囲になります。したがって、4つの並べ替えられたリストには約16GB以上のRAMが必要になる場合があります。代わりにメモリマップトファイルで優れた結果が得られますが、同様のサイズのデータセットではRAMを少なくする必要があります。
利用可能なオープンソースの実装があります。スペースで最高のものは、Moz、C ++によってSimhashに対して行われたものですが、32ビットではなく64ビットの文字列用に設計されたIMHOです。
この制限されたハッピング距離アプローチは、モーゼスチャリカルによって、その「simhash」独創的な論文と対応するGoogle特許で最初にAFAIKで説明されました。
- ハミング空間での近似最近傍探索
[...]
それぞれdビットで構成されるビットベクトルが与えられた場合、ビットのN = O(n 1 /(1+))ランダム順列を選択します。ランダム置換σごとに、ビットベクトルのソートされた順序Oσを、σによって置換されたビットの辞書式順序で維持します。クエリビットベクトルqが与えられると、次のようにして近似最近傍を見つけます。
各順列σについて、Oσで二分探索を実行して、qに最も近い2つのビットベクトルを見つけます(σによって順列されたビットによって取得される辞書式順序で)。ここで、qに一致する最長のプレフィックスの長さの順に、バイナリ検索によって返された位置の上下の要素を調べる、ソートされた順序Oσのそれぞれで検索します。
Monika Henzigerは、彼女の論文「ほぼ重複するWebページの検索:アルゴリズムの大規模な評価」でこれを拡張しました。
3.3アルゴリズムCの結果
各ページのビット文字列を重複しない12個の4バイト部分に分割し、20B個を作成し、少なくとも1個の共通部分を持つすべてのページのC類似度を計算しました。このアプローチでは、最大11の違い、つまりC類似度373のページのすべてのペアを見つけることが保証されていますが、大きな違いがある場合は一部を見逃す可能性があります。
これは、Gurmeet Singh Manku、Arvind Jain、およびAnishDasSarmaによる論文「 DetectingNear-DuplicatesforWebCrawlings 」でも説明されています。
- ハミング距離の問題
定義:fビットフィンガープリントのコレクションとクエリフィンガープリントFが与えられた場合、既存のフィンガープリントが最大kビットでFと異なるかどうかを識別します。(上記の問題のバッチモードバージョンでは、単一のクエリフィンガープリントではなく、一連のクエリフィンガープリントがあります)
[...]
直感:2dfビットの真にランダムなフィンガープリントのソートされたテーブルを考えてみましょう。表の最上位のdビットだけに注目してください。これらのdビット数のリストは、(a)かなりの数の2 dビットの組み合わせが存在し、(b)非常に少数のdビットの組み合わせが複製されるという意味で「ほぼカウンター」になります。一方、最下位のf −dビットは「ほぼランダム」です。
ここで、| d −d|となるようにdを選択します。は小さな整数です。テーブルはソートされているため、d個の最上位ビット位置でFに一致するすべてのフィンガープリントを識別するには単一のプローブで十分です。| d −d|以降 が少ない場合、そのような一致の数も少ないと予想されます。一致するフィンガープリントごとに、最大でkビット位置でFと異なるかどうかを簡単に判断できます(これらの違いは、当然、f − dの最下位ビット位置に制限されます)。
上記の手順は、kビット位置でFとは異なる既存のフィンガープリントを見つけるのに役立ちます。これらはすべて、Fの最下位f − dビットに制限されます。これにより、かなりの数のケースが処理されます。すべてのケースをカバーするには、次のセクションで正式に概説するように、少数の追加のソート済みテーブルを作成するだけで十分です。
注:関連するDBのみの質問に対して同様の回答を投稿しました