Log In Sign Up

Commit2Vec: Learning Distributed Representations of Code Changes

by   Rocío Cabrera Lozoya, et al.

Deep learning methods, which have found successful applications in fields like image classification and natural language processing, have recently been applied to source code analysis too, due to the enormous amount of freely available source code (e.g., from open-source software repositories). In this work, we elaborate upon a state-of-the-art approach to the representation of source code that uses information about its syntactic structure, and we adapt it to represent source changes (i.e., commits). We use this representation to classify security-relevant commits. Because our method uses transfer learning (that is, we train a network on a "pretext task" for which abundant labeled data is available, and then we use such network for the target task of commit classification, for which fewer labeled instances are available), we studied the impact of pre-training the network using two different pretext tasks versus a randomly initialized model. Our results indicate that representations that leverage the structural information obtained through code syntax outperform token-based representations. Furthermore, the performance metrics obtained when pre-training on a loosely related pretext task with a very large dataset (>10^6 samples) were surpassed when pretraining on a smaller dataset (>10^4 samples) but for a pretext task that is more closely related to the target task.


patch2vec: Distributed Representation of Code Changes

Deep learning methods, which have found successful applications in field...

AdaptivePaste: Code Adaptation through Learning Semantics-aware Variable Usage Representations

In software development, it is common for programmers to copy-paste code...

CODE-MVP: Learning to Represent Source Code from Multiple Views with Contrastive Pre-Training

Recent years have witnessed increasing interest in code representation l...

NatGen: Generative pre-training by "Naturalizing" source code

Pre-trained Generative Language models (e.g. PLBART, CodeT5, SPT-Code) f...

Finding Inlined Functions in Optimized Binaries

Much software, whether beneficent or malevolent, is distributed only as ...

I Introduction

Deep learning methods have been proven successful in a variety of problems, such as image classification, natural language processing, speech recognition, and others. More recently there is a growing interest in using similar approaches to programming-language related tasks [4, 5, 6, 19], using code as the main input source.

To this end, a key prerequisite is the ability to represent the code (or code fragments) as a numerical vector (

embedding), similarly to the word2vec [11] approach for natural language processing (NLP). Such vectorial representation should have the property of mapping similar instances of code elements onto close points in the embedding vector space. Using NLP methods to build representations of software code is meaningful, indeed, as empirically shown in [10]. Source code is characterized by similar statistical properties as natural language (naturalness hypothesis [2], which is not surprising considering that code is written and read by humans, in addition to being executable by machines). On the other hand, there are significant differences, since code is written in a programming language, which is a formal language: it presents minimal ambiguity, large re-use of identical “sentences”, and reduced robustness to small changes compared to natural language. In addition, the semantic units of text, as sentences or paragraphs, are typically relatively short, present a high level of locality, and they rarely used more than one time in the text. On the contrary, (sequences of) code statements or functions are clearly delimited, they may be used multiple times in different contexts, and present long range correlations (i.e., the semantic of a statement can be influenced by other statements in a somewhat distant part of the code).

For these reasons, beyond NLP-inspired methods, a number of representations that use the structural nature of code have been proposed, such as using data flow graphs, control flow graph and abstract syntax trees, and used to perform tasks as variable and method naming [1, 5], clone detection [18], code completion  [14, 16], summarization  [3], and algorithm classification [12].

Due the complexity of the code structure, training a deep learning algorithm to solve a code-related task needs a large amount of labeled data, which in many practical cases is not available. Ideally, we would like to build a low-dimensional representation using a task where a large amount of labeled data is available (or can be obtained in a relatively inexpensive way), and use the learned representation to solve a different (target) task, where fewer data point are available, but enough to fine tune the model (tranfer learning).

The contribution of this paper is twofold.

First, we propose a new model for representing code changes, called commit2vec, which, along the lines of [5], uses paths from the AST to build a representation of code changes.

Then, we evaluate the model on an industry-relevant use-case (security commit classification), where a limited number of samples is available. To this end, we construct datasets to support the pre-training of embedding models and we refine the learning by continuing the training on data related to the target task (transfer learning). We show how the performance of a model can be optmised by learning the code representation on a related task (prediction of the priority of issue-tracking tickets) where a large dataset can be easily created, and fine tune the model to solve the (target) task of identifying security-relevant commits.

