TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法

Slides:



Advertisements
Similar presentations
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 関数クローン変更管理システ.
Advertisements

Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 情報検索技術に基づく 関数クローン検出を用いた.
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 識別子名のタグクラウドを用いた.
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 保守支援を目的とした コードクローン情報検索ツール.
XHTML構文検証手法における スクリプト要素の静的解析アルゴリズム
AGMアルゴリズムを用いた ギャップを含むコードクローン情報の生成
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
変数間データフローグラフを用いた ソースコード間の移動支援
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
アイテムセットマイニングを利用した コードクローン分析作業の効率向上
コードクローン分析ツールGeminiを用いたコードクローン分析手順
コードクローンの分布情報を用いた特徴抽出手法の提案
ギャップを含むコードクローンの フィルタリング手法の提案
コーディングパターンと キーワードを用いて生成したコードスニペットの推薦
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の命名支援を目的とした動詞-目的語関係の辞書構築
識別子の共起関係に基づく類似コード検索法の提案と 欠陥検出への適用
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
ソードコードの編集に基づいた コードクローンの分類とその分析システム
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
関数の定義.
構文定義記述を用いた 多言語対応コードクローン検出ツールの改善
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
情報検索技術に基づくベクトル表現と 深層学習を用いたコード片の類似性判定法
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コード片のベクトル表現に基づく 大規模コードクローン集合の特徴調査
オープンソース開発支援のための リビジョン情報と電子メールの検索システム
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
ソースコードの静的特性を用いた Javaプログラム間類似度測定ツールの試作
プログラム実行履歴を用いたコードクローン検出手法
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
プログラム理解におけるThin sliceの 統計的調査による有用性評価
コードクローン編集者数に着目した開発履歴の分析
グラフマイニングアルゴリズムを用いた ギャップを含むクローン抽出手法の提案
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
多様なプログラミング言語に対応可能な コードクローン検出ツール CCFinderSW
Geminiを用いた効果的なコードクローン分析方法
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
既存ソフトウェア中の 頻出コード片を用いた コード補完手法の提案
コーディングパターンの あいまい検索の提案と実装
コードクローンの分布情報を用いた特徴抽出手法の提案
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
大阪大学 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
プログラム依存グラフの一貫性検査に基づく欠陥候補の検出手法
蓄積されたオブジェクトの動作履歴を用いた 実行履歴削減手法の提案
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
メソッド抽出リファクタリングが 行われるメソッドの特徴調査
Geminiを用いた効果的なコードクローン分析方法
識別子の読解を目的とした名詞辞書の作成方法の一試案
プログラム依存グラフを用いた ソースコードのパターン違反検出法
コードクローンを対象とした リファクタリングの有効性に関する調査
Presentation transcript:

TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法 井上研究室 山中裕樹

コードクローン ソースコード中に同一・類似した部分を持つコード片 ソースコードのコピーアンドペーストなどによって発生 本研究では関数単位のコードクローンが対象 関数A 関数C クローンペア 関数B

コードクローンの定義 [1] 種類 意味 タイプ1 レイアウト・空白・コメントの違いを除き完全に一致している タイプ2 タイプ1に加え変数名・型の違いを除き構文的に一致している タイプ3 タイプ2に加え文が挿入・削除・変更されている タイプ4 構文上異なる実装だが,類似処理を実行している [1]C. K. Roy, J. R. Cordy, R. Koschke. Comparison and evaluation of code clone detection techniques and tools: a qualitative approach. Science of Computer Programming, Vol. 74, No. 7, pp. 470–495, 2009.

コードクローン:タイプ1 関数A 関数B 種類 意味 タイプ1 レイアウト・空白・コメントの違いを除き完全に一致している タイプ2 タイプ1に加え変数名・型の違いを除き構文的に一致している タイプ3 タイプ2に加え文が挿入・削除・変更されている タイプ4 構文上異なる実装だが,類似処理を実行している int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum = sum + data[i] ; } return sum; int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum = sum + data[i] ; } return sum; 関数A 関数B

コードクローン:タイプ2 関数A 関数B 種類 意味 タイプ1 レイアウト・空白・コメントの違いを除き完全に一致している タイプ2 タイプ1に加え変数名・型の違いを除き構文的に一致している タイプ3 タイプ2に加え文の挿入・削除・変更されている タイプ4 構文上異なる実装だが,類似処理を実行している int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum = sum + data[i] ; } return sum; double sum(double[] data){ double sum = 0; for(int j=0; j<data.length; j++){ sum = sum + data[j] ; } return sum; 関数A 関数B

コードクローン:タイプ3 関数A 関数B 種類 意味 タイプ1 レイアウト・空白・コメントの違いを除き完全に一致している タイプ2 タイプ1に加え変数名・型の違いを除き構文的に一致している タイプ3 タイプ2に加え文が挿入・削除・変更されている タイプ4 構文上異なる実装だが,類似処理を実行している int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum = sum + data[i]; } return sum; int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum += data[i]; } return sum; 関数A 関数B

