プロテインとスポーツ飲料

プロテインは水よりスポーツ飲料方が溶けやすいというのをどっかで読んだので試してみたが、対して変わらない。というか違いが分からん。
しかもプロテインが元々甘くなっているので、スポーツ飲料の甘さと相まってすごく甘くなってしまった。
二度とやらない。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

スパム掲示板続報

スパムが大変なことになっていた掲示板ですが、三目認証と禁止ワードリジェクトにより、まあまあ何とかなっています。
三目認証でどれくらいはじいているかは、もはやログ取ってないんですが、禁止ワードによるリジェクトは今のところ下記のような感じです。
ブランド:30件
送料無料:2件

禁止ワードをこんなところに書いてしまっていいのかという話はありますが、もしここに書いてスパムが復活するようならそれはそれで興味深い。どこまで人力なんだと感心せざるを得ません。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

レーベンシュタイン距離の挿入コストと削除コスト

レーベンシュタイン距離っていうのは一つの文字列と文字列の距離の求め方です。
ざっくり言うと、Aという文字列とBという文字列の距離を求める場合、Aの各文字を削除したり置換したり、あるいはBにある文字をAに挿入したりしてBと同じ文字列を作り、そのときの手数を距離とします。
例えばA:”abbc”とB:”acbbd”の距離を求めると以下のようになります。

aとbの間にcを挿入→acbbc
最後のcをdに置換→acbbd

ということで距離は2です。編集の方法はいくつもありますが、最小の手数のものを距離と定義します。
例えば

aとbの間にcを挿入→acbbc
後ろのbとcの間にdを挿入→acbbdc
最後のcを削除→acbbd

だと手数が3なのでNGです。プログラムでこの最小手数を求めるにはDP法(動的計画法)を用います。
Wikipediaの解説
でも上記の擬似コードはコメントが間違っていると思います。
レーベンシュタイン距離はあくまで「Aを編集してBにするときの最小コスト」なので、編集はすべてAに対して行わなければなりません(たぶん)。なのでBの文字列を削除したりしてはイカンのです。
d[ i1, i2 ]は文字列Aのi1番目までの文字列と文字列Bのi2番目までの文字列の距離です。
A:a(1)a(2)…a(i1)
B:b(1)b(2)…b(i2)
DP法により、この距離をd[ i1 – 1, i2]、d[ i1, i2 – 1]、d[ i1 – 1, i2 – 1]を使って求めるわけですが、次のように考えるべきです。

・Aからの削除によりBに近づく場合:
Aから末尾の文字a(i1)を削除すれば「a(1)~a(i1 – 1)の文字列」と「b(1)~b(i2 – 1)の文字列」との距離に帰着されるので、d[ i1, i2 ]はd[ i – 1, i2]の距離に末尾文字a(i1)を削除するコストを足したものと等しい。
・Aへの挿入によりBに近づく場合:
a(1)~a(i1)の末尾にb(i2)を挿入すれば、
  “「a(1)~a(i1)b(i2)の文字列(A側の末尾にb(i2)を加えた)」と「b(1)~b(i2 – 1)の文字列」の距離”
  “「a(1)~a(i1)b(i2)の文字列」と「b(1)~b(i2)の文字列」の距離”
は等しくなるのでd[ i1, i2 ]はd[ i1, i2 – 1 ]の距離にb(i2)を挿入するコストを足したものに等しい。
・Aの文字を置換することでBに近づく場合:
a(i1)をb(i2)に置換すればよいので、d[ i1, i2 ]はd[ i1 – 1, i2 – 1]にa(i1)を置換するコストを足したものに等しい。

というわけで、PHPで書くと以下のようになります。


/**
 * レーベンシュタイン距離を求める。
 * @param $a A文字列
 * @param $b B文字列
 * @param $i_c 挿入コスト
 * @param $r_c 置換コスト
 * @param $d_c 削除コスト
 * @return 距離
 */
function leven($a, $b, $i_c=1, $r_c=1, $d_c=1)
{
   $len_a = strlen($a);
   $len_b = strlen($b);
   $matrix = array();
   for ($jj = 0; $jj <= $len_b; $jj++) {
      $matrix[0][$jj] = $jj*$i_c;   // 全挿入
   }
   for ($ii = 0; $ii <= $len_a; $ii++) {
      $matrix[$ii][0] = $ii*$d_c;   // 全削除
   }

   for ($i = 1; $i <= $len_a; $i++) for ($j = 1; $j <= $len_b; $j++) {
      $del = $matrix[$i-1][$j] + $d_c;   // 削除
      $ins = $matrix[$i][$j-1] + $i_c;   // 挿入
      $rep = $a[$i-1] == $b[$j-1] ? $matrix[$i-1][$j-1] : $matrix[$i-1][$j-1] + $r_c;   // 置換
      $matrix[$i][$j] = min($ins, $del, $rep);
   }
   return $matrix[$len_a][$len_b];
}

PHPにはそもそもlevenshtein()という関数があり、上記のような関数を自分で作る必要はないです。挿入コスト・置換コスト・削除コストをいろいろ変えたとき、上記関数はPHPの組込関数と結果が一致します。しかし、Wikipediaのものは一致しません。Wikipedia方式は次のような解釈と思います。