Ii Motivating Scenario

The motivation for this work stems from our interest in the problem of ensuring that the open-source components included in the products of our company are free from (known) vulnerabilities. This is among the most urgent security challenges that the software industry is facing [8], and has hit the headlines multiple times in the recent past [7, 9].

The adoption of open-source software (OSS) components by commercial software developers has increased considerably over the past few years: according to [17], 80 to 90% of commercial software includes OSS components. While this practice allows commercial software vendors to speed up innovation and decrease development costs, it raises important concerns, especially related to security. The number of open-source components, the variety of practices according to which they are developed, and the complexity of their interdependencies translate into a composition that is difficult to understand and to maintain.

The current approach to vulnerability management consists in keeping track of publicly disclosed vulnerabilities in the National Vulnerability Database (NVD), which is known to have consistency and coverage issues, among others. More in general, this approach does not scale well as the amount of open-source code developed by the community (and incorporated in commercial products) increases at a steady pace.

To make the problem worse, a study by [17] reported that as many as 25% of the OSS projects fix vulnerabilities without ever disclosing them in an official advisory (so-called silent fixes), making it even harder for projects that depend on OSS components to take informed decisions as to whether they should upgrade to a more recent (non-vulnerable) version.

The urgent need of rigorous practices to ensure the security of the software supply chain is reflected in the landscape of commercial offerings that have appeared over the past three years, some of which claim to have extensive vulnerability data, obtained via monitoring of advisories and project code repositories.

Given the amount of open-source code produced and consumed nowadays, it is clear that any approach that is based on manual effort is doomed to fail, and the role of automated tools (in particular, those based on machine-learning technology) is destined to grow steadily.

The problem of representing code (and code changes) is receing more and more attention both in academia and industry. However, how to represent source code in a way that can be used effectively in machine learning applications is an open research question. Given the huge amount of freely available code and the recent breakthroughs in other fields such as computer vision, speech recognition and natural language processing, code analysis is a strong candidate to be the next application to benefit from deep learning techniques.

Iii Background and Related Work

In this section we first present some background information on code2vec [5], which we extend and adapt in this work. Then, we briefly overview related literature.

i Code2Vec

The work in code2vec [5] uses a bag of aggregated contexts to create distributed representations for single methods, and is trained to predict the name of a method given its body. We adapt the same idea to represent commits (code changes), as opposed to individual code snapshots; also, our method represents a commit as a whole, aggregating data of all the methods changed in the commit, whereas code2vec focuses on individual methods. In [5], to process a method, the model first builds the abstract syntax tree associated to the method, and then creates a set of triplets (named contexts) composed of two terminals in the tree and their connecting path. Each path and terminal has an associated embedding of size 128. The three embeddings of the triplet are then concatenated to a single context vector of size 384. Each context vector is propagated to a fully connected layer producing a vector of size 128. Finally, an attention mechanism combines the resulting vectors and creates the code-vector

of the method. A final layer connected to this code-vector is added in order to compute the loss. In the original paper, a lookup table for the method name and a softmax layer form the last layer. As explained in the next section, we use

code2vec as a building block in our method to represent code changes.

ii Other Works on Code Representation and Classification

The work in [15] is motivated by the same use-case as this work: the automated classification of commits that are security-relevant (i.e., that are likely to fix a vulnerability). They train two independent classifiers on the patch introduced by a commit (Patch Classifier) and the log messages (Message Classifier), without relying on information from vulnerability advisories. Inspired by the naturalness hypothesis [2, 10], both classifiers treat their input as documents written in natural language (code-as-text), and classify them using established natural language processing (NLP) methods. Their results are combined with a voting mechanism flagging a commit as security-relevant if either model does. To process code changes in a commit, they keep only added and deleted lines of the commit and then treat these as natural language. In our experiments, as a baseline, we use token based models that follows a similar approach.

Unlike the work in [15], we focus exclusively on the code as a source of information (that is, we do not use the commit message nor text in natural language, coming, e.g., from code comments). This makes our method applicable to the detection of silent fixes (security fixed that are committed to source code repositories without a specific mention of their security-relevance in the commit message and for which there is no explicit announcement through an advisory).

