2008年5 月16日 (金)

画像認識システム学

1. 二値化
 画像の前処理などに使われる。
 0-Ngの輝度で示される画像を、与えた閾値NBで分割し、
 0-NBまでの画素は0、NB-Ngまでの画素はNgに変換する。
 ヒストグラムの谷の間を見つけるモード法と、
 累積分布が一定の割合になるところで分割するPタイル法などがある。

2. ラベリング法
 二値化画像における同じ輝度を持つ画素を連結して、まとまった一つの領域として区別する。
 連結された領域を連結成分という。連結成分にそれぞれラベル(一般に1,2,3...)をつける。
 ラベリングにより画像内に点在する領域ををかたまりとしてそれぞれ扱うことができる。

 出し方は、まず二値化したものからラベリングする輝度を決定する。
 原点から順に探し、その輝度をもった最初の画素を見つける。
 順に同一輝度の画素を連結していく。
 連結できなくなったら、また次の輝度を持った画素を探し連結する。

3. フェレ径
 ラベリング後に各領域の大きさを測定するために使う。
 x軸の最大の長さから最小の長さを引き、1を足した数が水平方向のフェレ径。
 y軸も同様に行う。

4. エッジ処理
 輝度差の大きいところを、画像の特徴として強調する。
 x,y軸で輝度差の変化が閾値を超えたところをエッジとする。
 その他に周辺8方向の輝度差を計算する方法がある。

5. フェレ径による多角形頂点の認識
 縦と横のフェレ径を組み合わせて対象物を囲んだ矩形をつくり、
 フェレ形状の点を頂点として認識する。
 おそらくxyの最大最小値を見つけるのと同じだと思う。
 問題として、へこんだ頂点がある場合(180°以上)頂点を発見できない。

6. 重心からの多角形頂点の認識
 ラベリングした領域から重心を見つける。
 フェレ径上の点を始点として、輪郭線から重心の距離を測定していく。
 距離の極大値・極小値となる点が頂点である。

7. ハフ変換を用いた直線の認識
 ハフ変換を用いると、点線など完全ではない直線も認識することができる。
 入力画像内の全ての画素に対して、輝度値が閾値以上になる場合、
 その画素の座標(x0, y0)を以下の式で、変数(u, v)上の曲線に変換する。

 v = x0 ・cos(u) + y0 ・sin(u)

 任意の点で曲線をつくっていき、一番多い交点から、u, vを求め、直線の式をつくる。
 交点が多いほど精度が高い。

2008年5 月11日 (日)

シンプリシティの法則

単純に考えれば、機能が多ければ多いほど、製品の価値は高まるように思われる。しかし、機能の乏しい上に高価なiPodが、他のプレーヤよりも売れていることからも分かるように、人はシンプルに作られているものを、そうでないものよりも遙かに強く需要している。だから、過度な複雑さを減らし、シンプルであることを追求することで、すばらしいプロダクトを作ることができる。

本書では、シンプリシティのための10の法則が上げられている。

  1. 削減 :本質を生かしたまま、それ以外の要素をできるかぎり減らす。
  2. 組織化:要素をまとめて、わかりやすくする。
  3. 時間 :待ち時間を感じさせない。
  4. 学習 :基本知識を学習させる。
  5. 相違 :意識的に複雑さを用いて比較させる。
  6. 余白 :見えないものを活かす。
  7. 感情 :共感させ、愛着をもたせる。
  8. 信頼 :信頼を獲得する。リラックスさせる。
  9. 失敗 :完全なシンプリシティは実現不可能。
  10. 1   :明白なものを除き、有意義なものを加える。

基本となるのは、1の削減である。削減の手法は縮小(SHRINK)、隠蔽(HIDE)、具体化(EMBODY)の3つで著者がSHEと名付けている。これは、一言で表すと、できることを減らし、他の全てを隠しつつ、本質的価値を具体化することだ。

シンプリシティはゼロにシンプリシティを足して得られるのではなく、複雑なものを研磨することで得られるのだと思った。シンプルにすることは重要だが、始めにあるものに価値が乏しければ、シンプルにしてもゼロになるだけでしかない。本書の中でも、シンプルさと複雑さを揺り戻させることの重要さが繰り返し語られている。シンプルさを追求することは、複雑にする努力を惜しまないことでもあるのだ。

2008年5 月 1日 (木)

ロングテール

昨日、Freeについての論文を読んだが、クリス・アンダーソンのロングテールを実はまだ読んでいなかった。ただ、先日たまたまBookOffで見つけて積読してあったので、この機会に開いてみた。

一気に読み切った。要約すると「ネットは在庫コストがかからないから、ニッチも全てとらえて、ユーザ数を拡大しろ」ってことだと思う。
また、mp3.comの失敗で、「テールがいくらあっても、ヘッドが無ければ、ユーザは何を選べばいいかわからない」という話が興味深かった。当たり前なんだけど、テールよりもヘッドが重要なことには変わりない。

