Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コードレビュー向け コメント行位置予測ツールの試作

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Toshihiro Kamiya Toshihiro Kamiya
October 19, 2020
310

コードレビュー向け コメント行位置予測ツールの試作

神谷 年洋, “コードレビュー向けコメント行位置予測ツールの試作,” 信学技報, vol. 120, no. 193, SS2020-12, DC2020-29, pp. 43-48, 2020年10月.

Avatar for Toshihiro Kamiya

Toshihiro Kamiya

October 19, 2020
Tweet

Transcript

  1. 2 コメントによるソースコード理解の補助 ソースコード理解にはコメントが重要である • ソースコードを扱う時間の半分以上は理解 [10][12] • 理解を助けるためにコメントは効果的 [18][17] ⬇

    コメントに関する研究がされている • 自動生成したい(ドキュメントコメント) – 自然言語の要約手法を応用 [5][11] – 機械翻訳を応用 [13][9][7] • 出現位置を予測したい [8]
  2. 3 コメントの種類 Java のコメントを構文により分類した • ドキュメントコメント – JavaDoc 形式で /**

    … */ – ドキュメントを生成する • 行頭コメント – 行頭に書かれる – 続く数行のブロックの処理内容を表す • 文末コメント – 文末の「 ; 」に続けて書かれる – その文についての注釈 • その他 – 上記の分類以外
  3. 4 コメントの種類 Java のコメントを構文により分類した • ドキュメントコメント – JavaDoc 形式で /**

    … */ – ドキュメントを生成する • 行頭コメント – 行頭に書かれる – 続く数行のブロックの処理内容を表す • 文末コメント – 文末の「 ; 」に続けて書かれる – その文についての注釈 • その他 – 上記の分類以外
  4. 5 コメントの種類 Java のコメントを構文により分類した • ドキュメントコメント – JavaDoc 形式で /**

    … */ – ドキュメントを生成する • 行頭コメント – 行頭に書かれる – 続く数行のブロックの処理内容を表す • 文末コメント – 文末の「 ; 」に続けて書かれる – その文についての注釈 • その他 – 上記の分類以外
  5. 6 コメントの種類 Java のコメントを構文により分類した • ドキュメントコメント – JavaDoc 形式で /**

    … */ – ドキュメントを生成する • 行頭コメント – 行頭に書かれる – 続く数行のブロックの処理内容を表す • 文末コメント – 文末の「 ; 」に続けて書かれる – その文についての注釈 • その他 – 上記の分類以外 本研究で予測する対象
  6. 7 文末コメント 文末コメントが付けられない文のほうが多い • 「文末コメントを付けるべき」といった指針が作りにくい(適切に運 用しにくい) • ⇔ ドキュメントコメントは「 public

    なメソッドやクラスには付け る」といった指針が作りやすい ⬇ 文末コメントの位置を予測する手法 • 文末コメントが必要な部分に書かれているかチェックする作業を補助 ➡ コードレビュー ➡ プログラム開発演習
  7. 8 文末コメントの位置を予測する手法 機械学習によるアプローチ • 文末コメントを含むトークンの列を NN に教師あり学習させる • 文末コメントが出現する位置を予測するツールを実装する 入力

    ソースファイル 出力 文末コメントが出現すると予測された行(行番号のリスト) どうすれば文末コメントの位置を学習させられるか?(検討事項) • 人はどうやって文末コメントの有無を決定しているのか • ソースコードの表現・ NN の構成 • 訓練データの生成
  8. 9 RNN( 回帰型ニューラルネットワーク ) ユニット ( 単位となる人工ニューロン)を繋げることで、データ列を入 力する NN を構成する

    入力 前段の出力 出力 利用例 • 売上予測 (N 日前の売上 , … , 前日の売上 → 当日の売上 ) • 感情分析 (I, am, happy → ポジティブな感情 ) 入力1 出力1 入力2 出力2 0 入力n 最終段の出力 … …
  9. 12 ソースコードの表現 Java のソースファイルをトークンの列で表現する • キーワード、演算子、カッコ、リテラル、識別子、コメント • 識別子は「識別子の出現」を意味するトークンと識別子を構成 する英単語のトークンに分解する –

    getWidth → $I: get Width – キャメルケースにより(小文字の次が大文字になっている 箇所で) • 各トークンのソースファイル中での行番号を記録しておく 各コメントを「 $C 」という特別なトークンにする (中身は不要。位置だけわかればよい)
  10. 13 ソースコードの表現 Java のソースファイルをトークンの列で表現する • キーワード、演算子、カッコ、リテラル、識別子、コメント • 識別子は「識別子の出現」を意味するトークンと識別子を構成 する英単語のトークンに分解する –

    getWidth → $I: get Width – キャメルケースにより(小文字の次が大文字になっている 箇所で) • 各トークンのソースファイル中での行番号を記録しておく ・識別子の出現の位置 ・識別子を構成する英単語 の両方を学習に用いる
  11. 14 ソースコードの表現 Java のソースファイルをトークンの列で表現する • キーワード、演算子、カッコ、リテラル、識別子、コメント • 識別子は「識別子の出現」を意味するトークンと識別子を構成 する英単語のトークンに分解する –

    getWidth → $I: get Width – キャメルケースにより(小文字の次が大文字になっている 箇所で) • 各トークンのソースファイル中での行番号を記録しておく 行頭コメントと文末コメントを区別するため 文末コメント→「 ; 」「 $C 」が同じ行 行頭コメント→「 ; 」「 $C 」が異なる行
  12. 15 生成されるトークン列の例 15 「 } 」 「 $K:catch 」 「

    ( 」 「 $I: 」 「 Illegal 」 「 Argument 」 「 Exception 」 「 $I: 」 「 e 」 「 ) 」 「 { 」 16 「 $I: 」 「 System 」 「 . 」 「 $I: 」 「 err 」 「 . 」 「 $I: 」 「 println 」 「 ( 」 「 $S 」 「 ) 」 「 ; 」 「 $C 」 17 「 $I: 」 「 System 」 「 . 」 「 $I: 」 「 exit 」 「 ( 」 「 $N:1 」 「 ) 」 「 ; 」 「 ; 」と「 $C 」が同じ行 → 文末コメント Illegal, Argument, Exception と いう 3 つの英単語の並びからなる識別子
  13. 16 予測モデルとなる DNN ユニットとして GRU (ゲート付き回帰 型ユニット ) を用いた RNN

    を含む DNN 入力 • 基準位置(文末コメントが出現でき る位置。「 ; 」の直後)を起点に • 前のトークン列( 100 個) • 後ろのトークン列 (100 個) 出力 • 基準位置に文末コメントが出現する かの予測 GRU GRU u 99 u 0 … GRU GRU … GRU d 0 GRU GRU d 99 GRU 24 24 24 24 160 … … 160 16 16 160 16 p … … ・・・◯ ◯ ; ◯ ◯ ・・・ 基準位置に文末コメ ントが出現するかの 予測 基準位置から前の トークン列 基準位置より後ろ のトークン列
  14. 17 予測モデルとなる DNN 2つの出力を最終段で合わせる構造 • 基準位置から前のトークン列を入力 する RNN • 基準位置より後ろのトークン列を

    入力する RNN • それらを合わせる最終段 • それぞれの RNN は基準位置に近いも のが後段 – 基準位置に近いものほど予測に 大きく影響するように • 基準位置から前のトークン列の方に 大きな次元を割り当て (160 対 16) GRU GRU u 99 u 0 … GRU GRU … GRU d 0 GRU GRU d 99 GRU 24 24 24 24 160 … … 160 16 16 160 16 p … … ・・・◯ ◯ ; ◯ ◯ ・・・ 基準位置に文末コメ ントが出現するかの 予測 基準位置から前の トークン列 基準位置より後ろ のトークン列
  15. 18 訓練データの生成 ① 実際のソースファイルを字句解析してトーク ン列を抽出 (ファイル中に文末コメントが含まれない場 合は除外する) ② トークン列の最初から基準位置を探す ③

    基準位置に文末コメントが • 「ある」 – 前後の部分列を「正例データ」に追加 – 部分列の次から基準位置を探す • 「ない」 – 基準位置の直後から次の基準位置を探す ③’ 「ない」「負例データ」「ある」と読み替 えたのものを行う ◯ ◯ ・・・ ◯ ◯ ; $C ◯ ◯ ◯ ◯ ; ◯ ◯ ◯ ① ② 正例データ ③ 負例データ 文末コメントが出現できる 位置に出現しているトーク ン列 〃 出現してい ないトークン列 ③’
  16. 19 実験の手順 対象データ • GitHub Java コーパス [1] のうち 5000

    個の Java プロジェクト、計 68,745 個の *.java k 分割交差検証 • プロジェクト 500 個ずつに分割して 10 のグループを作成 • 訓練データに 8 グループ、バリデーションデータに 1 グループ、テストデータ 1 にグループを割 り当てる 学習 (誤差逆伝搬) 過学習の 判定 評価 40 エポックを上限として繰り返し 訓練データ バリデーション データ テストデータ 予測モデル (NN) 予測 実 測 混合行列 学習パラメータを変えながら 50 回繰り返し
  17. 20 実装・実行環境 実装 • Python のスクリプト • 学習ツール – 入力したソースファイル

    から学習を行い、予測モ デルの DNN を出力 • 適用ツール – 入力したソースファイル に予測モデルを適用し、 文末コメントが出現する と予測される行を出力 利用したライブラリ • Keras(Tensorflow から ) • Optuna( 学習パラメータ最 適化) • Pygments( 字句解析 ) 実行環境 • Nvidia Tesla V100 DGXS( メモリ 32GiB)×4 • Intel Xeon E5-2698 • メモリ 256GiB 並列実行するの はうまくできな かった
  18. 21 実験結果 交差検証の 10 通りの割り当ての うち 5 回を実施 • 1

    回あたり 9 〜 14 時間 • 時間切れ 1回目の結果 (→) では • 適合率 : 出現すると予測され た箇所の 30% に書かれていた • 再現率 : 文末コメントか書か れていた箇所の 67% は出現が 予測されていた 予測 無 有 実測 無 38,225 8,785 有 1,880 3,745 実験1回目の混合行列 他の 4 回も同じ ような傾向
  19. 22 適合率 予測有 × 要素数 予測有 +適合率 予測無 × 要素数

    予測無 要素数 予測有 +要素数 予測無 重み付き適合率・再現率・ F 値 • 予測クラスの要素数(有と予測した数、無と予測した数)で重み付け 適合率 再現率 F 値 1 回目 0.797 0.778 0.788 2 回目 0.791 0.787 0.789 3 回目 0.821 0.823 0.822 4 回目 0.853 0.848 0.851 5 回目 0.810 0.793 0.801 = 重み付き適合率 適合率 予測有 が通常の適合率 既存研究 [8] の重み付き F 値( 0.601 )より良い 結果
  20. 23 まとめと課題・展望 まとめ • コードレビューの補助などに利 用することを想定した、 • 文末コメントの出現位置を予測 する手法・ツールを提案 •

    5000 個の Java プロジェクト を対象とした、 k 分割交差検 証による実験的評価(の途中) – 既存の手法と比較して改善 (しそう) 課題・展望 • 残り 5 回の実験を実施 • グループの基準を検討 – ファイル数で 4.5k 〜 11.5k のばらつき • 予測モデルを改善 • 訓練データをクリーニング • 行頭コメントも対象? • 人間による評価?
  21. 25 Huang らの手法 [8] • 機械学習による手法 • 3種のコンテキストを入力とする予 測 –

    構造コンテキスト (if 文や for 文の支配にあるか等 ) – 構文コンテキスト ( 対象のコー ド断片が初期化文であるかリタ ーン文であるか等 ) – 意味的コンテキスト ( 識別子に 含まれる単語 ) • 対象 : 大規模なオープンソースの Java のプロジェクト 10 個 • プロジェクト内予測 – F 値 0.954 – 学習データとテストデータを同 じプロジェクト内のソースファ イルから割り当て • プロジェクト間予測 – F 値 0.601 – 学習データとテストデータを別 のプロジェクトから割り当て • コンテキストを on/off して精度 を比較
  22. 27 入力層のユニットのそれぞはトークンを 24 次元 (24 個の 0 〜 1 の実数

    ) に埋め込んだものを入力 GRU u i GRU 24 160 出力層は 176 個 (Ui 由来の 160 個 di 由来の 16 個 ) のユ ニットの出力を入力 2 層目のユニットのそれぞれは入力層の 160 個のユニットの出力を入力 GRU GRU GRU GRU u i0 u i1 … u i23 GRU GRU 160 個の ユニット 160 個の ユニット GRU GRU GRU … 160 個の ユニット p