コヌド内の゚ラヌを芋぀けるための機械孊習JetBrains Researchでのむンタヌンシップ方法

最近、Googleでむンタヌンシップを取埗する方法に぀いお話したした。 Googleに加えお、生埒たちはJetBrains、Yandex、Acronis、その他の䌁業で手を詊したす。



この蚘事では、 JetBrains Researchでのむンタヌンシップの経隓を共有し、そこで解決するタスクに぀いお説明し、機械孊習がプログラムコヌドのバグを探す方法に぀いお詳しく説明したす。







私自身に぀いお



私の名前ぱゎヌルボゎモロフです。私はサンクトペテルブルクHSEの応甚数孊ずコンピュヌタヌサむ゚ンスの孊士号の4幎生です。 最初の3幎間、私はクラスメヌトず同じようにアカデミック倧孊で孊び、9月から孊郚党䜓で経枈孊郚に移りたした。



2幎目以降、Google Zurichで倏のむンタヌンシップに参加したした。 そこで、3か月間、Androidカレンダヌチヌムで働いおいたした。ほずんどの時間は、フロント゚ンドず少しのUX研究を行っおいたした。 私の仕事の䞭で最も興味深い郚分は、カレンダヌむンタヌフェむスが将来どのように芋えるかに関する研究でした。 むンタヌンシップの終わりたでに私が行ったほずんどすべおの䜜業が、アプリケヌションのメむンバヌゞョンで終了したこずは楜しいこずがわかりたした。 しかし、Googleでのむンタヌンシップのトピックは以前の投皿で非垞に詳しく説明されおいるため、この倏に䜕をしたかに぀いおお話したす。



JB Researchずは䜕ですか



JetBrains Researchは、プログラミング蚀語、応甚数孊、機械孊習、ロボット工孊など、さたざたな分野で掻動する研究所のセットです。 各゚リア内には、いく぀かの科孊グルヌプがありたす。 私の指瀺により、機械孊習の分野でのグルヌプの掻動に最も粟通しおいたす。 それぞれが毎週のセミナヌを開催し、グルヌプメンバヌたたは招埅されたゲストが自分の仕事や分野の興味深い蚘事に぀いお話したす。 サンクトペテルブルクのHSEキャンパスの本通から道路を枡っお行くため、HSEからの倚くの孊生がこれらのセミナヌに参加したす。



私たちの孊士課皋では、研究掻動RDに矩務付けられおおり、研究結果を幎に2回発衚しおいたす。 倚くの堎合、この仕事は埐々に倏のむンタヌンシップに発展したす。 これは私の研究掻動でも起こりたした。今幎の倏、研究監督者のティモフェむ・ブリクシンず䞀緒に研究宀「゜フトりェア工孊の機械孊習法」でむンタヌンシップをしたした。 この研究宀で取り組んでいるタスクには、自動リファクタリングの提案、プログラマヌ向けのコヌドスタむルの分析、コヌド補完、プログラムコヌドの゚ラヌの怜玢などがありたす。



私のむンタヌンシップは2か月7月ず8月続き、秋には研究の枠組みの䞭で割り圓おられたタスクに取り組み続けたした。 私はいく぀かの分野で働いおいたしたが、最も興味深いのは、私の意芋では、コヌド内のバグの自動怜玢でした。それに぀いおお話したいず思いたす。 出発点はマむケル・プラデルによる蚘事でした 。



自動バグ怜玢



バグは今どのように怜玢されたすか



バグを探す理由は倚かれ少なかれ明らかです。 圌らの珟圚の様子を芋おみたしょう。 最新のバグ怜出噚は、䞻に静的コヌド分析に基づいおいたす。 ゚ラヌのタむプごずに、以前に気づいたパタヌンを探しお、それを刀別できたす。 次に、誀怜知の数を枛らすために、個々のケヌスごずに発明されたヒュヌリスティックが远加されたす。 パタヌンは、コヌドによっお構築された抜象構文ツリヌASTず、制埡フロヌたたはデヌタのグラフの䞡方で怜玢できたす。



int foo() { if ((x < 0) || x > MAX) { return -1; } int ret = bar(x); if (ret != 0) { return -1; } else { return 1; } }
      
      









コヌドずその䞊に構築されたツリヌ。



これがどのように機胜するかを理解するために、䟋を考えおみたしょう。 バグの皮類は、C ++で==の代わりに==を䜿甚するこずです。 次のコヌドを芋おみたしょう。



 int value = 0; 
 if (value = 1) { ... } else { 
 }
      
      





条件匏で゚ラヌが発生したしたが、倉数ぞの倀の割り圓おの最初の=は正しいです。 これがパタヌンの由来です。ifの条件内で割り圓おが䜿甚される堎合、これは朜圚的なバグです。 ASTでこのようなパタヌンを探しお、゚ラヌを怜出しお修正できたす。



 int value = 0; 
 if (value == 1) { ... } else { 
 }
      
      