自分に関していえば、本は好きなのでAmazonでニッチな本は見つけられるが、音楽をITMSで探すのは相当しんどい。どう探せばいいかわからない。
そのあたりから考えると、やはりフィルタリングが重要なんだなと思う。
ただレコメンドもいいのだけど、それだけで選ばせられるのもちょっと味気ない。ちょっとぶらぶらしながら、自分の好きなものが見つかっていくような、ユーザー体験を与えられないものか。

2008年4 月24日 (木)

リーン開発の本質

トヨタ生産方式(TPS)をソフトウェア開発に適用する

■原則
 原則1:ムダをなくす
  ムダとは価値を生まないあらゆるもの。
  ならば、ムダを無くすには、まず顧客にとっての価値を理解しなければならない。
  次にムダを見抜く能力を身につける。

 原則2:品質を作り込む
  テスト駆動開発や継続的インテグレーションで最初から欠陥が入り込まないようにする。
  新たな機能を追加する前に、リファクタリングを行い、コードをシンプルに保つ。

 原則3: 知識を作り出す
  プロセスを継続的に改善する。
  どのような異常であれ、元凶を見つけ出し、再発防止のためにプロセスを変更する。

 原則4: 決定を遅らせる。
   システムの初期機能を開発している時点で、重要な決定をしてしまい、
  将来の変更を妨げてはならない。
  難しい決断はなるべく遅らせ、選択可能な状態を保つ。

  原則5: 速く提供する
   ムダがなくなれば、スピードが上がる。
  スピードと品質は共存する。
   サイクルタイムを重視し、重要なところから改善する。

 原則6: 人を尊重する
  リーダーシップを発揮させる。専門知識を備えた人を育成する。
  やるべきことややり方を指図するのではなく、人が頭を使い、
  自らそれを見つけ出すことのできる、自律した組織を作る。

  原則7: 全体を最適化する
  注文を受けた時点から、ニーズ解決されるまでの、バリューストリーム全体を解決する。
  部分最適に陥ってはならない。
  バリューストリームの中で、ボトルネックとなっている箇所を見つけ出し、
 本当に重要な一つだけを最適化する。

■7つのムダ

 1. 未完成の作業のムダ
  ・コード化されていないドキュメント
  ・コミットされていないコード
  ・開発したがリリース待ちのコード

 2. 余分な機能のムダ
  ・必要性に疑問があるものを作ってはならない

 3. 再学習のムダ
  ・一度覚えたことは、次に必ず引き出せるようにする。
  ・同じ失敗を繰り返してはならない

 4. 引き継ぎのムダ
  ・引き継ぎの回数を減らす
  ・暗黙知が共有されるよう、コミュニケーションを増やす

 5. タスク切り替えのムダ
  ・マルチタスクではなくシングルタスク
  ・開発チームが保守も行う

 6. 遅れのムダ
  ・全ての待ち時間を無くす

 7. 欠陥のムダ
  ・できるだけ早期に欠陥を見つける

■待ち行列理論
 バリューストリームマップの各プロセスで、平均サイクルタイムを測定する。

 サイクルタイム =  やるべきことの数/平均完成率

 待ち行列を最小にするには、
 ・作業を特定のプロセスに集中させない。
 ・やるべきことを減らす
 ・やるべきことのリリースサイクルを小さくする
 ・イテレーションを一定にする
 ・許容能力を超えた仕事をしない
 ・プル型のスケジューリング

2008年4 月18日 (金)

スケーラブルWEBサイト

Flickrのエンジニアリングマネージャが書いた、スケーラブルなシステム・ネットワーク設計についての本。
開発環境や監視体制なども含まれ、網羅的。
大規模サイトでなくとも参考にできることが多い。

■ボトルネックの特定
パフォーマンスが劣化した際は、場当たり的に対応するのではなく、ボトルネックになっている箇所を特定する。

1. CPUのボトルネック
CPUがボトルネックになることは殆どない。むしろディスクI/OやネットワークI/O、メモリI/Oの問題による、他のリソースの割当待ちで、プロセッサが空転し、これをプロセッサの問題としてとらえてしまうことが多い。
本当にCPUが足りないのならば、サーバを増設するか、強力なCPUを購入すればよい。

2. ディスクI/Oのボトルネック
iostatで劣化時は発見できるが、問題になる前に、可能なパフォーマンスを割り出しておくのが望ましい。
Bonnie, Bonnie++を使うと、ディスクのパフォーマンスをベンチマークできる。
ディスクI/Oの速度を制限するのは、主にディスクの回転数である。ディスクの回転数を上げる方が、ディスクやマシンを増設するよりも低コストである。ディスクの読み込み/書き込みキャッシュは、性能向上につながるが、電源バックアップの機能がないと、ハードウェアダウン時にデータが失われる可能性がある。
単純にディスクを追加するだけでも、高速化される。

3. ネットワークI/Oのボトルネック
netstatやslurmで特定する。
設定ミスなどで、イーサネットの性能を使い切れていない場合がある。
またブロードキャストドメインの中にあるホスト数が多いと、ブロードキャストストームという現象が起こる。この場合はルータでネットワークを適切に分割する必要がある。
その他に、データベースのレプリケーションでトラフィックが埋まることがあり、セグメントを分割した方が望ましい。

