Chapter 6 · Part I · Learning from labels
Neoantigen immunogenicity for cancer vaccine design
Model: Neural network
Given peptides already displayed on a tumour cell, can a neural network predict which ones a T cell will actually notice?
Summary
A neural network was trained on peptides that all bind HLA-A*02:01, a cohort of 1,200 with 606 immunogenic and 594 not, split by sequence cluster rather than by peptide into 899 peptides for training and 301 for validation, 146 of those immunogenic. On the validation peptides the selected network scored 0.610 AUPRC and 0.665 AUC against 0.591 and 0.629 for a baseline that used binding affinity alone, with chance at 0.485 and 0.5, and that margin of 0.019 in AUPRC is the size of the network’s own run-to-run variation. Weaker binders turned out to be more often immunogenic than tighter ones, with two explanations the data cannot separate. The pre-registered final test on TESLA’s tumour-derived peptides never ran, because the table of validated peptides could not be retrieved: the public deposit holds only raw sequencing, and the supplement that carries the table was blocked by a browser challenge at PMC while Europe PMC refused the article as not open access.
Somewhere on the surface of a tumour cell, a protein is sitting that the immune system has never seen before. Cancer cells accumulate mutations, and some of those mutations change a protein’s sequence enough that a fragment of it, displayed on the cell surface, looks foreign. That fragment is called a neoantigen, and it exists nowhere else in the body.
Chapter 2 asked whether a peptide binds MHC and gets displayed at all. That question mattered, but it was only the first hurdle. Most displayed neoantigens are still ignored. A T cell has to notice the fragment and mount a response, and most of the time none does.
Here is the question this chapter asks. Given candidate neoantigens and the MHC molecule presenting them, can a neural network predict which ones will actually provoke a T-cell response, rather than which ones merely get displayed?
The question underneath that question matters for a practical reason. A personalised cancer vaccine can only carry a small number of targets. A candidate that gets displayed but is never noticed wastes a manufacturing slot that a genuinely immunogenic one could have filled.
One limitation belongs here and not at the end. The model can learn what tends to provoke a response in general. It cannot see a particular patient’s own T-cell repertoire, and two people can react differently to exactly the same neoantigen. That ceiling holds for every number this chapter reports.
6.1 Why a neural network
Immunogenicity depends on interactions across the whole peptide, position by position, combined with which HLA molecule is presenting it. That is not a boundary a single line or split can capture. It is closer to a pattern a network has to learn.
Chapter 5 took up a support vector machine, which finds the widest boundary between two outcomes. It was chosen for six numbers per person, the abundances of the genes of one bacterial pathway, and that design never ran, because the public data could not support it. The approach works when the features are few and the relationship between them is fairly stable.
This chapter hands the model the peptide itself, nine amino acids in sequence. Whether a peptide is noticed by a T cell does not depend on any one position alone. It depends on how the positions combine, an anchor residue holding the peptide in the MHC groove while a different position further along is what the T-cell receptor actually touches. Change one position and the meaning of another can change with it.
A support vector machine can be given those combinations by hand, multiplying features together before fitting the boundary. A network learns which combinations matter on its own, from the data, without being told in advance which positions interact. That is the actual difference this chapter is testing. Not a bigger model for its own sake: a model built for inputs where position matters and positions talk to each other.
The architecture choice is not exotic. A small feedforward network reading the encoded sequence, compared against a version built explicitly to model interactions between positions, with the choice made on validation performance before the TESLA benchmark is ever opened (Figure 6.1).
6.2 The data
Most of what is known about T-cell response is not about cancer at all.
The data this chapter needs comes from IEDB, the same database Chapter 2 used. It records whether a peptide, once shown to a T cell, actually provoked a response. That is immunogenicity data, and it is rarer than binding data. Most peptides in IEDB have only ever been tested for binding, not for response. Of the peptides that do have a response recorded, most come from viruses and other pathogens. Tumour-derived neoantigens are a small fraction of the whole.
There is a second problem underneath that one. A peptide that never binds MHC in the first place cannot be immunogenic, because it is never shown to a T cell at all. If a model trains on all peptides, bound and unbound together, it can learn to predict binding and call that immunogenicity. The two get confounded.
So the rule going in is this. Every peptide used here, for training or for testing, already binds MHC. The question the model answers is narrower than “is this peptide dangerous”. It is “given a peptide already sitting on the cell surface, does a T cell actually notice it”.
That narrows the training data further, to mostly pathogen epitopes that bind and provoke a response, tested against the much smaller set of tumour neoantigens that do the same. TESLA, a benchmark of real tumour neoantigens with confirmed T-cell response, is the largest of those. The model trains on the broad set. It gets tested, once, on the narrow one (Figure 6.2).
6.3 The rules
These rules were written before any pipeline ran.
Rules for this chapter
Data. IEDB’s T-cell assay records, restricted to HLA-A*02:01, the same allele Chapter 2 used. Every peptide included already has confirmed MHC binding, nothing that was never displayed. TESLA is held out completely, untouched until the very end.
Features. The nine peptide positions, nothing else. No HLA sequence, no clinical data, no patient information. HLA-A*02:01 is fixed across the whole dataset, so it cannot be a feature.
Outcome. Positive means a T-cell response was recorded in the assay. Negative means the peptide was tested and no response was detected. That definition is fixed before anyone looks at how many of each there are.
Split. Peptides are clustered by sequence similarity first, then split by cluster, not by individual peptide. Near-identical peptides landing on both sides of the split would let the model memorise instead of learn.
Metric. Immunogenic peptides are the minority class here, so accuracy is not the number that matters. The primary metric is the area under the precision-recall curve (AUPRC), reported alongside standard AUC. Chance is not 0.5 this time. Chance is whatever fraction of the dataset is actually positive.
Baseline. A model that predicts immunogenicity using only the binding score, nothing about the sequence itself. If the network cannot beat a model that only knows binding strength, sequence pattern recognition added nothing.
6.4 Four ways this could be wrong
I wrote these down in advance as well (Figure 6.3).
One. Assay negative is not biological negative. A T-cell assay tests one donor’s blood at one point in time. A peptide marked non-immunogenic may simply have met a donor whose repertoire did not include the right T cell that day. Absence of response in the data is not proof that the peptide can never provoke one.
Two. The training data still leans pathogen, not tumour, even after restricting to confirmed binders. Most immunogenic peptides in IEDB come from viruses. A pattern the network learns there may not transfer cleanly to a mutated self protein on a tumour cell.
Three. HLA-A*02:01 only. A large share of people do not carry this allele at all. Whatever this model learns says nothing about immunogenicity on any other HLA type, and that scope stays in the headline, not the fine print.
Four. Memorisation. The positive class here is small, and small positive classes are exactly where a network can learn the specific peptides in front of it rather than the pattern behind them. Clustering by similarity at the split reduces this. It does not remove it, and performance on TESLA is the real check.
6.5 What happened
I built this chapter’s model to clearly beat a simpler one. It did not.
The cohort came to 1,200 peptides, all confirmed to bind HLA-A*02:01. Of those, 606 were immunogenic and 594 were not. The rules had been written expecting the immunogenic peptides to be the minority class, and the memorisation risk rested on the same expectation. At 50.5% of the cohort they were a slim majority instead.
The label also hides a choice. A peptide counts as immunogenic if any one of its assays recorded a response, and 340 of the 1,200, 28.3%, have at least one assay that did and at least one that did not. All 340 are labelled immunogenic, and every number in this chapter inherits that ambiguity.
I split by cluster rather than by peptide. Near-identical variants of the same epitope are not the rule in this data: 1,061 of the 1,098 clusters hold a single peptide, and only 139 of the 1,200 peptides sit in a cluster with any other. That small group is what a random split would have spread across both sides, leaving 13.7% of validation peptides within two substitutions of a training peptide. The cluster split brought that to zero, and left 899 peptides for training and 301 for validation, 146 of them immunogenic. Listing 6.1 shows how the clusters are formed.
Listing 6.1 Joining every pair of peptides that differ at no more than two positions and taking each connected group as one cluster, from scripts/02_cluster_split.py.
n = len(peptides)
codes = np.array([[common.AA_INDEX[a] for a in p] for p in peptides], dtype=np.int8)
parent = np.arange(n)
def find(x: int) -> int:
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
def union(a: int, b: int) -> None:
ra, rb = find(a), find(b)
if ra != rb:
parent[max(ra, rb)] = min(ra, rb)
for i in range(n - 1):
# distance from peptide i to every peptide after it, in one vector op
d = (codes[i + 1:] != codes[i]).sum(axis=1)
for j in np.nonzero(d <= max_distance)[0]:
union(i, i + 1 + int(j))
roots = np.array([find(i) for i in range(n)])
_, cluster_id = np.unique(roots, return_inverse=True)
return cluster_id
I compared the two architectures, the feedforward network and the interaction model. The second was expected to win. It did not win clearly. All six configurations I tried scored between 0.603 and 0.615 AUPRC on the outer validation peptides, inside each other’s seed-to-seed noise, the spread a single configuration shows when it is run again from a different random starting point. The rule fixed in advance selected the feedforward network, using an inner validation split taken from inside the training data. On the outer validation split the ranking flipped, and the interaction model scored higher. Both numbers belong here, not only the one that favours the winner.
The core comparison came out just as narrow. Every peptide here is a confirmed binder, but confirmed binders still differ in how tightly they bind, so an affinity score has something left to rank them by. On the outer validation peptides the baseline using only binding affinity, with no sequence at all, scored 0.591 AUPRC. The selected network scored 0.610. Chance there is 0.485, the fraction of the 301 validation peptides that are immunogenic, and not the 0.505 of the cohort as a whole. That margin of 0.019 is the same size as the network’s own run-to-run variation.
The standard AUC the rules promised beside the AUPRC puts the two in the same order. The selected network reached 0.665 on the validation peptides, and the binding-affinity baseline 0.629, against 0.5 for chance, which on that curve does not move with the class balance.
6.6 What the result does and does not show
One result ran backwards from expectation. Weaker binders were more often immunogenic than tighter ones. Two explanations fit equally well. The immune system may delete the T-cell clones that would recognise tight-binding, self-like peptides; or tightly measured peptides may simply be the ones researchers chose to test. This data cannot tell which.
The bigger gap is the pre-registered final test, on TESLA’s tumour-derived peptides, which never ran. I could not get the table of validated peptides. The public Synapse deposit, syn21048999, holds only raw whole-exome and RNA sequencing, with no peptide-level table in it. The table is published in the supplementary material of the TESLA paper, and at PMC that download was blocked by a browser challenge, while Europe PMC would not serve the article either, reporting it as not open access. A person can still fetch that file in a browser, and the script that would score it is written and has been exercised on a synthetic table, so what is missing is the file itself. The headline number here has not been checked against real tumour neoantigens. It is the same pattern as Chapter 5. The real result is sometimes about what data you can actually reach, rather than the biology you set out to test.
Six chapters have now taken up six models, the fifth of them planned and never run, and every model that did run was handed the correct label during training and asked to reproduce it, the last of them a network learning for itself which combinations of positions mattered. Chapter 7 has no answer key. The model sees only the data and has to find structure inside it unaided, the way a biologist already does at a bench, sorting cells by what they look like rather than by a name someone assigned in advance. One chapter is left, and the book ends there on purpose, at a real stopping point, not because the models ran out.
This chapter is rewritten from the posts for Days 55 to 61 of the series.
Cite this chapter
Hussain, Q. (2026). Neoantigen immunogenicity for cancer vaccine design. In Machine Learning for Biology, chapter 6.