コードクローン:タイプ4 関数A 関数B 種類 意味 タイプ1 レイアウト・空白・コメントの違いを除き完全に一致している タイプ2 タイプ1に加え変数名・型の違いを除き構文的に一致している タイプ3 タイプ2に加え文が挿入・削除・変更されている タイプ4 構文上異なる実装だが,類似処理を実行している int sum(int[] data){ int sum = 0; for(int i=0; i<data.length; i++){ sum = sum + data[i]; } return sum; int sum(int[] data){ int sum = 0, i=0; while(i<data.length){ sum += data[i]; i++; } return sum; 関数A 関数B

コードクローン検出の目的 リファクタリング支援 一貫した修正漏れによるバグの検出(タイプ3,4) メソッド の引上げ クローンペア Class S メソッド の引上げ Class A Class B hoge() hoge() hoge() Class A Class B クローンペア int sum(int[] data){ if ( data == null) return null; ・・・ } 例外処理の 追加漏れ int sum(int[] data){ //例外処理漏れ ・・・ }

既存のコードクローン検出手法 構文的な類似性に着目した手法 処理の意味的な類似性に着目した手法 CCFinder[2] など メリット:タイプ1,2のコードクローンを高速に検出可能 デメリット:タイプ3,タイプ4のコードクローンの検出が困難 処理の意味的な類似性に着目した手法 MeCC[3] など メリット:タイプ1- タイプ4のコードクローンを検出可能 デメリット:検出時間に膨大な時間がかかる [2] T. Kamiya, S. Kusumoto, K. Inoue. CCFinder: a multilinguistic token-based code clone detection system for large scale source code. IEEE Trans. Softw. Eng., Vol. 28, No. 7, pp. 654–670, 2002. [3] H. Kim, Y. Jung, S. Kim, K. Yi. MeCC: memory comparison-based clone detector. In Proc. of ICSE ’11, pp. 301–310, 2011.

全タイプの関数単位のコードクローンを高速に検出 提案手法の概要 関数中のワードに重み付けを行い特徴ベクトルを計算 識別子名を構成する単語 ( 関数名,変数名 ) 予約語に含まれる単語 ( if, while ) 近似アルゴリズムを用いて特徴ベクトルをクラスタリング 全タイプの関数単位のコードクローンを高速に検出

検出アルゴリズム STEP1:各関数からワードの抽出 STEP2: TF-IDF法を用いて関数を特徴ベクトルに変換 STEP3: LSHアルゴリズムを用いて特徴ベクトルをクラスタリング STEP4: クラスタ中の特徴ベクトル間の類似度を計算 STEP1 STEP2 STEP3 STEP4 類似度 関数対 クローン 0.95 Function A ✓ Function B 0.70 Function C Function D Function E 0.90 ・・・ Function A Function A ワード 回数 xxx 3 yyy 2 ・・・ Function A Function B Function B Function B Function C Function D Function E ワード 回数 xxx 2 yyy 4 ・・・ ソースコード クローンペアリスト ワードリスト 特徴ベクトル クラスタ

STEP1:ワードの抽出 各関数から識別子名・予約語を抽出 2文字以下の識別子は全て同一のワード(メタワード)として扱う 複数の単語の場合,区切り文字や大文字で分割 例:dataSize ⇒ data + size 関数 Aのワードリスト 関数 Aのソースコード ワード 出現回数 予約語 int 4 for 1 return 分割した 識別子名 data sum size 2 メタワード int sum(int[] data, int dataSize){ int sum = 0; for(int i=0; i<dataSize; i++) sum += data[i]; return sum; }

STEP2:特徴ベクトルの計算 × TF-IDF法を利用 各ワードの重みを特徴量として 各関数を特徴ベクトルに変換 文書中の単語に関する重み付けの手法 TF値とIDF値の積で表される TF値 IDF値 関数中の ワードの出現頻度 ソースコード全体の ワードの希少さ × 各ワードの重みを特徴量として 各関数を特徴ベクトルに変換

STEP3:特徴ベクトルのクラスタリング LSH(Locality-Sensitive Hashing)[4]を利用 近似最近傍探索アルゴリズムの一つ ハッシュ関数を用いて高速にクラスタリング可能 クローンペアと成りうる候補を絞ることが目的 関数名 特徴ベクトル Function A (5,4,2,1,・・・ ) Function B (0,0,2,2,・・・ ) Function C Function D (3,4,2,1,・・・ ) Function E (5,4,2,3,・・・ ) Function F (0,1,2,2,・・・ ) ・・・ Function A Function D Function F Function B Function C Function E クラスタリング 関数のクラスタ 各関数の特徴ベクトル [4] P. Indyk, R. Motwani. Approximate nearest neighbors: towards removing the curse of dimensionality. In Proc. of STOC ’98, pp. 604-613, 1998.

閾値(0.9)以上であればクローンペアとして検出 STEP4: ベクトル間の類似度計算 各クラスタ内で特徴ベクトル間の類似度を計算 コサイン類似度を利用 特徴ベクトル 間の類似度の計算方法 閾値(0.9)以上であればクローンペアとして検出

評価実験 実験1:ベンチマークを用いた検出性の評価 実験2:既存手法との比較実験 実験3:検出したコードクローンの調査 本手法でコードクローンを検出することができるか 実験2:既存手法との比較実験 検出時間と検出精度の比較 実験3:検出したコードクローンの調査 本手法でどのようなタイプ4のコードクローンを検出できたか

全タイプのコードクローンを検出することを確認 実験1:検出性の評価 Royらのベンチマーク[5]を利用 タイプ1-タイプ4の16個のクローンペアが用意 タイプ1 タイプ2 タイプ3 タイプ4 ベンチマーク 3 4 5 検出結果 2 全タイプのコードクローンを検出することを確認 [5] C. K. Roy, J. R. Cordy, R. Koschke. Comparison and evaluation of code clone detection techniques and tools: a qualitative approach. Science of Computer Programming, Vol. 74, No. 7, pp.470-495, 2009.

実験2:既存手法との比較 メモリベースの検出ツールMeCCと比較 MeCCの評価実験で利用されたOSSに適用 タイプ1-タイプ4の関数単位のコードクローン検出 MeCCの評価実験で利用されたOSSに適用 検出精度・検出時間を比較 プロジェクト名 言語 サイズ バージョン ApacheHTTPD C 343KLOC 2.2.14 Python 435KLOC 2.5.1 PostgreSQL 937KLOC 8.5.1

検出精度の比較結果 適合率と各タイプの正解検出数を比較 MeCCよりも高い適合率で検出可能である 各タイプの検出数もMeCCを上回っている プロジェクト名 適合率 検出クローン タイプ1 タイプ2 タイプ3 タイプ4 本手法 ApacheHTTPD 95.4% 71 100 190 11 Python 94.5% 19 103 159 21 PostgreSQL 94.7% 57 230 341 17 合計 94.6% 147 433 690 49 MeCC 87.5% 2 84 10 85.3% 3 127 82 13 83.1% 9 120 88 14 85.0% 331 241 37 MeCCよりも高い適合率で検出可能である 各タイプの検出数もMeCCを上回っている

MeCCよりも高速な検出を行うことが可能 検出時間の比較結果 MeCCの実行環境と同一のものを利用 Ubuntu 64-bit ( RAM: 8.0GB, CPU: Intel Xeon 2.4GHz) ApacheHTTPD Python PostgreSQL 本手法 1m43s 2m13s 4m39s MeCC 310m34s 65m26s 428m32s MeCCよりも高速な検出を行うことが可能

実験3:コードクローンの実例(1/2) 繰り返し処理の置き換え for文を用いた繰り返し do-while文を用いた繰り返し static const XML_Char * poolCopyStringN(STRING_POOL *pool, const    XML_Char *s, int n) { if (!pool->ptr && !poolGrow(pool)) return NULL; for (; n > 0; --n, s++) { if (!poolAppendChar(pool, *s)) } s = pool->start; poolFinish(pool); return s; static const XML_Char * FASTCALL poolCopyString(STRING_POOL *pool, const   XML_Char *s) { // 例外処理漏れの可能性がある! do { if (!poolAppendChar(pool, *s)) return NULL; }while (*s++); s = pool->start; poolFinish(pool); return s; } for文を用いた繰り返し do-while文を用いた繰り返し

実験3:コードクローンの実例(2/2) 文の並び替え 例外処理の 位置が異なる static PyObject * dequeiter_next(dequeiterobject *it) { PyObject *item; if (it->deque->state != it->state) { it->counter = 0; PyErr_SetString(PyExc_RuntimeError, "deque mutated during iteration"); return NULL; } if (it->counter == 0) assert (!(it->b == it->deque->rightblock && it->index > it->deque->rightindex)); ・ static PyObject * dequereviter_next(dequeiterobject *it) { PyObject *item; if (it->counter == 0) return NULL; if (it->deque->state != it->state) { it->counter = 0; PyErr_SetString(PyExc_RuntimeError, "deque mutated during iteration"); } assert (!(it->b == it->deque->leftblock && it->index < it->deque->leftindex)); ・ 例外処理の 位置が異なる

まとめと今後の課題 まとめ 今後の課題 全タイプの関数単位のコードクローン検出法を提案 既存手法と比較して高精度・高速な検出を実現 TF-IDF法を利用して関数を特徴ベクトルに変換 LSHアルゴリズムを用いて特徴ベクトルをクラスタリング 既存手法と比較して高精度・高速な検出を実現 今後の課題 LSI(Latent Semantic Indexing)などの手法との比較 様々なプログラミング言語に対応 他のコードクローン検出ツールとの比較

ご清聴ありがとうございました