Firefoxのロケーションバーに表示される候補はfrecencyと呼ばれるスコアで決まる。

frecencyはfrequencyとrecencyを合わせた造語で、スコアは再訪問数、訪問のタイプ、どれくらい新しいか、URIがブックマークまたはタグ付けされているかによって決定される。

計算方法はPlaces frecencyアルゴリズム | MDNに載っている。

そこの計算方法で計算してみたけどなんか合わなかったなぁ。2,3倍以上差がでた。ひどいものだと10倍以上違った。

まぁNotesに書いてある

標本訪問の数は min(10 most recent visits pref, 総訪問数)

というのがわからなかったので、10で固定してしまったのがまずかったか。

あとabout:configを見てみると、

  • places.frecency.unvisitedTypedBonus
  • places.frecency.unvisitedBookmarkBonus
  • places.frecency.framedLinkVisitBonus

という値があるけど、これが何に使われているかわからない。

計算するにあたって、FirefoxのSQLiteのデータを使ったが、それについては以下のサイトが役に立った。

ちなみにVimperatorのopenとかで出てきた候補を選択して移動した時はlinkVisitとしてカウントされることをDBを見て確認した。ロケーションバーで選択した時はtypedvisitなので、openもそちらでカウントされてほうがよいのではと思った。

計算が合わないので、考えてもしょうがないんだけど、about:configのvisitBonusとBucketCutoffの最適化を考えてみた。

履歴から、ロケーションバーもしくはopenから移動してきたURLを抽出して、そのURLの当時のfrecencyを合計して、これが高くなるような設定をしてやると良さそう。

それぞれのvisitBonusの設定値を(b_i)、それぞれのbucketWeightの設定値を(c_i)として、それぞれのvisit typeとweightに対応する訪問数を(C_{ij})とすると、frecencyの合計値は

$$ \sum b_i w_j C_{ij}$$

で表される。(C_{ij})は履歴からわかる値。でもこれだけだと、係数を大きくすればどこまで大きくなるので、(\sum b_i = 1)、(\sum w_i = 1)という制限をつけてやる。

で、この制限のもとでラグランジュ未定乗数法とガウスの消去法でうまくいくかなと思って計算したが、係数にマイナスが出てきてしまってダメだった。

次に(b_i)と(w_i)を単位ベクトルにして、各角度を10分割して、全部値について調べ上げようかと思ったけど、これは計算量が多すぎて無理だった。その辺のことをしたコードがこれ。

なんかコメントアウトでごちゃごちゃしてるけど。

でも、よくよく考えると角度をすべて調べ上げる必要はなく、例えば(b)の第一成分が1で、他を0にした時、合計値を最大にする(w)は、(i)について足し上げてできるベクトル

$$\sum b_i C_{ij}$$

に平行な単位ベクトルである。こうして求められた(w)を使い、今度は(j)について足し上げ、それに平行な単位ベクトルを(b)として、さらに……なことをしていくと2,3回で収束する。

ただし、これだけだと(b)の第一成分を1にした時の局所的な最大値かもしれないので、第二、三…成分を1にして最大値を確かめて、その中の最大値を最大値として採用する。実際にやってみる。それをやったのがこちら。

結果はこんな感じ。

set! places.frecency.linkVisitBonus=98
set! places.frecency.typedVisitBonus=15
set! places.frecency.bookmarkVisitBonus=1
set! places.frecency.embedVisitBonus=0
set! places.frecency.permRedirectVisitBonus=13
set! places.frecency.tempRedirectVisitBonus=1
set! places.frecency.downloadVisitBonus=0

set! places.frecency.firstBucketWeight=94
set! places.frecency.secondBucketWeight=33
set! places.frecency.thirdBucketWeight=7
set! places.frecency.fourthBucketWeight=6
set! places.frecency.defaultBucketWeight=3

Vimperatorな方はこれを.vimperatorrcに貼り付けると、about:configの値を変更できる。

デフォルトだとtypedVisitBonusの値が2000で非常に高いけど、vimperatorでopenしてることが多いので、大幅に減ったのは納得できる。

また、デフォルトだとpermRedirectVisitBonusが0だけど、恒久的にリダイレクトされるなら、リダイレクト先が候補にあがるべきで、13になったのは納得できる。

でも、frecencyの計算方法が怪しいので、役に立たないかも。