昨日は、スクロールバーを用いて閾値を上下に操作してみた。
infoment.hatenablog.com
これを応用して、今回は「最も高い一致率のもの」を表示することに挑戦する。
昨日は、スクロールバーの値変更イベントで、一致率の高いものを絞り込んだ。
そこで今回も、この仕組みを利用することにした。
- まず、100%で絞り込む
- 一致するものがあれば、表示する。
- 一致するものが無い場合、スクロールバーの値を1つ下げる。
※100だったものが、99になる。 - スクロールバーの値が変わったので、自分自身を呼び出して(再帰)改めて絞り込みが行われる。
これを繰り返していくと、最も一致率が高いところまで、自動的にスクロールバーが下がっていって止まることになる。
ユーザーフォーム(BookShelfForm)
まず、最後にスクロールバーの値を100にする。
Private Sub TextBox1_Change() Dim str1 As String str1 = TextBox1.Value Dim str2 As String Dim i As Long Dim j As Long j = j + 1 Dim MatchRatio As Long For i = 1 To UBound(Books) str2 = Books(i).書籍名称 MatchRatio = Levenshtein3(str1, str2) BookList(i, 1) = str2 BookList(i, 2) = i BookList(i, 3) = MatchRatio Next ScrollBar1.Enabled = True ScrollBar1.Value = 100 End Sub
次いで、昨日のものに下記の4行を加える。
Private Sub ScrollBar1_Change() Dim TempList As Variant ReDim TempList(1 To UBound(Books), 1 To 3) Dim i As Long Dim j As Long j = 1 For i = 1 To UBound(Books) If BookList(i, 3) >= ScrollBar1.Value Then TempList(j, 1) = BookList(i, 1) TempList(j, 2) = BookList(i, 2) TempList(j, 3) = BookList(i, 3) j = j + 1 End If Next ' 今回の追加個所。↓ここから↓ If j = 1 Then ScrollBar1.Value = ScrollBar1.Value - 1 Exit Sub End If ' 今回の追加個所。↑ここまで↑ Dim SQC As SeaquenceClass Set SQC = New SeaquenceClass TempList = SQC.SpecialRedim(TempList, j - 1) ListBox1.Clear ListBox1.List = TempList MatchRatioLabel = "一致率:" & ScrollBar1.Value & "%" End Sub
実際に検索してみると、このようになる。
「ハリー・ポッターと賢者の」までを入力すると、最も一致率の高い「ハリー・ポッターと賢者の石」が、一致率92%でヒットした。
これはこれで、成功か?そうとも言い切れない。なぜなら一文字ずつ入力すると、このような挙動になるからだ。
これは、「ハリー・ポッターと賢者の石」がシリーズ内で最も文字数が少ないため、正しく題名を入力し続ける限り、常に最も一致率が高くなることに起因する。
また、響きだけうろ覚えだと、このようなる。
音だけで言えば「賢者の石」なのに、文字数等から「秘密の部屋」が候補として挙がってしまった。
結局のところ、この仕組みだけだと、以下の傾向があるようだ。
- 情報量が少ない内は(例えば「ハ」しか入力されていない)、正しい候補が表示されない。
- 情報量が増えるにつれて、候補は一時的に増加する。
- さらに情報が増えると、新ためて絞り込みが行われる。ただし入力が正しくない場合は、最終的に残る候補が正しいとは限らない。
従って一旦入力した後、めぼしいものが無ければスクロールバーで一致率を下げてみる、などの操作が必要かもしれない。
或いは100%一致するものが無い場合、TOP10を表示するのも良いかもしれない。しかしTOP10が良いのかTOP5が良いのか、何とも言えない。ハリー・ポッターシリーズは全部で10冊あるので、これに特化すれば、TOP10が都合がよい。だが、そのようなチューニングに意味は無いと思われる。
結局のところ一致率で絞り込む場合、誤記などによる候補の除外を避けることはできるが、逆に上記のような現象に対する「折り合い」が必要になる。実用化には、もう一工夫以上が必要だ。
でも、作ってみて面白かったので、これはこれでアリということにしよう。
参考まで。