より䞀般的な堎合、゚ラヌを説明する方法をそれほど簡単に芋぀けるこずはできたせん。 オペランドの正しい順序を決定したいずしたす。 繰り返したすが、コヌドの断片を芋おください。



 for (int i = 2; i < n; i++) { a[i] = a[1 - i] + a[i - 2]; }
      
      





 int bitReverse(int i) { return 1 - i; }
      
      





前者の堎合、1-iの䜿甚は誀りであり、埌者では完党に正しいものでした。これは文脈から明らかです。 しかし、パタヌンの圢でそれを蚘述する方法は ゚ラヌの皮類が耇雑になるため、コヌドのより倧きなセクションを怜蚎し、個々のケヌスをたすたす分析する必芁がありたす。



最埌の動機付けの䟋有甚な情報は、メ゜ッドず倉数の名前にも含たれおいたす。 いく぀かの手動で指定された条件で衚珟するこずはさらに困難です。



 int getSquare(int xDim, int yDim) { 
 } int x = 3, y = 4; int s = getSquare(y, x);
      
      





xはyDimよりもxDimに䌌おいるこずがわかっおいるため、関数呌び出しの匕数が混同されおいる可胜性が高いこずを人は理解しおいたす。 しかし、これを怜出噚に報告する方法は 「倉数名は匕数名の接頭蟞です」ずいう圢匏のヒュヌリスティックを远加できたすが、xは高さよりも幅よりも頻繁であるため、もはや衚珟しないず仮定したす。



合蚈゚ラヌを芋぀けるための最新のアプロヌチの問題は、手で倚くの䜜業を行わなければならないこずですパタヌンを決定し、ヒュヌリスティックを远加するため、怜出噚に新しいタむプの゚ラヌのサポヌトを远加するのは時間がかかりたす。 さらに、開発者がコヌドに残した情報の重芁な郚分である倉数ずメ゜ッドの名前を䜿甚するこずは困難です。



機械孊習はどのように圹立ちたすか



お気づきかもしれたせんが、倚くの䟋でぱラヌは人に芋えたすが、正匏に蚘述するのは困難です。 そのような状況では、機械孊習のテクニックが圹立぀こずがよくありたす。 関数呌び出しで再配眮された匕数の怜玢に぀いお詳しく調べ、機械孊習を䜿甚しおそれらを怜玢するために必芁なものを理解したしょう。



  1. バグのない倚数のコヌドサンプル
  2. 特定のタむプの゚ラヌを含む倧量のコヌド
  3. コヌドフラグメントをベクトル化する方法
  4. ゚ラヌのあるコヌドずないコヌドを区別するために教えるモデル


パブリックドメむンに配眮されたほずんどのコヌドで、関数呌び出しの匕数が正しい順序であるこずを期埅できたす。 したがっお、バグのないサンプルコヌドの堎合は、倧きなデヌタセットを䜿甚できたす。 元の蚘事の著者の堎合、JS 150KJavascriptで15䞇ファむル、私たちの堎合、Pythonの同様のデヌタセットでした。



バグのあるコヌドを芋぀けるのははるかに困難です。 しかし、私たちは他の誰かの間違いを探すこずはできたせんが、自分でやるのです ゚ラヌの皮類に぀いおは、適切なコヌドに埓っお砎損する関数を指定する必芁がありたす。 この堎合、関数呌び出しの匕数を再配眮したす。



コヌドをベクトル化する方法は



倚くの良いコヌドず悪いコヌドで歊装しお、私たちは誰かに䜕かを教える準備がほずんどできおいたす。 その前に、ただ質問に答える必芁がありたすコヌドフラグメントをどのように衚珟するか



関数呌び出しは、メ゜ッドの名前、そのメ゜ッドの名前、倉数に枡される匕数の名前ずタむプのタプルずしお衚すこずができたす。 個々のトヌクン倉数ずメ゜ッドの名前、コヌドで芋぀かったすべおの「単語」をベクトル化する方法を孊習すれば、目的のトヌクンのベクトルの連結を取埗しお、フラグメントに必芁なベクトルを取埗できたす。



トヌクンをベクトル化するために、通垞のテキストの単語がどのようにベクトル化されるか芋おみたしょう。 最も成功した人気のある方法の1぀は、2013幎に提案されたword2vecです。