To the best of our knowledge, the state of the art in academic research for source code distributed representations has mostly focused on the representation of methods rather than whole commits [4, 5]. There seems to still be a lack of a more global representation for code, as code commits can be composed of changes in multiple methods located in multiple files.

More importantly, the scope of these two works [4, 5] is restricted to the representation of a code snapshot, and does not consider the temporal component necessary to represent changes in code commits (differences between two code snapshots).

The work in [19] does include a temporal component, as it aims to represent edits in source code, however its scope is restricted to small edits of only a few lines of code, which would not meet the requirement of our application scenario (Section II) for which a representation of entire commits is necessary.

Figure 1: commit2vec: the prior () and posterior () versions of all code-relevant files in a commit, , are transformed into contexts through an AST-based code representation, generating both and . The commit representation, , is computed as the symmetric difference between and

and is provided as the input to a neural network. In this diagram, the exemplified task is that of classification of security and non-security relevant commits.

Iv commit2vec

Finding the best-suited representation of code in machine learning frameworks is an open research question. The survey in [2] classifies the representation of code into three main categories:

  • token-level models treat code as a sequence of tokens in a similar way as traditional natural language processing (NLP) techniques represent text as a sequence of words in a given language

  • syntactic models leverage on the underlying structural information of code through their abstract syntax tree (AST) representations

  • semantic models represent code as a graph generalizing both token-level and syntactic models

The concept of word embeddings, made popular by the work in  [11], allowed a breakthrough in many NLP-related tasks. Over the last few years, approaches inspired on the same concept are emerging in the domain of source code analysis. The work in [6] presents a survey of different works that use the concept of embeddings at different granularities of code.

In this work, we introduce a method to represent source code changes (such as those contained in the commits of a source code repository). Differently from the approaches that represent a static snaphot of code [5], or that represent changes in small code fragments [19], we focus on representing full commits, which can contain changes across multiples methods, classes, and even files.

i Commit Representation

Our method uses code2vec as a basic building block: for a given commit, we extract all the methods that are changed and use the same preprocessing steps as code2vec to extract a set of paths over the AST (context in the terminology of [5]); we then discard the contexts that are identical in the code before and after the commit, and use the remaining paths as the basis for the commit representation111Because our focus is on investigating the representation of source code, we do not consider commits that change only non-code files (e.g., metadata, readme, changelogs, documentation, etc.) or that change only comments..

More precisely, let a code commit, , be defined as a change in the source code of a given project in a set of files , where , where is the number of files changed within C.

The concept of a commit implies an prior and a posterior version of files , which we denote as and respectively.

Analogously to textual tokens in token-based representations, our model uses paths constructed traversing the abstract syntax tree (AST) of each method changed in . Consistenly with the terminology of [5], we call contexts the triplets of two terminal nodes and their connecting path on the AST.

Let the union of all the contexts of the prior versions of all methods in all files in commit be defined as and the union of all the contexts of the posterior versions of all methods in all files in commit be defined as . We then define the set of contexts describing commit as the symmetric difference between and :


Intuitively, the symmetric difference between the two sets of contexts contains the contexts that have been changed in the commit .

is the input provided to the neural network architecture that yields a distributed representation of the code changes performed in commit . In order to generate meaningful representations, the neural network typically requires large amounts of data to be trained on. Unfortunately, in many applications the data available is not sufficient. In these cases, transfer learning techniques are applied, where the network is pre-trained on a similar task for which large amounts of data are available, often called the pretext task, and then fine-tuned on the target task using a smaller dataset.

In the following sections, we evaluate the performance of token-based and AST-based commit representations for the classification of security-relevant commits. In the follwing,

  • Token-based commit representation will refer to the use of addition of removal of lines in code as particles. Nevertheless, the raw tokens inside these lines were preprocessed by splitting composite tokens (e.g. camel-case identifiers) and by removing stopwords, non-alphanumeric characters, integers and single letter values, as well as reserved keywords from the Java language.

  • AST-based commit representation will refer to the use of contexts as particles. We consider the definition of  [5] of context: a triplet of two terminal nodes and their connecting path from the abstract syntax tree (AST) of a code snippet.

ii Research questions

