私はUとVのアドレスを持っています。私はそれらが幾分似ているかどうか、 "更新"と言いたいのですか?2つのアドレス欄を比較する
たとえば、Uの246 N High street
とVの246 North High St
は、Update
の値を返します。 Uの 246 N High Street
とVの458 Auburn Drive
は、Omit
の値を返します。
アイデア?
私はUとVのアドレスを持っています。私はそれらが幾分似ているかどうか、 "更新"と言いたいのですか?2つのアドレス欄を比較する
たとえば、Uの246 N High street
とVの246 North High St
は、Update
の値を返します。 Uの 246 N High Street
とVの458 Auburn Drive
は、Omit
の値を返します。
アイデア?
ファジーマッチングを行うアルゴリズムはたくさんあります。優れた実装方法の1つはN-Gramです。
nグラム一致を実行するには、各アドレスを小さな文字長のセットのリストに分割する必要があります。あなたの住所246 N High street
の2グラムのリストは、24,46,6 , N,N , H,Hi,ig,gh,h , s,st,tr,re,ee,et
のようになります。 246,46 ,6 N, N ,N H, Hi,Hig,igh,gh ,h s, st,str,tre,ree,eet
これを両方のアドレスで行い、最初のアドレスのリストの各項目をチェックして、2番目のアドレスのリストに表示されているかどうかを調べることができます。一致を数え、最初のリストの項目数で除算します。それは彼らがどれほど近づいているかのパーセンテージを与えます。
シート式でこれを行うには、セル式mid()
とcountif()
が好きかもしれませんが、VBAで書き出してUDFにする方が簡単だと思います。
Function NGramCompare(string1 As String, string2 As String, intGram As Integer) As Double
'Take in two strings and the N-gram
Dim intChar As Integer, intGramMatch As Integer
Dim ngramList1 As String, ngramList2 As String, nGram As Variant
Dim nGramArr1 As Variant
'split the first string into a list of ngrams
For intChar = 1 To Len(string1) - (intGram-1)
If ngramList1 <> "" Then ngramList1 = ngramList1 & ","
ngramList1 = ngramList1 & Mid(string1, intChar, intGram)
Next intChar
'split the secong string into a list of ngrams
For intChar = 1 To Len(string2) - (intGram-1)
If ngramList2 <> "" Then ngramList2 = ngramList2 & ","
ngramList2 = ngramList2 & Mid(string2, intChar, intGram)
Next intChar
'Split the ngramlist1 into an array through which we can iterate
nGramArr1 = Split(ngramList1, ",")
'Iterate through array and compare values to ngramlist2
For Each nGram In nGramArr1
If InStr(1, ngramList2, nGram) Then
'we found a match, add to the counter
intGramMatch = intGramMatch + 1
End If
Next nGram
'output the percentage of grams matching.
NGramCompare = intGramMatch/(UBound(nGramArr1) + 1)
End Function
あなたはUDFを使用したことがない場合:ブックを見つけ、VBAプロジェクトウィンドウでAltキー+ F11
次に、アドレス1と仮定するとA1
にあり、アドレス2は、あなたがC1
に、置くことができるB1
である:
=NGramCompare(A1, B1, 2)
どの、あなたの最初のアドレスのために、56%を吐き出すます。それは合理的に良い試合のように思える。ポジティブヒットが多すぎる場合は、最後のパラメータを変更して2グラムを3グラムに変更することができます。
=If(NGramCompare(A1, B1, 2)>.30, "Update", "Omit")
私はちょうどそれが30%以上の一致何かを検討するようにすることを設定しています:それはあなたができる「更新」または「省略」と言うだろうさらに一歩それを取るために
必要に応じて調整することができます。どこに設定しても、誤検知や偽のネガティブな割合の比較が行われることになりますが、これがファジーマッチングの方法です。
ナイーブなアプローチのいくつかは、最初の数文字
=LEFT(A1,5)=LEFT(B1,5)
を比較するか、彼らはおそらくのために調整した後、大きな醜い式に変わります
=(SUBSTITUTE(SUBSTITUTE(LOWER(A2)," street"," ST")," north "," N ")
=SUBSTITUTE(SUBSTITUTE(LOWER(B2)," street"," ST")," north "," N "))
両方に一致するまで、部品を交換することができますほとんどの場合
これは一般的に難しい問題です。何らかのファジーマッチングを使用する必要があります。それについてどうすればいいのかについての解答[ここ](http://stackoverflow.com/questions/14821345/excel-approximate-text-match)をご覧ください。 –