「Java 6 でIVSを比較すると何が起こるか」の記事の誤り(続編)

先日のエントリで「ざっとチェックした限りでは,それらにはまだIVSがらみの変更はないようだが,もし見落としがあれば教えて頂きたい」と書いておいたら,さっそく仕様書に記述はないが,Unicode DatabaseのDUCET(Default Unicode Collation Element Table)はすでに変更されていると指摘して頂いた.どうもありがとう.
DUCETをチェックしなかったのは,「Unicode Collation Algorithm」でjava.text.Collatorクラスとjava.text.RuleBasedCollatorクラスが引用されているように,Mark Davisjava.textパッケージの設計に直接関わっていて,Unicode Databaseがそのままjava.textパッケージに使われていると思っていたからだが,指摘されて実はjava.text.Collatorクラスの実装では,ロケールごとに照合規則を定義して,それをロードしていることを思い出した.
以下が現在のままでも正しく動くコードである.

import java.text.Collator;
import java.text.RuleBasedCollator;

public class VariationSelectorTest {
    public static void main(String[] args) throws Exception {
	String nonIvs = "与太郎";
	String ivs1 = "与\uDB40\uDD00太郎";
	String ivs2 = "与\uDB40\uDD02太郎";
	String nonIvsNext = "与那国";

	RuleBasedCollator c = new RuleBasedCollator(",\uDB40\uDD00 ,\uDB40\uDD02 " + ((RuleBasedCollator)Collator.getInstance()).getRules());
	c.setStrength(Collator.PRIMARY);

	System.out.println("Compare " + ivs1 + " with " + nonIvs + ": " +
			   c.compare("test", "test\t"));
	System.out.println("Compare " + ivs1 + " with " + nonIvs + ": " +
			   c.compare(ivs1, nonIvs));
	System.out.println("Compare " + ivs1 + " with " + ivs2 + ": " +
			   c.compare(ivs1, ivs2));
	System.out.println("Compare " + nonIvs + " with " + nonIvsNext + ": " +
			   c.compare(nonIvs, nonIvsNext));
	System.out.println("Compare " + nonIvsNext + " with " + ivs1 + ": " +
			   c.compare(nonIvsNext, ivs1));
    }
}

このコードのポイントは以下の通りだ.

  • setStrength()で照合の強さを指定している.
  • デフォルトの照合規則に,異体字選択子を無視する(このコードで対象とする最低限の)規則を追加している.

RuleBasedCollatorは正しく動作するが,デフォルトの照合規則に入っていないのが問題なので,それはバグレポートして修正要求するとよいだろう.
なお,面白いことにApache HarmonyのRuleBasedCollatorの実装のコメントには,「If a character is not located in the RuleBasedCollator, the default Unicode Collation Algorithm (UCA) rulebased table is automatically searched as a backup.」と書かれているので,こちらでは正しく動くかもしれない(未確認).
なお,Togetterでは,照合よりも正規化の話が進行していたのだが,現在の正規化方法ではまだ区別されてしまうという理解でよいのだろうか?(確かにテストコードは,そのように動くのだが…)

「Java 6 でIVSを比較すると何が起こるか」の記事の誤り

以下の記事に誤りが散見されるが,それが広まるのは望ましくないので,ここで誤りを指摘しておく.
「Java 6 でIVSを比較すると何が起こるか」(yanok.net)
まず,Javaの文字列の同一性判定の話である.

これは想像通りですね。単にcharの列を比較しただけの結果になっています。つまり、見た目の区別がつかなくても容赦なく別々の文字列として扱っています。これが何をもたらすかというと、Stringクラスで比較しているプログラムに対しては、"与" と "与[0E0100]" と "与[0E0102]" を、見た目の区別がないにもかかわらず、人が入力し分けてやらないと困ることになるということです。