We define a performance baseline by using token-based commit representations. We first replicate the work of [15] by treating code as a collection of tokens in a bag of words (BoW)

approach coupled with a support vector machine (SVM) classifier. To obtain a stronger baseline, we improve upon that model by adopting a method capable of interpreting code as a


of tokens (and not just as a set, asn in BoW); we use a long short-term memory (LSTM) network for this purpose.

Following the creation of a baseline with token-based commit representations, we explore the following research questions:

  • RQ1 - Is there an added value in using syntactic models as opposed to token-level models to construct code representations? To answer this question, we compare the performances of the models trained on the token-based representations in the baseline to an AST-based representation.

  • RQ2 - Does pre-training a neural network on a very big ( samples), but loosely related, dataset provide an increase in performance for the target task? Training on an extensive database, sometimes in the order of millions of samples, is the basis for transfer learning techniques which has been widely applied in other domains. We use the network from [5] trained on a dataset of 12M samples to predict method names for our task of predicting security-relevant commits.

  • RQ3 - Does pre-training a neural network on a smaller dataset ( samples rather than ), but on a highly relevant task provide an increase in performance for the target task? We compare the results obtained while answering RQ2 to those obtained by pre-training a network on a pretext task which we hypothesize is more closely related to our target task. We use a large, but not massive dataset,(tens of thousand data points, as opposed to millions), to train a classifier on this pretext task.

V Datasets

In order to run experiments that could answer the research questions outlined in the previous section, we took an existing dataset of security-relevant commits as a starting point, and we complemented it with additional commits that we mined automatically as explained below. Also, to tackle the pretext task, we constructed a dataset of Jira tickets obtained mining hundreds of projects from the Apache Software Foundation (ASF).

i Security-relevant commit dataset

The security-relevant commit dataset used is a combination of two sources:

  • Manually curated dataset. We use the dataset introduced in [13] where each entry represents a commit that contributes to fixing a vulnerability (so-called fix-commits). The dataset covers a representative sample of OSS projects of practical industrial relevance. This dataset was constructed and manually curated, monitoring the disclosure of security advisories, not only from the NVD, but also from numerous project-specific Web pages.

  • Mining commits from Jira issues. We retrieved, from the Jira system of each of the OSS projects in the manually curated dataset, all the issues that were manually tagged as “security-related” (that is, that had labels such as: security, authorization, authentication) by the user or developper who created the issue. We then extracted the commits linked to these issues (via a reference to the issue identifier found in the commit message).

Both of the previously described sources consist of only positive samples for our problem formulation so we augment the dataset with an equal number of negative instances (non-security commits). For each positive instance from repository , we take a random commit from and, under the assumption that security-relevant commits are rare compared to other types of commits, we treated these as negative

examples. To avoid including obvious outliers (extremely large, empty, or otherwise invalid commits), a manual review of these commits was performed, supported by ad-hoc scripts and pattern matching (similarly to 


). These patterns are used to speedup the manual review by searching for patterns in the commit messages that would indicate with high probability that the commit was security-relevant.

Only the commits with code changes are kept (i.e., changes in non-code files, or comments within the code are not considered). This results in a dataset containing a total of 1950 commits, with 975 positive instances (security related) and 975 negative instances (not security related).

ii Jira Ticket Dataset

Jira is an issue tracking system developed by Atlassian which allows developers and users of a given software to manage issues, bug reports, and development tasks in general. To create our labeled dataset of commits, we considered all the Apache Software Foundation projects written in Java (195 out of 264) and collected the Jira issues associated to them. A large percentage of Apache projects use the Jira platform for their issues.

The projects hosted in the Apache Software Foundation (ASF) where chosen because of their industrial relevance; also, the majority of the ASF projects follow the practice of linking source code commits to Jira tickets by including the identifier of one or more tickets in the commit message. By mining source code repositories, we could construct a dataset of commits mapped onto the corresponding tickets. A commit linked to a ticket is considered as the fix of the issue described in the ticket. For this work, the pretext task we consider is the prediction of the priority of tickets based on the code changes in the corresponding commit(s). Other pretext tasks could be defined, based on other attributes of the Jira ticket that can serve as labels. Using ticket priority, allows us to include commits that are not linked to a Jira issue (we assign these commits to the NoTicket class).