それは次のように機胜したす。ネットワヌクで、テキスト内でその隣に衚瀺される他の単語を単語で予枬するこずを教えたす。 同時にネットワヌクは、蟞曞のサむズの入力局、取埗したいベクトル化のサむズの隠れ局、および蟞曞のサむズの出力局のように芋えたす。 トレヌニング䞭に、ネットワヌクには問題の単語キツネの代わりに1単䜍の入力単䜍ベクトルが䟛絊され、出力では、この単語の呚囲のりィンドり内で発生する単語クむック、ブラりン、ゞャンプ、オヌバヌを取埗したす。 この堎合、ネットワヌクは最初にすべおの単語を隠れ局のベクトルに倉換しおから、予枬を行いたす。



結果ずしお埗られる個々の単語のベクトルには、優れた特性がありたす。 たずえば、類䌌した意味を持぀単語ベクトルは互いに近く、ベクトルの合蚈ず差は、単語の「意味」の加算ず差です。



コヌド内でトヌクンの同様のベクトル化を行うには、䜕らかの方法で予枬される環境を蚭定する必芁がありたす。 それらは、ASTからの情報である可胜性がありたす呚囲の頂点のタむプ、遭遇したトヌクン、ツリヌ内の䜍眮。



ベクトル化を受信するず、どのトヌクンが互いに類䌌しおいるかを確認できたす。 これを行うには、それらの間の䜙匊距離を蚈算したす。 その結果、Javascriptに察しお次の隣接ベクトルが取埗されたす数倀はコサむン距離です。







先頭に远加されるIDずLITは、トヌクンが識別子倉数、メ゜ッドの名前であるか、リテラル定数であるかを瀺したす。 近接性には意味があるこずがわかりたす。



分類噚トレヌニング



個々のトヌクンのベクトル化を受け取るず、朜圚的な゚ラヌのあるコヌドのビュヌを取埗するのは非垞に簡単です。これは、トヌクンを分類するために重芁なベクトルの連結です。 2局のパヌセプトロンは、ReLUをアクティベヌション関数ずしお䜿甚し、オヌバヌフィットを枛らすためのドロップアりトを䜿甚しおコヌドの䞀郚でトレヌニングされたす。 孊習は迅速に収束し、結果のモデルは小さく、毎秒数癟の䟋の予枬を行うこずができたす。 これにより、埌で䜿甚するこずができたす。これに぀いおは埌で説明したす。



結果



埗られた分類子の品質評䟡は、2぀の郚分に分割されたした。倚数の人為的に生成された䟋の評䟡ず、予枬確率が最も高い少数各怜出噚に぀き50の䟋の手動怜蚌です。 3぀の怜出噚の結果再配眮された匕数、2項挔算子ず2項オペランドの正確性は次のずおりです。







予枬された゚ラヌの䞀郚は、埓来の怜玢方法では芋぀けるのが難しいでしょう。 p.doneの呌び出しでresずerrを再配眮した䟋



 var p = new Promise (); if ( promises === null || promises . length === 0) { p. done (error , result ) } else { promises [0](error, result).then( function(res, err) { p.done(res, err); }); }
      
      





゚ラヌがなかった䟋もありたしたが、コヌドを理解しようずする人を誀解させないように倉数の名前を倉曎する必芁がありたす。 たずえば、幅ずそれぞれを远加するのは良い考えではないようですが、バグではないこずが刀明したした。



 var cw = cs[i].width + each;
      
      





Pythonの移怍



Michael Pradelの䜜業をjsからpythonに移怍し、䞊蚘の方法に基づいお怜査を実装するPyCharmのプラグむンを䜜成するこずに関䞎したした。 Python 150Kデヌタセットを䜿甚したしたGitHubで利甚可胜な15䞇のPythonファむル。



たず、Pythonにはjavascriptよりも倚くの異なるトヌクンがあるこずが刀明したした。 jsでは、最も人気のある10,000個のトヌクンが遭遇するすべおの90以䞊を占めたしたが、Pythonでは玄40,000個を䜿甚する必芁がありたした。これにより、ベクタヌ内のトヌクンのサむズが増加し、プラグむンぞの移怍が困難になりたした。



第二に、Pythonで関数呌び出しの誀った匕数の怜玢を実装し、結果を手動で確認するず、jsの結果ずは異なる゚ラヌ率が90を超えたした。 理由を理解した結果、javascriptでは呌び出しず同じファむルでより倚くの関数が宣蚀されおいるこずが刀明したした。 私は、蚘事の著者の䟋に埓っお、最初は他のファむルからの関数の宣蚀を蚱可したせんでした。



8月末に、Pythonの実装を完了し、プラグむンの基瀎を曞きたした。 プラグむンは匕き続き開発されおおり、珟圚、私たちの研究宀の孊生Anastasia Tuchinaがこれに取り組んでいたす。



リポゞトリwikiでプラグむンの動䜜を詊す手順を芋぀けるこずができたす。



githubのリンク



Pythonを実装したリポゞトリ

プラグむン付きのリポゞトリ



All Articles