Java言語でUnicode文字列が同一性を判定するには,いくつかの方法がある.

  1. java.lang.String#equals()…単なるUnicode文字シーケンスの同一性を判定する
  2. java.text.Collator#equals()…Unicode照合規則に基づいて動的に同一性を判定する
  3. java.text.Collator#getCollationKey()+java.text.CollationKey#compareTo()…Unicode照合規則に基づいて静的にオブジェクトの同一性を判定する
  4. java.text.Collator#getCollationKey()+java.text.CollationKey#toByteArray()+バイナリ比較…Unicode照合規則に基づいて静的にバイト列の同一性を判定する
  5. java.text.Normalizer#normalize()+java.lang.String#equals()…Unicode正規化規則に基づいて静的に文字列の同一性を判定する

このように多くの方法があるのは,文字列の同一性判定にいろいろな要求があるからである.たとえば,自然言語の正しい比較は2以降でしか行えないが,プログラミング言語ではUnicode正規化規則や照合規則をあえて適用しないと仕様で規定しているものが多く,その場合には1を用いることになる.また,String#equals()自体はUnicode文字シーケンスを比較しているだけだが,事前にNormalizerを使って正規化しておけば,毎回Collatorを使うよりも高速に処理できることになる(この機能はデータベースの実装に必要なので,私が強く要求して実現したものである).
次にIVSの仕様に関する解釈である.

UTS #37のIVDの仕様には「variation selectors are default ignorable」と書いてありますが、Javaはignoreしてくれないようです。

この引用部分をさらに長く引用すると,以下の通りである.

Furthermore, variation selectors are default ignorable. This implies that registrants are expected to ensure that the glyphic subset associated with an IVS is indeed a subset of the glyphs which are acceptable for the base character alone. Stated another way, the shapes in the glyphic subset of an IVS should be unifiable with the base character of that IVS. One possible way to determine this is to consider the unification rules for Han ideographs; see [Unicode], section 12.1 Han, and [ISO 10646], annex S.

これを読めばすぐ分かるが,ここで述べているのは異体字選択子があったとしても無視して基底文字のグリフで代用してもよいというグリフやレンダリングエンジンにおける話であり,Unicode照合規則やUnicode正規化規則の話ではない(ざっとチェックした限りでは,それらにはまだIVSがらみの変更はないようだが,もし見落としがあれば教えて頂きたい).
つまり,ここでチェックすべき実装の部分はレンダリングエンジンでどのように表示されるかであり,文字列の比較に関してはJavaの実装はUnicode標準に沿って実装されていると言える.もし,この部分の仕様に関して実装をチェックするとしたら,Javaレンダリングエンジンでどのように表示されるかであろう.
もちろん,今後各言語仕様や実装において,どのような機能拡張をすべきかという議論はあるだろう.その場合には,私もJavaC#ECMAScriptの仕様策定や標準化に関わってきたので,何らかの協力ができるかもしれない.

ネットワークが創発する知能研究会 JWEIN10 参加者募集

日本ソフトウェア科学会のネットワークが創発する知能研究会のワークショップJWEIN10が,2010年8月20日(金)〜8月22日(日)の3日間,田町のキャンパス・イノベーションセンター東京で開催される.「ネットワークダイナミクス」と「ネットワークが創発する知能」に関した研究に興味のある人は参加して頂きたい.
http://www.ai.sanken.osaka-u.ac.jp/ndei/index.php?cmd=read&page=jwein_summer_2010
なお,今回は,一般講演に加えて,次のような招待講演をおこなう予定である.

  1. 折田 明子 氏(慶応大)「意図せず生まれる知識共有」
  2. 中谷 裕教 氏(理化学研究所)「将棋棋士の駒組認識」
  3. 堀本 勝久 氏 (産総研)「システム生物学研究におけるネットワーク解析」

