【VBAリファレンス】Excel VBAで実現するレーベンシュタイン距離:文字列の「曖昧さ」を数値化しデータ名寄せを自動化するプロフェッショナル手法

スポンサーリンク

概要:文字列の類似性を測る「レーベンシュタイン距離」の重要性

ビジネスの現場において、データの名寄せは避けて通れない課題です。例えば、「株式会社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`関数の結果がどのように変化するかを確認してみてください。この「距離」を理解することが、データマネジメントの第一歩となります。ぜひ、貴方の実務環境にこのプロフェッショナルなツールを取り入れ、データ品質の劇的な改善を実感してください。

タイトルとURLをコピーしました