概要:文字列の類似性を測る「レーベンシュタイン距離」の重要性
ビジネスの現場において、データの名寄せは避けて通れない課題です。例えば、「株式会社ABC」と「(株)ABC」、「ABC株式会社」という表記揺れが混在する顧客リストを扱う際、単純な文字列比較(=演算子)ではこれらを同一とみなすことはできません。このような場面で強力な武器となるのが「レーベンシュタイン距離(Levenshtein Distance)」です。
レーベンシュタイン距離とは、ある文字列を別の文字列に変形するために必要な「挿入」「削除」「置換」の最小回数を指します。この値が0に近いほど、その文字列は類似していると判断できます。本記事では、このアルゴリズムをExcel VBAで実装する方法を解説し、さらに最新のExcel環境(Office 365以降)の強みである「スピル」を活用したハイブリッドなアプローチを伝授します。
詳細解説:アルゴリズムの論理構成
レーベンシュタイン距離を算出するためには、動的計画法(Dynamic Programming)を用いるのが一般的です。二つの文字列の長さをそれぞれM, Nとしたとき、(M+1) × (N+1) の行列を作成し、各セルに編集距離を蓄積していきます。
計算の基本ルールは以下の通りです。
1. 文字が一致する場合:左上の斜めセルの値をそのまま引き継ぐ。
2. 文字が一致しない場合:左、上、左上の3つのセルの最小値に「1」を加算する。
この計算をVBAで行う際、セルへの書き出しを繰り返すと処理速度が極端に低下します。そのため、メモリ内で配列処理を行い、一括して結果を返す手法が必須となります。今回は、UDF(ユーザー定義関数)として実装し、ワークシート上で直接関数のように呼び出せる形式を採用します。
サンプルコード:高速実行可能なVBA実装
以下のコードを標準モジュールに貼り付けてください。この関数は、ワークシート上で引数に範囲を指定すれば、動的配列として結果を返すことが可能です。
Option Explicit
' レーベンシュタイン距離を算出するUDF
Public Function GetLevenshteinDistance(ByVal str1 As String, ByVal str2 As String) As Long
Dim len1 As Long, len2 As Long
Dim i As Long, j As Long
Dim cost As Long
Dim matrix() As Long
len1 = Len(str1)
len2 = Len(str2)
' 行列の初期化
ReDim matrix(0 To len1, 0 To len2)
For i = 0 To len1: matrix(i, 0) = i: Next i
For j = 0 To len2: matrix(0, j) = j: Next j
' 動的計画法による計算
For i = 1 To len1
For j = 1 To len2
If Mid(str1, i, 1) = Mid(str2, j, 1) Then
cost = 0
Else
cost = 1
End If
matrix(i, j) = Application.WorksheetFunction.Min( _
matrix(i - 1, j) + 1, _
matrix(i, j - 1) + 1, _
matrix(i - 1, j - 1) + cost)
Next j
Next i
GetLevenshteinDistance = matrix(len1, len2)
End Function
' 範囲内の類似度を一括計算するスピル対応プロシージャ
Public Function CalcSimilarityRange(rng1 As Range, targetStr As String) As Variant
Dim arr As Variant
Dim i As Long
Dim result() As Long
arr = rng1.Value
ReDim result(1 To UBound(arr, 1), 1 To 1)
For i = 1 To UBound(arr, 1)
result(i, 1) = GetLevenshteinDistance(CStr(arr(i, 1)), targetStr)
Next i
CalcSimilarityRange = result
End Function
このコードの肝は、`CalcSimilarityRange`関数です。範囲(`rng1`)を引数に取ることで、ワークシート上で一度の関数入力だけで、隣接するセルに結果が自動的に展開(スピル)されます。これにより、数式をコピー&ペーストする手間から解放されます。
実務アドバイス:精度とパフォーマンスの最適化
VBAでレーベンシュタイン距離を扱う際、実務上注意すべき点がいくつかあります。
1. **大文字・小文字・全角・半角の統一**:
アルゴリズムは文字コードベースで判定するため、「A」と「a」は別物とみなされます。計算前に`StrConv(str, vbWide)`や`LCase`を用いて正規化を行う処理を関数内に組み込むことで、名寄せの精度が飛躍的に向上します。
2. **処理負荷の考慮**:
このアルゴリズムは計算量がO(MN)です。数千行を超えるリストに対してリアルタイム計算を行うとExcelが固まる可能性があります。その場合は、`Application.Calculation = xlCalculationManual`で再計算を手動に切り替えるか、結果を値として固定する運用を推奨します。
3. **閾値によるフィルタリング**:
距離が「0」であることは完全一致を意味しますが、表記揺れを許容する場合、距離が「1〜3」の範囲にあるものを「類似候補」として条件付き書式でハイライトする運用が最も効果的です。すべてを自動で名寄せしようとせず、あくまで「人間が確認するためのフラグ立て」として活用するのが、ベテランの知恵です。
まとめ:VBAがもたらすデータ品質の向上
レーベンシュタイン距離は、単なる文字列操作のアルゴリズムに留まりません。これは、不完全なデータから「意味」を読み解くための強力なツールです。
今回紹介したスピル対応のVBA手法を用いれば、複雑なマクロを組まずとも、標準関数のように自然な形でデータクレンジングの基盤を構築できます。Excelの標準機能だけでは困難な「表記揺れによるデータ分断」という課題に対して、このVBAアプローチは非常に強力なソリューションとなります。
まずは小さなリストから検証し、`GetLevenshteinDistance`関数の結果がどのように変化するかを確認してみてください。この「距離」を理解することが、データマネジメントの第一歩となります。ぜひ、貴方の実務環境にこのプロフェッショナルなツールを取り入れ、データ品質の劇的な改善を実感してください。