In our experiments, we keep only consider projects adhering to the five priority class convention: Trivial, Minor, Major, Critical and Blocker. Table 1 shows the number of commits and their respective priority classes that we were able to collect. The distribution of priority labels for our dataset is shown in Figure 2.

References found Valid commits Proportion
Blocker 30,001 10,194 0.34
Critical 39,868 14,318 0.36
Major 463,556 178,070 0.38
Minor 123,252 43,457 0.35
Trivial 21,222 5,883 0.28
NoTicket 1,049,636 272,953 0.26
Total 1,727,535 524,875 0.30
Table 1: Number of commits found for each priority and remaining number of commits in the final dataset
Figure 2: Jira Ticket Priority dataset distribution.
Precision (%) Recall (%) F1-score Accuracy (%) PR-AUC () BoW-SVM 66.09 2.41 73.13 1.14 69.41 1.64 67.74 2.19 66.361.51 LSTM 70.91 4.15 68.71 3.08 69.63 1.42 70.00 2.24 74.702.69 commit2vec (no pre-training) 69.41 1.70 77.22 3.19 73.08 2.11 71.59 1.98 82.511.57 commit2vec (code2vec pre-trained) 70.04 1.52 76.09 3.30 72.90 1.73 71.75 1.54 82.111.93 commit2vec (Jira pre-trained) 72.01 2.69 78.16 1.16 74.92 1.26 73.80 1.92 84.411.42 Table 2: Classification performance () of models on the security-relevant commit dataset (5-fold cross-validation). Figure 3: Boxplot visualizations of performance metrics of models on 5-fold cross-validation on the security-relevant commit dataset.

Vi Experiments

The following section describes the use of both token-based and AST-based commit representations, , for the classification of security-relevant commits. Table 2 and Figure 3 summarize the precision, recall, F1-score, accuracy and area under the precision-recall curve (PR-AUC) metrics obtained after performing 5-fold cross validation on the security-relevant commit dataset.

i Baseline

We compare two token-based commit representations for the classification of security-relevant commits which will serve as a baseline to compare the rest of the proposed approaches. For both approaches, a dictionary size of 20,000 tokens was used.

i.1 Bag of Words and SVM

Similarly to the approach presented in [15], the token-based commit representation, , is vectorized as a bag of words (BoW). The vectors are then fed into a support vector machine (SVM) with a linear kernel. For ease of replication, we show pseudocode for this implementation in Listing 1 using the Sci-kit learn framework. Variable refers to the dictionary size, and is a dataframe containing in column Sc the lines of code remaining after performing the symmetric difference between the two file versions.

As shown in Table 2, this approach yields an average F1-score of and an average PR-AUC of across 5 folds.

v = CountVectorizer(analyzer = "word", max_features = d)[’Sc’].values))
X_train = vectorizer.transform(df_train[’Sc’].values)
clf = SVC(kernel=’linear’, probability=True), Y_train)
Listing 1: BoW+SVM model

i.2 Lstm

Here we represent

as a sequence of tokens of maximum length of 500 tokens. Each element in the sequence will be embedded to a vector size of 32. This sequence will be fed into a long-short term memory (LSTM) network. The model is composed of an LSTM layer of 100 units and a dense layer with a sigmoid activation function. The loss function used is binary cross entropy, and the Adam optimizer. The code in Listing


demonstrates the implementation using the Keras framework. Variable

refers to the dictionary size, to the embedding size, to the number of units in the LSTM layer and to the maximum sequence length.

This approach yields an average F1-score of an an average PR-AUC of across 5 folds.

model = Sequential()
model.add(Embedding(d, e, input_length=s))
model.add(LSTM(h, return_sequences=True))
model.add(Dense(1, activation=’sigmoid’))
model.compile(loss=’binary_crossentropy’, optimizer=’adam’)
Listing 2: LSTM model

In the experiments performed, treating as a sequence of tokens yielded a non conclusive increase of percentual points in F1-score with respect to a bag of words approach. Nevertheless, when comparing the PR-AUC scores, we observe an increase of

