めいふの備忘ログ

メモの代わりです。

StrategyパターンでNGramモデルの文生成器を作った時のおもいで(プログラム作成の一般的方法論 設計の段)

2.プログラム作成の一般的な方法論

今回のNgramモデル作成Javaプログラムですが、企業や研究機関でのよくあるソフトウェアの書き方に則って作成してみました。すなわち、プログラム保守のしやすさや品質を維持するために、以下の作法に則ってプログラムを書いた次第です。

1. 設計
2. 実装
3. テスト
4. 仕様書の作成(ドキュメンテーション。普通は1と平行して行う)
5. リリース(インテグレーション)

RubyPythonなどのスクリプト言語の使い手には「書きながら(設計やアルゴリズムを)考えてる!」という豪の者もいるそうなのですが、今回はJavaですし、設計図からプログラムを起こしたのでした。

2.1 設計

NGramモデルのあらましはわかりました(わかったことにしましょう)。「走れメロス」でNGramモデルを学習して、走れメロスっぽい文生を生成するを文生成器を作りたいと思います。では、どのようなポリシーでプログラムを作るべきなのでしょうか?

このポリシーを決定することがソフトウェアの設計のスタートです。ワタクシもこのポリシーに従ってソフトウェアが実現するべき機能(機能要件といいます)や性能的な特徴など(非機能要件といいます)を定め、ソフトウェアの静的な構造(どんなクラスで作るか)や振る舞い(オブジェクト間の呼び出しの手順)を決めていきます(今回はクラス設計までを行います)。

さて、今回はBack Off smoothing によるNGramモデルのプログラムを作成しますが、smoothing methodには他にも色々ありますし、NGramではない言語モデルもあります。将来的にはいろんな手法を試してみたい、と思うのです。そこで、ワタクシ、TINときたのです。


f:id:meihuno_huno_san:20170114040507p:plain:w400
キン肉マンⅡ世」25巻(ゆでたまご著)、Page69より。戦況に応じて戦術(ストラテジー)を変えるBエボリューションズの2人。

戦術(ストラテジー)パターンだ!と。

パターンとはデザインパターンのことです。過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものなのです(Wikipediaより)。

今回はStrategyパターンを採用します。Strategyパターンでは、様々なルールやアルゴリズムを、場合に応じて使い分けられるようにします。該当アルゴリズムの実装(この場合はモデルやスムージング手法)からアルゴリズムを個別に切り出します。色んなスムージング手法を試したい今回のような場合にぴったりです。

デザインパターンについては以下の本で勉強してみました。

オブジェクト指向のこころ(Alan Shalloway先生、James R.Trott先生著)
オブジェクト指向のこころ (SOFTWARE PATTERNS SERIES)

Ruby によるデザインパターン(Russ Olsen 先生著)
Rubyによるデザインパターン

StrategyパターンによるNGramモデル実装のためのクラス図も書いてみました。

f:id:meihuno_huno_san:20170114050549p:plain:w700

NGramモデルは確率計算用のWordSequenceProbクラスを持ってはいますが、計算アルゴリズム自体はWordSequenceProbクラスにまかせています。スムージングの個別のアルゴリズムはWordSequenceProbクラスを継承したサブクラス内で行っています。新しいスムージング手法を試したい場合はWordSequenceProbクラスを継承したサブクラスを追加していけばよい、というわけです。

また、クラス図を書くとどのクラスがどのクラスに依存しているかなど言葉ではなく視覚でとらえることができます。クラス図をレビューすることで保守性の高いメンテナンスしやすいソフトウェアの構造に近づけていくこともできます。レビューはもちろん他の人にしてもらうのが一番ですが、ぼっちでもできます。

例えば、今回のクラス構造も最初はSentenceGeneratorクラスがFindFileを使用する形になっていましたが、ワタクシがクラス図をせっせと書いていると、NGramからもFindFileクラスを使用していることが白日の元にさらされたのでした。結果、テキストデータの読み込みはNGramにまかせて、SentenceGeneratorクラスからのFindFileクラスへと伸びていた依存の線はなくなったのでした。プログラムを書く時は最初にかるくでいいのでクラス図を書くと将来のめんどーごとを減らせるかもしれません。

さてさて、これでプログラムの設計ができあがったということにして、いよいよ実装です。記事は「StrategyパターンでNGramモデルの文生成器を作った時の思い出(プログラム作成の一般的方法論 実装/テストの段)」に続くのです。

なお、クラス図などのUML記述ツールはChangeVisionさんの astah* community - 無償UMLモデリングツール | Astah を使わせてもらっています。astahは業界標準UMLツールなんじゃないでしょうか。いつもお世話になっております。