折田氏は,ブログやTwitterなどのインターネット上のサービスでユーザの知識が蓄積され,それが他のユーザによって活用される点に着目して,それがうまくおこなわれるためにはどのように設計すべきかを,調査結果を分析して説明してくれる.
中谷氏は,将棋の棋士の脳活動が一般人とどう違うか?ということを説明してくれる.今年の人工知能学会全国大会でもこれは話題になったが,羽生名人の脳活動は凄いらしい.
堀本氏は,生物を,単なる分子としてではなく,それが関係したネットワークとして分析する方法について説明してくれるらしい.特定の条件を満たした時に活性化する制御ネットワークとは何か,当日明らかにされると思う.
この三人の講演者によるパネルディスカッションもおこなう予定だ.

樋浦秀樹さんを送る会(西麻布・クリニカ・ガストロノミカ・エスペリア)

ガンで亡くなられた樋浦秀樹氏を送る会が開催されたので,私も行ってきた.

確か15年ぐらい前に私の発言に関して直接メールを頂いたのがきっかけで,それからはいろいろ面倒を見て頂き,私の著書のレビューなどもお願いしたことがあったし,アメリカや日本で一緒に食事をしたこともあった.病気の話を聞いた時も,訃報を聞いた時も心の中で信じたくない気持ちがずっとあったが,この会に参加して彼が本当に亡くなったんだとようやく実感した.
なお,この日は彼の誕生日だったそうで,バースデーケーキが用意されていた.

樋浦氏の偉大さを痛感したのは,この口コミで広まった会にものすごい人数の人達が集まったことだ(100名以上?).しかも,IT業界で活躍されている凄い人達が多く.このような人達が組織や分野の垣根を越えてこれだけ集まる機会はめったにないだろう.
しかし,我々も彼の死を悲しむだけでなく,彼に教えてもらったことを,さらに世の中に広めていかねばならないだろう.
蛇足:私が知っている人の中には,どうも私を覚えていない人が多かったようだ.その時は「まあ,私って印象薄いからなあ…」と思っていたのだが,後から三年前に15kg以上減量したので,最近会っていなかった人は私のことがわからなくて当然だったのだ(爆)こちらから積極的に声を掛けなくてごめんなさい.

竹内郁雄教授最終講義「研究・開発は楽しく」(東京大学)

3月3日に東京大学で竹内郁雄教授の最終講義がおこなわれた.

なお,今回は参加者が多かった他の最終講義の参加人数から推測して340名の会場を用意したのだが,予想をはるかに上回る参加人数(400名くらい?)で,一部の人達は立ち見になってしまった.また,鵺シール・竹内郁雄最終講義スペシャルバージョン(普通は文字がオレンジ,これは文字がブルー)も300枚用意したのだが,全然足りなくて一部の人達には渡すことができなかった.この場を借りて準備不足をお詫びしたい.
なお,最終講義の様子は二台のビデオカメラで撮影してある.大学の許可が出れば,公開されるかもしれないので,その時はこのブログでもお知らせしようと思う.
さて,今回の講義の題名は「研究・開発は楽しく」である.竹内先生によると,通常の最終講義で喋る内容はすでに別の場所で喋ったので,それは講演の資料として配ることにして,最終講義では別の話にしたいということだった.その後知らされた題名を聞いてちょっとびっくりしたが,私は今回の講義の内容は情報処理分野の研究者・開発者に対して送る竹内教授のメッセージだと思っている.若かりしころのエピソード,電電公社・NTT在籍時代のとんでもない話(爆)やユニークな,TAO/ELIS開発時の数々の逸話,Lispというプログラミング言語の本質など,様々なことを話して頂いたと思うが,その根底にあるのは「人生と仕事を真面目に存分に楽しめ.そうすれば,成果はその後についてくる.」ということだろう.ただし,その裏には補食(当時存在した残業すると支給されるご飯.Googleの只飯のようなもの)を食べて終電間際まで仕事をし,それなのに朝4時にインターネット接続の障害が起こるといきなりメールが飛び交ってリモートで問題を解決する(本当に,みんないつ寝ていたんだろう?(笑))ような真摯さがあったことも忘れてはならない.昨今,企業も大学もかなり締め付けが厳しくなってしまったが,竹内教授の最終講義を聞いた人は,信念を持って仕事は楽しくやって頂きたいと思う.
最終講義は爆笑ものであっただけでなく,以下の最後のスライドのように非常に含蓄のある言葉も沢山あったと思う.