percentual points. It should be reminded that the precision and recall values reported are those computed for a classification threshold of 0.5, whereas a precision-recall curve shows the tradeoff between precision and recall for different thresholds. Therefore, a PR-AUC will provide a more comprehensive performance measurement in the case where 0.5 would not belong to the optimal classification threshold for the given task.

Given these results, we can state that treating code as a sequence of tokens, which provides more information than the mere collection of tokens, increases the performance for the prediction of security-relevant commits. In the next sections, we compare this baseline to AST-based commit representations. These representations contain information about the structure of code and better capture the dependencies between related tokens, despite them being far apart in the code. We hypothesize that AST-based representations will outperform token-based representations for our target classification task.

Figure 4: Precision-recall curves for each model averaged over 5-fold cross validation results.

ii AST-based commit representation

We compare the use of an AST-based commmit representation for the classification of security-relevant commits with and without the use of external databases to pre-train the network. In all the following cases, we restrict the size of

to maximum 500 contexts. Commits with less contexts are padded with empty values and for those with higher number of contexts, an sample of 500 contexts is randomly chosen. We empirically found this number to be suitable to represent a code commit which can be composed of changes in multiple methods in multiple files.

ii.1 commit2vec (no pre-training)

We use the security-relevant commit dataset described in Section i to train a classifier. We trained a model with a similar architecture as the one described in [5]. The last layer of the original model architecture is replaced by a binary softmax layer as output corresponding to the two classes, security-relevant and non security-relevant commit. All network weights, including embeddings of terminals and paths, are initialized randomly. The model was trained using binary cross-entropy as a loss function and the Adam optimizer. The average F1-score obtained by this approach is of and the average PR-AUC score is of over 5 folds .

  • Answer to RQ1 From the results in Table 2, it can be seen that training a model on AST-based commit representations came with an increase of at least % in F1-score and % in PR-AUC score with respect to their token-base counterparts. Furthermore, by inspecting Figure 4 it is clear that training on an AST-based representation translates to substantially higher precision performances for any given recall value. We believe this increase in performance is due to the structural information of code contained in an AST-based representation.

ii.2 commit2vec (code2vec pre-trained)

We used the pre-trained network provided by [5]. This network was trained on over 12M methods for the prediction of method names and the learned code-vectors have been shown to capture semantic similarities, combinations, and analogies [5]. In a similar way as in the previous section, the last layer of the original model was stripped and replaced by a binary softmax layer. All the network weights were allowed to evolve during the fine-tuning stage using the training set of the security-relevant commit dataset. The average F1-score obtained was of and the average PR-AUC was of .

  • Answer to RQ2 From the experiments performed in this work, we found a slight decrease of percentual points on the F1-score and a decrease of percentual points on the PR-AUC score averaged across five folds when pre-training the network on a dataset for method name prediction. This marginal decrease can be due to the very loose relation between the chosen pretext and the target tasks. Indeed, even though the inputs to the models are both composed of collection of triplets from the AST of code, there are two main differences. First, the original task in [5] aimed to predict the names of individual methods, therefore, the input to the network consisted of a collection of triplets which were all related to each other because they shared the same AST. Nevertheless, our input, , is not composed of contexts coming all from the same AST and do not consitute a method on its own. The contents of our commit representation can come from multiple AST representing different methods located in various files of the project whose relationship between each other is not necessarily direct. Therefore, cannot be interpreted as a method. A second, and perhaps more important difference, is that does not represent a static version of code as would be the case of the input in the task in [5]. It represents a code commit which inherently implies a temporal change. These differences can explain the results obtained. In the following experiment, we explore the use of a pretext task more closely related to our target task. Notably, we chose a pretext task where the input to the network can contain contexts from multiple methods but also contains the notion of a code change.

ii.3 commit2vec (Jira pre-trained)

We used the Jira Ticket Priority dataset described in Section ii to pretrain our network. We hypothesize that commit fixes related to higher priority tickets are more likely to contain fixes of important bugs, and that these could be more closely related to security-relevant fixes. This is supported by Figure 5 which shows that security-relevant commits have a higher proportion of Critical and Blocker issues than non-security relevant commits. Similarly, non-security commits tend to have a higher proportion of Minor and Trivial issues than positives. However, both classes contain a big majority of Major issues.

