2010年04月21日
MeCabがiPhone,OSXに載っていると言うのは止めようと思う
iPhoneのSDKの条項に変更が加わり、Flashのクロスコンパイルを含む 純正開発ツール以外で作成されたバイナリの配布が禁止となるようです。 世間でも散々言われていますが、この変更は正直とても残念です。Apple的には「製品のクオリティーが保てないから」という理由だそうですが、 Windows版iTunesが意味もなくQuickTime入れたり、Windows非標準のUIを 使いまくっていて、お世辞にもクオリティーが高いとは言えないのを棚にあげて、 クオリティー云々と言い訳できるのでしょうか。アプリなんて所詮 玉石混淆。決めるのはユーザです。
MeCabは以前GPL/LGPLでした。Appleを含む複数の方からこのライセンスでは 使いにくいと言う指摘をうけ、前職の同僚と協議をしながらBSD/LGPL/GPL のトリプルライセンスにしたという経緯があります。結果としてこの変更は うまくいきましたし、AppleがOSXやiPhoneにMeCabを搭載できるようになりました。 私はこのことをとても誇りに思っていましたが、今回の件以降、矛盾を感じずに いられません。他人にはオープンだBSDだと「オープン路線」を要求するのに、 (実際Appleの製品は数多くのオープンソースプロジェクトで構成されています。) 自分は、開発者の囲い込みで「クローズド路線」を追求しています。 そんなにクローズドでやりたいのなら、MeCabなんて使わないで自社開発 すればいいのに。技術力不足の部分をオープンソースで補い、それ以外は 厳しい審査ってのはムシが良すぎます。
私がオープンソースで公開しているソフトウェアは基本的にクロスプラットフォームで動作します。 たとえば手書き文字認識エンジンのZinniaは、様々な方がLinux,Android,iPhone,Windowsといった プラットフォームで動作させています。私自身、ユーザの自由度を最大化するために、そして 自分がつぶしがきかなくなるのを避けるために、特定のプラットフォームに 特化したコードなんて書きたくありませんし、極力プラットフォームに中立 な立場をとっています。MeCabを苦労してクロスプラットフォームで動くように 作ったところ、Appleはそのうま味だけを(ライセンス変更要求付きで)搾取し、 逆にクロスプラットフォームで動くiPhone上のアプリは「気にくわないから」 という理由だけで排除する.... 営利目的だと分からなくもないですし、 多くの一般ユーザにとってはどうでもいいことかもしれませんが、 私のようなオープンソースを(金銭の絡まない)ライフワークにしている 人間にとってはなんとも理解しがたいです。
私にはどうすることもできませが、MeCabがiPhoneやOSXで使われているということを、 MeCabのプレゼンなどではもう言わないと思います。いやMeCabをC#で 書いて、Objectiv-Cに変換すればいいのかな。いずれにせよ残念。
投稿者 taku : 23:18 | トラックバック (0)
2009年09月27日
sudo のGUIダイアログはセキュリティ的に大丈夫なのか?
UbuntuやMac OSXを使っていると、権限の高いオペレーションを実行しようとしたときに、ユーザのパスワードを要求するダイアログが起動します。毎回ハイハイと思いつつ入力しているのですが、ふと考えるとこのセキュリティモデルというかユーザビリティー的に大丈夫なのかどうかと思うようになりました。例えば、インストーラーでダミーのパスワードダイアログを表示させればマルウェア作者はユーザのパスワードを取り放題だし、OSのファイル保存ダイアログをクラックして、適当なファイル保存のタイミングで同ダイアログを出せば、無知なユーザはホイホイパスワードを入力してしまうのではないでしょうか。Webサイトのフィッシングと全く同じ話です。
このダイアログはそもそも CUIプログラム sudo のラッパーにすぎません。しかし、話はそんなに単純ではありません。CUIの場合は、ほとんどの操作が「能動的」なために、sudo をする場合は、今から行うコマンドは 管理者権限が必要だと分かって明示的に認証操作を実行します。一方、GUIの場合は、操作が「受動的」な場合が多いため、これからアプリケーションが行う操作に認証操作が必要かどうかは普通のユーザはパッと見てもわかりません。GUIに sudo のモデルを持ってくるのは不都合が多いような気がします。
sudo と同じようなシステムに Windows の UAC (User access control)があります。よく sudo = UAC みたいな誤解が多いのですが、ユーザビリティも実際の実装も全く異なります。
まず、UACの場合は「認証する」というモデルではありません。あくまでも「これから行う作業はシステムに重大な影響を及ぼしますがよろしいですか?」の Yes/No クエスチョンにすぎません。(ユーザがAdministrationグループにいないときにはパスワードを聞きますが..) そもそも、一般ユーザが重大な操作を及ぼすようなコンテクストで「認証操作」しかも「自分のパスワードを入力する」という手続きの意味付けが正しく理解できるとはあまり思えません。いっそ UAC のような Yes/No クエスチョンのほうが親切だし、直感的です。
そしたら、Ubuntu も Mac もUACみたいな Yes/No クエスチョンにすればいいいじゃんという話になりますが、そうすることは Unixのセキュリティモデル的にかなり難しいとおもいます。 Unixのセキュリティモデルは権限を「ユーザ」という単位で切り分けます。ですので、重大操作を行うには別のユーザ(主に root)にユーザを切り替える必要があります。一方, UACは同じユーザ内での権限レベル(正確には integrity level, 整合性レベル) の変更です。重大な作業が必要なプロセスの時に、Yes/No クエスチョンで聞いた後にintegrity level high でプロセスを実行します。ユーザを変えないので、この操作はelevation(昇格)と呼ばれます。実行権限の制御とユーザ認証を分離している点で Windows のセキュリティモデルの方が柔軟性があります。
仮に、UnixでUACみたいな Yes/No型に変えたとしても、これもこれで注意すべき点があります。別のマルウェアが勝手に Yes ボタンをクリックしないように、UACダイアログはセキュリティ的に隔離された空間で実行させる必要があります。VistaのUACがブラックアウトしている理由は、視覚的な効果もありますが、別の隔離されたデスクトップを作りそこで実行させているからです。Xで別のデスクトップといえばDISPLAYを変更すればできるかもしれません。Macで複数のデスクトップがあるのかどうかは知りません。
Unixのセキュリティモデルはシンプルでいいのですが、デスクトップ環境ではユーザビリティ上の不都合やデザイン上のセキュリティーホールがあるような気がしています。特に実行権限の制御が柔軟にできないというのは致命的です。 こういう話を防ぐには、実行権限の制御(sandbox)の機構を使ってアプリケーションサイドで根元から絶たないとお話になりません。Linuxにもいろいろなsandbox機構があって Chromiumでもどれにするか議論が行われているみたいです。 Macでも sandboxの機構があって、Mac版 Chromeはこれを使っているみたいですが、Windowsのsandboxに比べるとまだまだ貧弱です。Windows版のChromeは、Windowsのsandboxの機構をこれでもかというぐらい使いまくってセキュリティを確保しています。さきほどのデスクトップ分離も使っていて、レンダラプロセスは全く別のデスクトップ空間で実行されているためユーザとのインタラクションすらできません。お暇な方はこの辺のソースを読むと勉強になると思います。
投稿者 taku : 15:50 | トラックバック (0)
2009年08月29日
勉強会は発表してこそ意味がある
最近IT業界界隈で勉強会がブームになっているようです。子持ちエンジニアにとっては 参加したくても参加できないのが残念だったりしますが、時間のある 若い人には参加するだけでなく、ぜひそこで発表し意見をぶつけ合って欲しいです。私が在籍していたNAISTの松本研は、それこそ勉強会だらけの研究室でした。 いまでもその伝統は残っており、スケジュールを見ると勉強会の多さに驚かされます。 私はデータマイニング・機械学習の勉強会に参加していたのですが、 6~7人のメンバーで週二回のペースで論文を読みまくっていたので、 結構な頻度で担当が回ってきました。最初の頃はこのハイペースに戸惑う学生 もいますが、徐々になれてきてこのペースの勉強会に積極的に参加し発表(論文紹介) できるようになってきます。物心がつくと、勉強会のために論文を読むのではなく、 日頃から暇を見つけては論文を読むような習慣が身についてきます。
こういう状態の勉強会は有意義で健康的です。馴れ合いとか義務感ではなく、 みんなに紹介したいというモチベーションで勉強会に参加するようになります。 準備をそれなりにした題材は今でも内容を覚えています。
若いうちに仲間と一緒に「自発的な」勉強会・輪講をすることの重要さを 松本先生はいつも強調なさっています。松本先生自信も、電総研時代にそういう 経験をなさっていて、その実体験から松本研が勉強会主体の研究室になったのだと 思います。松本先生自ら今でも勉強会に参加して学生と同じ立場で発表しているところも 普通じゃありえないことかもしれません。松本研での経験は貴重な存在です。 自発的な研究・調査が苦にならず逆に楽しんで出来るようになりましたし、 人にあたらしい技術を紹介するいい訓練になったことは間違いありません。
投稿者 taku : 09:23 | トラックバック (0)
2009年07月19日
「ハードウェア」プログラマと「ソフトウェア」プログラマ
プログラマ・ソフトウェアエンジニアと呼ばれる人間には、 2つのタイプがあるような気がしています。 ひとつは、もともと機械いじりやハードウェアが好きな 「ハードウェア」プログラマ、もう一つはその反対の「ソフトウェア」プログラマ。 それぞれどういう特徴があるか、独断と偏見でまとめてみました。 (私自身ハード出身なのでそちらに偏重していますw )「ハードウェア」プログラマ
「ソフトウェア」プログラマ
個人にしろチームにしろ、この2つのバランスが重要なのは言うまでもありません。 ハードウェアプログラマだけだと、些末なタコツボ議論に陥りがちで本来時間を かけなくていいような最適化に無駄にリソースを投入してしまいます。 出来上がるものもすごーく平凡になりがちです。「ソフトウェア」プログラマだけだと、 プロトタイプはすぐに出来上がるのですが、そのあとの地道な安定性の向上 高速化や省メモリ化スケールアウトに苦しみます。
最後に、経験上「ハードウェア」から「ソフトウェア」に転向することは 比較的簡単ですが、その逆は難しいです。若いときはハードウェア (もっと簡単には機械いじり)をやっておいた方がいかもしれません。 私も元々電気の出身ですが、そこでの経験や考え方は今の ソフトウェア開発に役に立っています。
投稿者 taku : 20:41 | トラックバック (0)
2009年07月12日
ファンに支えられるプロダクトとユーザにdisられるプロダクト
世の中には熱狂的なファンに支えられるサービスやプロダクトがあります。 Appleファン、Googleファン、日産ファンといえばピンときますが、 Microsoftファン、Yahooファン、トヨタファンと言うとあまり聞きません。ファンに支えられることは素晴らしいことですが、ファンが多いからといって プロダクトの完成度やクオリティが高いとは限りません。私がファンになるのは アイドルぐらいで、ソフトウェアに関してこれとってファンはないのですが (いやむしろありとあらゆるプロダクトを触ってみては〇〇はウンコと言っていますが...) 某製品の改善点をそのファンに伝えると「愛が足りない」とか 「そんな所誰が気にするのか」とかわされます。
あるプロダクトのファンになるかどうかは、中の人がどれだけカリスマ性があるかとか、 彼らの長期的なビジョンや理念がどれだけ魅力的かと言ったハイレベルなところで 決まります。そのため、いったんファンになってしまうとバイアスの影響で その製品の正当な評価が出来にくくなってきます。個々の機能の完成度の許容量が低くなり、 少しのことではイライラしなくなります。この状態は実は危険です。 開発者はファンの声に満足してしまい、一般ユーザがイライラするような 改善点を見落としてしまいます。
開発者が自身のプロダクトでユーザを「驚かせる」方法には二種類あります。 前者は正の驚き。セクシーなインタラクションやビジュアル、クールな機能。 もう一つは負の驚き。ウンコなインタラクション、直感的ではない動作、 データ喪失、甘い作り込みなどです。開発者はどうしても正の驚きにフォーカスをあて、 合コン受けするようなプロダクトを作りたがりですが、私に言わせれば、 1000個の正の驚きを生み出すぐらいなら、1個の負の驚きを潰すほうがはるかに重要です。
ファンも同様に正の驚きを誇張しがちです。ファンじゃない普通の ユーザは「この部分はウンコだ」と負の驚き、改善点を正直にぶつけてきます。 Microsoftのスゴイところは、ユーザ(not ファン)にdisられまくってますが、 それらを真摯に受け止めコツコツと改善していっているところです。Vistaになって セキュリティモデルが一新され、IEが乗っ取られてもシステムには 影響がないような設計になってますし、VistaのウンコなUIは Windows7で それなりに改善されています。
私もオープンソースのソフトウェアをいくつか公開しています。 ポジティブなファンの応援は確かに励みになりますが、改善点を 正直にぶつけてdisってくれるユーザ(not ファン)を大事にしていきたいと思います。 良くも悪くも言われないんだけど、誰もが空気のように使っている というのが私の理想のプロダクトです
投稿者 taku : 22:31 | トラックバック (0)
2009年05月09日
「読めてしまう」コピペがなぜ読めてしまうのか
http://www.asks.jp/users/hiro/59059.htmlhttp://www.itmedia.co.jp/news/articles/0905/08/news021.html
最初読んだとき、違和感なく読めてしまったのですが、よくよく見てみると、そんなトリックがあったのですね。
さて、この「読めてしまう」がなぜよめてしまうのでしょうか?
人間の言語モデルの単語パープレキシティは、約100ぐらいであると言われています。どういうことかというと、 人間が文章を読んでいるときに、次の単語を過去の文章から推測するのは 1/100 程度の 確率で正解するということです。
件のコピペですが、最初の文字は変わらないので、その正解率は平仮名の数(52)倍になります。 すなわち、52/100 =~ 0.5 実際には、最後の文字も変わらないし、 単語の長さが変わらないというもの、大きなヒントになって、平均正解率は1.0に近くなるのではないかと思います。
ちなみに、統計的言語モデルのパープレキシティは50~150ぐらいで、条件やデータによって変わります。 あのコピペのような文章を作っても、非常に高い精度で元の文章が機械的に復元できると思います。
投稿者 taku : 18:28 | トラックバック (0)
2009年04月19日
ファイルIOではなくバイト列IO
組込用のIMEを作っている方とお話したことあるのですが、組込用のIMEは ポータビリティを高めるために、いわゆるファイルIOは使っておらず システムからimmutableメモリ領域(システム辞書など)とmutableメモリ領域(ユーザ辞書など) をわたしてもらって使うような仕様になっているそうです。 ファイルIOはポータビリティを考えるといろいろ面倒なことがあるのでなるほどな思いました。実はこういうバイト列を辞書のシリアライズ先として使うことはプリミティブですが身軽です。 自然言語処理のシステムでは静的な辞書や機械学習結果のモデルをロードすることが多々あります。
自分が何かを作るときは、辞書や学習モデルをバイナリのバイト列として格納し、メモリイメージとして読み込むような設計にしています。
例えば、Dictionary というクラスがあったときには、ファイルから辞書を読み込むような インタフェイス Dictionary::OpenFile(const string &filename) を作るのではなく Dictionary::OpenFromArray(const char *array, size_t size) をまず作ります。 ディクショナリの読み込みも、バイト列 array をメモリイメージとして使い、 ポインタのみでアクセスし、内部でコピーを作りません。これを徹底すると、 システムが使用する辞書のメモリ容量は array_size になることが保証され、 システム全体のサイズの予想がつけやすくなります。
ファイルをオープンする場合は、mmap や MapViewOfFile といったファイルを メモリーイメージにマッピングするシステムコールを使います。こうすることで ファイルIOがシステムと分離でき、ポータビリティが高まります。
Mmapmmap; // mmap, MapViewOfFile をラップしたクラス mmap.Open("foo.dic"); Dictionary dic; dic.OpenFromArray(mmap.begin(), mmap.size());
投稿者 taku : 15:27 | トラックバック (0)
2009年04月12日
pubic static はコンピュータに伝える約束事ではない
http://www.atmarkit.co.jp/news/200904/10/matz.htmlPerlやRuby、Pythonといったスクリプト言語では、 記述が非常にストレートで端的になる。JavaやC++といった言語では、 「public static void mainなど、コンピュータに伝える約束事が多くて、 やりたいことが頭の中から逃げてしまう。簡潔さは力なのです」(まつもと氏)。 これは書くときだけでなく、読むときにも同様だ。
まつもと氏の記事を読んで、仕事として大規模な共同開発の経験に基づいているのかなと思いました。
publicとかstaticとかconstというのは書く側からすると約束事で めんどいということには同意しますが、毎日のようにコードレビューを している経験からいうと、コードレビューをする側にとってこいうキーワードがあるかないかで全く意味が異なります。メソッドがconstであれば、
約束事は面倒だと言い切ることは短期的には問題ないかもしれません。 しかし、規模が大きくなったりユーザや開発者が増えると本題ではない些末な仕事が 増える結果となります。たとえば「暗黙の約束」みたいなものをドキュメント化 しないといけなかったり、アンドキュメントな使い方をされたときのユーザの対処 など... こいう本筋ではない仕事を技術的な制約で減らすこと、すなわち自分の仕事とユーザの間にファイアウォールを作ることは自分の本来の仕事に集中するために重要です。public/static などという話は「技術的なファイアウォール」の構築のためのとっかかりです。
投稿者 taku : 13:23 | トラックバック (0)
2008年09月27日
手書き文字認識エンジン Zinnia on iPhone
手書き文字認識エンジンZinniaを先日公開しました。全くデモがなくていまいちどういうライブラリか分かりにくかったのですが、Youtube 上に Zinnia を iPhone 上で動作させたというデモ動画を見つけました。すばらしい。http://www.youtube.com/watch?v=i88uaIu3Khk
ほかにもいくつかフィードバック等を見つけました。
Mathieu Blondel さんは、zinnia と tomoe, そして自身が開発なさっている hmm ベースの手書き文字認識エンジンを客観的に比較なさっています。 私自身こういう比較を 行なったことなかったのですが、tomoe に比べて、速度面でも精度面でもsignificantに上回っているようです。特に速度は 10倍ぐらいtomoenに比べて高速なようです。
他にも、tomoe本体の認識エンジンに zinniaを使うような実験コードがチェックインされています。
Zinnia はオンライン手書き文字認識に特化した実装になっているため、書き順や画数が狂うととたんに精度が低下します。オンラインの要素を残しつつ、オフライン手書き文字認識を今後やっていきたいと思います。オフライン手書き文字認識はどちらかというと画像の認識になるので特徴量の抽出は全く別物になりそうです。
投稿者 taku : 11:44 | トラックバック (0)
2008年09月15日
Zinnia: 機械学習ベースのポータブルなオンライン手書き文字認識エンジン
オンライン手書き文字認識エンジンZinniaを公開しました。http://zinnia.sourceforge.net/index-ja.html
Zinniaは機械学習アルゴリズム SVM を用いたポータブルで汎用的な オンライン手書き文字認識エンジンです。Zinniaは組み込みの容易さと汎用性を高めるために、 文字のレンダリング機能は持っていません。Zinniaは文字のストローク情報を座標の連続として受け取り、 確からしい順にスコア付きでN文字の認識結果を返すだけに機能を限定しています。 また、認識エンジンは完全に機械学習ベースであるために、文字のみならずユーザの任意のマウス・ペンストロークに対して任意の文字列をマッピングするような認識エンジンを小コスト作成することができます。
2年前に、Ajax手書き文字認識と言うものを作ったのですが、その認識エンジンをスクラッチからポータブルでつかいやすいライブラリになるように作り直しました。基本的にC/C++のライブラリですが、SWIG経由で ruby, perl, python からも利用できます。
投稿者 taku : 15:59 | トラックバック (0)
2008年07月11日
Mac OS X Leopard に「標準で」インストールされている MeCabを使ってみる
Mac OS X Leopard の Spotlight に MeCab が使われているらしいという情報を聞いたので、実際に深追いしてみました。いとも簡単に /usr/lib/libmecab* , /usr/include/mecab.h と /usr/lib/mecab/dic/apple/{ja,tc,sc} というディレクトリを発見しました。ts, sc は traditional/simplified Chinese (繁体字/簡体字) の略で、中国語の辞書だと推察されます。辞書のディレクトリはさらに dic/apple/ja/{LE,BE} という風に、エンディアンごとに分かれています。MeCabの辞書はエンディアン依存なので、こうするしかないのかもしれません。
さて、この辞書を使って、UTF8の文字列を流し込んでみたのですが、うまいこと解析してくれません。MeCabのバイナリ辞書形式には文字コードの情報が文字列で埋め込まれているので、その部分を バイナリエディタで見ると、UTF-16LE となっています。どうやら入出力を UTF-16LE にすれば形態素解析ができそうです。
確認のためのコード
#include <mecab.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iconv.h> char *iconv_convert_helper(iconv_t ic, const char *input, size_t ilen, size_t *length) { size_t olen = ilen * 4; char *result = (char *)malloc(olen); char *ibuf = (char *)input; char *obuf_org = result; char *obuf = result; size_t olen_org = olen; memset(result, 0, olen); if (ic == (iconv_t)(-1)) { exit(-1); } while (ilen != 0) { if (iconv(ic, (char **)(&ibuf), &ilen, &obuf, &olen) == (size_t)(-1)) { fprintf(stderr, "error in iconv\n"); free(result); return NULL; } } *length = olen_org - olen; obuf_org[*length] = '\0'; iconv_close(ic); return result; } char *utf8_to_utf16(const char *input, size_t ilen, size_t *olen) { iconv_t ic = iconv_open("UTF-16LE", "UTF-8"); return iconv_convert_helper(ic, input, ilen, olen); } char *utf16_to_utf8(const char *input, size_t ilen, size_t *olen) { iconv_t ic = iconv_open("UTF-8", "UTF-16LE"); return iconv_convert_helper(ic, input, ilen, olen); } int main (int argc, char **argv) { mecab_t *mecab; const mecab_node_t *node; char buf[8192]; char *buf2; mecab = mecab_new2("-d /usr/lib/mecab/dic/apple/ja/LE"); if (mecab == NULL) { fprintf(stderr, "error in mecab_new2: %s\n", mecab_strerror(NULL)); return -1; } while (fgets(buf, sizeof(buf), stdin)) { buf[strlen(buf) - 1] = '\0'; size_t olen = 0; buf2 = utf8_to_utf16(buf, strlen(buf), &olen); node = mecab_sparse_tonode2(mecab, buf2, olen); if (node == NULL) { fprintf(stderr, "error\n"); exit(-1); } node = node->next; for (; node->next != NULL; node = node->next) { char *r = utf16_to_utf8(node->surface, node->length, &olen); printf("%s|", r); free(r); } free(buf2); printf("\n"); } mecab_destroy(mecab); return 0; }
% gcc test.c -lmecab -liconv % echo 私の名前は中野です | ./a.out 私|の|名前|は|中野|です|
うひょー。分かち書きできます。品詞情報もあるみたいですが、Spotlight ではほとんど使われないようなので、一文字の品詞に省略されています。
投稿者 taku : 01:57 | トラックバック (0)
2008年06月02日
Linuxデスクトップ上でYahooかな漢字変換経由で日本語入力を実現するラッパーライブラリ
少し前の話ですが、Yahooがかな漢字変換Webサービスを出したようです。拙作のAjaximeみたいなサービスを簡単に作れるインフラが整ってきたようです。早速 Ajaxime のバックエンドをこれになーんてハックもいいのですが、やってて手応えがないので、Linux上で動く変換エンジンをYahooかな漢字変換サービスを使ってできないかと思って libanthy のラッパーライブラリを書いてみました。http://chasen.org/~taku/software/anthy-yahoojimservice/
Anthyのドキュメントを読んでみると、APIセットが小粒で直感的で、数十のAPI関数を独自に実装したlibanthy.so をLD_LIBRARY_PATHで突っ込んでやればよさそうです。この方法のいいところは、UIの面倒なところを全くいじることなく、Yahooかな漢字変換Webサービス経由でLinuxデスクトップ上で日本語入力ができることです。
実装はかなり手抜きです。(C++で自力で適当 XML parsing したり..) 文節を伸ばしたり縮めたり、予測入力もいちようサポートしていますが、いかんせん 週末quick hack なので、動作があやしいかもしれません。予測入力をWebベースでやることは懐疑的だったのですが、意外とサクサクと動いています。驚き。
しかし、すべての入力が ネット上に流出されてしまうのはやはり問題です。ライブラリを乗っ取ってしまうので、一見ローカルで動いているかのように見えます。実際これが使えるところは、共用マシンやキオスク端末などに限られるでしょう。
学習機能をつけたりいろいろアイデアはあると思いますが、本人のやる気が続くかどうか謎です。引き継いでくれる方募集します。
投稿者 taku : 01:34 | トラックバック (0)