(57)【要約】【課題】プログラムのクラスタに対応付ける付加情報の精度を向上させる。【解決手段】情報処理装置１０は、クラスタに属する複数のプログラムに対応する複数のノードとプログラム間の依存関係を示す複数のエッジとを含むグラフ１４を取得する。情報処理装置１０は、複数のノードのうち、グラフ１４から除去した場合にグラフ１４が非連結な複数の部分グラフに分割される切断点ノード１４ａを選択する。情報処理装置１０は、複数のプログラムのうち切断点ノード１４ａに対応するプログラムで使用される単語を抽出し、抽出した単語を用いてクラスタに対応付ける付加情報１５を生成する。【選択図】図１
2019021232.tif 000002
【特許請求の範囲】
【請求項１】
クラスタに属する複数のプログラムを示すクラスタ情報を記憶する記憶部と、
前記クラスタ情報が示す前記複数のプログラムに対応する複数のノードと前記複数のプログラムの間の依存関係を示す複数のエッジとを含むグラフを取得し、前記複数のノードのうち、前記グラフから除去した場合に前記グラフが非連結な複数の部分グラフに分割される切断点ノードを選択し、前記複数のプログラムのうち前記切断点ノードに対応するプログラムで使用される単語を抽出し、前記抽出した単語を用いて前記クラスタに対応付ける付加情報を生成する処理部と、
を有する情報処理装置。
【請求項２】
前記付加情報の生成では、前記処理部は、前記抽出した単語に他のプログラムで使用される単語よりも大きい重みを付与し、前記複数のプログラムで使用される複数の単語の中から、出現頻度と前記重みとに基づいて前記付加情報に用いる特徴語を選択する、
請求項１記載の情報処理装置。
【請求項３】
前記処理部は更に、前記複数の部分グラフのうちの異なる部分グラフに含まれる異なるノードに対応する異なるプログラムで共通に使用される共通単語を抽出し、
前記付加情報は、前記抽出した単語に加えて前記共通単語を用いて生成される、
請求項１記載の情報処理装置。
【請求項４】
前記グラフは、前記複数のエッジそれぞれが方向をもつ有向グラフであり、
前記処理部は更に、前記グラフに基づいて前記切断点ノードと前記複数の部分グラフそれぞれとの間の依存関係の方向を判定し、
前記付加情報の生成では、前記処理部は、前記抽出した単語に加えて前記判定した依存関係の方向に応じた語句を用いて前記付加情報を生成する、
請求項１記載の情報処理装置。
【請求項５】
前記切断点ノードの選択では、前記処理部は、前記グラフに複数の切断点ノードの候補が存在する場合、分割後の部分グラフの数が多くなる候補を優先的に選択する、
請求項１記載の情報処理装置。
【請求項６】
前記切断点ノードの選択では、前記処理部は、前記グラフに複数の切断点ノードの候補が存在する場合、部分グラフ間のノード数の偏りが小さくなる候補を優先的に選択する、
請求項１記載の情報処理装置。
【請求項７】
前記複数のプログラムそれぞれには階層的な分類名が付与されており、
前記切断点ノードの選択では、前記処理部は、前記グラフに複数の切断点ノードの候補が存在する場合、異なる分類名が付与されたプログラムに対応するノードが混在する部分グラフが少なくなる候補を優先的に選択する、
請求項１記載の情報処理装置。
【請求項８】
コンピュータが実行する情報処理方法であって、
クラスタに属する複数のプログラムに対応する複数のノードと前記複数のプログラムの間の依存関係を示す複数のエッジとを含むグラフを取得し、
前記複数のノードのうち、前記グラフから除去した場合に前記グラフが非連結な複数の部分グラフに分割される切断点ノードを選択し、
前記複数のプログラムのうち前記切断点ノードに対応するプログラムで使用される単語を抽出し、前記抽出した単語を用いて前記クラスタに対応付ける付加情報を生成する、
情報処理方法。
【請求項９】
コンピュータに、
クラスタに属する複数のプログラムに対応する複数のノードと前記複数のプログラムの間の依存関係を示す複数のエッジとを含むグラフを取得し、
前記複数のノードのうち、前記グラフから除去した場合に前記グラフが非連結な複数の部分グラフに分割される切断点ノードを選択し、
前記複数のプログラムのうち前記切断点ノードに対応するプログラムで使用される単語を抽出し、前記抽出した単語を用いて前記クラスタに対応付ける付加情報を生成する、
処理を実行させる情報処理プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は情報処理装置、情報処理方法および情報処理プログラムに関する。
【背景技術】
【０００２】
情報処理システム上で実行されるアプリケーションソフトウェアを新規に開発するとき、通常は各種の設計情報が作成される。新規開発時に作成された設計情報はその後に行われるアプリケーションソフトウェアの保守・改良のために有用である一方、そのような設計情報が保守・改良のときまで保管されていないことも多い。また、アプリケーションソフトウェアの運用開始後に軽微な改良を繰り返し行う場合、改良についての設計情報が作成されないことや保管されないことがあり、保管されている設計情報と現在のアプリケーションソフトウェアの実体とが整合しないこともある。
【０００３】
このため、ソースコードやオブジェクトコードなどのプログラムを分析し、現在のアプリケーションソフトウェアの構造を把握することが行われている。
例えば、アプリケーションソフトウェアの理解を容易にするため、既存のプログラム群を複数のクラスタに分割する分割装置が提案されている。提案の分割装置は、プログラム群を分析して、プログラムを示すノード（節点）とプログラム間の依存関係を示すエッジ（リンク）とを含む依存関係グラフを生成する。分割装置は、部分グラフ内ではエッジが密になり部分グラフ間ではエッジが疎になるように、依存関係グラフを複数の部分グラフに分割する。分割装置は、同一の部分グラフに含まれるノードに対応するプログラムを、同一のクラスタに属するプログラムとして取り扱う。
【０００４】
また、プログラム群を複数のクラスタに分割した結果から、アプリケーションソフトウェアの構造を示すソフトウェア地図を生成する可視化方法が提案されている。提案のソフトウェア地図では、各プログラムが二次元または三次元のブロックとして表現され、同一のクラスタに属するプログラムを示すブロックが同一の区画内に密集して配置される。
【０００５】
また、クラスタの特徴の理解を容易にするため、クラスタに対応付ける付加情報を生成するラベリング方法が提案されている。生成された付加情報は、例えば、ソフトウェア地図においてクラスタを示す区画に重ねて表示される。提案のラベリング方法では、クラスタ毎に当該クラスタに属するプログラムのクラス名から複数の単語を抽出し、抽出した各単語について出現頻度からｔｆ−ｉｄｆ（Term Frequency - Inverse Document Frequency）値を算出する。そして、クラスタ毎にｔｆ−ｉｄｆ値が高い方から３つの単語を特徴語として選択し、３つの特徴語を連結した文字列を付加情報として生成する。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開平７−１４１１６６号公報
【特許文献２】特開平７−３１９６７６号公報
【特許文献３】特開２０１３−１４８９８７号公報
【特許文献４】特開２０１６−１３４０７９号公報
【非特許文献】
【０００７】
【非特許文献１】John Hopcroft and Robert Tarjan, "Algorithm 447: Efficient Algorithms for Graph Manipulation", Communications of the ACM, Volume 16 Issue 6, pages 372-378, June 1973.
【非特許文献２】Kenichi Kobayashi, Manabu Kamimura, Keisuke Yano, Koki Kato and Akihiko Matsuo, "SArF Map: Visualizing Software Architecture from Feature and Layer Viewpoints", the 21st IEEE International Conference on Program Comprehension (ICPC 2013), pages 43-52, May 2013.
【非特許文献３】Keisuke Yano and Akihiko Matsuo, "Labeling Feature-Oriented Software Clusters for Software Visualization Application", the 22nd Asia-Pacific Software Engineering Conference (APSEC 2015), December 2015.
【発明の概要】
【発明が解決しようとする課題】
【０００８】
しかし、単純に単語の出現頻度からプログラムのクラスタに対応付ける付加情報を生成すると、付加情報がクラスタの特徴を適切に表さないことがあり付加情報の精度が低くなることがあるという問題がある。例えば、中心となる１つのプログラムが周辺の複数のプログラムと依存関係をもつというスター型構造のクラスタが考えられる。そのようなクラスタでは、中心のプログラムが重要な役割をもっているにもかかわらず、中心のプログラムのみに現れる単語は出現頻度が低いために特徴語として抽出されないことがある。
【０００９】
１つの側面では、プログラムのクラスタに対応付ける付加情報の精度を向上させる情報処理装置、情報処理方法および情報処理プログラムを提供することを目的とする。
【課題を解決するための手段】
【００１０】
１つの態様では、記憶部と処理部とを有する情報処理装置が提供される。記憶部は、クラスタに属する複数のプログラムを示すクラスタ情報を記憶する。処理部は、クラスタ情報が示す複数のプログラムに対応する複数のノードと複数のプログラムの間の依存関係を示す複数のエッジとを含むグラフを取得する。処理部は、複数のノードのうち、グラフから除去した場合にグラフが非連結な複数の部分グラフに分割される切断点ノードを選択する。処理部は、複数のプログラムのうち切断点ノードに対応するプログラムで使用される単語を抽出し、抽出した単語を用いてクラスタに対応付ける付加情報を生成する。
【００１１】
また、１つの態様では、コンピュータが実行する情報処理方法が提供される。また、１つの態様では、コンピュータに実行させる情報処理プログラムが提供される。
【発明の効果】
【００１２】
１つの側面では、プログラムのクラスタに対応付ける付加情報の精度が向上する。
【図面の簡単な説明】
【００１３】
【図１】第１の実施の形態の情報処理装置を説明する図である。
【図２】第２の実施の形態の分析装置のハードウェア例を示すブロック図である。
【図３】分析装置の機能例を示すブロック図である。
【図４】ソースコードの例を示す図である。
【図５】全体の依存関係グラフの例を示す図である。
【図６】依存関係グラフに対応する隣接行列の例を示す図である。
【図７】プログラムのクラスタリング例を示す図である。
【図８】ソフトウェア地図の例を示す図である。
【図９】クラスタ内の依存関係グラフの例を示す図である。
【図１０】クラスタテーブルの例を示す図である。
【図１１】切断点テーブルと部分グラフテーブルの例を示す図である。
【図１２】単語重みテーブルの例を示す図である。
【図１３】クラスタ単語テーブルの例を示す図である。
【図１４】単語スコアテーブルの例を示す図である。
【図１５】付加情報テーブルの例を示す図である。
【図１６】切断点の評価値の算出例を示す第１の図である。
【図１７】切断点の評価値の算出例を示す第２の図である。
【図１８】切断点の評価値の算出例を示す第３の図である。
【図１９】ソフトウェア可視化の手順例を示すフローチャートである。
【図２０】クラスタリングの手順例を示すフローチャートである。
【図２１】単語スコア算出の手順例を示すフローチャートである。
【図２２】説明文生成の手順例を示すフローチャートである。
【発明を実施するための形態】
【００１４】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
第１の実施の形態を説明する。
【００１５】
図１は、第１の実施の形態の情報処理装置を説明する図である。
第１の実施の形態の情報処理装置１０は、ソフトウェアの構造を可視化する。情報処理装置１０は、クライアントコンピュータなどユーザが操作する端末装置でもよいし、サーバコンピュータなど端末装置からアクセスされるサーバ装置でもよい。
【００１６】
情報処理装置１０は、記憶部１１および処理部１２を有する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の半導体メモリでもよいし、ＨＤＤ（Hard Disk Drive）やフラッシュメモリなどの不揮発性のストレージでもよい。処理部１２は、例えば、ＣＰＵ（Central Processing Unit）やＤＳＰ（Digital Signal Processor）などのプロセッサである。ただし、処理部１２は、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。プロセッサは、ＲＡＭなどのメモリに記憶されたプログラムを実行する。複数のプロセッサの集合を「マルチプロセッサ」または「プロセッサ」と言うことがある。
【００１７】
記憶部１１は、クラスタ情報１３を記憶する。クラスタ情報１３は、可視化対象のソフトウェアに含まれるプログラム群のうち同一のクラスタに属するプログラムを示す情報である。プログラム群を複数のクラスタに分類するクラスタリングは、情報処理装置１０が行ってもよいし他の情報処理装置が行ってもよい。クラスタは、依存関係が密であるプログラムの集合である。クラスタリングでは、例えば、プログラム群を分析して、プログラム間の呼び出し関係や継承関係などの依存関係を表す依存関係グラフを生成し、依存関係グラフから依存関係が密である部分グラフをクラスタとして抽出する。プログラムの単位は、クラスや関数やファイルなど任意の単位でよい。記憶部１１は、ソースコードやオブジェクトコードなどプログラム自体を記憶してもよい。
【００１８】
処理部１２は、クラスタ情報１３が示す同一クラスタに属する複数のプログラムの間の依存関係を示すグラフ１４を取得する。グラフ１４は、同一クラスタに属する複数のプログラムに対応する複数のノード（節点）と、それら複数のプログラムの間の依存関係を表すようにノード間を接続する複数のエッジ（リンク）とを含む。グラフ１４は、エッジが依存方向を表している有向グラフであってもよい。処理部１２は、クラスタリング時に生成された依存関係グラフのうちクラスタに相当する部分をグラフ１４として流用してもよい。また、処理部１２は、クラスタ情報１３とプログラム自体から、同一クラスタに属するプログラムの間の依存関係を分析してグラフ１４を生成してもよい。
【００１９】
処理部１２は、グラフ１４の構造を分析して、グラフ１４に含まれる複数のノードの中から切断点ノード１４ａ（単に「切断点」と言うことがある）を選択する。切断点ノード１４ａは、グラフ１４からそれを除去した場合にグラフ１４が非連結な複数の部分グラフに分割されるようなノードである。図１の例では、グラフ１４から切断点ノード１４ａを除去すると、グラフ１４は、ノード数＝３の部分グラフとノード数＝１の部分グラフとノード数＝３の部分グラフの３つの部分グラフに分割されることになる。
【００２０】
グラフ１４の中に複数の候補が存在する場合、処理部１２は、１つの切断点ノードのみを選択してもよいし２以上の切断点ノードを選択してもよい。処理部１２は、選択する切断点ノードを所定の評価基準に従って絞り込んでもよい。例えば、処理部１２は、分割後の部分グラフの数が多くなるような切断点ノードを優先的に選択してもよい。また、処理部１２は、分割後の部分グラフ間のノード数の偏りが小さくなるような切断点ノードを優先的に選択してもよい。また、処理部１２は、異なる分類名が付与されたプログラムに対応するノードが混在している部分グラフが少なくなるような切断点ノードを優先的に選択してもよい。分類名は、パッケージ名やディレクトリ名などプログラム作成時に付与された分類の名称である。なお、プログラム作成時にユーザにより付与される分類と依存関係の分析によって判定されるクラスタとは、異なるグループ概念である。
【００２１】
処理部１２は、同一クラスタに属する複数のプログラムのうち、切断点ノード１４ａに対応するプログラムで使用される単語を抽出する。抽出する単語は、例えば、パッケージ名やクラス名やディレクトリ名やファイル名や関数名など、プログラムに記載されているプログラムの識別名称に含まれる単語である。処理部１２は、抽出した単語を用いて、クラスタに対応付ける付加情報１５を生成する。切断点ノード１４ａに対応するプログラムから２以上の単語を抽出可能である場合、何れか１つの単語を用いて付加情報１５を生成してもよいし２以上の単語を用いて付加情報１５を生成してもよい。
【００２２】
付加情報１５は、クラスタの特徴を示すラベルや説明文など、ソフトウェアの構造の可視化にあたってクラスタの意味の理解を促進する情報である。ラベルは１以上の単語を列挙した文字列であってもよい。例えば、処理部１２は、切断点ノード１４ａに対応するプログラムから抽出した単語を付加情報１５に挿入する。処理部１２は、他のプログラムから抽出した単語を付加情報１５に挿入してもよい一方で、切断点ノード１４ａに対応するプログラムから抽出した単語を優先的に付加情報１５に挿入することが好ましい。処理部１２は、ソフトウェア地図などプログラム群のクラスタリング結果を可視化した可視化データを表示するにあたり、クラスタを示す図形の近くに付加情報１５を表示してもよい。
【００２３】
第１の実施の形態の情報処理装置１０によれば、同一クラスタに属するプログラムを示すノードとプログラム間の依存関係を示すエッジとを含むグラフ１４が取得され、グラフ１４から切断点ノード１４ａが選択される。そして、切断点ノード１４ａに対応するプログラムで使用される単語が抽出され、抽出された単語を用いてクラスタに対応付ける付加情報１５が生成される。これにより、付加情報１５の精度を向上させることができる。
【００２４】
例えば、単純にクラスタにおける単語の出現頻度から付加情報１５に用いる単語を選択すると、付加情報がクラスタの特徴を適切に表さないことがある。これは、中心のプログラムが周辺の複数のプログラムと依存関係をもつというスター型構造のクラスタでは、中心のプログラムが重要な役割をもっているにもかかわらず、中心のプログラムのみに現れる単語は出現頻度が低いために選択されづらいためである。これに対し、第１の実施の形態では、切断点ノード１４ａに対応するプログラムで使用される単語が重視されることになり、クラスタの構造を反映した適切な付加情報１５が生成されるようになる。
【００２５】
［第２の実施の形態］
次に、第２の実施の形態を説明する。
第２の実施の形態の分析装置１００は、既存のアプリケーションソフトウェアのソースコードを分析し、アプリケーションソフトウェアの構造を可視化する。分析装置１００は、アプリケーションソフトウェアに含まれるプログラム群を複数のクラスタに分類し、クラスタリング結果を視覚的に表現したソフトウェア地図を生成する。また、分析装置１００は、各クラスタの特徴を説明した付加情報を生成してソフトウェア地図上に表示する。分析装置１００は、クライアントコンピュータでもよいしサーバコンピュータでもよい。
【００２６】
図２は、第２の実施の形態の分析装置のハードウェア例を示すブロック図である。
分析装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、媒体リーダ１０６および通信インタフェース１０７を有する。ＣＰＵ１０１は、第１の実施の形態の処理部１２に対応する。ＲＡＭ１０２またはＨＤＤ１０３は、第１の実施の形態の記憶部１１に対応する。
【００２７】
ＣＰＵ１０１は、プログラムの命令を実行するプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを含んでもよく、分析装置１００は複数のプロセッサを有してもよく、以下で説明する処理を複数のプロセッサまたはプロセッサコアを用いて並列に実行してもよい。また、複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００２８】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に用いるデータを一時的に記憶する揮発性の半導体メモリである。なお、分析装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数個のメモリを備えてもよい。
【００２９】
ＨＤＤ１０３は、ＯＳ（Operating System）やミドルウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性の記憶装置である。なお、分析装置１００は、フラッシュメモリやＳＳＤ（Solid State Drive）などの他の種類の記憶装置を備えてもよく、複数の不揮発性の記憶装置を備えてもよい。
【００３０】
画像信号処理部１０４は、ＣＰＵ１０１からの命令に従って、分析装置１００に接続されたディスプレイ１１１に画像を出力する。ディスプレイ１１１としては、ＣＲＴ（Cathode Ray Tube）ディスプレイ、液晶ディスプレイ（ＬＣＤ：Liquid Crystal Display）、プラズマディスプレイ、有機ＥＬ（ＯＥＬ：Organic Electro-Luminescence）ディスプレイなど、任意の種類のディスプレイを用いることができる。
【００３１】
入力信号処理部１０５は、分析装置１００に接続された入力デバイス１１２から入力信号を取得し、ＣＰＵ１０１に出力する。入力デバイス１１２としては、マウス・タッチパネル・タッチパッド・トラックボールなどのポインティングデバイス、キーボード、リモートコントローラ、ボタンスイッチなどを用いることができる。また、分析装置１００に、複数の種類の入力デバイスが接続されていてもよい。
【００３２】
媒体リーダ１０６は、記録媒体１１３に記録されたプログラムやデータを読み取る読み取り装置である。記録媒体１１３として、例えば、磁気ディスク、光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）、半導体メモリなどを使用できる。磁気ディスクには、フレキシブルディスク（ＦＤ：Flexible Disk）やＨＤＤが含まれる。光ディスクには、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）が含まれる。
【００３３】
媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータを、ＲＡＭ１０２やＨＤＤ１０３などの他の記録媒体にコピーする。読み取られたプログラムは、例えば、ＣＰＵ１０１によって実行される。なお、記録媒体１１３は可搬型記録媒体であってもよく、プログラムやデータの配布に用いられることがある。また、記録媒体１１３やＨＤＤ１０３を、コンピュータ読み取り可能な記録媒体と言うことがある。
【００３４】
通信インタフェース１０７は、ネットワーク１１４を介して他の情報処理装置と通信を行うインタフェースである。通信インタフェース１０７は、スイッチやルータなどの有線通信装置に接続される有線通信インタフェースでもよいし、基地局やアクセスポイントなどの無線通信装置に接続される無線通信インタフェースでもよい。
【００３５】
図３は、分析装置の機能例を示すブロック図である。
分析装置１００は、ソースコード記憶部１２１、クラスタ情報記憶部１２２、中間情報記憶部１２３、付加情報記憶部１２４、クラスタリング部１２５、付加情報生成部１２６およびソフトウェア地図表示部１２７を有する。ソースコード記憶部１２１、クラスタ情報記憶部１２２、中間情報記憶部１２３および付加情報記憶部１２４は、例えば、ＲＡＭ１０２またはＨＤＤ１０３の記憶領域を用いて実装される。クラスタリング部１２５、付加情報生成部１２６およびソフトウェア地図表示部１２７は、例えば、ＣＰＵ１０１が実行するプログラムモジュールを用いて実装される。
【００３６】
ソースコード記憶部１２１は、分析対象のアプリケーションソフトウェアのソースコード群を記憶する。ソースコードは、理解容易な高級言語を用いて記載されたプログラムである。ソースコードは、例えば、アプリケーションソフトウェアの所有者や運用者などの分析依頼者から提供される。第２の実施の形態では、一纏まりの処理単位のソースコードを１つの「プログラム」として取り扱う。ソースコードの単位としては、クラスやメソッドや関数などが挙げられる。以下では主に、オブジェクト指向言語を用いてソースコードが記述されており、ソースコードの単位をクラスとする場合を想定する。
【００３７】
クラスタ情報記憶部１２２は、プログラムを複数のクラスタに分類するクラスタリングの結果を示すクラスタ情報を記憶する。クラスタ情報は、クラスタを識別するクラスタＩＤとプログラムを識別するクラス名とを対応付けた情報である。なお、クラスの集合はアプリケーションソフトウェアの開発時に階層構造のパッケージに分類されており、クラス名にはそのクラスが属するパッケージを示すパッケージ名が含まれる。
【００３８】
中間情報記憶部１２３は、クラスタに付与する付加情報を生成する過程で内部的に使用する中間情報を記憶する。付加情報は、クラスタの特徴の理解を促進するためにプログラムを分析して自動的に生成される情報であり、ラベルと説明文が含まれる。中間情報は、後述するように、プログラムから抽出した単語や単語の重みなどの情報を含む。
【００３９】
付加情報記憶部１２４は、各クラスタに付与されるラベルおよび説明文を含む付加情報を記憶する。ラベルは、クラスタの特徴を表す単語である特徴語を所定数（例えば、３個）連結した文字列である。説明文は、クラスタの構造、すなわち、同じクラスタに属する複数のプログラムの間の関係を説明した短い文章である。
【００４０】
クラスタリング部１２５は、ソースコード記憶部１２１に記憶されたプログラムをクラスタに分類するクラスタリングを行い、クラスタリング結果を示すクラスタ情報を生成してクラスタ情報記憶部１２２に格納する。クラスタリングでは、クラスタリング部１２５は、呼び出し関係や継承関係などのプログラム間の依存関係を示す依存関係グラフを生成する。依存関係グラフは、プログラムに対応するノードと、プログラム間の依存関係に従ってノード間を接続するエッジとを含む。エッジは依存関係の方向も表しており、依存関係グラフは有向グラフとなる。クラスタリング部１２５は、同一クラスタに属するノード間にはエッジが多くなり、異なるクラスタに属するノード間にはエッジが少なくなるように、依存関係グラフに含まれるノードをクラスタに分類する。
【００４１】
付加情報生成部１２６は、クラスタ情報記憶部１２２に記憶されたクラスタ情報を参照して、複数のクラスタそれぞれに対応付ける付加情報を生成して付加情報記憶部１２４に格納する。付加情報にはラベルと説明文が含まれる。付加情報を生成する過程で、付加情報生成部１２６は、中間情報を適宜生成して中間情報記憶部１２３に格納する。
【００４２】
後述するように、付加情報生成部１２６は、クラスタに属するプログラムのクラス名から単語を抽出し、出現頻度に基づいてクラスタ毎に特徴語を選択し、選択した特徴語を用いて付加情報を生成する。単語は、クラス名のうちパッケージ名の部分からも抽出され得る。ただし、付加情報生成部１２６は、単純に単語の出現頻度に基づいて特徴語を選択するのではなく、クラスタ内のプログラムの依存関係の構造も考慮して特徴語を選択する。
【００４３】
特徴語の選択にあたり、付加情報生成部１２６は、クラスタ毎に依存関係グラフを取得し、その依存関係グラフの中で複数の異なる部分を連結している切断点を選択する。切断点は、グラフから当該ノードを除去すると当該グラフが非連結な複数の部分グラフに分割されるようなノードである。付加情報生成部１２６は、クラスタリング部１２５が生成した全体の依存関係グラフを流用してクラスタ毎の依存関係グラフを取得してもよい。また、付加情報生成部１２６は、ソースコード記憶部１２１に記憶されたプログラムを分析してクラスタ毎の依存関係グラフを生成してもよい。付加情報生成部１２６は、切断点に対応するプログラムから抽出される単語を他の単語よりも重視する。また、付加情報生成部１２６は、切断点の周辺にある複数の部分グラフから共通に抽出される共通単語を他の単語よりも重視する。これにより、クラスタ構造を反映した付加情報が生成される。
【００４４】
ソフトウェア地図表示部１２７は、クラスタ情報記憶部１２２に記憶されたクラスタ情報を用いて、プログラムのクラスタリング結果を可視化したソフトウェア地図を生成する。ソフトウェア地図は、クラスタを区画に対応させ、クラスタに属するプログラムを区画内に設置された建物に対応させた、二次元または三次元の地図形式画像である。ソフトウェア地図表示部１２７は、生成したソフトウェア地図をディスプレイ１１１に表示させる。また、ソフトウェア地図表示部１２７は、付加情報記憶部１２４に記憶された付加情報を、ソフトウェア地図の区画に重ねて表示させる。このとき、ソフトウェア地図表示部１２７は、付加情報に含まれるラベルと説明文の両方を表示させてもよいし、ユーザ操作に応じて何れか一方のみを表示させてもよい。
【００４５】
次に、プログラムのクラスタリングについて説明する。
図４は、ソースコードの例を示す図である。
ソースコード１３１ａ，１３１ｂは、ソースコード記憶部１２１に記憶されたソースコードの一例である。ソースコード１３１ａ，１３１ｂは、オブジェクト指向言語によって記載されている。ソースコード１３１ａ，１３１ｂは、それぞれ１つのクラスを含む。
【００４６】
ソースコード１３１ａには、クラスＣ０２が記載されている。クラスＣ０２は、他のクラスから呼び出し可能なメソッド「ｐｒｏｃｅｓｓ」を含む。メソッド「ｐｒｏｃｅｓｓ」は、クラスＣ０５のメソッド「ｃｏｌｌｅｃｔＯｒｄｅｒ」と、クラスＣ０９のメソッド「ｃｏｌｌｅｃｔＢａｃｋｌｏｇ」と、クラスＣ１４のメソッド「ｉｓｓｕｅ」と、クラスＣ０１のメソッド「ｌｏｇ」を呼び出す。ソースコード１３１ｂには、クラスＣ０５が記載されている。クラスＣ０５は、他のクラスから呼び出し可能なメソッド「ｃｏｌｌｅｃｔＯｒｄｅｒ」を含む。メソッド「ｃｏｌｌｅｃｔＯｒｄｅｒ」は、クラスＣ０１のメソッド「ｌｏｇ」を呼び出す。このクラスＣ０２，Ｃ０５がそれぞれ１つのプログラムとして扱われる。クラスタリング部１２５は、ソースコード１３１ａ，１３１ｂを分析し、クラスＣ０２からクラスＣ０５への呼び出し関係を検出する。
【００４７】
図５は、全体の依存関係グラフの例を示す図である。
ここでは、ソースコードにクラスＣ０１〜Ｃ１６の１６個のクラスが記載されている場合を考える。依存関係グラフ１３２は、クラスＣ０１〜Ｃ１６の間の呼び出し関係を示す有向グラフである。依存関係グラフ１３２は、クラスＣ０１〜Ｃ１６に対応する複数のノードと、クラスＣ０１〜Ｃ１６の間の呼び出し関係を示す複数のエッジとを含む。矢印の元（ソース）は呼び出し元を表し、矢印の先（ターゲット）は呼び出し先を表す。例えば、クラスＣ０２は、クラスＣ０１，Ｃ０５，Ｃ０９，Ｃ１４を呼び出している。
【００４８】
依存関係グラフ１３２のエッジには重みが付与される。あるクラスを呼び出し先とするエッジそれぞれの重みは、当該クラスを呼び出し先とするエッジの数に反比例する。あるクラスを呼び出し先とするエッジがＫ個存在する場合、それらＫ個（Ｋは１以上の整数）のエッジそれぞれに対し１／Ｋの重みが付与される。例えば、クラスＣ０５を呼び出し先とするエッジが６個存在するため、それら６個のエッジの重みは１／６と算出される。
【００４９】
図６は、依存関係グラフに対応する隣接行列の例を示す図である。
クラスタリング部１２５は、ソースコードを分析することで隣接行列１３３（隣接行列Ｘ）を生成する。隣接行列１３３の行は呼び出し元のプログラム（クラス）に相当し、列は呼び出し先のプログラム（クラス）に相当する。隣接行列１３３は、図５の依存関係グラフ１３２に対応している。クラスＣ０１〜Ｃ１６に相当する１６個のプログラムが存在するため、隣接行列１３３は１６行１６列の正方行列である。
【００５０】
隣接行列１３３のｉ行ｊ列の要素（要素Ｘij）は、ｉ番目のプログラムからｊ番目のプログラムへの呼び出し関係を示す。要素Ｘijは０以上１以下の有理数である。要素Ｘij＝０であることは、ｉ番目のプログラムからｊ番目のプログラムに対して呼び出し関係が存在しないことを示す。要素Ｘij＝１／Ｋであることは、ｉ番目のプログラムからｊ番目のプログラムに対して重み１／Ｋの呼び出し関係が存在することを示す。例えば、隣接行列１３３の２行５列の要素は１／６である。これは、２番目のプログラムから５番目のプログラムに対して重み１／６の呼び出し関係が存在することを示している。
【００５１】
図７は、プログラムのクラスタリング例を示す図である。
クラスタリング部１２５は、隣接行列１３３を用いてプログラム（クラス）を複数のクラスタに分類する。１つのクラスタは１以上のプログラムを含む。原則として、呼び出し関係が密なプログラムの集合は同じクラスタに分類され、呼び出し関係が疎なプログラム同士は異なるクラスタに分類される。
【００５２】
一例として、クラスタ１３４ａ，１３４ｂ，１３４ｃ（クラスタＧ１〜Ｇ３）が生成される。クラスタ１３４ａは、クラスＣ０２，Ｃ０５，Ｃ０６，Ｃ１１，Ｃ１４に相当する５個のプログラムを含む。クラスタ１３４ｂは、クラスＣ０１，Ｃ０７，Ｃ０９，Ｃ１０，Ｃ１５，Ｃ１６に相当する６個のプログラムを含む。クラスタ１３４ｃは、クラスＣ０３，Ｃ０４，Ｃ０８，Ｃ１２，Ｃ１３に相当する５個のプログラムを含む。
【００５３】
プログラムを複数のクラスタに分類するにあたり、数式（１）に示すモジュラリティ評価値Ｑが用いられる。モジュラリティ評価値Ｑは、−１以上１以下の有理数である。モジュラリティ評価値Ｑが大きいほど良いクラスタリングであることを示し、モジュラリティ評価値Ｑが小さいほど悪いクラスタリングであることを示す。
【００５４】
【数１】
2019021232.tif 000003
【００５５】
数式（１）において、ｍは隣接行列１３３の全要素を合計した値である。ｋioutは、隣接行列１３３のｉ行目の要素を合計した値、すなわち、ｉ番目のプログラムを呼び出し元とするエッジの重みの合計である。ｋjinは、隣接行列１３３のｊ列目の要素を合計した値、すなわち、ｊ番目のプログラムを呼び出し先とするエッジの重みの合計である。ｇiはｉ番目のプログラムが属するクラスタを示し、ｇjはｊ番目のプログラムが属するクラスタを示す。δ（ｇi，ｇj）は、クロネッカーのデルタ関数である。ｇiとｇjが同じ場合はδ（ｇi，ｇj）＝１であり、ｇiとｇjが異なる場合はδ（ｇi，ｇj）＝０である。δ（ｇi，ｇj）は、同じクラスタ内の呼び出し関係をモジュラリティ評価値Ｑに反映させ、異なるクラスタ間の呼び出し関係を無視するものである。
【００５６】
クラスタリング部１２５は、モジュラリティ評価値Ｑが最大になるように、プログラムをクラスタに分類する。クラスタリングの手順の詳細は後述する。このようにしてクラスタリングが行われ、各プログラムが属するクラスタが決定される。
【００５７】
次に、分析装置１００が生成するソフトウェア地図について説明する。
図８は、ソフトウェア地図の例を示す図である。
ソフトウェア地図表示部１２７は、上記のクラスタリングによって生成されるクラスタ情報と後述する付加情報とを用いてソフトウェア地図を生成する。ソフトウェア地図１３５は、ソフトウェア地図表示部１２７が生成するソフトウェア地図の一例である。
【００５８】
ソフトウェア地図１３５は、７個のクラスタに対応する区画１３５ａ，１３５ｂ，１３５ｃ，１３５ｄ，１３５ｅ，１３５ｆ，１３５ｇを含む。また、ソフトウェア地図１３５は、５１個のプログラムに対応する５１個の建物相当のブロックを含む。区画１３５ａは９個のブロックを含む。区画１３５ｂは９個のブロックを含む。区画１３５ｃは１２個のブロックを含む。区画１３５ｄは５個のブロックを含む。区画１３５ｅは７個のブロックを含む。区画１３５ｆは４個のブロックを含む。区画１３５ｇは５個のブロックを含む。ソフトウェア地図１３５はブロックを二次元で表しているが、三次元で表してもよい。
【００５９】
ソフトウェア地図１３５は更に、クラスタに付与されたラベルを区画に重ねて表示する。ここではラベルは、クラスタから抽出された３個の特徴語を連結した文字列である。区画１３５ａには「ｆｒａｍｅ；ｍｅｎｕ；ｂａｒ」が重畳表示される。区画１３５ｂには「ａｃｔｉｏｎ；ｌｉｓｔｅｎｅｒ；ｄｉａｌｏｇ」が重畳表示される。区画１３５ｃには「ｕｔｉｌ；ｏｕｔｐｕｔ；ｇｅｎｅｒａｔｉｏｎ」が重畳表示される。区画１３５ｄには「ｔｙｐｉｃａｌ；ｒｏｕｔｅ；ｍｏｄｅｌ」が重畳表示される。区画１３５ｅには「ｈｉｄｅ；ｔｒａｎｓｉｔｉｏｎ；ｂｕｓｉｎｅｓｓ」が重畳表示される。区画１３５ｆには「ｉｎｄｉｖｉｄｕａｌ；ｒｏｕｔｅ；ｐａｎｅｌ」が重畳表示される。区画１３５ｇには「ｒｏｕｔｅ；ｉｎｓｔａｎｃｅ；ｏｕｔｐｕｔ」が重畳表示される。
【００６０】
このように、クラスタを区画として表現しプログラムを建物として表現することで、アプリケーションソフトウェアの全体構造をわかりやすく可視化することができる。また、ソフトウェア地図１３５に各クラスタのラベルを表示することで、クラスタに属するプログラムの用途や機能を理解することが容易となる。なお、ソフトウェア地図１３５では各クラスタのラベルを表示しているが、ラベルに代えてまたはラベルと共に説明文を表示してもよい。また、ユーザ操作に応じて、一部または全部のクラスタのラベルのＯＮ／ＯＦＦを切り替えるようにしてもよく、ユーザ操作に応じて、一部または全部のクラスタの説明文のＯＮ／ＯＦＦを切り替えるようにしてもよい。
【００６１】
次に、付加情報の生成について説明する。
図９は、クラスタ内の依存関係グラフの例を示す図である。
依存関係グラフ１４１は、１つのクラスタの中のプログラム間の依存関係を示す。付加情報生成部１２６は、クラスタリング時に生成された全体の依存関係グラフから特定のクラスタの部分を抽出することで依存関係グラフ１４１を取得してもよい。また、付加情報生成部１２６は、クラスタリング部１２５と同様にプログラム間の呼び出し関係を分析することでクラスタ毎の依存関係グラフを生成してもよい。
【００６２】
依存関係グラフ１４１は、ノード１４１ａ，１４１ｂ，１４１ｃ，１４１ｄ，１４１ｅ，１４１ｆ，１４１ｇ，１４１ｈ，１４１ｉを含む。このクラスタは、メニューバーを介して複数のフレームが繋がっているＧＵＩ（Graphical User Interface）のプログラム群を想定している。ノード１４１ａはクラス名が「ＭｅｎｕＢａｒ」のクラスに対応する。ノード１４１ｂはクラス名が「ｍｅｒｇｅ．ＭｅｒｇｅＮｏｄｅＦｒａｍｅ」のクラスに対応する。ノード１４１ｃはクラス名が「ｍｅｒｇｅ．ＭｅｒｇｅＰｒｏｃｅｓｓＦｒａｍｅ」のクラスに対応する。ノード１４１ｄはクラス名が「ｃｏｍｐａｒｅ．ＣｏｍｐａｒｉｎｇＣｏｎｄｉｔｉｏｎＦｒａｍｅ」のクラスに対応する。ノード１４１ｅはクラス名が「ｃｏｍｐａｒｅ．ＣｏｍｐａｒｉｎｇＦｒａｍｅ」のクラスに対応する。
【００６３】
ノード１４１ｆはクラス名が「ｃｏｎｃｕｒｒｅｎｔ．ＣｏｎｃｕｒｒｅｎｔＥｖｅｎｔＦｒａｍｅ」のクラスに対応する。ノード１４１ｇはクラス名が「ＰｒｏｐｅｒｔｙＣｏｎｄｉｔｉｏｎＦｒａｍｅ」のクラスに対応する。ノード１４１ｈはクラス名が「ＥｖｅｎｔＳｏｒｔｅｄＦｒａｍｅ」のクラスに対応する。ノード１４１ｉはクラス名が「ＯｕｔＳｔａｔｉｓｔｉｃａｌＣｓｖＬｉｓｔｅｎｅｒ」のクラスに対応する。なお、クラス名のうちドットの前までの文字列はパッケージ名である。
【００６４】
依存関係グラフ１４１は、ノード１４１ａからノード１４１ｂ，１４１ｄ，１４１ｆ，１４１ｇ，１４１ｈ，１４１ｉへのエッジと、ノード１４１ｃ，１４１ｅからノード１４１ａへのエッジを含む。また、依存関係グラフ１４１は、ノード１４１ｂからノード１４１ｃへのエッジと、ノード１４１ｄからノード１４１ｅへのエッジを含む。
【００６５】
図１０は、クラスタテーブルの例を示す図である。
クラスタテーブル１４２は、クラスタ情報記憶部１２２に記憶される。クラスタテーブル１４２は、クラス名およびクラスタＩＤの項目を含む。クラス名の項目には、ソースコードに記載されたクラス名であって、パッケージ名を含むフルパスのクラス名が登録される。クラスタＩＤの項目には、クラス名が示すプログラムの属するクラスタを識別する識別子が登録される。クラスタＩＤは、クラスタリングの際にクラスタリング部１２５が各クラスタに対して割り当てる識別子であり、クラスタ間で重複しなければよい。
【００６６】
クラスタテーブル１４２には、複数のクラスタの情報が登録され得る。例えば、図９に示した９個のクラス名がクラスタテーブル１４２に登録され、それら９個のクラス名に対応付けて同一のクラスタＩＤがクラスタテーブル１４２に登録される。
【００６７】
図１１は、切断点テーブルと部分グラフテーブルの例を示す図である。
切断点テーブル１４３は、中間情報記憶部１２３に記憶される。切断点テーブル１４３は、クラスタＩＤ、切断点、部分グラフＩＤおよび共通単語の項目を含む。
【００６８】
クラスタＩＤの項目には、クラスタを識別する識別子が登録される。切断点の項目には、選択した切断点に対応するプログラムのクラス名が登録される。切断点は、各クラスタの依存関係グラフに含まれるノードのうち、当該ノードを除去すると当該依存関係グラフが非連結な複数の部分グラフに分割されるようなノードである。通常、１つのクラスタの依存関係グラフには、上記の切断点の定義を満たすノードが複数存在する。付加情報生成部１２６は、できる限り中心に位置する切断点が選択されるように、後述するように複数の切断点それぞれについて評価値を算出し、評価値が最大の切断点を選択する。
【００６９】
ただし、付加情報生成部１２６は、依存関係グラフから２以上の切断点を選択してもよい。例えば、付加情報生成部１２６は、評価値が閾値を超える切断点を全て選択してもよいし、評価値が高い方から所定個の切断点を選択してもよい。一例として、図９の依存関係グラフ１４１ではノード１４１ａが切断点として選択される。
【００７０】
部分グラフＩＤの項目には、クラスタの依存関係グラフから切断点を除去することで生成される複数の部分グラフを識別する識別子が列挙される。図９の依存関係グラフ１４１は、ノード１４１ａを除去すると６個の部分グラフに分割される。部分グラフｓｇ１はノード１４１ｂ，１４１ｃを含む。部分グラフｓｇ２はノード１４１ｄ，１４１ｅを含む。部分グラフｓｇ３はノード１４１ｇを含む。部分グラフｓｇ４はノード１４１ｈを含む。部分グラフｓｇ５はノード１４１ｉを含む。部分グラフｓｇ６はノード１４１ｆを含む。
【００７１】
共通単語の項目には、複数の部分グラフのうち多くの部分グラフのクラス名に共通に現れる共通単語が登録される。共通単語は、例えば、複数の部分グラフのうち過半数の部分グラフのクラス名に共通に現れる単語とする。図９の依存関係グラフ１４１の場合、５／６＝８３％に相当する部分グラフｓｇ１，ｓｇ２，ｓｇ３，ｓｇ４，ｓｇ６に単語「ｆｒａｍｅ」が現れるため、「ｆｒａｍｅ」が共通単語である。なお、共通単語が存在しない場合もある。切断点テーブル１４３には、複数のクラスタの情報が登録され得る。
【００７２】
部分グラフテーブル１４４は、中間情報記憶部１２３に記憶される。部分グラフテーブル１４４は、部分グラフＩＤ、ノードおよび関連方向の項目を含む。部分グラフＩＤの項目には、部分グラフを識別する識別子が登録される。ノードの項目には、部分グラフに属する１以上のノードに対応する１以上のプログラムのクラス名が列挙される。
【００７３】
関連方向の項目には、切断点と部分グラフとの間の依存関係の方向が登録される。部分グラフに属するノードから切断点へのエッジが存在し、その逆方向のエッジが存在しない場合、関連方向は「ｕｓｅ」になる。これは、部分グラフに対応するプログラム群が切断点に対応するプログラムを使用していることを示す。切断点から部分グラフに属するノードへのエッジが存在し、その逆方向のエッジが存在しない場合、関連方向は「ｕｓｅｄ」になる。これは、部分グラフに対応するプログラム群が切断点に対応するプログラムから使用されていることを示す。部分グラフに属するノードから切断点へのエッジが存在し、かつ、切断点から部分グラフに属するノードへのエッジが存在する場合、関連方向は「ｍｕｔｕａｌ」になる。これは、関連方向を一方向に特定できないことを示す。部分グラフテーブル１４４には、複数のクラスタの情報が登録され得る。
【００７４】
図１２は、単語重みテーブルの例を示す図である。
単語重みテーブル１４５は、中間情報記憶部１２３に記憶される。単語重みテーブル１４５は、クラスタＩＤ、単語および重みの項目を含む。クラスタＩＤの項目には、クラスタを識別する識別子が登録される。単語の項目には、クラスタに属するプログラムのクラス名から抽出される単語が登録される。重みの項目には、単語の重みを示す数値が登録される。単語重みテーブル１４５には、重みが１．０でない単語が登録され、重みが１．０である単語は省略される。前者はクラス名から抽出される単語のうち所定の条件を満たす単語であり、後者はそれ以外の全ての単語である。
【００７５】
付加情報生成部１２６は、各クラスタについて、切断点に対応するプログラムのクラス名に含まれる単語の重みを大きく設定する。例えば、付加情報生成部１２６は、切断点の単語の重みを５．０に設定する。図９の依存関係グラフ１４１の場合、単語「ｍｅｎｕ」と「ｂａｒ」の重みが大きくなる。また、付加情報生成部１２６は、各クラスタについて共通単語の重みを大きく設定する。ただし、共通単語の重みは切断点の重みより小さいことが好ましい。例えば、付加情報生成部１２６は、共通単語の重みを２．０に設定する。図９の依存関係グラフ１４１の場合、単語「ｆｒａｍｅ」の重みが大きくなる。
【００７６】
なお、ある単語が切断点の単語でありかつ共通単語である場合、付加情報生成部１２６は、その単語に対して大きい方の重み（例えば、５．０と２．０のうちの５．０）のみを設定する。同じ単語に対してクラスタによって異なる重みが付与されることもある。単語重みテーブル１４５には、複数のクラスタの情報が登録され得る。
【００７７】
図１３は、クラスタ単語テーブルの例を示す図である。
クラスタ単語テーブル１４６は、中間情報記憶部１２３に記憶される。クラスタ単語テーブル１４６は、クラスタＩＤおよび単語の項目を含む。クラスタＩＤの項目には、クラスタを識別する識別子が登録される。単語の項目には、クラスタに属するプログラムのクラス名から抽出された１以上の単語が列挙される。ここでは重複する単語もそのまま列挙される。付加情報生成部１２６は、単語辞書を用いてクラス名から単語を抽出してもよい。クラス名の中のドットを区切り文字として認識してもよい。また、クラス名にアルファベットの大文字が含まれる場合、大文字を単語の先頭と認識してもよい。クラスタ単語テーブル１４６には、複数のクラスタの情報が登録され得る。
【００７８】
図１４は、単語スコアテーブルの例を示す図である。
単語スコアテーブル１４７は、中間情報記憶部１２３に記憶される。単語スコアテーブル１４７は、クラスタＩＤ、単語およびスコアの項目を含む。クラスタＩＤの項目には、クラスタを識別する識別子が登録される。単語の項目には、クラスタに属するプログラムのクラス名から抽出された単語が登録される。スコアの項目には、単語重みテーブル１４５およびクラスタ単語テーブル１４６から算出された単語スコアが登録される。
【００７９】
単語スコアは、重み付きの単語出現回数を示す。付加情報生成部１２６は、クラスタ単語テーブル１４６に列挙された単語を集計して、クラスタ毎に各単語の出現回数をカウントする。単語重みテーブル１４５に重みが登録されていないクラスタと単語の組については、重みが１．０とみなされるため、カウントした出現回数が単語スコアとなる。一方、単語重みテーブル１４５に重みが登録されているクラスタと単語の組については、カウントした出現回数に重みを乗じた値が単語スコアとなる。
【００８０】
例えば、図９の依存関係グラフ１４１の場合、単語「ｆｒａｍｅ」は出現回数が７回で重みが２．０であるため、単語スコアは１４と算出される。また、単語「ｍｅｎｕ」は出現回数が１回で重みが５．０であるため、単語スコアは５と算出される。また、単語「ｂａｒ」も出現回数が１回で重みが５．０であるため、単語スコアは５と算出される。単語スコアテーブル１４７には、複数のクラスタの情報が登録され得る。
【００８１】
図１５は、付加情報テーブルの例を示す図である。
付加情報テーブル１４８は、付加情報記憶部１２４に記憶される。付加情報テーブル１４８は、クラスタＩＤ、ラベルおよび説明文の項目を含む。クラスタＩＤの項目には、クラスタを識別する識別子が登録される。ラベルの項目には、クラスタに付与されるラベルが登録される。説明文の項目には、クラスタに付与される説明文が登録される。
【００８２】
付加情報生成部１２６は、単語スコアテーブル１４７に基づいて、クラスタ毎に各単語のｔｆ−ｉｄｆ値を算出し、ｔｆ−ｉｄｆ値が高い方から所定数（例えば、３個）の単語をクラスタの特徴語として選択する。付加情報生成部１２６は、選択した特徴語を連結した文字列をラベルとして生成して付加情報テーブル１４８に登録する。
【００８３】
ｔｆ−ｉｄｆ値は、ｔｆ値とｉｄｆ値の積である。ｔｆ値としては、例えば、単語スコアテーブル１４７に登録された単語スコアが用いられる。ｉｄｆ値としては、例えば、その単語を含むクラスタの割合の逆数、すなわち、＜クラスタ総数＞÷＜単語を含むクラスタの数＞が用いられる。クラスタ総数は、クラスタリングによって生成されたクラスタの数である。その単語を含むクラスタの数は、クラスタ単語テーブル１４６や単語スコアテーブル１４７を参照して算出することができる。その単語の出現回数や重みが大きいほど、ｔｆ値が大きくなりｔｆ−ｉｄｆ値が大きくなる。また、その単語を含むクラスタが少ないほど、ｉｄｆ値が大きくなりｔｆ−ｉｄｆ値が大きくなる。
【００８４】
また、付加情報生成部１２６は、切断点テーブル１４３や部分グラフテーブル１４４に基づいて、クラスタ毎に説明文を生成して付加情報テーブル１４８に登録する。説明文は、クラスタの構造を端的に表した短文である。説明文は、「＜ｎ＞が＜ｍ＞を用いる」、「＜ｍ＞が＜ｎ＞を用いる」および「＜ｍ＞が＜ｎ＞と互いに関係する」の何れかのフォーマットに従って記載される。説明語句ｎは、切断点テーブル１４３に登録された切断点のクラス名である。説明語句ｍは、切断点テーブル１４３に登録された共通単語である。ただし、共通単語が存在しない場合、付加情報生成部１２６は、複数の部分グラフから１つずつ特徴語を抽出し、抽出した特徴語を連結した文字列を説明語句ｍとして使用する。
【００８５】
切断点と複数の部分グラフとの間の関連方向が「ｕｓｅｄ」のみかまたは「ｕｓｅｄ」と「ｍｕｔｕａｌ」の混合である場合、上記の１番目のフォーマットが使用される。切断点と複数の部分グラフとの間の関連方向が「ｕｓｅ」のみかまたは「ｕｓｅ」と「ｍｕｔｕａｌ」の混合である場合、上記の２番目のフォーマットが使用される。それ以外の場合、上記の３番目のフォーマットが使用される。図９の依存関係グラフ１４１の場合、「ＭｅｎｕＢａｒがｆｒａｍｅを用いる」という説明文が生成される。付加情報テーブル１４８には、複数のクラスタの情報が登録され得る。
【００８６】
次に、切断点の評価値の算出について説明する。
依存関係グラフの中に複数の切断点が存在する場合、付加情報生成部１２６は、切断点毎に評価値を算出して評価値が最大の切断点を選択する。切断点は部分グラフ数Ａとノード数均一度Ｂと部分グラフ異質度Ｃの３つの観点から評価され、これら３つの指標値を重み付けして切断点の評価値が算出される。切断点の評価値は、αＡ＋βＢ＋γＣと算出される。α，β，γは予め設定される正の数の重みであり、α＝β＝γ＝１でもよい。
【００８７】
図１６は、切断点の評価値の算出例を示す第１の図である。
ここでは、切断点を部分グラフ数Ａの観点から評価する例を説明する。部分グラフ数Ａは、ある切断点を選択することで生成される部分グラフの数である。部分グラフ数Ａが大きいほど切断点の評価値が高くなる。依存関係グラフ１５１は、ノード１５１ａ，１５１ｂを含む７個のノードをもつ。ノード１５１ａ，１５１ｂは共に切断点である。ノード１５１ａを選択した場合、部分グラフ数Ａ＝２となる。一方、ノード１５１ｂを選択した場合、部分グラフ数Ａ＝４となる。よって、部分グラフ数Ａの観点からは、ノード１５１ａよりもノード１５１ｂの方が好ましいことになる。
【００８８】
図１７は、切断点の評価値の算出例を示す第２の図である。
ここでは、切断点をノード数均一度Ｂの観点から評価する例を説明する。ノード数均一度Ｂは、ある切断点を選択することで生成される複数の部分グラフの間のノード数の偏りを示す指標である。ノード数の偏りが小さいほど、ノード数均一度Ｂが大きくなり切断点の評価値が高くなる。ノード数均一度Ｂは、＜クラスタの依存関係グラフのノード数＞−（＜最大の部分グラフのノード数＞−＜最小の部分グラフのノード数＞）と算出される。
【００８９】
依存関係グラフ１５２は、ノード１５２ａ，１５２ｂを含む９個のノードをもつ。ノード１５２ａ，１５２ｂは共に切断点である。ノード１５２ａを選択した場合、依存関係グラフ１５２はノード数が３個と２個と３個の部分グラフに分割され、ノード数均一度Ｂ＝９−（３−２）＝８と算出される。一方、ノード１５２ｂを選択した場合、依存関係グラフ１５２はノード数が６個と１個と１個の部分グラフに分割され、ノード数均一度Ｂ＝９−（６−１）＝４と算出される。よって、ノード数均一度Ｂの観点からは、ノード１５２ｂよりもノード１５２ａの方が好ましいことになる。なお、部分グラフ数Ａの観点からは、ノード１５２ａとノード１５２ｂの価値は等価である。
【００９０】
図１８は、切断点の評価値の算出例を示す第３の図である。
ここでは、切断点を部分グラフ異質度Ｃの観点から評価する例を説明する。部分グラフ異質度Ｃは、ある切断点を選択することで生成される個々の部分グラフの中に、異なるパッケージ名が付されたノードが混在していない程度を示す指標である。異なるパッケージ名のノードが混在していない部分グラフが多いほど、部分グラフ異質度Ｃが大きくなり切断点の評価値が高くなる。部分グラフ異質度Ｃは、クラスタに現れるパッケージ名のうち、少なくとも１つの部分グラフを占有しているパッケージ名の数である。
【００９１】
依存関係グラフ１５３は、ノード１５３ａ，１５３ｂを含む１２個のノードをもつ。ノード１５３ａ，１５３ｂは共に切断点である。ノード１５３ａを選択した場合、依存関係グラフ１５３は、パッケージ名ｐ１のみ含む部分グラフと、パッケージ名ｐ２のみ含む部分グラフと、パッケージ名ｐ３のみ含む部分グラフに分割される。よって、部分グラフ異質度Ｃ＝３となる。一方、ノード１５３ｂを選択した場合、依存関係グラフ１５３は、パッケージ名ｐ１，ｐ２が混在した部分グラフと、パッケージ名ｐ３のみ含む部分グラフと、パッケージ名ｐ３のみ含む部分グラフに分割される。よって、部分グラフ異質度Ｃ＝１となる。よって、部分グラフ異質度Ｃの観点からは、ノード１５３ｂよりもノード１５３ａの方が好ましいことになる。なお、部分グラフ数Ａやノード数均一度Ｂの観点からは、ノード１５３ａとノード１５３ｂの価値は等価である。
【００９２】
次に、分析装置１００の処理手順について説明する。
図１９は、ソフトウェア可視化の手順例を示すフローチャートである。
（Ｓ１０）クラスタリング部１２５は、ソースコード記憶部１２１に記憶されたプログラム群を複数のクラスタに分類するクラスタリングを行う。クラスタリング部１２５は、クラスタリング結果を示すクラスタテーブル１４２を生成してクラスタ情報記憶部１２２に格納する。クラスタリングの手順については後述する。
【００９３】
（Ｓ１１）付加情報生成部１２６は、クラスタテーブル１４２を参照してクラスタ毎に切断点を選択し、切断点テーブル１４３および部分グラフテーブル１４４を生成する。付加情報生成部１２６は、切断点テーブル１４３を参照してクラスタ毎に単語の重みを決定し、単語重みテーブル１４５を生成する。また、付加情報生成部１２６は、クラスタ毎にプログラムのクラス名から単語を抽出してクラスタ単語テーブル１４６を生成する。そして、付加情報生成部１２６は、単語重みテーブル１４５およびクラスタ単語テーブル１４６を参照してクラスタ毎に各単語の単語スコアを算出し、単語スコアテーブル１４７を生成する。単語スコア算出の手順については後述する。
【００９４】
（Ｓ１２）付加情報生成部１２６は、クラスタ単語テーブル１４６または単語スコアテーブル１４７を参照して、単語毎に当該単語が出現するクラスタの割合の逆数をｉｄｆ値として算出する。また、付加情報生成部１２６は、単語スコアテーブル１４７に登録された単語スコアをｔｆ値として使用する。そして、付加情報生成部１２６は、クラスタ毎に各単語のｔｆ値とｉｄｆ値を乗じてｔｆ−ｉｄｆ値を算出する。
【００９５】
（Ｓ１３）付加情報生成部１２６は、クラスタ毎に単語をｔｆ−ｉｄｆ値の高い順にソートし、ｔｆ−ｉｄｆ値の高い方から３つの単語を特徴語として選択する。付加情報生成部１２６は、クラスタ毎に３つの特徴語を連結したラベルを生成し、付加情報記憶部１２４に記憶された付加情報テーブル１４８に登録する。
【００９６】
（Ｓ１４）付加情報生成部１２６は、切断点テーブル１４３および部分グラフテーブル１４４を参照して、クラスタ毎に切断点とその周辺の部分グラフとの間の関係を示す説明文を生成する。付加情報生成部１２６は、付加情報テーブル１４８に説明文を登録する。説明文生成の手順については後述する。
【００９７】
（Ｓ１５）ソフトウェア地図表示部１２７は、クラスタテーブル１４２を参照して、クラスタを区画に対応させクラスタに属するプログラムを区画内の建物に対応させた、二次元または三次元のソフトウェア地図を生成する。ソフトウェア地図表示部１２７は、付加情報テーブル１４８に登録されたラベルおよび説明文の少なくとも一方を、クラスタに対応する区画の上に重ね合わせる。そして、ソフトウェア地図表示部１２７は、生成したソフトウェア地図をディスプレイ１１１に表示させる。
【００９８】
なお、第２の実施の形態では生成したラベルや説明文をソフトウェア地図上に表示しているが、ラベルや説明文を異なる形態で出力してもよい。例えば、付加情報テーブル１４８のようなリストをディスプレイ１１１やその他の出力デバイスに出力してもよい。
【００９９】
図２０は、クラスタリングの手順例を示すフローチャートである。
クラスタリングは、上記のステップＳ１０で実行される。
（Ｓ２０）クラスタリング部１２５は、ソースコード記憶部１２１に記憶されたプログラムの数（クラスの数）をカウントする。クラスタリング部１２５は、空の隣接行列１３３（隣接行列Ｘ）として一辺がプログラム数の正方行列を生成する。
【０１００】
（Ｓ２１）クラスタリング部１２５は、プログラムｉを選択する。
（Ｓ２２）クラスタリング部１２５は、プログラムｉの中からメソッド呼び出しを抽出し、依存先である呼び出し先のプログラムｊを特定する。
【０１０１】
（Ｓ２３）クラスタリング部１２５は、ステップＳ２０で生成した隣接行列１３３のｉ行ｊ列の要素（要素Ｘij）を「１」に更新する。
（Ｓ２４）クラスタリング部１２５は、ステップＳ２１で全てのプログラムが選択されたか判断する。全てのプログラムが選択された場合はステップＳ２５に処理が進み、未選択のプログラムがある場合はステップＳ２１に処理が進む。
【０１０２】
（Ｓ２５）クラスタリング部１２５は、隣接行列１３３の各列を正規化する。すなわち、クラスタリング部１２５は、隣接行列１３３の列毎に「１」の要素の数（Ｋ）をカウントし、当該列の「１」の要素を１／Ｋに更新する。
【０１０３】
（Ｓ２６）クラスタリング部１２５は、仮のクラスタとしてプログラム数に相当する数のクラスタを生成し、全てのプログラムを互いに異なるクラスタに分類する。
（Ｓ２７）クラスタリング部１２５は、ステップＳ２６のクラスタリング結果について、前述の数式（１）を用いてモジュラリティ評価値Ｑを算出する。
【０１０４】
（Ｓ２８）クラスタリング部１２５は、現在のクラスタリング結果の中から２つのクラスタを選択し、選択した２つのクラスタを併合するクラスタ併合案を生成する。クラスタリング部１２５は、そのクラスタ併合案を採用した場合のモジュラリティ評価値Ｑを算出する。クラスタリング部１２５は、現在のクラスタリング結果の中から２つのクラスタを選択する選択パターンそれぞれについてクラスタ併合案の生成とモジュラリティ評価値Ｑの算出を繰り返し、モジュラリティ評価値Ｑが最大になるクラスタ併合案を特定する。
【０１０５】
（Ｓ２９）クラスタリング部１２５は、ステップＳ２８で特定したクラスタ併合案を採用した場合のモジュラリティ評価値Ｑが、現在のクラスタリング結果のモジュラリティ評価値Ｑよりも改善しているか（例えば、前者が後者より大きいか）判断する。モジュラリティ評価値Ｑが改善している場合はステップＳ３０に処理が進み、モジュラリティ評価値Ｑが同じかまたは悪化した場合はステップＳ３１に処理が進む。
【０１０６】
（Ｓ３０）クラスタリング部１２５は、ステップＳ２８で特定したクラスタ併合案を採用し、２つのクラスタを併合する。そして、併合後のクラスタリング結果を現在のクラスタリング結果として、ステップＳ２８に処理が進む。
【０１０７】
（Ｓ３１）クラスタリング部１２５は、ステップＳ２８で特定したクラスタ併合案を採用せず、現在のクラスタリング結果を確定させる。クラスタリング部１２５は、プログラムのクラス名とクラスタＩＤとを対応付けたクラスタテーブル１４２を生成する。
【０１０８】
図２１は、単語スコア算出の手順例を示すフローチャートである。
単語スコア算出は、上記のステップＳ１１で実行される。付加情報生成部１２６は、以下のステップＳ４０〜Ｓ５０を複数のクラスタそれぞれについて実行する。
【０１０９】
（Ｓ４０）付加情報生成部１２６は、着目するクラスタの依存関係グラフを取得する。クラスタの依存関係グラフは、クラスタリング時に生成された全体の依存関係グラフの一部分を流用してもよいし、付加情報生成部１２６がクラスタに属するプログラムの呼び出し関係を分析して生成してもよい。付加情報生成部１２６は、クラスタの依存関係グラフから全ての切断点を検出する。切断点は、依存関係グラフから除去すると当該依存関係グラフが非連結な複数の部分グラフに分割されるという条件を満たすノードである。切断点の検出には、例えば、前述の非特許文献１の方法を用いることができる。
【０１１０】
（Ｓ４１）付加情報生成部１２６は、ステップＳ４０で検出した切断点それぞれについて、部分グラフ数Ａとノード数均一度Ｂと部分グラフ異質度Ｃを算出する。部分グラフ数Ａは、その切断点を選択した場合に生成される部分グラフの数である。ノード数均一度Ｂは、部分グラフの間のノード数の偏りを示す指標であり、＜クラスタの依存関係グラフのノード数＞−（＜最大の部分グラフのノード数＞−＜最小の部分グラフのノード数＞）と算出される。部分グラフ異質度Ｃは、個々の部分グラフの中に異なるパッケージ名が付されたノードが混在していない程度を示す指標であり、クラスタに現れるパッケージ名のうち少なくとも１つの部分グラフを占有しているパッケージ名の数である。
【０１１１】
（Ｓ４２）付加情報生成部１２６は、予め設定された重みα，β，γとステップＳ４１で算出したＡ，Ｂ，Ｃを用いて、各切断点の評価値αＡ＋βＢ＋γＣを算出する。なお、付加情報生成部１２６は、部分グラフ数Ａとノード数均一度Ｂと部分グラフ異質度Ｃのうちの１個または２個のみを用いて評価値を算出するようにしてもよい。
【０１１２】
（Ｓ４３）付加情報生成部１２６は、ステップＳ４０で検出された切断点のうちステップＳ４２で算出された評価値が最大の切断点を選択する。なお、ステップＳ４０で検出された切断点が１個のみである場合、ステップＳ４１のＡ，Ｂ，Ｃの算出やステップＳ４２の評価値の算出は省略してもよい。また、評価値が閾値を超える切断点を全て選択してもよいし、評価値が高い方から所定個の切断点を選択してもよい。
【０１１３】
（Ｓ４４）付加情報生成部１２６は、ステップＳ４３で選択した切断点に対応するプログラムからクラス名を抽出し、切断点テーブル１４３に登録する。また、付加情報生成部１２６は、選択した切断点を依存関係グラフから除去した場合に生成される複数の部分グラフを特定する。付加情報生成部１２６は、各部分グラフに属するノードに対応するプログラムからクラス名の集合を抽出し、部分グラフテーブル１４４に登録する。
【０１１４】
（Ｓ４５）付加情報生成部１２６は、選択した切断点と各部分グラフに属するノードとの間に存在するエッジの方向から、部分グラフ毎に関連方向を判定して部分グラフテーブル１４４に登録する。部分グラフ内のノードから切断点に向かうエッジが存在し、その逆方向のエッジが存在しない場合、関連方向は「ｕｓｅ」になる。切断点から部分グラフ内のノードに向かうエッジが存在し、その逆方向のエッジが存在しない場合、関連方向は「ｕｓｅｄ」になる。それ以外の場合、関連方向は「ｍｕｔｕａｌ」になる。
【０１１５】
（Ｓ４６）付加情報生成部１２６は、複数の部分グラフそれぞれについて、部分グラフに属するノードに対応するプログラムのクラス名から単語を抽出する。付加情報生成部１２６は、所定割合を超える部分グラフ（例えば、過半数の部分グラフ）から共通に抽出された単語を検索し、存在すれば共通単語として切断点テーブル１４３に登録する。
【０１１６】
（Ｓ４７）付加情報生成部１２６は、切断点テーブル１４３に登録された切断点のクラス名から単語を抽出し、抽出した切断点の単語に対して所定の重み（例えば、５．０）を付与して単語重みテーブル１４５に登録する。
【０１１７】
（Ｓ４８）付加情報生成部１２６は、切断点テーブル１４３に共通単語が登録されている場合、共通単語に対して所定の重み（例えば、２．０）を付与して単語重みテーブル１４５に登録する。なお、共通単語の重みは切断点の重みより小さいことが好ましい。共通単語が切断点のクラス名にも含まれている場合、付加情報生成部１２６は、その単語に対して切断点の重みを優先的に付与して共通単語の重みは付与しない。
【０１１８】
（Ｓ４９）付加情報生成部１２６は、クラスタに含まれるノードに対応するプログラムのクラス名から単語を抽出し、抽出した単語をクラスタ単語テーブル１４６に登録する。パッケージ名を含むクラス名からの単語の抽出は、例えば、予め用意した単語辞書、ドットやハイフンなどの区切り文字、語頭を示す大文字などを考慮して行われる。
【０１１９】
（Ｓ５０）付加情報生成部１２６は、クラスタ単語テーブル１４６から各単語の出現回数をカウントする。付加情報生成部１２６は、各単語について出現回数に単語重みテーブル１４５の重みを乗じて単語スコアを算出し、単語スコアテーブル１４７に登録する。
【０１２０】
図２２は、説明文生成の手順例を示すフローチャートである。
説明文生成は、上記のステップＳ１４で実行される。付加情報生成部１２６は、以下のステップＳ６０〜Ｓ６８を複数のクラスタそれぞれについて実行する。
【０１２１】
（Ｓ６０）付加情報生成部１２６は、切断点テーブル１４３に登録された切断点のクラス名を、説明語句ｎとして選択する。
（Ｓ６１）付加情報生成部１２６は、クラスタに共通単語が存在するか、すなわち、切断点テーブル１４３に共通単語が登録されているか判断する。共通単語が存在する場合はステップＳ６２に処理が進み、存在しない場合はステップＳ６３に処理が進む。
【０１２２】
（Ｓ６２）付加情報生成部１２６は、切断点テーブル１４３に登録された共通単語を、説明語句ｍとして選択する。そして、ステップＳ６４に処理が進む。
（Ｓ６３）付加情報生成部１２６は、複数の部分グラフから１つずつ特徴語を抽出し、抽出した複数の特徴語を連結した文字列を説明語句ｍとして生成する。例えば、付加情報生成部１２６は、クラスタ内で部分グラフ毎に各単語のｔｆ−ｉｄｆ値を算出し、部分グラフ毎にｔｆ−ｉｄｆ値が最大の単語を特徴語として抽出する。ｔｆ値としては、部分グラフ内での単語の出現回数を用いることができる。ｉｄｆ値としては、単語が出現する部分グラフの割合の逆数、すなわち、＜部分グラフ数＞÷＜その単語を含む部分グラフの数＞を用いることができる。ｔｆ−ｉｄｆ値は、このｔｆ値とこのｉｄｆ値の積である。
【０１２３】
（Ｓ６４）付加情報生成部１２６は、部分グラフテーブル１４４からクラスタ内の部分グラフの関連方向を検索し、関連方向が「ｕｓｅｄ」のみかまたは「ｕｓｅｄ」と「ｍｕｔｕａｌ」の混合であるか判断する。この条件を満たす場合はステップＳ６５に処理が進み、この条件を満たさない場合はステップＳ６６に処理が進む。
【０１２４】
（Ｓ６５）付加情報生成部１２６は、「＜説明語句ｎ＞が＜説明語句ｍ＞を用いる」という文字列を説明文として生成し、付加情報テーブル１４８に登録する。
（Ｓ６６）付加情報生成部１２６は、関連方向が「ｕｓｅ」のみかまたは「ｕｓｅ」と「ｍｕｔｕａｌ」の混合であるか判断する。この条件を満たす場合はステップＳ６７に処理が進み、この条件を満たさない場合はステップＳ６８に処理が進む。
【０１２５】
（Ｓ６７）付加情報生成部１２６は、「＜説明語句ｍ＞が＜説明語句ｎ＞を用いる」という文字列を説明文として生成し、付加情報テーブル１４８に登録する。
（Ｓ６８）付加情報生成部１２６は、「＜説明語句ｍ＞が＜説明語句ｎ＞と互いに関係する」という文字列を説明文として生成し、付加情報テーブル１４８に登録する。
【０１２６】
第２の実施の形態の分析装置１００によれば、クラスタの依存関係グラフから中心となる切断点が選択され、切断点に対応するプログラムのクラス名に含まれる単語に対して大きな重みが付与される。また、選択された切断点の周辺の部分グラフに共通に現れる共通単語が検出され、共通単語に対して大きな重みが付与される。そして、付与された重みに基づいてクラスタの特徴を示す特徴語が選択され、特徴語を含むラベルが生成される。これにより、クラスタの構造を反映した適切なラベルが生成されラベルの精度が向上する。
【０１２７】
例えば、クラスタにおける単語の出現頻度のみから特徴語を選択すると、切断点に対応するプログラムが重要な役割をもっているにもかかわらず、当該プログラムのみに含まれる単語は出現頻度が低いために特徴語として選択されづらくなってしまう。これに対し、第２の実施の形態では、切断点に対応するプログラムに含まれる単語が重視されることになり、クラスタにとって重要な単語が特徴語として選択されやすくなる。
【０１２８】
また、切断点に対応するプログラムとその周辺の部分グラフに対応するプログラムとの間の関係が、切断点のクラス名や周辺の部分グラフの共通単語を用いて簡潔に表現される。これにより、切断点に対応するプログラムの役割やクラスタの構造の理解が容易となる。従って、クラスタリング結果を示す可視化情報の有用性が向上する。
【符号の説明】
【０１２９】
１０  情報処理装置
１１  記憶部
１２  処理部
１３  クラスタ情報
１４  グラフ
１４ａ  切断点ノード
１５  付加情報
【図１】
2019021232.tif 000004
【図２】
2019021232.tif 000005
【図３】
2019021232.tif 000006
【図４】
2019021232.tif 000007
【図５】
2019021232.tif 000008
【図６】
2019021232.tif 000009
【図７】
2019021232.tif 000010
【図８】
2019021232.tif 000011
【図９】
2019021232.tif 000012
【図１０】
2019021232.tif 000013
【図１１】
2019021232.tif 000014
【図１２】
2019021232.tif 000015
【図１３】
2019021232.tif 000016
【図１４】
2019021232.tif 000017
【図１５】
2019021232.tif 000018
【図１６】
2019021232.tif 000019
【図１７】
2019021232.tif 000020
【図１８】
2019021232.tif 000021
【図１９】
2019021232.tif 000022
【図２０】
2019021232.tif 000023
【図２１】
2019021232.tif 000024
【図２２】
2019021232.tif 000025