Figure 5: Proportion of ticket priorities for (a) security relevant and (b) non-security relevant commits

The network used has small architecture variations from the one presented in [5]. The softmax layer was replaced by a smaller one of six classes corresponding to the six priority levels. Our dataset is split into 80% training and 20% test sets.

Pretext task. Results on the classification of Jira Ticket Priority can be found on Table 3. Precision and recall curves are given in Figure ii.3. It can be seen that, as expected, the highest classification performances are obtained by the predominant classes, NoTicket and Major. Nevertheless, the model presents micro-average performances of 79.69, indicating an overall good performance.

Target task. After pre-training on the Jira Ticket Priority dataset, the network was fine-tuned using the security-relevant commit dataset. Similar to the previously presented experiment, all network weights were allowed to evolve during fine-tuning. The average F1-score obtained on the target task across 5-folds was of and the average PR-AUC score was of .

F1-score Precision Recall
Blocker 66.47 73.19 60.88
Critical 69.42 76.13 63.81
Major 76.76 77.32 76.21
Minor 60.03 64.16 56.40
Trivial 55.52 67.23 47.28
NoTicket 85.76 83.73 87.89
micro average 79.69 79.69 79.69
macro average 68.99 73.63 65.41
weighted average 79.42 79.34 79.69
Table 3: Model performances on the pretext task: Jira Ticket Priority classification
Figure 6: Precision-recall curves for each class in the pretext task: Jira Ticket Priority classification
  • Answer to RQ3 Results on Table 2 show that pretraining on a smaller, yet more relevant, dataset yield an increase of percentual points in F1-score and percentual points in PR-AUC with respect to training on a loosely related task and of percentual points in F1-score and in PR-AUC when not using a pretext task to pretrain the network at all. These results highlight the importance of adequately choosing the pretext task.

Precision Recall F1-score Accuracy BoW-SVM 63.67 0.00% 68.27 0.00% 65.89 0.00% 64.66 0.00% LSTM 68.24 3.94% 67.74 6.25% 67.66 1.85% 67.66 2.99% commit2vec (no pre-training) 69.01 6.37% 72.33 8.52% 69.87 2.03% 68.92 3.27% commit2vec (code2vec pre-trained) 69.89 1.05% 72.12 1.52% 70.97 0.56% 70.50 0.59% commit2vec (Jira pre-trained) 72.64 1.61% 71.10 1.73% 71.83 0.66% 72.12 0.82% Table 4: Effect of random initialization in the variability of a classifier’s performance (100 runs). Figure 7: Boxplots showing the high variability of performance metrics on models with high proportions of randomly initialized weights.

Vii Discussion

Our experiments show a superior performance for AST-based commit representations compared to the token-based baseline, as illustrated by the larger area under the precision-recall curves in Figure 4. Also, in these experiments, training on a highly relevant pretext task proved to be more effective than training on a much larger dataset but for a losely related task.

In the rest of this section, we discuss some of the current limitations our work and the factors that might impact the ability to generalize our findings.

i Programming language and preprocessing

Our approach inherits some of the limitations of the code2vec implementation, such as the fact that only Java is supported. As a consequece, we could not use the entire dataset of [13] (which also includes vulnerabilities affecting Python projects, and that we had to exclude).

Moreover, in the code2vec implementation, the extraction of contexts from the AST only takes into account methods (in particular, constructors or other changes outside of methods are not supported). Finally, for efficiency reasons we did not consider methods that were completely removed or added in a commit. Most of these limitations could be addressed with modifications to code2vec as well as to commit2vec, which we plan to do as future work.

ii Randomness of Context Sampling

As mentioned in Section , we set the maximum size of

to 500, which means that for commits that resulted in more than 500 contexts, we randomly sampled 500 contexts. In our experiments, this sampling was done once and kept for all runs. However, we cannot exclude that sampling different contexts for a given commit might influence the results of the classification task. We plan to address this limitation in our future work. We are considering to design a variant of our method that could use a deterministic algorithms to reduce the number of contexts in large commits (e.g., removing very common contexts or applying expert-defined heuristics to prioritize the contexts to keep).

iii Effect of Random Initialization