・Bからの削除によりAに近づく場合:
Bからb(i2)を削除すれば良いので、d[ i1, i2 ]はd[ i1, i2 – 1 ]にb(i2)を削除するコストを足したものに等しい。
・Aへの挿入によりBに近づく場合:
a(1)~a(i1 – 1)の文字列にb(i2)を挿入すればよいので、d[ i1, i2 ]はd[ i1 – 1, i2 ]にb(i2)を挿入するコストを足したものに等しい。
・Aの文字を置換することでBに近づく場合:
a(i1)をb(i2)に置換すればよいので、d[ i1, i2 ]はd[ i1 – 1, i2 – 1]にa(i1)を置換するコストを足したものに等しい。

この方が理解しやすいですが、両方の文字列を編集しているのでもともとの定義からは外れていると思います。ただし、たいていの場合に上記の2つの解釈は結果が一致します。というか、挿入コストと削除コストが等しい場合には同じになります。逆に言うと、コストが挿入と削除で対称でない場合は違う結果になります。
ただし、レーベンシュタイン距離が距離の公理を満たすためには挿入と削除に対して対称でなければならないため、結局どっちでもイイっていう。
あるいは基本的に私が勘違いしている可能性も高いです。

以上

カテゴリー: PHP, プログラム, 聞いて欲しい独り言 | コメントする

キリンのコーラ飲んでみた

正直、悪くない。
あっさりしてておいしい。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

mp3をwmaに変換しようと思った

思ってBatchWoo!っていうのを入れてみた。
http://www.vector.co.jp/soft/win95/art/se457459.html
そしたら、初回起動時。yahooのツールバーを入れようとしやがったので断ったのに、その隙に裏で勝手にJWordをインストールしやがった。消えて無くなれよ、BatchWoo!。ということで速攻JWordをアンインストールしたら「再起動が必要です。」消えて無くなれよ、JWord。
BatchWoo!を入れるならjw_setup.exeを削除しとくこと。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

VS2008の正規表現

VS2008のエディタで正規表現を使って置換しようとしたとき、はまりました。
故あって、次のような正規表現を書いて


(\* .+ : .+)\n

以下のような行を検索したかったのです。


* hogehoge : fugafuga

でもこれが引っかからないどころか「グループ化された式に ‘)’ がありません。」というエラーを出しやがるのです!「’)’あるだろ、よく見ろよ!」と怒り狂うこと3分、なんとなくコロンの前にエスケープを付けてみたら・・・動いた!検索できた!えー?こんなんにエスケープいるんだっけ?と思いつつも、まあ検索できたのでいいやと思い、おもむろにサクラエディタのノリで置換文字列に「\1<br/>」と書いて置換を実行したら・・・・「<br/>」になった!そ、そんな!後方参照できないの!?ヘルプを見てみたけどそれ(後方参照)らしい記述はない・・・。
VS2008の正規表現使えねええ!!!!!ってことで。

以上

カテゴリー: 聞いて欲しい独り言 | 2件のコメント

危うく高額ドラクエ9を買うところだった

amazonで普通に予約したつもりが、実は「マリオネット24」(あるいはドリーム24)という転売屋からの購入になっていた。定価なんてシランので「7900円たけえなあ」くらいにしか思っていなかったが、なぜか発売6日前に「発送しました」メールが来たので怪しく思ってよくよく見てみると販売元がamazonじゃなくて上記の店になっていた。amazonは商品の在庫が無くなると同じページでマーケットプレイスから販売するようになるという仕様を何とかして欲しい。
ちょっと検索してみると定価の2割増しで販売する転売屋ということが判明したので、速攻で電話してキャンセルした。どうも同じような罠にはまっている人は多いらしく、電話先では電話対応に追われているようであった。「キャンセルしたいんですけど」というとなんの商品についてかこちらからは言及していないのに「ドラクエでしょうか?」と切り返された。さすがにみんなの怒りが爆発したか。

というわけで、私も怒りにまかせて書き殴ってみた。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

firefox3.5いれたけど

TabMixPlusとSBMカウンタが対応してないな-。
あと、今までページ中の単語を選択してGoogleツールバーにドラッグしたら自動的に検索してくれたんだけど、できなくなった。
とりあえずTab Kit入れてがんばる。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

アラキドン酸?

アラキドン酸がどうのこうのっていうCM、最後にいつもの「詳しくはWebで」的に検索ワードが出るけど、すぐに人の名前を思い出せない人が、
「サントリー健康情報レポート」
なんつう長いワードは覚えていられないと思う。

以上

カテゴリー: 聞いて欲しい独り言 | コメントする

TTBaseのプラグインのdragextをちょっと更新

ちょっとだけ更新しました。
dragext
なんとかマウスだけで操作できるようにしたかったんだけど、意外とめんどくさくて中途半端に対応しました。
本当だったらmousemoveをフックしないといけないんだろうな・・・。

以上

カテゴリー: プログラム, 聞いて欲しい独り言 | コメントする