最後に講義中で紹介された二冊の本「初めての人のためのLISP[増補改訂版]」,「ガベージコレクションアルゴリズムと実装」を紹介しておこう.特に「初めての人のためのLISP」を読むと,「研究・開発は楽しく」という哲学を理解して頂けるのではないかと思う.

初めての人のためのLISP[増補改訂版]

初めての人のためのLISP[増補改訂版]

ガベージコレクションのアルゴリズムと実装

ガベージコレクションのアルゴリズムと実装

竹内郁雄教授の最終講義のお知らせ

Tak functionの生みの親でもあり,TAO/ELISに代表されるようなLispハッカーであり,未踏ユースのプロジェクトマネージャでもある「あの」東大の竹内郁雄教授が,ついに今年度末で定年退官する.
それに際して,3/3に東大本郷キャンパスで「研究・開発は楽しく」という題名で最終講義を行うので,私の様に竹内教授を心の師と仰ぐ人間やNTT・電通大・東大の竹内教授関係者はぜひ聴講を検討して頂きたい.事前登録は不要だそうだ.

竹内郁雄 教授 最終講義のご案内 2010年3月3日 (水)

各位
(重複受信された場合はご容赦ください)

東京大学大学院情報理工学系研究科創造情報学専攻竹内郁雄教授におかれましては,
2010年3月31日をもちまして東京大学を退職されることになりました.

つきましては,下記のとおり最終講義が開催されますので,ご案内申し上げます.
御多用の折とは存じますが,ご臨席賜わりますようお願い申し上げます.

東京大学大学院情報理工学系研究科創造情報学専攻
専攻長 石川正俊

1. 最終講義
日時: 2010年3月3日(水)  (16:30 - 18:00)
会場: 東京大学本郷キャンパス (工学部2号館1階213講義室)
(東京都文京区本郷7-3-1)
講義題目 研究・開発は楽しく

2. お問い合わせ
竹内郁雄教授最終講義運営委員会事務局
final-lecture at ci.i.u-tokyo.ac.jp (atを@に置き換えてください)

なお,最終講義のあと,工学部2号館展示室 (松本楼) において,
竹内先生を囲んだ懇親会も予定してございます.
こちらにつきましてもご参加くださいますようお願い申し上げます.

Google Marketingにおけるコンピューターサイエンスと統計学(内田誠・グーグル)

第87回知識ベースシステム研究会は,65名の方々に参加して頂き,議論をおこなった.この場を借りて,発表者と参加者に感謝したい.
昨年のように仕事に追われて忘れないように(爆),早めに内田誠氏の招待講演「Google Marketingにおけるコンピューターサイエンスと統計学」についてざっと報告しておきたい.また,Twitterのつぶやきも#sigkbsというハッシュタグで検索できる.資料は非公開であるが,聞いたことを他の伝えるのはかまわないそうなので,簡単に報告する.(追記:なお内田氏の指摘を受けて,一部修正した)
内田氏は,GoogleのQuantitative Marketingと呼ばれるデータ分析部門に属している.20名程度のチーム(数学・統計学などの分野の学位取得者ばかり)の中で,唯一のアジアパシフィック担当(日本にいるが,本社の部門直属)である.今回は彼らがGoogleのインフラを使ってどのような分析をしているのかを紹介して頂いた.
Google Marketingにおける7原則を紹介した(今回初公開)が,特に重要な二つの点は「仮説よりもデータを重視すること(Data. Not hype.)」,「結果は常に検証できなければいけないこと(Results must be trackable.)」らしい.Quantitative Marketingという部門は,既存のサービスの有効性分析だけでなく,新しいサービスのコンセプトを立ち上げる時点から関わることがあるらしい.
彼らの仕事は,大きく分けて次の4つの段階で構成される.

  1. ログデータからのデータの抽出.
  2. データの加工
  3. データの分析
  4. データの可視化