4. メモリI/Oのボトルネック
メモリからの読み込み速度、プロセッサキャッシュへの書き込み速度、メモリとキャッシュ間のバンド幅の3要因から発生。これを改善するのは容易ではないが、マシンの数を増やせば直線的にメモリのバンド幅を増大させることができる。

5. スワップ
ps -axlでVSZからRSSを引くことで、それぞれのプロセスのスワップ使用量がわかる。
MySQLやSquiidなどディスクからメモリに大量のデータをキャッシュしているようなアプリケーションは、スワッピングするとパフォーマンスがひどく低下する。
スワッピングを減らすにはメモリを増やすか、アプリケーションのメモリ割当を減らす方法がある。
後者だけでも問題を解決できることがある。

6. 外部サービス
そのサービスのせいにしたくなるが、通信方法がボトルネックになっていることがある。
リクエストの発信とレスポンスの受信が高速に行われているかをまず確認する。
 実際に外部サービスの問題だとすると、打つ手があまりなくなってしまう。

7. データベース
標準的なLAMPシステムで最大のボトルネックになるのは、データベースの処理量で、通常原因はディスクI/Oである。ただネットワークI/O が問題になっていることもあり、始めに調べて切り分けておく。
負荷の高いクエリを特定することが必要だが、MySQLではクエリーにコメントを埋め込めるので、processlistだけではわからないときは有用。
クエリのチューニング以外に、データをキャッシュしたり、データを非正規化して複数テーブルに保持する方法もある。

■スケーリング
スケーラブルなシステムとは以下の3つを備えたもの

  • 使用量が増えても対応できる
  • データセットが増えても対応できる
  • メンテナンスが可能

よく誤解されるが、スケーラブルとは関係ないもの

  •  スピードや性能
  • Javaなどのコンパイル言語
  • XML

ハードウェア的な視点から、拡張容易に設計し、将来的なソフトウェア変更の可能性を減らすのが望ましい。はじめはハードウェアがコスト高に見えるが、次第にソフトウェアのコストが上回るようになるから。

垂直方向のスケーリングと水平方向のスケーリングがある。

 ・垂直方向
  より強力なマシンに交換する。
  よい:設計が容易
  悪い:マシンスペックは青天井ではない。強力なマシンが存在しないか、非常に高価になる。

 ・水平方向
  ハードウェアを次々に買い足していく
  よい:追加コストが低い。
  悪い:マシンの所有コストがかかる。管理費、電力、スペース、ラック代など。
     スペックを活用しきれないマシンが出てくる。

結論
コストと便益を比較しながら、垂直/水平のスケーリングを組み合わせた設計にすることが望ましい。

2008年3 月26日 (水)

要求を可視化するための要求定義・要求仕様書の作り方

ソフトウェア開発が失敗するのは
1.  納入できなかった
2.  納入したが使われなかった
3.  納入され、使われたが、廃棄された
4.  納入されたが、変更した上で、使われた

これらの原因は以下のような要求仕様の問題として帰着できる

a.  要求仕様が不完全や曖昧で望まれるソフトウェアを実現できなかった
b.  要求仕様を満足するソフトウェアを開発したが、要求仕様が顧客の目標に合っていなかった
c.  要求仕様を満足するソフトウェアを開発したが、変化した顧客の目標に対してソフトウェアを修正できなかった
d.  要求仕様を満足するソフトウェアを開発し、変化した顧客の目標に対してソフトウェアを修正する必要があった

これに対処するのが要求工学の課題である

要求仕様とは与えられた要求を満足する仕様である。
仕様を確定したとしても、それが顧客の要求を満足する場合としない場合がある

要求は次のような要求特性を持つ

1. 一意性/正規化
 各要求は一度だけ説明される。他の要求または他の要求の機能には言及しない

2. 完全性
 要求仕様書には、システム定義に必要な要求に加え、顧客によって識別される全ての要求を含める。また矛盾がない。

3. システム境界の明確化
 要求の境界、範囲、および言葉の定義を明確にする。

4. 進化容易性
 要求仕様書のバージョンを管理することで、修正を明確にし、進化を容易にする

9. 粒度
 機能要求の粒度は機能階層に対応づける。大分類・中分類・小分類という風に詳細化する。

また次のような要求属性を明確にすることで要求分析を効率化できる

1. 識別子
 番号などを用いて要求を一意に識別する

2. 優先順位
 顧客は各要求の優先度を識別しなければならない。

3. 重要度
 分析者は各要求のクリティカリティを定義しなければならない。
 顧客視点では優先度が低くてもシステムを成立させるために重要なものもある。

4. 実現可能性
 技術的可能性、顧客にとっての環境変化の受容可能度、費用、法的リスクなど

  • 山本 修一郎
  • 定価 : ¥ 2,100
  • 発売日 : 2006/03
  • 出版社/メーカー : ソフトリサーチセンター
  • おすすめ度 : (3 reviews)
    システム素人なのにシステム開発を任された人、必携です
    参考になりました
    わかりやすさと論理のバランスが絶妙