Most of the models used in this work rely on a random initialization of the weights in their networks. Different initialization values can drive the (stochastic) optimizer to converge to different minima in the search space. This effect can impact repeatability, since different initial values could result in differences in the classifier performance. Initializing a part of the weights in the network with pre-trained weights can reduce this effect, and we studied experimentally the variability of the classifier performance with different random initializations for each of the models.

We fixed a training () and testing () set and ran each of the models 100 times. The results are given in Table 4 and Figure ii.3. Firstly, because the BoW+SVM model is deterministic there is no variation in the performances obtained. Next, we can see that the models with a larger proportion of randomly initialized weights, such as the LSTM and the commit2vec without pre-training, have a higher variability in the performance metrics. The pre-trained versions of commit2vec are also affected by the randomness in the initialization but because the pre-trained weights (which are a big proportion of the total number of weights) are fixed to the same value on each run, the variability in the classifier performance is smaller.

iv Pretext Task: Classification of Jira Tickets

For this work, we defined a pretext task to aid us solve the task of classifying security-relevant commits through transfer learning. We chose the prediction of the priority of Jira tickets based on our experience and on the practical observation (see Figure 5) that security-relevant commits tend to be associated with tickets of higher priority, while no-security-relevant commits are associated to lower-priority tickets.

Nevertheless, the task of predicting the priority of Jira ticket task has multiple challenges of its own. First, there is no one-to-one correspondence between a commit and a ticket. In fact, an issue can be referred to in multiple commits (e.g., because a single commit may not be enough to solve the issue). Moreover, we observed that multiple commits from different projects can refer to a same issue. This can happen, for example, when one or multiple projects have another project as a dependency. If the dependency has a ticket, then a first commit that addresses it could me made, after which other commits will be created in the dependent projects referring to the same issue. We observed this situation in projects that belong to the same ecosystem or that are developed by the same community (e.g., Hive, Hadoop and Spark, or Camel and ActiveMQ). Figure 8 shows the number of commits per Jira issue. While most of the issues are associated to only one commit, a considerable number of issues are associated to two or more commits. In these cases, our criterion to link tickets to the fix-commits can introduce incorrect associations and result in noisy data, that ultimately affect negatively the training of models.

Figure 8: Number of commits per Jira Ticket issue.

Furthermore, the ticket priority is manually set by the users, which can have different interpretations of what a Major or a Minor priority should be.

Finally, another challenge to this task derives from the priority distributions we encountered (shown in Figure 2). Most of the projects have a large proportion of commits that are either associated to tickets with priority Major or that have no associated ticket at all(NoTicket); the other priorities concern a minority of commits.

There are also projects in which commits that reference Jira tickets are rare. For these projects, almost every issue gets labeled as NoTicket. This could make the classification of commits from these projects trivial if the project has a very unique vocabulary. Indeed, the vocabulary of tokens, terminals and paths of the project could be very different from the global projects vocabulary. In these cases, the risk is that the model could learn the project vocabulary distribution and not its ticket priority distribution.

Figure 9: Proportion of NoTicket labeled examples for each project.

To verify that this phenomenon does not happen in our study, we used t-SNE on the code-vectors of the test dataset to generate a 2D visualization. Figure 10 shows two plots of a sample of code-vectors. In order not to clutter the diagram, we plot only code-vectors from the 20 largest projects. On the right-hand plot, each color represents a priority; on the left-hand, colors correspond to projects. We can see that there is no clear separation or clustering of projects, meaning that the model did not learn a distributed representation of projects. The two biggest classes, Major and NoTicket, contain many different projects and form large, sparse overlapping clusters, showing a large intra-class distance, but with quite a distinguishable separation between the two. The other classes form small and more dense clusters.

Figure 10: t-SNE plot of generated code-vectors.

Viii Conclusion

In this work, we introduced a method to represent source code changes capable of representing full commits, which can be composed of changes in multiples methods and in multiple files.

We exemplify the use of the our code commit representation by applying it to the problem of classifying security-relevant commits. We compare the use of token-based commit representation to AST-based commit representations. We observed a clear superior performance for AST-based commit representations. Furthermore, we explored the use of transfer learning techniques by pre-training our models on different pretext tasks. We conclude that training on a highly relevant pretext task is to be more beneficial than training on an extensive task with a larger dataset.