データ抽出段階では,Sawzallというスクリプト言語(論文は公開されているが,Google以外では実装・使われていない)を用いるが,これは以下の特徴から,エラー処理・並列計算をコード上で特に意識する必要もないので記述コード量は非常に短く,スクリプト言語でも大規模データを高速に処理できる.ただし,この段階では総和や出現頻度の計算,上位n件の抽出など,単純な処理に限定されている.

  • ログに記録されている構造化データはProtocol Bufferを使ってシリアライズ化・バイナリ化されており,Sawzallでは既存定義を読み込むだけで簡単に構造化データを参照できる.
  • ログデータ中に存在することが多い異常データは自動的に無視されるので,コーディングで気を使う必要はない.
  • GFS上では大規模データでも最初から小さいサイズのチャンクに分割されており,計算機クラスタ上で大規模並列処理がしやすい.
  • IPアドレスから緯度・軽度への変換など,Googleで必要な機能の多くが基本関数として提供されている.クラスタ上の分散並列計算も内部的に処理される.

データの加工段階では,主にPythonというスクリプト言語で,BigtableGoogle独自のデータベース)やMy SQL(独自改良版?)を用いる.
データ分析段階では,Rを用いることが多い.この段階では計算機クラスタと独立に実行するので,前段階まででRで扱える規模のデータにしておく必要がある.分析には,例えば次のようなモデルを用いているらしい.

  • Time-series (seasonal ARIMA) model
  • Linear mixed efffects (LME) model
  • Random forest model
  • DnD, propensity scoring

可視化段階では,Google Visualization APIを用いることが多い(Excelなどの既存のツールを使うこともあるらしい).表現力が多彩で簡単に使うことができる.
実際の事例としては,世界のどこでGoogleで検索しているかの可視化や,サービス利用の分析など,2例ほどが紹介された.
なお,各種ツールの選定の基本方針は,オープンソースや自社ツールに限らず,「社内に開発者がいる」ということのようだ.ツールの開発者がいれさえすれば,プロプライエタリなツールを使わなくても,自分たちの要求に合わせたり,問題を解決できる.これは当たり前のようでありながら,高いレベルで実現するのは難しいと言える.また,スクリプト言語を多用しているが,これはデータ分析が簡単にできるかららしい.
以上の話からわかるように,Quantitative Marketingでは,数学・統計と計算機科学の両方の知識が必要となるが,実際にはそのような人間は少ないようである.彼は,周囲には統計学の博士が多いのに,日本では統計という学問が軽く見られているのではないか?と感じているらしい.
興味深い点として,Quantitative Marketingでは学会発表が強く推奨されているようで,JSM(Joint Statistical Meetings) 2010などで発表しているようだ.
今回の招待講演は,Googleの独自技術の特徴を理解できていないと理解が難しかったかもしれないが,後からゆっくり考えて頂きたい.また,マーケティングとエンジニアリングの両方に発表許可を得るのに時間が掛かり,当初予定していた紹介事例の多くが発表不可となってしまって事例数が減った状態で講演することになってしまったそうだが,今後また同様の講演依頼があれば,また別の問題のない事例も紹介して頂けると思う.
なお,私は今年度でこの研究会の幹事を終えるが,来年度は新しい主査の東工大の村田剛志准教授が中心になるので,開催時期は違うかもしれないが,同様にWeb系の特集が組まれると思う.来年度以降も,知識ベースシステム研究会をよろしくお願いしたい.