rikardsaqe commited on
Commit
85d34f2
Β·
verified Β·
1 Parent(s): 9879016

Concise copy + em-dash removal + calibration on leaderboard

Browse files
website/src/App.tsx CHANGED
@@ -55,8 +55,7 @@ export default function App() {
55
  <footer className="footer">
56
  <div className="footer-inner">
57
  <span>
58
- HydroPD β€” MS detectability prediction for non-animal food-protein
59
- hydrolysates
60
  </span>
61
  <span>
62
  <a
 
55
  <footer className="footer">
56
  <div className="footer-inner">
57
  <span>
58
+ HydroPD. MS detectability for non-animal protein hydrolysates.
 
59
  </span>
60
  <span>
61
  <a
website/src/components/ConditionMatcher.tsx CHANGED
@@ -40,8 +40,7 @@ export default function ConditionMatcher({
40
  <div className="field-label">
41
  Match my conditions{' '}
42
  <span className="field-hint">
43
- Describe how your peptides were made β€” we rank the models by similarity
44
- (species β†’ enzyme β†’ protocol).
45
  </span>
46
  </div>
47
 
 
40
  <div className="field-label">
41
  Match my conditions{' '}
42
  <span className="field-hint">
43
+ How were your peptides made? We rank models by species, then enzyme, then protocol.
 
44
  </span>
45
  </div>
46
 
website/src/data/generated/model_leaderboard.json CHANGED
@@ -7,7 +7,9 @@
7
  "f1",
8
  "precision",
9
  "recall",
10
- "specificity"
 
 
11
  ],
12
  "metricLabels": {
13
  "auroc": "AUROC",
@@ -17,11 +19,13 @@
17
  "f1": "F1",
18
  "precision": "Precision",
19
  "recall": "Sensitivity / recall",
20
- "specificity": "Specificity"
 
 
21
  },
22
  "nSpecies": 8,
23
  "nDatasets": 30,
24
- "note": "Aggregated across species from 5-fold protein-grouped CV on the 30 usable datasets. Per-metric values are the mean over folds, then over a species' datasets, then across species; min/max identify the weakest/strongest species.",
25
  "models": [
26
  {
27
  "id": "pfly_ft",
@@ -106,7 +110,7 @@
106
  "classifier": "xgb",
107
  "featureSet": "pep_phys",
108
  "label": "XGBoost \u00b7 PepBERT + physicochemical",
109
- "description": "Gradient-boosted decision trees (XGBoost) \u2014 the most consistent winner across datasets. PepBERT embeddings concatenated with the 14 physicochemical descriptors.",
110
  "nSpecies": 8,
111
  "nDatasets": 30,
112
  "agg": {
@@ -173,6 +177,22 @@
173
  "minSpecies": "Faba bean (Vicia faba)",
174
  "maxSpecies": "gracilaria",
175
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
177
  },
178
  "bySpecies": [
@@ -186,7 +206,9 @@
186
  "f1": 0.8409,
187
  "precision": 0.818,
188
  "recall": 0.8682,
189
- "specificity": 0.7887
 
 
190
  },
191
  {
192
  "species": "Spirulina (Arthrospira platensis)",
@@ -198,7 +220,9 @@
198
  "f1": 0.8249,
199
  "precision": 0.8005,
200
  "recall": 0.8569,
201
- "specificity": 0.7778
 
 
202
  },
203
  {
204
  "species": "Potato (Solanum tuberosum)",
@@ -210,7 +234,9 @@
210
  "f1": 0.7936,
211
  "precision": 0.7814,
212
  "recall": 0.8093,
213
- "specificity": 0.779
 
 
214
  },
215
  {
216
  "species": "Soybean (Glycine max)",
@@ -222,7 +248,9 @@
222
  "f1": 0.7349,
223
  "precision": 0.7065,
224
  "recall": 0.8187,
225
- "specificity": 0.7451
 
 
226
  },
227
  {
228
  "species": "wheat",
@@ -234,7 +262,9 @@
234
  "f1": 0.7695,
235
  "precision": 0.7272,
236
  "recall": 0.8239,
237
- "specificity": 0.6711
 
 
238
  },
239
  {
240
  "species": "Red rice bran (Oryza sativa)",
@@ -246,7 +276,9 @@
246
  "f1": 0.7278,
247
  "precision": 0.6995,
248
  "recall": 0.7826,
249
- "specificity": 0.5952
 
 
250
  },
251
  {
252
  "species": "Tetradesmus obliquus (microalga)",
@@ -258,7 +290,9 @@
258
  "f1": 0.7062,
259
  "precision": 0.716,
260
  "recall": 0.7314,
261
- "specificity": 0.6509
 
 
262
  },
263
  {
264
  "species": "Faba bean (Vicia faba)",
@@ -270,7 +304,9 @@
270
  "f1": 0.7302,
271
  "precision": 0.7042,
272
  "recall": 0.8037,
273
- "specificity": 0.4583
 
 
274
  }
275
  ],
276
  "partial": false
@@ -280,7 +316,7 @@
280
  "classifier": "xgb",
281
  "featureSet": "esm2_phys",
282
  "label": "XGBoost \u00b7 ESM2 + physicochemical",
283
- "description": "Gradient-boosted decision trees (XGBoost) \u2014 the most consistent winner across datasets. ESM2 embeddings concatenated with the 14 physicochemical descriptors \u2014 best overall.",
284
  "nSpecies": 8,
285
  "nDatasets": 30,
286
  "agg": {
@@ -347,6 +383,22 @@
347
  "minSpecies": "Faba bean (Vicia faba)",
348
  "maxSpecies": "gracilaria",
349
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  }
351
  },
352
  "bySpecies": [
@@ -360,7 +412,9 @@
360
  "f1": 0.8377,
361
  "precision": 0.8395,
362
  "recall": 0.8406,
363
- "specificity": 0.8315
 
 
364
  },
365
  {
366
  "species": "Spirulina (Arthrospira platensis)",
@@ -372,7 +426,9 @@
372
  "f1": 0.8161,
373
  "precision": 0.8009,
374
  "recall": 0.8394,
375
- "specificity": 0.7867
 
 
376
  },
377
  {
378
  "species": "Potato (Solanum tuberosum)",
@@ -384,7 +440,9 @@
384
  "f1": 0.7895,
385
  "precision": 0.7781,
386
  "recall": 0.804,
387
- "specificity": 0.7759
 
 
388
  },
389
  {
390
  "species": "Soybean (Glycine max)",
@@ -396,7 +454,9 @@
396
  "f1": 0.7253,
397
  "precision": 0.7045,
398
  "recall": 0.7994,
399
- "specificity": 0.7512
 
 
400
  },
401
  {
402
  "species": "wheat",
@@ -408,7 +468,9 @@
408
  "f1": 0.7691,
409
  "precision": 0.7208,
410
  "recall": 0.8322,
411
- "specificity": 0.6561
 
 
412
  },
413
  {
414
  "species": "Faba bean (Vicia faba)",
@@ -420,7 +482,9 @@
420
  "f1": 0.7492,
421
  "precision": 0.7059,
422
  "recall": 0.8477,
423
- "specificity": 0.4192
 
 
424
  },
425
  {
426
  "species": "Tetradesmus obliquus (microalga)",
@@ -432,7 +496,9 @@
432
  "f1": 0.6923,
433
  "precision": 0.703,
434
  "recall": 0.7307,
435
- "specificity": 0.6084
 
 
436
  },
437
  {
438
  "species": "Red rice bran (Oryza sativa)",
@@ -444,7 +510,9 @@
444
  "f1": 0.6993,
445
  "precision": 0.6735,
446
  "recall": 0.76,
447
- "specificity": 0.5337
 
 
448
  }
449
  ],
450
  "partial": false
@@ -454,7 +522,7 @@
454
  "classifier": "xgb",
455
  "featureSet": "esm2",
456
  "label": "XGBoost \u00b7 ESM2",
457
- "description": "Gradient-boosted decision trees (XGBoost) \u2014 the most consistent winner across datasets. ESM2-t12-35M protein-language-model embeddings of the peptide sequence.",
458
  "nSpecies": 8,
459
  "nDatasets": 30,
460
  "agg": {
@@ -521,6 +589,22 @@
521
  "minSpecies": "Faba bean (Vicia faba)",
522
  "maxSpecies": "gracilaria",
523
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524
  }
525
  },
526
  "bySpecies": [
@@ -534,7 +618,9 @@
534
  "f1": 0.8437,
535
  "precision": 0.8542,
536
  "recall": 0.8348,
537
- "specificity": 0.8482
 
 
538
  },
539
  {
540
  "species": "Spirulina (Arthrospira platensis)",
@@ -546,7 +632,9 @@
546
  "f1": 0.8062,
547
  "precision": 0.7921,
548
  "recall": 0.8305,
549
- "specificity": 0.7758
 
 
550
  },
551
  {
552
  "species": "Potato (Solanum tuberosum)",
@@ -558,7 +646,9 @@
558
  "f1": 0.7876,
559
  "precision": 0.7791,
560
  "recall": 0.7993,
561
- "specificity": 0.779
 
 
562
  },
563
  {
564
  "species": "Soybean (Glycine max)",
@@ -570,7 +660,9 @@
570
  "f1": 0.7316,
571
  "precision": 0.7042,
572
  "recall": 0.8162,
573
- "specificity": 0.7473
 
 
574
  },
575
  {
576
  "species": "wheat",
@@ -582,7 +674,9 @@
582
  "f1": 0.7676,
583
  "precision": 0.7208,
584
  "recall": 0.8298,
585
- "specificity": 0.6573
 
 
586
  },
587
  {
588
  "species": "Faba bean (Vicia faba)",
@@ -594,7 +688,9 @@
594
  "f1": 0.8437,
595
  "precision": 0.8045,
596
  "recall": 0.9401,
597
- "specificity": 0.4138
 
 
598
  },
599
  {
600
  "species": "Tetradesmus obliquus (microalga)",
@@ -606,7 +702,9 @@
606
  "f1": 0.6943,
607
  "precision": 0.7133,
608
  "recall": 0.7203,
609
- "specificity": 0.6343
 
 
610
  },
611
  {
612
  "species": "Red rice bran (Oryza sativa)",
@@ -618,7 +716,9 @@
618
  "f1": 0.682,
619
  "precision": 0.6612,
620
  "recall": 0.7473,
621
- "specificity": 0.5105
 
 
622
  }
623
  ],
624
  "partial": false
@@ -628,7 +728,7 @@
628
  "classifier": "mlp",
629
  "featureSet": "esm2_phys",
630
  "label": "Neural net (MLP) \u00b7 ESM2 + physicochemical",
631
- "description": "A small multilayer-perceptron neural net over the feature vector. ESM2 embeddings concatenated with the 14 physicochemical descriptors \u2014 best overall.",
632
  "nSpecies": 8,
633
  "nDatasets": 30,
634
  "agg": {
@@ -695,6 +795,22 @@
695
  "minSpecies": "Faba bean (Vicia faba)",
696
  "maxSpecies": "Spirulina (Arthrospira platensis)",
697
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
  }
699
  },
700
  "bySpecies": [
@@ -708,7 +824,9 @@
708
  "f1": 0.8312,
709
  "precision": 0.8172,
710
  "recall": 0.8486,
711
- "specificity": 0.7985
 
 
712
  },
713
  {
714
  "species": "Spirulina (Arthrospira platensis)",
@@ -720,7 +838,9 @@
720
  "f1": 0.8057,
721
  "precision": 0.8098,
722
  "recall": 0.8099,
723
- "specificity": 0.8039
 
 
724
  },
725
  {
726
  "species": "Soybean (Glycine max)",
@@ -732,7 +852,9 @@
732
  "f1": 0.7471,
733
  "precision": 0.7302,
734
  "recall": 0.8094,
735
- "specificity": 0.7795
 
 
736
  },
737
  {
738
  "species": "Potato (Solanum tuberosum)",
@@ -744,7 +866,9 @@
744
  "f1": 0.7797,
745
  "precision": 0.7812,
746
  "recall": 0.781,
747
- "specificity": 0.7872
 
 
748
  },
749
  {
750
  "species": "wheat",
@@ -756,7 +880,9 @@
756
  "f1": 0.7729,
757
  "precision": 0.7312,
758
  "recall": 0.8273,
759
- "specificity": 0.6748
 
 
760
  },
761
  {
762
  "species": "Faba bean (Vicia faba)",
@@ -768,7 +894,9 @@
768
  "f1": 0.7464,
769
  "precision": 0.7107,
770
  "recall": 0.8304,
771
- "specificity": 0.462
 
 
772
  },
773
  {
774
  "species": "Tetradesmus obliquus (microalga)",
@@ -780,7 +908,9 @@
780
  "f1": 0.682,
781
  "precision": 0.6966,
782
  "recall": 0.721,
783
- "specificity": 0.6002
 
 
784
  },
785
  {
786
  "species": "Red rice bran (Oryza sativa)",
@@ -792,7 +922,9 @@
792
  "f1": 0.6743,
793
  "precision": 0.6503,
794
  "recall": 0.7413,
795
- "specificity": 0.4788
 
 
796
  }
797
  ],
798
  "partial": false
@@ -869,6 +1001,22 @@
869
  "minSpecies": "Faba bean (Vicia faba)",
870
  "maxSpecies": "gracilaria",
871
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
872
  }
873
  },
874
  "bySpecies": [
@@ -882,7 +1030,9 @@
882
  "f1": 0.8367,
883
  "precision": 0.8287,
884
  "recall": 0.8483,
885
- "specificity": 0.8114
 
 
886
  },
887
  {
888
  "species": "Spirulina (Arthrospira platensis)",
@@ -894,7 +1044,9 @@
894
  "f1": 0.8065,
895
  "precision": 0.81,
896
  "recall": 0.8144,
897
- "specificity": 0.8011
 
 
898
  },
899
  {
900
  "species": "Soybean (Glycine max)",
@@ -906,7 +1058,9 @@
906
  "f1": 0.7636,
907
  "precision": 0.7428,
908
  "recall": 0.8383,
909
- "specificity": 0.7812
 
 
910
  },
911
  {
912
  "species": "Potato (Solanum tuberosum)",
@@ -918,7 +1072,9 @@
918
  "f1": 0.7786,
919
  "precision": 0.7812,
920
  "recall": 0.7791,
921
- "specificity": 0.7874
 
 
922
  },
923
  {
924
  "species": "wheat",
@@ -930,7 +1086,9 @@
930
  "f1": 0.765,
931
  "precision": 0.7259,
932
  "recall": 0.8171,
933
- "specificity": 0.6682
 
 
934
  },
935
  {
936
  "species": "Faba bean (Vicia faba)",
@@ -942,7 +1100,9 @@
942
  "f1": 0.7456,
943
  "precision": 0.7047,
944
  "recall": 0.8359,
945
- "specificity": 0.4296
 
 
946
  },
947
  {
948
  "species": "Tetradesmus obliquus (microalga)",
@@ -954,7 +1114,9 @@
954
  "f1": 0.6799,
955
  "precision": 0.6978,
956
  "recall": 0.6933,
957
- "specificity": 0.6218
 
 
958
  },
959
  {
960
  "species": "Red rice bran (Oryza sativa)",
@@ -966,7 +1128,9 @@
966
  "f1": 0.6764,
967
  "precision": 0.6675,
968
  "recall": 0.7195,
969
- "specificity": 0.5521
 
 
970
  }
971
  ],
972
  "partial": false
@@ -1043,6 +1207,22 @@
1043
  "minSpecies": "Faba bean (Vicia faba)",
1044
  "maxSpecies": "gracilaria",
1045
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1046
  }
1047
  },
1048
  "bySpecies": [
@@ -1056,7 +1236,9 @@
1056
  "f1": 0.8505,
1057
  "precision": 0.8453,
1058
  "recall": 0.8591,
1059
- "specificity": 0.8321
 
 
1060
  },
1061
  {
1062
  "species": "Spirulina (Arthrospira platensis)",
@@ -1068,7 +1250,9 @@
1068
  "f1": 0.8189,
1069
  "precision": 0.8074,
1070
  "recall": 0.8361,
1071
- "specificity": 0.7977
 
 
1072
  },
1073
  {
1074
  "species": "Soybean (Glycine max)",
@@ -1080,7 +1264,9 @@
1080
  "f1": 0.733,
1081
  "precision": 0.7256,
1082
  "recall": 0.8035,
1083
- "specificity": 0.768
 
 
1084
  },
1085
  {
1086
  "species": "Potato (Solanum tuberosum)",
@@ -1092,7 +1278,9 @@
1092
  "f1": 0.7783,
1093
  "precision": 0.7763,
1094
  "recall": 0.784,
1095
- "specificity": 0.7798
 
 
1096
  },
1097
  {
1098
  "species": "wheat",
@@ -1104,7 +1292,9 @@
1104
  "f1": 0.7615,
1105
  "precision": 0.7341,
1106
  "recall": 0.7972,
1107
- "specificity": 0.6942
 
 
1108
  },
1109
  {
1110
  "species": "Red rice bran (Oryza sativa)",
@@ -1116,7 +1306,9 @@
1116
  "f1": 0.6983,
1117
  "precision": 0.6933,
1118
  "recall": 0.7455,
1119
- "specificity": 0.584
 
 
1120
  },
1121
  {
1122
  "species": "Tetradesmus obliquus (microalga)",
@@ -1128,7 +1320,9 @@
1128
  "f1": 0.6748,
1129
  "precision": 0.7103,
1130
  "recall": 0.6921,
1131
- "specificity": 0.6543
 
 
1132
  },
1133
  {
1134
  "species": "Faba bean (Vicia faba)",
@@ -1140,7 +1334,9 @@
1140
  "f1": 0.72,
1141
  "precision": 0.7012,
1142
  "recall": 0.8006,
1143
- "specificity": 0.4236
 
 
1144
  }
1145
  ],
1146
  "partial": false
@@ -1150,7 +1346,7 @@
1150
  "classifier": "rf",
1151
  "featureSet": "pep_phys",
1152
  "label": "Random forest \u00b7 PepBERT + physicochemical",
1153
- "description": "Random forest \u2014 bagged decision trees; robust but usually a step behind XGBoost. PepBERT embeddings concatenated with the 14 physicochemical descriptors.",
1154
  "nSpecies": 8,
1155
  "nDatasets": 30,
1156
  "agg": {
@@ -1217,6 +1413,22 @@
1217
  "minSpecies": "Faba bean (Vicia faba)",
1218
  "maxSpecies": "gracilaria",
1219
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
  }
1221
  },
1222
  "bySpecies": [
@@ -1230,7 +1442,9 @@
1230
  "f1": 0.8393,
1231
  "precision": 0.8325,
1232
  "recall": 0.8493,
1233
- "specificity": 0.8173
 
 
1234
  },
1235
  {
1236
  "species": "Spirulina (Arthrospira platensis)",
@@ -1242,7 +1456,9 @@
1242
  "f1": 0.8094,
1243
  "precision": 0.7938,
1244
  "recall": 0.8352,
1245
- "specificity": 0.7732
 
 
1246
  },
1247
  {
1248
  "species": "Potato (Solanum tuberosum)",
@@ -1254,7 +1470,9 @@
1254
  "f1": 0.7745,
1255
  "precision": 0.7705,
1256
  "recall": 0.7838,
1257
- "specificity": 0.7729
 
 
1258
  },
1259
  {
1260
  "species": "Soybean (Glycine max)",
@@ -1266,7 +1484,9 @@
1266
  "f1": 0.7182,
1267
  "precision": 0.6867,
1268
  "recall": 0.8085,
1269
- "specificity": 0.723
 
 
1270
  },
1271
  {
1272
  "species": "wheat",
@@ -1278,7 +1498,9 @@
1278
  "f1": 0.7497,
1279
  "precision": 0.7113,
1280
  "recall": 0.8047,
1281
- "specificity": 0.651
 
 
1282
  },
1283
  {
1284
  "species": "Red rice bran (Oryza sativa)",
@@ -1290,7 +1512,9 @@
1290
  "f1": 0.6922,
1291
  "precision": 0.6962,
1292
  "recall": 0.7371,
1293
- "specificity": 0.5902
 
 
1294
  },
1295
  {
1296
  "species": "Tetradesmus obliquus (microalga)",
@@ -1302,7 +1526,9 @@
1302
  "f1": 0.6913,
1303
  "precision": 0.7102,
1304
  "recall": 0.7419,
1305
- "specificity": 0.6087
 
 
1306
  },
1307
  {
1308
  "species": "Faba bean (Vicia faba)",
@@ -1314,7 +1540,9 @@
1314
  "f1": 0.7217,
1315
  "precision": 0.6949,
1316
  "recall": 0.8117,
1317
- "specificity": 0.3821
 
 
1318
  }
1319
  ],
1320
  "partial": false
@@ -1324,7 +1552,7 @@
1324
  "classifier": "rf",
1325
  "featureSet": "esm2_phys",
1326
  "label": "Random forest \u00b7 ESM2 + physicochemical",
1327
- "description": "Random forest \u2014 bagged decision trees; robust but usually a step behind XGBoost. ESM2 embeddings concatenated with the 14 physicochemical descriptors \u2014 best overall.",
1328
  "nSpecies": 8,
1329
  "nDatasets": 30,
1330
  "agg": {
@@ -1391,6 +1619,22 @@
1391
  "minSpecies": "Faba bean (Vicia faba)",
1392
  "maxSpecies": "gracilaria",
1393
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1394
  }
1395
  },
1396
  "bySpecies": [
@@ -1404,7 +1648,9 @@
1404
  "f1": 0.8185,
1405
  "precision": 0.8316,
1406
  "recall": 0.8115,
1407
- "specificity": 0.829
 
 
1408
  },
1409
  {
1410
  "species": "Spirulina (Arthrospira platensis)",
@@ -1416,7 +1662,9 @@
1416
  "f1": 0.8028,
1417
  "precision": 0.7936,
1418
  "recall": 0.8219,
1419
- "specificity": 0.7809
 
 
1420
  },
1421
  {
1422
  "species": "Potato (Solanum tuberosum)",
@@ -1428,7 +1676,9 @@
1428
  "f1": 0.7744,
1429
  "precision": 0.7729,
1430
  "recall": 0.7805,
1431
- "specificity": 0.7768
 
 
1432
  },
1433
  {
1434
  "species": "Soybean (Glycine max)",
@@ -1440,7 +1690,9 @@
1440
  "f1": 0.7093,
1441
  "precision": 0.7035,
1442
  "recall": 0.7739,
1443
- "specificity": 0.7522
 
 
1444
  },
1445
  {
1446
  "species": "wheat",
@@ -1452,7 +1704,9 @@
1452
  "f1": 0.7526,
1453
  "precision": 0.7065,
1454
  "recall": 0.8162,
1455
- "specificity": 0.6377
 
 
1456
  },
1457
  {
1458
  "species": "Faba bean (Vicia faba)",
@@ -1464,7 +1718,9 @@
1464
  "f1": 0.7349,
1465
  "precision": 0.7016,
1466
  "recall": 0.8311,
1467
- "specificity": 0.391
 
 
1468
  },
1469
  {
1470
  "species": "Tetradesmus obliquus (microalga)",
@@ -1476,7 +1732,9 @@
1476
  "f1": 0.6834,
1477
  "precision": 0.7126,
1478
  "recall": 0.7116,
1479
- "specificity": 0.6356
 
 
1480
  },
1481
  {
1482
  "species": "Red rice bran (Oryza sativa)",
@@ -1488,7 +1746,9 @@
1488
  "f1": 0.6812,
1489
  "precision": 0.6718,
1490
  "recall": 0.7442,
1491
- "specificity": 0.5299
 
 
1492
  }
1493
  ],
1494
  "partial": false
@@ -1498,7 +1758,7 @@
1498
  "classifier": "rf",
1499
  "featureSet": "esm2",
1500
  "label": "Random forest \u00b7 ESM2",
1501
- "description": "Random forest \u2014 bagged decision trees; robust but usually a step behind XGBoost. ESM2-t12-35M protein-language-model embeddings of the peptide sequence.",
1502
  "nSpecies": 8,
1503
  "nDatasets": 30,
1504
  "agg": {
@@ -1565,6 +1825,22 @@
1565
  "minSpecies": "Faba bean (Vicia faba)",
1566
  "maxSpecies": "gracilaria",
1567
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1568
  }
1569
  },
1570
  "bySpecies": [
@@ -1578,7 +1854,9 @@
1578
  "f1": 0.8064,
1579
  "precision": 0.8091,
1580
  "recall": 0.8092,
1581
- "specificity": 0.7869
 
 
1582
  },
1583
  {
1584
  "species": "Spirulina (Arthrospira platensis)",
@@ -1590,7 +1868,9 @@
1590
  "f1": 0.7992,
1591
  "precision": 0.7952,
1592
  "recall": 0.8139,
1593
- "specificity": 0.7851
 
 
1594
  },
1595
  {
1596
  "species": "Potato (Solanum tuberosum)",
@@ -1602,7 +1882,9 @@
1602
  "f1": 0.7701,
1603
  "precision": 0.7724,
1604
  "recall": 0.7725,
1605
- "specificity": 0.7786
 
 
1606
  },
1607
  {
1608
  "species": "Soybean (Glycine max)",
@@ -1614,7 +1896,9 @@
1614
  "f1": 0.7155,
1615
  "precision": 0.7011,
1616
  "recall": 0.7971,
1617
- "specificity": 0.7447
 
 
1618
  },
1619
  {
1620
  "species": "wheat",
@@ -1626,7 +1910,9 @@
1626
  "f1": 0.7509,
1627
  "precision": 0.7056,
1628
  "recall": 0.8134,
1629
- "specificity": 0.6371
 
 
1630
  },
1631
  {
1632
  "species": "Faba bean (Vicia faba)",
@@ -1638,7 +1924,9 @@
1638
  "f1": 0.7386,
1639
  "precision": 0.7023,
1640
  "recall": 0.8383,
1641
- "specificity": 0.3918
 
 
1642
  },
1643
  {
1644
  "species": "Tetradesmus obliquus (microalga)",
@@ -1650,7 +1938,9 @@
1650
  "f1": 0.6622,
1651
  "precision": 0.7013,
1652
  "recall": 0.6863,
1653
- "specificity": 0.6165
 
 
1654
  },
1655
  {
1656
  "species": "Red rice bran (Oryza sativa)",
@@ -1662,7 +1952,9 @@
1662
  "f1": 0.6593,
1663
  "precision": 0.6537,
1664
  "recall": 0.7253,
1665
- "specificity": 0.4949
 
 
1666
  }
1667
  ],
1668
  "partial": false
@@ -1672,7 +1964,7 @@
1672
  "classifier": "rf",
1673
  "featureSet": "phys",
1674
  "label": "Random forest \u00b7 Physicochemical",
1675
- "description": "Random forest \u2014 bagged decision trees; robust but usually a step behind XGBoost. 14 physicochemical descriptors only (length, charge, hydrophobicity, \u2026). Fast, no embeddings.",
1676
  "nSpecies": 8,
1677
  "nDatasets": 30,
1678
  "agg": {
@@ -1739,6 +2031,22 @@
1739
  "minSpecies": "Faba bean (Vicia faba)",
1740
  "maxSpecies": "Spirulina (Arthrospira platensis)",
1741
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1742
  }
1743
  },
1744
  "bySpecies": [
@@ -1752,7 +2060,9 @@
1752
  "f1": 0.788,
1753
  "precision": 0.7707,
1754
  "recall": 0.826,
1755
- "specificity": 0.7283
 
 
1756
  },
1757
  {
1758
  "species": "Spirulina (Arthrospira platensis)",
@@ -1764,7 +2074,9 @@
1764
  "f1": 0.8018,
1765
  "precision": 0.7896,
1766
  "recall": 0.8239,
1767
- "specificity": 0.7706
 
 
1768
  },
1769
  {
1770
  "species": "Potato (Solanum tuberosum)",
@@ -1776,7 +2088,9 @@
1776
  "f1": 0.7579,
1777
  "precision": 0.75,
1778
  "recall": 0.7701,
1779
- "specificity": 0.7487
 
 
1780
  },
1781
  {
1782
  "species": "Faba bean (Vicia faba)",
@@ -1788,7 +2102,9 @@
1788
  "f1": 0.749,
1789
  "precision": 0.728,
1790
  "recall": 0.8072,
1791
- "specificity": 0.5762
 
 
1792
  },
1793
  {
1794
  "species": "Soybean (Glycine max)",
@@ -1800,7 +2116,9 @@
1800
  "f1": 0.646,
1801
  "precision": 0.659,
1802
  "recall": 0.697,
1803
- "specificity": 0.7169
 
 
1804
  },
1805
  {
1806
  "species": "wheat",
@@ -1812,7 +2130,9 @@
1812
  "f1": 0.7237,
1813
  "precision": 0.6861,
1814
  "recall": 0.7745,
1815
- "specificity": 0.6242
 
 
1816
  },
1817
  {
1818
  "species": "Tetradesmus obliquus (microalga)",
@@ -1824,7 +2144,9 @@
1824
  "f1": 0.6949,
1825
  "precision": 0.7324,
1826
  "recall": 0.6974,
1827
- "specificity": 0.6867
 
 
1828
  },
1829
  {
1830
  "species": "Red rice bran (Oryza sativa)",
@@ -1836,7 +2158,9 @@
1836
  "f1": 0.6967,
1837
  "precision": 0.7086,
1838
  "recall": 0.7247,
1839
- "specificity": 0.6185
 
 
1840
  }
1841
  ],
1842
  "partial": false
@@ -1846,7 +2170,7 @@
1846
  "classifier": "xgb",
1847
  "featureSet": "phys",
1848
  "label": "XGBoost \u00b7 Physicochemical",
1849
- "description": "Gradient-boosted decision trees (XGBoost) \u2014 the most consistent winner across datasets. 14 physicochemical descriptors only (length, charge, hydrophobicity, \u2026). Fast, no embeddings.",
1850
  "nSpecies": 8,
1851
  "nDatasets": 30,
1852
  "agg": {
@@ -1913,6 +2237,22 @@
1913
  "minSpecies": "Faba bean (Vicia faba)",
1914
  "maxSpecies": "Spirulina (Arthrospira platensis)",
1915
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1916
  }
1917
  },
1918
  "bySpecies": [
@@ -1926,7 +2266,9 @@
1926
  "f1": 0.8122,
1927
  "precision": 0.7824,
1928
  "recall": 0.8552,
1929
- "specificity": 0.7457
 
 
1930
  },
1931
  {
1932
  "species": "Spirulina (Arthrospira platensis)",
@@ -1938,7 +2280,9 @@
1938
  "f1": 0.7966,
1939
  "precision": 0.7895,
1940
  "recall": 0.8119,
1941
- "specificity": 0.7723
 
 
1942
  },
1943
  {
1944
  "species": "Potato (Solanum tuberosum)",
@@ -1950,7 +2294,9 @@
1950
  "f1": 0.7616,
1951
  "precision": 0.7475,
1952
  "recall": 0.7794,
1953
- "specificity": 0.7417
 
 
1954
  },
1955
  {
1956
  "species": "Faba bean (Vicia faba)",
@@ -1962,7 +2308,9 @@
1962
  "f1": 0.8344,
1963
  "precision": 0.8231,
1964
  "recall": 0.8792,
1965
- "specificity": 0.5668
 
 
1966
  },
1967
  {
1968
  "species": "Tetradesmus obliquus (microalga)",
@@ -1974,7 +2322,9 @@
1974
  "f1": 0.7017,
1975
  "precision": 0.7197,
1976
  "recall": 0.7183,
1977
- "specificity": 0.6611
 
 
1978
  },
1979
  {
1980
  "species": "Soybean (Glycine max)",
@@ -1986,7 +2336,9 @@
1986
  "f1": 0.649,
1987
  "precision": 0.6453,
1988
  "recall": 0.7208,
1989
- "specificity": 0.6825
 
 
1990
  },
1991
  {
1992
  "species": "wheat",
@@ -1998,7 +2350,9 @@
1998
  "f1": 0.7217,
1999
  "precision": 0.6847,
2000
  "recall": 0.7696,
2001
- "specificity": 0.6256
 
 
2002
  },
2003
  {
2004
  "species": "Red rice bran (Oryza sativa)",
@@ -2010,7 +2364,9 @@
2010
  "f1": 0.7092,
2011
  "precision": 0.7075,
2012
  "recall": 0.7422,
2013
- "specificity": 0.6158
 
 
2014
  }
2015
  ],
2016
  "partial": false
@@ -2020,7 +2376,7 @@
2020
  "classifier": "xgb",
2021
  "featureSet": "pepbert",
2022
  "label": "XGBoost \u00b7 PepBERT",
2023
- "description": "Gradient-boosted decision trees (XGBoost) \u2014 the most consistent winner across datasets. PepBERT protein-language-model embeddings of the peptide sequence.",
2024
  "nSpecies": 8,
2025
  "nDatasets": 30,
2026
  "agg": {
@@ -2087,6 +2443,22 @@
2087
  "minSpecies": "Faba bean (Vicia faba)",
2088
  "maxSpecies": "gracilaria",
2089
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2090
  }
2091
  },
2092
  "bySpecies": [
@@ -2100,7 +2472,9 @@
2100
  "f1": 0.8353,
2101
  "precision": 0.8244,
2102
  "recall": 0.8497,
2103
- "specificity": 0.7981
 
 
2104
  },
2105
  {
2106
  "species": "Spirulina (Arthrospira platensis)",
@@ -2112,7 +2486,9 @@
2112
  "f1": 0.8036,
2113
  "precision": 0.7972,
2114
  "recall": 0.8186,
2115
- "specificity": 0.7851
 
 
2116
  },
2117
  {
2118
  "species": "Potato (Solanum tuberosum)",
@@ -2124,7 +2500,9 @@
2124
  "f1": 0.7806,
2125
  "precision": 0.7771,
2126
  "recall": 0.7871,
2127
- "specificity": 0.7799
 
 
2128
  },
2129
  {
2130
  "species": "Soybean (Glycine max)",
@@ -2136,7 +2514,9 @@
2136
  "f1": 0.7229,
2137
  "precision": 0.695,
2138
  "recall": 0.8075,
2139
- "specificity": 0.7324
 
 
2140
  },
2141
  {
2142
  "species": "wheat",
@@ -2148,7 +2528,9 @@
2148
  "f1": 0.7588,
2149
  "precision": 0.7197,
2150
  "recall": 0.8101,
2151
- "specificity": 0.664
 
 
2152
  },
2153
  {
2154
  "species": "Red rice bran (Oryza sativa)",
@@ -2160,7 +2542,9 @@
2160
  "f1": 0.6984,
2161
  "precision": 0.6867,
2162
  "recall": 0.7438,
2163
- "specificity": 0.5761
 
 
2164
  },
2165
  {
2166
  "species": "Tetradesmus obliquus (microalga)",
@@ -2172,7 +2556,9 @@
2172
  "f1": 0.6924,
2173
  "precision": 0.6974,
2174
  "recall": 0.7256,
2175
- "specificity": 0.6102
 
 
2176
  },
2177
  {
2178
  "species": "Faba bean (Vicia faba)",
@@ -2184,7 +2570,9 @@
2184
  "f1": 0.8102,
2185
  "precision": 0.7944,
2186
  "recall": 0.8821,
2187
- "specificity": 0.41
 
 
2188
  }
2189
  ],
2190
  "partial": false
@@ -2261,6 +2649,22 @@
2261
  "minSpecies": "Faba bean (Vicia faba)",
2262
  "maxSpecies": "gracilaria",
2263
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2264
  }
2265
  },
2266
  "bySpecies": [
@@ -2274,7 +2678,9 @@
2274
  "f1": 0.8133,
2275
  "precision": 0.7946,
2276
  "recall": 0.8374,
2277
- "specificity": 0.7739
 
 
2278
  },
2279
  {
2280
  "species": "Spirulina (Arthrospira platensis)",
@@ -2286,7 +2692,9 @@
2286
  "f1": 0.8084,
2287
  "precision": 0.7936,
2288
  "recall": 0.8329,
2289
- "specificity": 0.7732
 
 
2290
  },
2291
  {
2292
  "species": "Potato (Solanum tuberosum)",
@@ -2298,7 +2706,9 @@
2298
  "f1": 0.7783,
2299
  "precision": 0.7728,
2300
  "recall": 0.7872,
2301
- "specificity": 0.7734
 
 
2302
  },
2303
  {
2304
  "species": "Soybean (Glycine max)",
@@ -2310,7 +2720,9 @@
2310
  "f1": 0.7185,
2311
  "precision": 0.7165,
2312
  "recall": 0.7735,
2313
- "specificity": 0.7616
 
 
2314
  },
2315
  {
2316
  "species": "wheat",
@@ -2322,7 +2734,9 @@
2322
  "f1": 0.7544,
2323
  "precision": 0.7211,
2324
  "recall": 0.7991,
2325
- "specificity": 0.6735
 
 
2326
  },
2327
  {
2328
  "species": "Faba bean (Vicia faba)",
@@ -2334,7 +2748,9 @@
2334
  "f1": 0.625,
2335
  "precision": 0.6004,
2336
  "recall": 0.7079,
2337
- "specificity": 0.4211
 
 
2338
  },
2339
  {
2340
  "species": "Red rice bran (Oryza sativa)",
@@ -2346,7 +2762,9 @@
2346
  "f1": 0.6815,
2347
  "precision": 0.6645,
2348
  "recall": 0.7515,
2349
- "specificity": 0.5091
 
 
2350
  },
2351
  {
2352
  "species": "Tetradesmus obliquus (microalga)",
@@ -2358,7 +2776,9 @@
2358
  "f1": 0.6919,
2359
  "precision": 0.6807,
2360
  "recall": 0.746,
2361
- "specificity": 0.5542
 
 
2362
  }
2363
  ],
2364
  "partial": false
@@ -2368,7 +2788,7 @@
2368
  "classifier": "rf",
2369
  "featureSet": "pepbert",
2370
  "label": "Random forest \u00b7 PepBERT",
2371
- "description": "Random forest \u2014 bagged decision trees; robust but usually a step behind XGBoost. PepBERT protein-language-model embeddings of the peptide sequence.",
2372
  "nSpecies": 8,
2373
  "nDatasets": 30,
2374
  "agg": {
@@ -2435,6 +2855,22 @@
2435
  "minSpecies": "Faba bean (Vicia faba)",
2436
  "maxSpecies": "gracilaria",
2437
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2438
  }
2439
  },
2440
  "bySpecies": [
@@ -2448,7 +2884,9 @@
2448
  "f1": 0.8302,
2449
  "precision": 0.8346,
2450
  "recall": 0.8286,
2451
- "specificity": 0.8219
 
 
2452
  },
2453
  {
2454
  "species": "Spirulina (Arthrospira platensis)",
@@ -2460,7 +2898,9 @@
2460
  "f1": 0.7834,
2461
  "precision": 0.7843,
2462
  "recall": 0.7963,
2463
- "specificity": 0.7724
 
 
2464
  },
2465
  {
2466
  "species": "Potato (Solanum tuberosum)",
@@ -2472,7 +2912,9 @@
2472
  "f1": 0.7599,
2473
  "precision": 0.7692,
2474
  "recall": 0.7571,
2475
- "specificity": 0.7791
 
 
2476
  },
2477
  {
2478
  "species": "Soybean (Glycine max)",
@@ -2484,7 +2926,9 @@
2484
  "f1": 0.7028,
2485
  "precision": 0.6751,
2486
  "recall": 0.7892,
2487
- "specificity": 0.71
 
 
2488
  },
2489
  {
2490
  "species": "wheat",
@@ -2496,7 +2940,9 @@
2496
  "f1": 0.7402,
2497
  "precision": 0.7024,
2498
  "recall": 0.7949,
2499
- "specificity": 0.6406
 
 
2500
  },
2501
  {
2502
  "species": "Red rice bran (Oryza sativa)",
@@ -2508,7 +2954,9 @@
2508
  "f1": 0.6816,
2509
  "precision": 0.6801,
2510
  "recall": 0.7353,
2511
- "specificity": 0.555
 
 
2512
  },
2513
  {
2514
  "species": "Tetradesmus obliquus (microalga)",
@@ -2520,7 +2968,9 @@
2520
  "f1": 0.6469,
2521
  "precision": 0.6841,
2522
  "recall": 0.6966,
2523
- "specificity": 0.5675
 
 
2524
  },
2525
  {
2526
  "species": "Faba bean (Vicia faba)",
@@ -2532,7 +2982,9 @@
2532
  "f1": 0.7049,
2533
  "precision": 0.6921,
2534
  "recall": 0.7872,
2535
- "specificity": 0.3767
 
 
2536
  }
2537
  ],
2538
  "partial": false
@@ -2609,6 +3061,22 @@
2609
  "minSpecies": "Red rice bran (Oryza sativa)",
2610
  "maxSpecies": "gracilaria",
2611
  "nSpecies": 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2612
  }
2613
  },
2614
  "bySpecies": [
@@ -2622,7 +3090,9 @@
2622
  "f1": 0.8234,
2623
  "precision": 0.7979,
2624
  "recall": 0.8571,
2625
- "specificity": 0.7733
 
 
2626
  },
2627
  {
2628
  "species": "Spirulina (Arthrospira platensis)",
@@ -2634,7 +3104,9 @@
2634
  "f1": 0.7919,
2635
  "precision": 0.7815,
2636
  "recall": 0.8151,
2637
- "specificity": 0.7621
 
 
2638
  },
2639
  {
2640
  "species": "Faba bean (Vicia faba)",
@@ -2646,7 +3118,9 @@
2646
  "f1": 0.741,
2647
  "precision": 0.7295,
2648
  "recall": 0.7976,
2649
- "specificity": 0.5743
 
 
2650
  },
2651
  {
2652
  "species": "Potato (Solanum tuberosum)",
@@ -2658,7 +3132,9 @@
2658
  "f1": 0.7467,
2659
  "precision": 0.7403,
2660
  "recall": 0.7579,
2661
- "specificity": 0.7378
 
 
2662
  },
2663
  {
2664
  "species": "Soybean (Glycine max)",
@@ -2670,7 +3146,9 @@
2670
  "f1": 0.6638,
2671
  "precision": 0.6707,
2672
  "recall": 0.7191,
2673
- "specificity": 0.73
 
 
2674
  },
2675
  {
2676
  "species": "wheat",
@@ -2682,7 +3160,9 @@
2682
  "f1": 0.7156,
2683
  "precision": 0.6822,
2684
  "recall": 0.7612,
2685
- "specificity": 0.6242
 
 
2686
  },
2687
  {
2688
  "species": "Tetradesmus obliquus (microalga)",
@@ -2694,7 +3174,9 @@
2694
  "f1": 0.7004,
2695
  "precision": 0.6996,
2696
  "recall": 0.7491,
2697
- "specificity": 0.6011
 
 
2698
  },
2699
  {
2700
  "species": "Red rice bran (Oryza sativa)",
@@ -2706,7 +3188,9 @@
2706
  "f1": 0.6507,
2707
  "precision": 0.6505,
2708
  "recall": 0.7177,
2709
- "specificity": 0.4784
 
 
2710
  }
2711
  ],
2712
  "partial": false
 
7
  "f1",
8
  "precision",
9
  "recall",
10
+ "specificity",
11
+ "brier",
12
+ "ece"
13
  ],
14
  "metricLabels": {
15
  "auroc": "AUROC",
 
19
  "f1": "F1",
20
  "precision": "Precision",
21
  "recall": "Sensitivity / recall",
22
+ "specificity": "Specificity",
23
+ "brier": "Brier",
24
+ "ece": "ECE"
25
  },
26
  "nSpecies": 8,
27
  "nDatasets": 30,
28
+ "note": "Aggregated across species from 5-fold protein-grouped CV on the 30 usable datasets. Each value is the mean over folds, then over a species' datasets, then across species. Brier and ECE are calibration metrics where lower is better.",
29
  "models": [
30
  {
31
  "id": "pfly_ft",
 
110
  "classifier": "xgb",
111
  "featureSet": "pep_phys",
112
  "label": "XGBoost \u00b7 PepBERT + physicochemical",
113
+ "description": "Gradient-boosted decision trees. The most consistent winner across datasets. PepBERT embeddings concatenated with the 14 physicochemical descriptors.",
114
  "nSpecies": 8,
115
  "nDatasets": 30,
116
  "agg": {
 
177
  "minSpecies": "Faba bean (Vicia faba)",
178
  "maxSpecies": "gracilaria",
179
  "nSpecies": 8
180
+ },
181
+ "brier": {
182
+ "mean": 0.186,
183
+ "min": 0.1178,
184
+ "max": 0.2698,
185
+ "minSpecies": "gracilaria",
186
+ "maxSpecies": "Faba bean (Vicia faba)",
187
+ "nSpecies": 8
188
+ },
189
+ "ece": {
190
+ "mean": 0.1555,
191
+ "min": 0.0626,
192
+ "max": 0.2674,
193
+ "minSpecies": "Potato (Solanum tuberosum)",
194
+ "maxSpecies": "Faba bean (Vicia faba)",
195
+ "nSpecies": 8
196
  }
197
  },
198
  "bySpecies": [
 
206
  "f1": 0.8409,
207
  "precision": 0.818,
208
  "recall": 0.8682,
209
+ "specificity": 0.7887,
210
+ "brier": 0.1178,
211
+ "ece": 0.0951
212
  },
213
  {
214
  "species": "Spirulina (Arthrospira platensis)",
 
220
  "f1": 0.8249,
221
  "precision": 0.8005,
222
  "recall": 0.8569,
223
+ "specificity": 0.7778,
224
+ "brier": 0.1394,
225
+ "ece": 0.1071
226
  },
227
  {
228
  "species": "Potato (Solanum tuberosum)",
 
234
  "f1": 0.7936,
235
  "precision": 0.7814,
236
  "recall": 0.8093,
237
+ "specificity": 0.779,
238
+ "brier": 0.1469,
239
+ "ece": 0.0626
240
  },
241
  {
242
  "species": "Soybean (Glycine max)",
 
248
  "f1": 0.7349,
249
  "precision": 0.7065,
250
  "recall": 0.8187,
251
+ "specificity": 0.7451,
252
+ "brier": 0.1834,
253
+ "ece": 0.1672
254
  },
255
  {
256
  "species": "wheat",
 
262
  "f1": 0.7695,
263
  "precision": 0.7272,
264
  "recall": 0.8239,
265
+ "specificity": 0.6711,
266
+ "brier": 0.1809,
267
+ "ece": 0.1174
268
  },
269
  {
270
  "species": "Red rice bran (Oryza sativa)",
 
276
  "f1": 0.7278,
277
  "precision": 0.6995,
278
  "recall": 0.7826,
279
+ "specificity": 0.5952,
280
+ "brier": 0.2226,
281
+ "ece": 0.2067
282
  },
283
  {
284
  "species": "Tetradesmus obliquus (microalga)",
 
290
  "f1": 0.7062,
291
  "precision": 0.716,
292
  "recall": 0.7314,
293
+ "specificity": 0.6509,
294
+ "brier": 0.2272,
295
+ "ece": 0.2209
296
  },
297
  {
298
  "species": "Faba bean (Vicia faba)",
 
304
  "f1": 0.7302,
305
  "precision": 0.7042,
306
  "recall": 0.8037,
307
+ "specificity": 0.4583,
308
+ "brier": 0.2698,
309
+ "ece": 0.2674
310
  }
311
  ],
312
  "partial": false
 
316
  "classifier": "xgb",
317
  "featureSet": "esm2_phys",
318
  "label": "XGBoost \u00b7 ESM2 + physicochemical",
319
+ "description": "Gradient-boosted decision trees. The most consistent winner across datasets. ESM2 embeddings plus the 14 physicochemical descriptors. Best overall.",
320
  "nSpecies": 8,
321
  "nDatasets": 30,
322
  "agg": {
 
383
  "minSpecies": "Faba bean (Vicia faba)",
384
  "maxSpecies": "gracilaria",
385
  "nSpecies": 8
386
+ },
387
+ "brier": {
388
+ "mean": 0.1918,
389
+ "min": 0.1168,
390
+ "max": 0.28,
391
+ "minSpecies": "gracilaria",
392
+ "maxSpecies": "Faba bean (Vicia faba)",
393
+ "nSpecies": 8
394
+ },
395
+ "ece": {
396
+ "mean": 0.1594,
397
+ "min": 0.0684,
398
+ "max": 0.2359,
399
+ "minSpecies": "Potato (Solanum tuberosum)",
400
+ "maxSpecies": "Faba bean (Vicia faba)",
401
+ "nSpecies": 8
402
  }
403
  },
404
  "bySpecies": [
 
412
  "f1": 0.8377,
413
  "precision": 0.8395,
414
  "recall": 0.8406,
415
+ "specificity": 0.8315,
416
+ "brier": 0.1168,
417
+ "ece": 0.1025
418
  },
419
  {
420
  "species": "Spirulina (Arthrospira platensis)",
 
426
  "f1": 0.8161,
427
  "precision": 0.8009,
428
  "recall": 0.8394,
429
+ "specificity": 0.7867,
430
+ "brier": 0.1454,
431
+ "ece": 0.1218
432
  },
433
  {
434
  "species": "Potato (Solanum tuberosum)",
 
440
  "f1": 0.7895,
441
  "precision": 0.7781,
442
  "recall": 0.804,
443
+ "specificity": 0.7759,
444
+ "brier": 0.1492,
445
+ "ece": 0.0684
446
  },
447
  {
448
  "species": "Soybean (Glycine max)",
 
454
  "f1": 0.7253,
455
  "precision": 0.7045,
456
  "recall": 0.7994,
457
+ "specificity": 0.7512,
458
+ "brier": 0.1795,
459
+ "ece": 0.1552
460
  },
461
  {
462
  "species": "wheat",
 
468
  "f1": 0.7691,
469
  "precision": 0.7208,
470
  "recall": 0.8322,
471
+ "specificity": 0.6561,
472
+ "brier": 0.1854,
473
+ "ece": 0.1304
474
  },
475
  {
476
  "species": "Faba bean (Vicia faba)",
 
482
  "f1": 0.7492,
483
  "precision": 0.7059,
484
  "recall": 0.8477,
485
+ "specificity": 0.4192,
486
+ "brier": 0.28,
487
+ "ece": 0.2359
488
  },
489
  {
490
  "species": "Tetradesmus obliquus (microalga)",
 
496
  "f1": 0.6923,
497
  "precision": 0.703,
498
  "recall": 0.7307,
499
+ "specificity": 0.6084,
500
+ "brier": 0.2279,
501
+ "ece": 0.2338
502
  },
503
  {
504
  "species": "Red rice bran (Oryza sativa)",
 
510
  "f1": 0.6993,
511
  "precision": 0.6735,
512
  "recall": 0.76,
513
+ "specificity": 0.5337,
514
+ "brier": 0.2506,
515
+ "ece": 0.227
516
  }
517
  ],
518
  "partial": false
 
522
  "classifier": "xgb",
523
  "featureSet": "esm2",
524
  "label": "XGBoost \u00b7 ESM2",
525
+ "description": "Gradient-boosted decision trees. The most consistent winner across datasets. ESM2-t12-35M protein-language-model embeddings of the peptide sequence.",
526
  "nSpecies": 8,
527
  "nDatasets": 30,
528
  "agg": {
 
589
  "minSpecies": "Faba bean (Vicia faba)",
590
  "maxSpecies": "gracilaria",
591
  "nSpecies": 8
592
+ },
593
+ "brier": {
594
+ "mean": 0.1954,
595
+ "min": 0.1208,
596
+ "max": 0.2773,
597
+ "minSpecies": "gracilaria",
598
+ "maxSpecies": "Faba bean (Vicia faba)",
599
+ "nSpecies": 8
600
+ },
601
+ "ece": {
602
+ "mean": 0.1604,
603
+ "min": 0.0685,
604
+ "max": 0.2511,
605
+ "minSpecies": "Potato (Solanum tuberosum)",
606
+ "maxSpecies": "Red rice bran (Oryza sativa)",
607
+ "nSpecies": 8
608
  }
609
  },
610
  "bySpecies": [
 
618
  "f1": 0.8437,
619
  "precision": 0.8542,
620
  "recall": 0.8348,
621
+ "specificity": 0.8482,
622
+ "brier": 0.1208,
623
+ "ece": 0.102
624
  },
625
  {
626
  "species": "Spirulina (Arthrospira platensis)",
 
632
  "f1": 0.8062,
633
  "precision": 0.7921,
634
  "recall": 0.8305,
635
+ "specificity": 0.7758,
636
+ "brier": 0.1477,
637
+ "ece": 0.1146
638
  },
639
  {
640
  "species": "Potato (Solanum tuberosum)",
 
646
  "f1": 0.7876,
647
  "precision": 0.7791,
648
  "recall": 0.7993,
649
+ "specificity": 0.779,
650
+ "brier": 0.1504,
651
+ "ece": 0.0685
652
  },
653
  {
654
  "species": "Soybean (Glycine max)",
 
660
  "f1": 0.7316,
661
  "precision": 0.7042,
662
  "recall": 0.8162,
663
+ "specificity": 0.7473,
664
+ "brier": 0.1791,
665
+ "ece": 0.1557
666
  },
667
  {
668
  "species": "wheat",
 
674
  "f1": 0.7676,
675
  "precision": 0.7208,
676
  "recall": 0.8298,
677
+ "specificity": 0.6573,
678
+ "brier": 0.1862,
679
+ "ece": 0.1316
680
  },
681
  {
682
  "species": "Faba bean (Vicia faba)",
 
688
  "f1": 0.8437,
689
  "precision": 0.8045,
690
  "recall": 0.9401,
691
+ "specificity": 0.4138,
692
+ "brier": 0.2773,
693
+ "ece": 0.2214
694
  },
695
  {
696
  "species": "Tetradesmus obliquus (microalga)",
 
702
  "f1": 0.6943,
703
  "precision": 0.7133,
704
  "recall": 0.7203,
705
+ "specificity": 0.6343,
706
+ "brier": 0.235,
707
+ "ece": 0.2382
708
  },
709
  {
710
  "species": "Red rice bran (Oryza sativa)",
 
716
  "f1": 0.682,
717
  "precision": 0.6612,
718
  "recall": 0.7473,
719
+ "specificity": 0.5105,
720
+ "brier": 0.2665,
721
+ "ece": 0.2511
722
  }
723
  ],
724
  "partial": false
 
728
  "classifier": "mlp",
729
  "featureSet": "esm2_phys",
730
  "label": "Neural net (MLP) \u00b7 ESM2 + physicochemical",
731
+ "description": "A small multilayer-perceptron neural net over the feature vector. ESM2 embeddings plus the 14 physicochemical descriptors. Best overall.",
732
  "nSpecies": 8,
733
  "nDatasets": 30,
734
  "agg": {
 
795
  "minSpecies": "Faba bean (Vicia faba)",
796
  "maxSpecies": "Spirulina (Arthrospira platensis)",
797
  "nSpecies": 8
798
+ },
799
+ "brier": {
800
+ "mean": 0.2029,
801
+ "min": 0.1327,
802
+ "max": 0.2769,
803
+ "minSpecies": "gracilaria",
804
+ "maxSpecies": "Red rice bran (Oryza sativa)",
805
+ "nSpecies": 8
806
+ },
807
+ "ece": {
808
+ "mean": 0.1802,
809
+ "min": 0.1191,
810
+ "max": 0.2531,
811
+ "minSpecies": "gracilaria",
812
+ "maxSpecies": "Red rice bran (Oryza sativa)",
813
+ "nSpecies": 8
814
  }
815
  },
816
  "bySpecies": [
 
824
  "f1": 0.8312,
825
  "precision": 0.8172,
826
  "recall": 0.8486,
827
+ "specificity": 0.7985,
828
+ "brier": 0.1327,
829
+ "ece": 0.1191
830
  },
831
  {
832
  "species": "Spirulina (Arthrospira platensis)",
 
838
  "f1": 0.8057,
839
  "precision": 0.8098,
840
  "recall": 0.8099,
841
+ "specificity": 0.8039,
842
+ "brier": 0.153,
843
+ "ece": 0.1241
844
  },
845
  {
846
  "species": "Soybean (Glycine max)",
 
852
  "f1": 0.7471,
853
  "precision": 0.7302,
854
  "recall": 0.8094,
855
+ "specificity": 0.7795,
856
+ "brier": 0.1722,
857
+ "ece": 0.1561
858
  },
859
  {
860
  "species": "Potato (Solanum tuberosum)",
 
866
  "f1": 0.7797,
867
  "precision": 0.7812,
868
  "recall": 0.781,
869
+ "specificity": 0.7872,
870
+ "brier": 0.1804,
871
+ "ece": 0.1544
872
  },
873
  {
874
  "species": "wheat",
 
880
  "f1": 0.7729,
881
  "precision": 0.7312,
882
  "recall": 0.8273,
883
+ "specificity": 0.6748,
884
+ "brier": 0.2017,
885
+ "ece": 0.175
886
  },
887
  {
888
  "species": "Faba bean (Vicia faba)",
 
894
  "f1": 0.7464,
895
  "precision": 0.7107,
896
  "recall": 0.8304,
897
+ "specificity": 0.462,
898
+ "brier": 0.2747,
899
+ "ece": 0.237
900
  },
901
  {
902
  "species": "Tetradesmus obliquus (microalga)",
 
908
  "f1": 0.682,
909
  "precision": 0.6966,
910
  "recall": 0.721,
911
+ "specificity": 0.6002,
912
+ "brier": 0.232,
913
+ "ece": 0.2226
914
  },
915
  {
916
  "species": "Red rice bran (Oryza sativa)",
 
922
  "f1": 0.6743,
923
  "precision": 0.6503,
924
  "recall": 0.7413,
925
+ "specificity": 0.4788,
926
+ "brier": 0.2769,
927
+ "ece": 0.2531
928
  }
929
  ],
930
  "partial": false
 
1001
  "minSpecies": "Faba bean (Vicia faba)",
1002
  "maxSpecies": "gracilaria",
1003
  "nSpecies": 8
1004
+ },
1005
+ "brier": {
1006
+ "mean": 0.2006,
1007
+ "min": 0.1231,
1008
+ "max": 0.2925,
1009
+ "minSpecies": "gracilaria",
1010
+ "maxSpecies": "Faba bean (Vicia faba)",
1011
+ "nSpecies": 8
1012
+ },
1013
+ "ece": {
1014
+ "mean": 0.1798,
1015
+ "min": 0.1037,
1016
+ "max": 0.2584,
1017
+ "minSpecies": "gracilaria",
1018
+ "maxSpecies": "Faba bean (Vicia faba)",
1019
+ "nSpecies": 8
1020
  }
1021
  },
1022
  "bySpecies": [
 
1030
  "f1": 0.8367,
1031
  "precision": 0.8287,
1032
  "recall": 0.8483,
1033
+ "specificity": 0.8114,
1034
+ "brier": 0.1231,
1035
+ "ece": 0.1037
1036
  },
1037
  {
1038
  "species": "Spirulina (Arthrospira platensis)",
 
1044
  "f1": 0.8065,
1045
  "precision": 0.81,
1046
  "recall": 0.8144,
1047
+ "specificity": 0.8011,
1048
+ "brier": 0.1563,
1049
+ "ece": 0.1306
1050
  },
1051
  {
1052
  "species": "Soybean (Glycine max)",
 
1058
  "f1": 0.7636,
1059
  "precision": 0.7428,
1060
  "recall": 0.8383,
1061
+ "specificity": 0.7812,
1062
+ "brier": 0.1703,
1063
+ "ece": 0.1648
1064
  },
1065
  {
1066
  "species": "Potato (Solanum tuberosum)",
 
1072
  "f1": 0.7786,
1073
  "precision": 0.7812,
1074
  "recall": 0.7791,
1075
+ "specificity": 0.7874,
1076
+ "brier": 0.1831,
1077
+ "ece": 0.1593
1078
  },
1079
  {
1080
  "species": "wheat",
 
1086
  "f1": 0.765,
1087
  "precision": 0.7259,
1088
  "recall": 0.8171,
1089
+ "specificity": 0.6682,
1090
+ "brier": 0.2043,
1091
+ "ece": 0.175
1092
  },
1093
  {
1094
  "species": "Faba bean (Vicia faba)",
 
1100
  "f1": 0.7456,
1101
  "precision": 0.7047,
1102
  "recall": 0.8359,
1103
+ "specificity": 0.4296,
1104
+ "brier": 0.2925,
1105
+ "ece": 0.2584
1106
  },
1107
  {
1108
  "species": "Tetradesmus obliquus (microalga)",
 
1114
  "f1": 0.6799,
1115
  "precision": 0.6978,
1116
  "recall": 0.6933,
1117
+ "specificity": 0.6218,
1118
+ "brier": 0.2167,
1119
+ "ece": 0.2017
1120
  },
1121
  {
1122
  "species": "Red rice bran (Oryza sativa)",
 
1128
  "f1": 0.6764,
1129
  "precision": 0.6675,
1130
  "recall": 0.7195,
1131
+ "specificity": 0.5521,
1132
+ "brier": 0.2585,
1133
+ "ece": 0.2447
1134
  }
1135
  ],
1136
  "partial": false
 
1207
  "minSpecies": "Faba bean (Vicia faba)",
1208
  "maxSpecies": "gracilaria",
1209
  "nSpecies": 8
1210
+ },
1211
+ "brier": {
1212
+ "mean": 0.2076,
1213
+ "min": 0.1189,
1214
+ "max": 0.3179,
1215
+ "minSpecies": "gracilaria",
1216
+ "maxSpecies": "Faba bean (Vicia faba)",
1217
+ "nSpecies": 8
1218
+ },
1219
+ "ece": {
1220
+ "mean": 0.1898,
1221
+ "min": 0.0905,
1222
+ "max": 0.2942,
1223
+ "minSpecies": "gracilaria",
1224
+ "maxSpecies": "Faba bean (Vicia faba)",
1225
+ "nSpecies": 8
1226
  }
1227
  },
1228
  "bySpecies": [
 
1236
  "f1": 0.8505,
1237
  "precision": 0.8453,
1238
  "recall": 0.8591,
1239
+ "specificity": 0.8321,
1240
+ "brier": 0.1189,
1241
+ "ece": 0.0905
1242
  },
1243
  {
1244
  "species": "Spirulina (Arthrospira platensis)",
 
1250
  "f1": 0.8189,
1251
  "precision": 0.8074,
1252
  "recall": 0.8361,
1253
+ "specificity": 0.7977,
1254
+ "brier": 0.1486,
1255
+ "ece": 0.1304
1256
  },
1257
  {
1258
  "species": "Soybean (Glycine max)",
 
1264
  "f1": 0.733,
1265
  "precision": 0.7256,
1266
  "recall": 0.8035,
1267
+ "specificity": 0.768,
1268
+ "brier": 0.1893,
1269
+ "ece": 0.1892
1270
  },
1271
  {
1272
  "species": "Potato (Solanum tuberosum)",
 
1278
  "f1": 0.7783,
1279
  "precision": 0.7763,
1280
  "recall": 0.784,
1281
+ "specificity": 0.7798,
1282
+ "brier": 0.1831,
1283
+ "ece": 0.1578
1284
  },
1285
  {
1286
  "species": "wheat",
 
1292
  "f1": 0.7615,
1293
  "precision": 0.7341,
1294
  "recall": 0.7972,
1295
+ "specificity": 0.6942,
1296
+ "brier": 0.1977,
1297
+ "ece": 0.1594
1298
  },
1299
  {
1300
  "species": "Red rice bran (Oryza sativa)",
 
1306
  "f1": 0.6983,
1307
  "precision": 0.6933,
1308
  "recall": 0.7455,
1309
+ "specificity": 0.584,
1310
+ "brier": 0.2559,
1311
+ "ece": 0.2624
1312
  },
1313
  {
1314
  "species": "Tetradesmus obliquus (microalga)",
 
1320
  "f1": 0.6748,
1321
  "precision": 0.7103,
1322
  "recall": 0.6921,
1323
+ "specificity": 0.6543,
1324
+ "brier": 0.2497,
1325
+ "ece": 0.2349
1326
  },
1327
  {
1328
  "species": "Faba bean (Vicia faba)",
 
1334
  "f1": 0.72,
1335
  "precision": 0.7012,
1336
  "recall": 0.8006,
1337
+ "specificity": 0.4236,
1338
+ "brier": 0.3179,
1339
+ "ece": 0.2942
1340
  }
1341
  ],
1342
  "partial": false
 
1346
  "classifier": "rf",
1347
  "featureSet": "pep_phys",
1348
  "label": "Random forest \u00b7 PepBERT + physicochemical",
1349
+ "description": "Bagged decision trees. Robust, usually a step behind XGBoost. PepBERT embeddings concatenated with the 14 physicochemical descriptors.",
1350
  "nSpecies": 8,
1351
  "nDatasets": 30,
1352
  "agg": {
 
1413
  "minSpecies": "Faba bean (Vicia faba)",
1414
  "maxSpecies": "gracilaria",
1415
  "nSpecies": 8
1416
+ },
1417
+ "brier": {
1418
+ "mean": 0.1867,
1419
+ "min": 0.1346,
1420
+ "max": 0.2391,
1421
+ "minSpecies": "gracilaria",
1422
+ "maxSpecies": "Faba bean (Vicia faba)",
1423
+ "nSpecies": 8
1424
+ },
1425
+ "ece": {
1426
+ "mean": 0.181,
1427
+ "min": 0.111,
1428
+ "max": 0.3165,
1429
+ "minSpecies": "Potato (Solanum tuberosum)",
1430
+ "maxSpecies": "Faba bean (Vicia faba)",
1431
+ "nSpecies": 8
1432
  }
1433
  },
1434
  "bySpecies": [
 
1442
  "f1": 0.8393,
1443
  "precision": 0.8325,
1444
  "recall": 0.8493,
1445
+ "specificity": 0.8173,
1446
+ "brier": 0.1346,
1447
+ "ece": 0.1433
1448
  },
1449
  {
1450
  "species": "Spirulina (Arthrospira platensis)",
 
1456
  "f1": 0.8094,
1457
  "precision": 0.7938,
1458
  "recall": 0.8352,
1459
+ "specificity": 0.7732,
1460
+ "brier": 0.1551,
1461
+ "ece": 0.1395
1462
  },
1463
  {
1464
  "species": "Potato (Solanum tuberosum)",
 
1470
  "f1": 0.7745,
1471
  "precision": 0.7705,
1472
  "recall": 0.7838,
1473
+ "specificity": 0.7729,
1474
+ "brier": 0.1653,
1475
+ "ece": 0.111
1476
  },
1477
  {
1478
  "species": "Soybean (Glycine max)",
 
1484
  "f1": 0.7182,
1485
  "precision": 0.6867,
1486
  "recall": 0.8085,
1487
+ "specificity": 0.723,
1488
+ "brier": 0.1781,
1489
+ "ece": 0.185
1490
  },
1491
  {
1492
  "species": "wheat",
 
1498
  "f1": 0.7497,
1499
  "precision": 0.7113,
1500
  "recall": 0.8047,
1501
+ "specificity": 0.651,
1502
+ "brier": 0.1879,
1503
+ "ece": 0.1169
1504
  },
1505
  {
1506
  "species": "Red rice bran (Oryza sativa)",
 
1512
  "f1": 0.6922,
1513
  "precision": 0.6962,
1514
  "recall": 0.7371,
1515
+ "specificity": 0.5902,
1516
+ "brier": 0.211,
1517
+ "ece": 0.204
1518
  },
1519
  {
1520
  "species": "Tetradesmus obliquus (microalga)",
 
1526
  "f1": 0.6913,
1527
  "precision": 0.7102,
1528
  "recall": 0.7419,
1529
+ "specificity": 0.6087,
1530
+ "brier": 0.2227,
1531
+ "ece": 0.2316
1532
  },
1533
  {
1534
  "species": "Faba bean (Vicia faba)",
 
1540
  "f1": 0.7217,
1541
  "precision": 0.6949,
1542
  "recall": 0.8117,
1543
+ "specificity": 0.3821,
1544
+ "brier": 0.2391,
1545
+ "ece": 0.3165
1546
  }
1547
  ],
1548
  "partial": false
 
1552
  "classifier": "rf",
1553
  "featureSet": "esm2_phys",
1554
  "label": "Random forest \u00b7 ESM2 + physicochemical",
1555
+ "description": "Bagged decision trees. Robust, usually a step behind XGBoost. ESM2 embeddings plus the 14 physicochemical descriptors. Best overall.",
1556
  "nSpecies": 8,
1557
  "nDatasets": 30,
1558
  "agg": {
 
1619
  "minSpecies": "Faba bean (Vicia faba)",
1620
  "maxSpecies": "gracilaria",
1621
  "nSpecies": 8
1622
+ },
1623
+ "brier": {
1624
+ "mean": 0.1839,
1625
+ "min": 0.1383,
1626
+ "max": 0.232,
1627
+ "minSpecies": "gracilaria",
1628
+ "maxSpecies": "Faba bean (Vicia faba)",
1629
+ "nSpecies": 8
1630
+ },
1631
+ "ece": {
1632
+ "mean": 0.1642,
1633
+ "min": 0.0897,
1634
+ "max": 0.2851,
1635
+ "minSpecies": "Potato (Solanum tuberosum)",
1636
+ "maxSpecies": "Faba bean (Vicia faba)",
1637
+ "nSpecies": 8
1638
  }
1639
  },
1640
  "bySpecies": [
 
1648
  "f1": 0.8185,
1649
  "precision": 0.8316,
1650
  "recall": 0.8115,
1651
+ "specificity": 0.829,
1652
+ "brier": 0.1383,
1653
+ "ece": 0.1139
1654
  },
1655
  {
1656
  "species": "Spirulina (Arthrospira platensis)",
 
1662
  "f1": 0.8028,
1663
  "precision": 0.7936,
1664
  "recall": 0.8219,
1665
+ "specificity": 0.7809,
1666
+ "brier": 0.1493,
1667
+ "ece": 0.1254
1668
  },
1669
  {
1670
  "species": "Potato (Solanum tuberosum)",
 
1676
  "f1": 0.7744,
1677
  "precision": 0.7729,
1678
  "recall": 0.7805,
1679
+ "specificity": 0.7768,
1680
+ "brier": 0.1602,
1681
+ "ece": 0.0897
1682
  },
1683
  {
1684
  "species": "Soybean (Glycine max)",
 
1690
  "f1": 0.7093,
1691
  "precision": 0.7035,
1692
  "recall": 0.7739,
1693
+ "specificity": 0.7522,
1694
+ "brier": 0.1729,
1695
+ "ece": 0.1762
1696
  },
1697
  {
1698
  "species": "wheat",
 
1704
  "f1": 0.7526,
1705
  "precision": 0.7065,
1706
  "recall": 0.8162,
1707
+ "specificity": 0.6377,
1708
+ "brier": 0.1836,
1709
+ "ece": 0.1071
1710
  },
1711
  {
1712
  "species": "Faba bean (Vicia faba)",
 
1718
  "f1": 0.7349,
1719
  "precision": 0.7016,
1720
  "recall": 0.8311,
1721
+ "specificity": 0.391,
1722
+ "brier": 0.232,
1723
+ "ece": 0.2851
1724
  },
1725
  {
1726
  "species": "Tetradesmus obliquus (microalga)",
 
1732
  "f1": 0.6834,
1733
  "precision": 0.7126,
1734
  "recall": 0.7116,
1735
+ "specificity": 0.6356,
1736
+ "brier": 0.2139,
1737
+ "ece": 0.2293
1738
  },
1739
  {
1740
  "species": "Red rice bran (Oryza sativa)",
 
1746
  "f1": 0.6812,
1747
  "precision": 0.6718,
1748
  "recall": 0.7442,
1749
+ "specificity": 0.5299,
1750
+ "brier": 0.2206,
1751
+ "ece": 0.187
1752
  }
1753
  ],
1754
  "partial": false
 
1758
  "classifier": "rf",
1759
  "featureSet": "esm2",
1760
  "label": "Random forest \u00b7 ESM2",
1761
+ "description": "Bagged decision trees. Robust, usually a step behind XGBoost. ESM2-t12-35M protein-language-model embeddings of the peptide sequence.",
1762
  "nSpecies": 8,
1763
  "nDatasets": 30,
1764
  "agg": {
 
1825
  "minSpecies": "Faba bean (Vicia faba)",
1826
  "maxSpecies": "gracilaria",
1827
  "nSpecies": 8
1828
+ },
1829
+ "brier": {
1830
+ "mean": 0.1862,
1831
+ "min": 0.1418,
1832
+ "max": 0.2309,
1833
+ "minSpecies": "gracilaria",
1834
+ "maxSpecies": "Faba bean (Vicia faba)",
1835
+ "nSpecies": 8
1836
+ },
1837
+ "ece": {
1838
+ "mean": 0.1634,
1839
+ "min": 0.0924,
1840
+ "max": 0.2759,
1841
+ "minSpecies": "Potato (Solanum tuberosum)",
1842
+ "maxSpecies": "Faba bean (Vicia faba)",
1843
+ "nSpecies": 8
1844
  }
1845
  },
1846
  "bySpecies": [
 
1854
  "f1": 0.8064,
1855
  "precision": 0.8091,
1856
  "recall": 0.8092,
1857
+ "specificity": 0.7869,
1858
+ "brier": 0.1418,
1859
+ "ece": 0.1188
1860
  },
1861
  {
1862
  "species": "Spirulina (Arthrospira platensis)",
 
1868
  "f1": 0.7992,
1869
  "precision": 0.7952,
1870
  "recall": 0.8139,
1871
+ "specificity": 0.7851,
1872
+ "brier": 0.1529,
1873
+ "ece": 0.126
1874
  },
1875
  {
1876
  "species": "Potato (Solanum tuberosum)",
 
1882
  "f1": 0.7701,
1883
  "precision": 0.7724,
1884
  "recall": 0.7725,
1885
+ "specificity": 0.7786,
1886
+ "brier": 0.1621,
1887
+ "ece": 0.0924
1888
  },
1889
  {
1890
  "species": "Soybean (Glycine max)",
 
1896
  "f1": 0.7155,
1897
  "precision": 0.7011,
1898
  "recall": 0.7971,
1899
+ "specificity": 0.7447,
1900
+ "brier": 0.1734,
1901
+ "ece": 0.1699
1902
  },
1903
  {
1904
  "species": "wheat",
 
1910
  "f1": 0.7509,
1911
  "precision": 0.7056,
1912
  "recall": 0.8134,
1913
+ "specificity": 0.6371,
1914
+ "brier": 0.1854,
1915
+ "ece": 0.1087
1916
  },
1917
  {
1918
  "species": "Faba bean (Vicia faba)",
 
1924
  "f1": 0.7386,
1925
  "precision": 0.7023,
1926
  "recall": 0.8383,
1927
+ "specificity": 0.3918,
1928
+ "brier": 0.2309,
1929
+ "ece": 0.2759
1930
  },
1931
  {
1932
  "species": "Tetradesmus obliquus (microalga)",
 
1938
  "f1": 0.6622,
1939
  "precision": 0.7013,
1940
  "recall": 0.6863,
1941
+ "specificity": 0.6165,
1942
+ "brier": 0.2177,
1943
+ "ece": 0.2235
1944
  },
1945
  {
1946
  "species": "Red rice bran (Oryza sativa)",
 
1952
  "f1": 0.6593,
1953
  "precision": 0.6537,
1954
  "recall": 0.7253,
1955
+ "specificity": 0.4949,
1956
+ "brier": 0.2254,
1957
+ "ece": 0.1924
1958
  }
1959
  ],
1960
  "partial": false
 
1964
  "classifier": "rf",
1965
  "featureSet": "phys",
1966
  "label": "Random forest \u00b7 Physicochemical",
1967
+ "description": "Bagged decision trees. Robust, usually a step behind XGBoost. 14 physicochemical descriptors only (length, charge, hydrophobicity, \u2026). Fast, no embeddings.",
1968
  "nSpecies": 8,
1969
  "nDatasets": 30,
1970
  "agg": {
 
2031
  "minSpecies": "Faba bean (Vicia faba)",
2032
  "maxSpecies": "Spirulina (Arthrospira platensis)",
2033
  "nSpecies": 8
2034
+ },
2035
+ "brier": {
2036
+ "mean": 0.181,
2037
+ "min": 0.1472,
2038
+ "max": 0.204,
2039
+ "minSpecies": "Spirulina (Arthrospira platensis)",
2040
+ "maxSpecies": "Red rice bran (Oryza sativa)",
2041
+ "nSpecies": 8
2042
+ },
2043
+ "ece": {
2044
+ "mean": 0.1465,
2045
+ "min": 0.0619,
2046
+ "max": 0.2681,
2047
+ "minSpecies": "Potato (Solanum tuberosum)",
2048
+ "maxSpecies": "Faba bean (Vicia faba)",
2049
+ "nSpecies": 8
2050
  }
2051
  },
2052
  "bySpecies": [
 
2060
  "f1": 0.788,
2061
  "precision": 0.7707,
2062
  "recall": 0.826,
2063
+ "specificity": 0.7283,
2064
+ "brier": 0.1515,
2065
+ "ece": 0.1121
2066
  },
2067
  {
2068
  "species": "Spirulina (Arthrospira platensis)",
 
2074
  "f1": 0.8018,
2075
  "precision": 0.7896,
2076
  "recall": 0.8239,
2077
+ "specificity": 0.7706,
2078
+ "brier": 0.1472,
2079
+ "ece": 0.0989
2080
  },
2081
  {
2082
  "species": "Potato (Solanum tuberosum)",
 
2088
  "f1": 0.7579,
2089
  "precision": 0.75,
2090
  "recall": 0.7701,
2091
+ "specificity": 0.7487,
2092
+ "brier": 0.1648,
2093
+ "ece": 0.0619
2094
  },
2095
  {
2096
  "species": "Faba bean (Vicia faba)",
 
2102
  "f1": 0.749,
2103
  "precision": 0.728,
2104
  "recall": 0.8072,
2105
+ "specificity": 0.5762,
2106
+ "brier": 0.192,
2107
+ "ece": 0.2681
2108
  },
2109
  {
2110
  "species": "Soybean (Glycine max)",
 
2116
  "f1": 0.646,
2117
  "precision": 0.659,
2118
  "recall": 0.697,
2119
+ "specificity": 0.7169,
2120
+ "brier": 0.1924,
2121
+ "ece": 0.1645
2122
  },
2123
  {
2124
  "species": "wheat",
 
2130
  "f1": 0.7237,
2131
  "precision": 0.6861,
2132
  "recall": 0.7745,
2133
+ "specificity": 0.6242,
2134
+ "brier": 0.1934,
2135
+ "ece": 0.0886
2136
  },
2137
  {
2138
  "species": "Tetradesmus obliquus (microalga)",
 
2144
  "f1": 0.6949,
2145
  "precision": 0.7324,
2146
  "recall": 0.6974,
2147
+ "specificity": 0.6867,
2148
+ "brier": 0.2025,
2149
+ "ece": 0.207
2150
  },
2151
  {
2152
  "species": "Red rice bran (Oryza sativa)",
 
2158
  "f1": 0.6967,
2159
  "precision": 0.7086,
2160
  "recall": 0.7247,
2161
+ "specificity": 0.6185,
2162
+ "brier": 0.204,
2163
+ "ece": 0.1712
2164
  }
2165
  ],
2166
  "partial": false
 
2170
  "classifier": "xgb",
2171
  "featureSet": "phys",
2172
  "label": "XGBoost \u00b7 Physicochemical",
2173
+ "description": "Gradient-boosted decision trees. The most consistent winner across datasets. 14 physicochemical descriptors only (length, charge, hydrophobicity, \u2026). Fast, no embeddings.",
2174
  "nSpecies": 8,
2175
  "nDatasets": 30,
2176
  "agg": {
 
2237
  "minSpecies": "Faba bean (Vicia faba)",
2238
  "maxSpecies": "Spirulina (Arthrospira platensis)",
2239
  "nSpecies": 8
2240
+ },
2241
+ "brier": {
2242
+ "mean": 0.2008,
2243
+ "min": 0.1622,
2244
+ "max": 0.2296,
2245
+ "minSpecies": "Spirulina (Arthrospira platensis)",
2246
+ "maxSpecies": "Soybean (Glycine max)",
2247
+ "nSpecies": 8
2248
+ },
2249
+ "ece": {
2250
+ "mean": 0.1679,
2251
+ "min": 0.0653,
2252
+ "max": 0.2183,
2253
+ "minSpecies": "Potato (Solanum tuberosum)",
2254
+ "maxSpecies": "Red rice bran (Oryza sativa)",
2255
+ "nSpecies": 8
2256
  }
2257
  },
2258
  "bySpecies": [
 
2266
  "f1": 0.8122,
2267
  "precision": 0.7824,
2268
  "recall": 0.8552,
2269
+ "specificity": 0.7457,
2270
+ "brier": 0.1685,
2271
+ "ece": 0.1553
2272
  },
2273
  {
2274
  "species": "Spirulina (Arthrospira platensis)",
 
2280
  "f1": 0.7966,
2281
  "precision": 0.7895,
2282
  "recall": 0.8119,
2283
+ "specificity": 0.7723,
2284
+ "brier": 0.1622,
2285
+ "ece": 0.1309
2286
  },
2287
  {
2288
  "species": "Potato (Solanum tuberosum)",
 
2294
  "f1": 0.7616,
2295
  "precision": 0.7475,
2296
  "recall": 0.7794,
2297
+ "specificity": 0.7417,
2298
+ "brier": 0.1657,
2299
+ "ece": 0.0653
2300
  },
2301
  {
2302
  "species": "Faba bean (Vicia faba)",
 
2308
  "f1": 0.8344,
2309
  "precision": 0.8231,
2310
  "recall": 0.8792,
2311
+ "specificity": 0.5668,
2312
+ "brier": 0.2292,
2313
+ "ece": 0.2118
2314
  },
2315
  {
2316
  "species": "Tetradesmus obliquus (microalga)",
 
2322
  "f1": 0.7017,
2323
  "precision": 0.7197,
2324
  "recall": 0.7183,
2325
+ "specificity": 0.6611,
2326
+ "brier": 0.2189,
2327
+ "ece": 0.2164
2328
  },
2329
  {
2330
  "species": "Soybean (Glycine max)",
 
2336
  "f1": 0.649,
2337
  "precision": 0.6453,
2338
  "recall": 0.7208,
2339
+ "specificity": 0.6825,
2340
+ "brier": 0.2296,
2341
+ "ece": 0.2106
2342
  },
2343
  {
2344
  "species": "wheat",
 
2350
  "f1": 0.7217,
2351
  "precision": 0.6847,
2352
  "recall": 0.7696,
2353
+ "specificity": 0.6256,
2354
+ "brier": 0.2107,
2355
+ "ece": 0.1344
2356
  },
2357
  {
2358
  "species": "Red rice bran (Oryza sativa)",
 
2364
  "f1": 0.7092,
2365
  "precision": 0.7075,
2366
  "recall": 0.7422,
2367
+ "specificity": 0.6158,
2368
+ "brier": 0.2214,
2369
+ "ece": 0.2183
2370
  }
2371
  ],
2372
  "partial": false
 
2376
  "classifier": "xgb",
2377
  "featureSet": "pepbert",
2378
  "label": "XGBoost \u00b7 PepBERT",
2379
+ "description": "Gradient-boosted decision trees. The most consistent winner across datasets. PepBERT protein-language-model embeddings of the peptide sequence.",
2380
  "nSpecies": 8,
2381
  "nDatasets": 30,
2382
  "agg": {
 
2443
  "minSpecies": "Faba bean (Vicia faba)",
2444
  "maxSpecies": "gracilaria",
2445
  "nSpecies": 8
2446
+ },
2447
+ "brier": {
2448
+ "mean": 0.1983,
2449
+ "min": 0.1212,
2450
+ "max": 0.3027,
2451
+ "minSpecies": "gracilaria",
2452
+ "maxSpecies": "Faba bean (Vicia faba)",
2453
+ "nSpecies": 8
2454
+ },
2455
+ "ece": {
2456
+ "mean": 0.1626,
2457
+ "min": 0.063,
2458
+ "max": 0.2647,
2459
+ "minSpecies": "Potato (Solanum tuberosum)",
2460
+ "maxSpecies": "Faba bean (Vicia faba)",
2461
+ "nSpecies": 8
2462
  }
2463
  },
2464
  "bySpecies": [
 
2472
  "f1": 0.8353,
2473
  "precision": 0.8244,
2474
  "recall": 0.8497,
2475
+ "specificity": 0.7981,
2476
+ "brier": 0.1212,
2477
+ "ece": 0.1036
2478
  },
2479
  {
2480
  "species": "Spirulina (Arthrospira platensis)",
 
2486
  "f1": 0.8036,
2487
  "precision": 0.7972,
2488
  "recall": 0.8186,
2489
+ "specificity": 0.7851,
2490
+ "brier": 0.1504,
2491
+ "ece": 0.1079
2492
  },
2493
  {
2494
  "species": "Potato (Solanum tuberosum)",
 
2500
  "f1": 0.7806,
2501
  "precision": 0.7771,
2502
  "recall": 0.7871,
2503
+ "specificity": 0.7799,
2504
+ "brier": 0.1527,
2505
+ "ece": 0.063
2506
  },
2507
  {
2508
  "species": "Soybean (Glycine max)",
 
2514
  "f1": 0.7229,
2515
  "precision": 0.695,
2516
  "recall": 0.8075,
2517
+ "specificity": 0.7324,
2518
+ "brier": 0.1895,
2519
+ "ece": 0.166
2520
  },
2521
  {
2522
  "species": "wheat",
 
2528
  "f1": 0.7588,
2529
  "precision": 0.7197,
2530
  "recall": 0.8101,
2531
+ "specificity": 0.664,
2532
+ "brier": 0.1858,
2533
+ "ece": 0.1187
2534
  },
2535
  {
2536
  "species": "Red rice bran (Oryza sativa)",
 
2542
  "f1": 0.6984,
2543
  "precision": 0.6867,
2544
  "recall": 0.7438,
2545
+ "specificity": 0.5761,
2546
+ "brier": 0.2397,
2547
+ "ece": 0.2443
2548
  },
2549
  {
2550
  "species": "Tetradesmus obliquus (microalga)",
 
2556
  "f1": 0.6924,
2557
  "precision": 0.6974,
2558
  "recall": 0.7256,
2559
+ "specificity": 0.6102,
2560
+ "brier": 0.2442,
2561
+ "ece": 0.2322
2562
  },
2563
  {
2564
  "species": "Faba bean (Vicia faba)",
 
2570
  "f1": 0.8102,
2571
  "precision": 0.7944,
2572
  "recall": 0.8821,
2573
+ "specificity": 0.41,
2574
+ "brier": 0.3027,
2575
+ "ece": 0.2647
2576
  }
2577
  ],
2578
  "partial": false
 
2649
  "minSpecies": "Faba bean (Vicia faba)",
2650
  "maxSpecies": "gracilaria",
2651
  "nSpecies": 8
2652
+ },
2653
+ "brier": {
2654
+ "mean": 0.2079,
2655
+ "min": 0.1282,
2656
+ "max": 0.3106,
2657
+ "minSpecies": "gracilaria",
2658
+ "maxSpecies": "Faba bean (Vicia faba)",
2659
+ "nSpecies": 8
2660
+ },
2661
+ "ece": {
2662
+ "mean": 0.1926,
2663
+ "min": 0.0947,
2664
+ "max": 0.3488,
2665
+ "minSpecies": "gracilaria",
2666
+ "maxSpecies": "Faba bean (Vicia faba)",
2667
+ "nSpecies": 8
2668
  }
2669
  },
2670
  "bySpecies": [
 
2678
  "f1": 0.8133,
2679
  "precision": 0.7946,
2680
  "recall": 0.8374,
2681
+ "specificity": 0.7739,
2682
+ "brier": 0.1282,
2683
+ "ece": 0.0947
2684
  },
2685
  {
2686
  "species": "Spirulina (Arthrospira platensis)",
 
2692
  "f1": 0.8084,
2693
  "precision": 0.7936,
2694
  "recall": 0.8329,
2695
+ "specificity": 0.7732,
2696
+ "brier": 0.1579,
2697
+ "ece": 0.1331
2698
  },
2699
  {
2700
  "species": "Potato (Solanum tuberosum)",
 
2706
  "f1": 0.7783,
2707
  "precision": 0.7728,
2708
  "recall": 0.7872,
2709
+ "specificity": 0.7734,
2710
+ "brier": 0.1857,
2711
+ "ece": 0.1601
2712
  },
2713
  {
2714
  "species": "Soybean (Glycine max)",
 
2720
  "f1": 0.7185,
2721
  "precision": 0.7165,
2722
  "recall": 0.7735,
2723
+ "specificity": 0.7616,
2724
+ "brier": 0.1854,
2725
+ "ece": 0.179
2726
  },
2727
  {
2728
  "species": "wheat",
 
2734
  "f1": 0.7544,
2735
  "precision": 0.7211,
2736
  "recall": 0.7991,
2737
+ "specificity": 0.6735,
2738
+ "brier": 0.2075,
2739
+ "ece": 0.1708
2740
  },
2741
  {
2742
  "species": "Faba bean (Vicia faba)",
 
2748
  "f1": 0.625,
2749
  "precision": 0.6004,
2750
  "recall": 0.7079,
2751
+ "specificity": 0.4211,
2752
+ "brier": 0.3106,
2753
+ "ece": 0.3488
2754
  },
2755
  {
2756
  "species": "Red rice bran (Oryza sativa)",
 
2762
  "f1": 0.6815,
2763
  "precision": 0.6645,
2764
  "recall": 0.7515,
2765
+ "specificity": 0.5091,
2766
+ "brier": 0.2476,
2767
+ "ece": 0.2472
2768
  },
2769
  {
2770
  "species": "Tetradesmus obliquus (microalga)",
 
2776
  "f1": 0.6919,
2777
  "precision": 0.6807,
2778
  "recall": 0.746,
2779
+ "specificity": 0.5542,
2780
+ "brier": 0.2401,
2781
+ "ece": 0.207
2782
  }
2783
  ],
2784
  "partial": false
 
2788
  "classifier": "rf",
2789
  "featureSet": "pepbert",
2790
  "label": "Random forest \u00b7 PepBERT",
2791
+ "description": "Bagged decision trees. Robust, usually a step behind XGBoost. PepBERT protein-language-model embeddings of the peptide sequence.",
2792
  "nSpecies": 8,
2793
  "nDatasets": 30,
2794
  "agg": {
 
2855
  "minSpecies": "Faba bean (Vicia faba)",
2856
  "maxSpecies": "gracilaria",
2857
  "nSpecies": 8
2858
+ },
2859
+ "brier": {
2860
+ "mean": 0.1961,
2861
+ "min": 0.1382,
2862
+ "max": 0.2547,
2863
+ "minSpecies": "gracilaria",
2864
+ "maxSpecies": "Faba bean (Vicia faba)",
2865
+ "nSpecies": 8
2866
+ },
2867
+ "ece": {
2868
+ "mean": 0.1858,
2869
+ "min": 0.1194,
2870
+ "max": 0.3196,
2871
+ "minSpecies": "wheat",
2872
+ "maxSpecies": "Faba bean (Vicia faba)",
2873
+ "nSpecies": 8
2874
  }
2875
  },
2876
  "bySpecies": [
 
2884
  "f1": 0.8302,
2885
  "precision": 0.8346,
2886
  "recall": 0.8286,
2887
+ "specificity": 0.8219,
2888
+ "brier": 0.1382,
2889
+ "ece": 0.1551
2890
  },
2891
  {
2892
  "species": "Spirulina (Arthrospira platensis)",
 
2898
  "f1": 0.7834,
2899
  "precision": 0.7843,
2900
  "recall": 0.7963,
2901
+ "specificity": 0.7724,
2902
+ "brier": 0.1722,
2903
+ "ece": 0.1562
2904
  },
2905
  {
2906
  "species": "Potato (Solanum tuberosum)",
 
2912
  "f1": 0.7599,
2913
  "precision": 0.7692,
2914
  "recall": 0.7571,
2915
+ "specificity": 0.7791,
2916
+ "brier": 0.1757,
2917
+ "ece": 0.1261
2918
  },
2919
  {
2920
  "species": "Soybean (Glycine max)",
 
2926
  "f1": 0.7028,
2927
  "precision": 0.6751,
2928
  "recall": 0.7892,
2929
+ "specificity": 0.71,
2930
+ "brier": 0.1823,
2931
+ "ece": 0.1758
2932
  },
2933
  {
2934
  "species": "wheat",
 
2940
  "f1": 0.7402,
2941
  "precision": 0.7024,
2942
  "recall": 0.7949,
2943
+ "specificity": 0.6406,
2944
+ "brier": 0.195,
2945
+ "ece": 0.1194
2946
  },
2947
  {
2948
  "species": "Red rice bran (Oryza sativa)",
 
2954
  "f1": 0.6816,
2955
  "precision": 0.6801,
2956
  "recall": 0.7353,
2957
+ "specificity": 0.555,
2958
+ "brier": 0.2175,
2959
+ "ece": 0.2014
2960
  },
2961
  {
2962
  "species": "Tetradesmus obliquus (microalga)",
 
2968
  "f1": 0.6469,
2969
  "precision": 0.6841,
2970
  "recall": 0.6966,
2971
+ "specificity": 0.5675,
2972
+ "brier": 0.2332,
2973
+ "ece": 0.2331
2974
  },
2975
  {
2976
  "species": "Faba bean (Vicia faba)",
 
2982
  "f1": 0.7049,
2983
  "precision": 0.6921,
2984
  "recall": 0.7872,
2985
+ "specificity": 0.3767,
2986
+ "brier": 0.2547,
2987
+ "ece": 0.3196
2988
  }
2989
  ],
2990
  "partial": false
 
3061
  "minSpecies": "Red rice bran (Oryza sativa)",
3062
  "maxSpecies": "gracilaria",
3063
  "nSpecies": 8
3064
+ },
3065
+ "brier": {
3066
+ "mean": 0.2003,
3067
+ "min": 0.1378,
3068
+ "max": 0.2363,
3069
+ "minSpecies": "gracilaria",
3070
+ "maxSpecies": "Red rice bran (Oryza sativa)",
3071
+ "nSpecies": 8
3072
+ },
3073
+ "ece": {
3074
+ "mean": 0.1695,
3075
+ "min": 0.1039,
3076
+ "max": 0.2554,
3077
+ "minSpecies": "gracilaria",
3078
+ "maxSpecies": "Faba bean (Vicia faba)",
3079
+ "nSpecies": 8
3080
  }
3081
  },
3082
  "bySpecies": [
 
3090
  "f1": 0.8234,
3091
  "precision": 0.7979,
3092
  "recall": 0.8571,
3093
+ "specificity": 0.7733,
3094
+ "brier": 0.1378,
3095
+ "ece": 0.1039
3096
  },
3097
  {
3098
  "species": "Spirulina (Arthrospira platensis)",
 
3104
  "f1": 0.7919,
3105
  "precision": 0.7815,
3106
  "recall": 0.8151,
3107
+ "specificity": 0.7621,
3108
+ "brier": 0.1581,
3109
+ "ece": 0.1185
3110
  },
3111
  {
3112
  "species": "Faba bean (Vicia faba)",
 
3118
  "f1": 0.741,
3119
  "precision": 0.7295,
3120
  "recall": 0.7976,
3121
+ "specificity": 0.5743,
3122
+ "brier": 0.2202,
3123
+ "ece": 0.2554
3124
  },
3125
  {
3126
  "species": "Potato (Solanum tuberosum)",
 
3132
  "f1": 0.7467,
3133
  "precision": 0.7403,
3134
  "recall": 0.7579,
3135
+ "specificity": 0.7378,
3136
+ "brier": 0.1863,
3137
+ "ece": 0.1183
3138
  },
3139
  {
3140
  "species": "Soybean (Glycine max)",
 
3146
  "f1": 0.6638,
3147
  "precision": 0.6707,
3148
  "recall": 0.7191,
3149
+ "specificity": 0.73,
3150
+ "brier": 0.2327,
3151
+ "ece": 0.2195
3152
  },
3153
  {
3154
  "species": "wheat",
 
3160
  "f1": 0.7156,
3161
  "precision": 0.6822,
3162
  "recall": 0.7612,
3163
+ "specificity": 0.6242,
3164
+ "brier": 0.2193,
3165
+ "ece": 0.1475
3166
  },
3167
  {
3168
  "species": "Tetradesmus obliquus (microalga)",
 
3174
  "f1": 0.7004,
3175
  "precision": 0.6996,
3176
  "recall": 0.7491,
3177
+ "specificity": 0.6011,
3178
+ "brier": 0.2119,
3179
+ "ece": 0.1918
3180
  },
3181
  {
3182
  "species": "Red rice bran (Oryza sativa)",
 
3188
  "f1": 0.6507,
3189
  "precision": 0.6505,
3190
  "recall": 0.7177,
3191
+ "specificity": 0.4784,
3192
+ "brier": 0.2363,
3193
+ "ece": 0.2012
3194
  }
3195
  ],
3196
  "partial": false
website/src/data/mockData.ts CHANGED
@@ -179,7 +179,7 @@ export const CLASSIFIER_OPTIONS = [
179
  ]
180
 
181
  export const SPLIT_OPTIONS = [
182
- { id: 'protein', label: 'Group by protein', desc: 'Production default β€” avoids peptide leakage' },
183
  { id: 'cluster90', label: 'Cluster (90% id)', desc: 'MMseqs2 sequence-identity clusters' },
184
  { id: 'cluster50', label: 'Cluster (50% id)', desc: 'Stricter homology grouping' },
185
  { id: 'peptide', label: 'By peptide', desc: 'Leakage baseline (inflates AUROC)' },
 
179
  ]
180
 
181
  export const SPLIT_OPTIONS = [
182
+ { id: 'protein', label: 'Group by protein', desc: 'Production default, avoids peptide leakage' },
183
  { id: 'cluster90', label: 'Cluster (90% id)', desc: 'MMseqs2 sequence-identity clusters' },
184
  { id: 'cluster50', label: 'Cluster (50% id)', desc: 'Stricter homology grouping' },
185
  { id: 'peptide', label: 'By peptide', desc: 'Leakage baseline (inflates AUROC)' },
website/src/pages/Benchmarking.tsx CHANGED
@@ -13,7 +13,8 @@ import stats from '../data/generated/cross_model_stats.json'
13
  const fmt = (v: number | null | undefined) => (v == null ? 'β€”' : v.toFixed(3))
14
 
15
  // Metric columns shown in the model-type leaderboard (order matters).
16
- const METRIC_COLS = ['auprc', 'accuracy', 'mcc', 'f1', 'recall', 'specificity', 'precision'] as const
 
17
 
18
  // ─────────────────────────────────────────────────────────────── Model-type leaderboard
19
  function TypeLeaderboard() {
@@ -41,16 +42,15 @@ function TypeLeaderboard() {
41
  return (
42
  <div>
43
  <p className="muted" style={{ marginTop: 0 }}>
44
- Every classifier Γ— feature-set combination, evaluated on all {LEADERBOARD.nDatasets} datasets
45
- (5-fold protein-grouped CV) and aggregated across the {LEADERBOARD.nSpecies} species. The headline
46
- is the <strong>mean AUROC across species</strong>; the range shows the weakest β†’ strongest species.
47
- Click a row for its description and per-species breakdown.
48
  </p>
49
 
50
  <div className="stat-row">
51
  <div className="stat">
52
  <div className="stat-value">{best.agg.auroc?.mean.toFixed(3)}</div>
53
- <div className="stat-label">Best mean AUROC β€” {best.label}</div>
54
  </div>
55
  <div className="stat">
56
  <div className="stat-value">{LEADERBOARD.nSpecies}</div>
@@ -78,6 +78,7 @@ function TypeLeaderboard() {
78
  {METRIC_COLS.map((k) => (
79
  <th key={k} className="num">
80
  {labels[k]}
 
81
  </th>
82
  ))}
83
  </tr>
@@ -154,6 +155,8 @@ function TypeDetail({ m }: { m: ModelType }) {
154
  <th className="num">F1</th>
155
  <th className="num">Sens.</th>
156
  <th className="num">Spec.</th>
 
 
157
  </tr>
158
  </thead>
159
  <tbody>
@@ -166,6 +169,8 @@ function TypeDetail({ m }: { m: ModelType }) {
166
  <td className="num">{fmt(s.f1 as number)}</td>
167
  <td className="num">{fmt(s.recall as number)}</td>
168
  <td className="num">{fmt(s.specificity as number)}</td>
 
 
169
  </tr>
170
  ))}
171
  </tbody>
@@ -187,8 +192,8 @@ function IndividualModels() {
187
  return (
188
  <div>
189
  <p className="muted" style={{ marginTop: 0 }}>
190
- The {MODELS.length} deployed per-dataset models β€” each is the winning classifier Γ— feature-set for
191
- that specific hydrolysate. Click for the paper, configuration, and caveats.
192
  </p>
193
  <div className="table-wrap">
194
  <table className="table">
@@ -275,15 +280,14 @@ function Analysis() {
275
  return (
276
  <div>
277
  <p className="muted" style={{ marginTop: 0 }}>
278
- Cross-dataset statistics over {stats.nContexts} contexts with full ablations (Friedman tests on
279
- mean CV ranks). Higher mean rank = better; charts show every treatment on the same scale.
280
  </p>
281
 
282
  <div className="grid-2">
283
- <Card title="Feature set" subtitle={`What to represent the peptide with Β· Friedman p = ${fs.friedmanP?.toExponential(1)}`}>
284
  <RankBars ranks={fs.meanRanks} labelFn={featureSetLabel} best={fs.bestByRank} />
285
  <p className="muted" style={{ fontSize: '0.82rem', marginBottom: 0, marginTop: 10 }}>
286
- Embeddings + physicochemical descriptors win; physicochemical alone is weakest.
287
  </p>
288
  </Card>
289
 
@@ -295,7 +299,7 @@ function Analysis() {
295
  </Card>
296
  </div>
297
 
298
- <Card title="Split rigor β€” the leakage check" subtitle="Mean AUROC by how train/test are separated; whiskers are the 95% CI">
299
  <div style={{ maxWidth: 560 }}>
300
  {tiers.map((t) => {
301
  const s = split[t.key]
@@ -319,8 +323,8 @@ function Analysis() {
319
  })}
320
  </div>
321
  <p className="muted" style={{ fontSize: '0.82rem', marginBottom: 0, marginTop: 10 }}>
322
- Peptide-level splitting inflates AUROC β€” the same protein leaks across train/test. HydroPD trains
323
- on the <strong>protein split</strong> (production), so reported numbers aren't leakage-inflated.
324
  </p>
325
  </Card>
326
 
@@ -328,9 +332,10 @@ function Analysis() {
328
  <p style={{ marginBottom: 6 }}>{neg.method}</p>
329
  {neg.seed_spread_ci && (
330
  <p className="muted" style={{ margin: 0 }}>
331
- AUROC moves only <strong>{neg.seed_spread_ci.mean.toFixed(2)}</strong> (95% CI{' '}
332
- {neg.seed_spread_ci.lo.toFixed(2)}–{neg.seed_spread_ci.hi.toFixed(2)}) across negative-sampling
333
- seeds β€” the choice of random negatives barely affects performance.
 
334
  </p>
335
  )}
336
  </Card>
@@ -347,8 +352,8 @@ export default function Benchmarking() {
347
  <div className="eyebrow">Leaderboards</div>
348
  <h1>Benchmarking</h1>
349
  <p className="lead">
350
- How the model types compare across species, the {MODELS.length} deployed per-dataset models, and
351
- the cross-model analysis of what actually drives detectability.
352
  </p>
353
  </div>
354
 
 
13
  const fmt = (v: number | null | undefined) => (v == null ? 'β€”' : v.toFixed(3))
14
 
15
  // Metric columns shown in the model-type leaderboard (order matters).
16
+ // brier + ece are calibration metrics where LOWER is better.
17
+ const METRIC_COLS = ['auprc', 'accuracy', 'mcc', 'f1', 'recall', 'specificity', 'precision', 'brier', 'ece'] as const
18
 
19
  // ─────────────────────────────────────────────────────────────── Model-type leaderboard
20
  function TypeLeaderboard() {
 
42
  return (
43
  <div>
44
  <p className="muted" style={{ marginTop: 0 }}>
45
+ Every classifier and feature-set combo, scored on all {LEADERBOARD.nDatasets} datasets and averaged
46
+ across {LEADERBOARD.nSpecies} species. Sorted by <strong>mean AUROC</strong>; the range shows
47
+ weakest to strongest species. Click a row for details.
 
48
  </p>
49
 
50
  <div className="stat-row">
51
  <div className="stat">
52
  <div className="stat-value">{best.agg.auroc?.mean.toFixed(3)}</div>
53
+ <div className="stat-label">Top model: {best.label}</div>
54
  </div>
55
  <div className="stat">
56
  <div className="stat-value">{LEADERBOARD.nSpecies}</div>
 
78
  {METRIC_COLS.map((k) => (
79
  <th key={k} className="num">
80
  {labels[k]}
81
+ {(k === 'brier' || k === 'ece') && ' ↓'}
82
  </th>
83
  ))}
84
  </tr>
 
155
  <th className="num">F1</th>
156
  <th className="num">Sens.</th>
157
  <th className="num">Spec.</th>
158
+ <th className="num">Brier ↓</th>
159
+ <th className="num">ECE ↓</th>
160
  </tr>
161
  </thead>
162
  <tbody>
 
169
  <td className="num">{fmt(s.f1 as number)}</td>
170
  <td className="num">{fmt(s.recall as number)}</td>
171
  <td className="num">{fmt(s.specificity as number)}</td>
172
+ <td className="num">{fmt(s.brier as number)}</td>
173
+ <td className="num">{fmt(s.ece as number)}</td>
174
  </tr>
175
  ))}
176
  </tbody>
 
192
  return (
193
  <div>
194
  <p className="muted" style={{ marginTop: 0 }}>
195
+ The {MODELS.length} deployed models, one per dataset. Each is the winning classifier and feature
196
+ set for that hydrolysate. Click for the paper, config, and caveats.
197
  </p>
198
  <div className="table-wrap">
199
  <table className="table">
 
280
  return (
281
  <div>
282
  <p className="muted" style={{ marginTop: 0 }}>
283
+ What drives detectability, across {stats.nContexts} datasets. Higher mean rank is better.
 
284
  </p>
285
 
286
  <div className="grid-2">
287
+ <Card title="Feature set" subtitle={`How to represent the peptide Β· Friedman p = ${fs.friedmanP?.toExponential(1)}`}>
288
  <RankBars ranks={fs.meanRanks} labelFn={featureSetLabel} best={fs.bestByRank} />
289
  <p className="muted" style={{ fontSize: '0.82rem', marginBottom: 0, marginTop: 10 }}>
290
+ Embeddings plus physicochemical features win. Physicochemical alone is weakest.
291
  </p>
292
  </Card>
293
 
 
299
  </Card>
300
  </div>
301
 
302
+ <Card title="Split rigor (leakage check)" subtitle="Mean AUROC by how train and test are separated. Whiskers show the 95% CI.">
303
  <div style={{ maxWidth: 560 }}>
304
  {tiers.map((t) => {
305
  const s = split[t.key]
 
323
  })}
324
  </div>
325
  <p className="muted" style={{ fontSize: '0.82rem', marginBottom: 0, marginTop: 10 }}>
326
+ Splitting by peptide inflates AUROC, because the same protein leaks across train and test.
327
+ HydroPD trains on the <strong>protein split</strong>, so these numbers aren't inflated.
328
  </p>
329
  </Card>
330
 
 
332
  <p style={{ marginBottom: 6 }}>{neg.method}</p>
333
  {neg.seed_spread_ci && (
334
  <p className="muted" style={{ margin: 0 }}>
335
+ Changing the negative-sampling seed moves AUROC by only{' '}
336
+ <strong>{neg.seed_spread_ci.mean.toFixed(2)}</strong> (95% CI{' '}
337
+ {neg.seed_spread_ci.lo.toFixed(2)}–{neg.seed_spread_ci.hi.toFixed(2)}). The choice of random
338
+ negatives barely matters.
339
  </p>
340
  )}
341
  </Card>
 
352
  <div className="eyebrow">Leaderboards</div>
353
  <h1>Benchmarking</h1>
354
  <p className="lead">
355
+ Compare model types, browse the {MODELS.length} deployed models, and see what drives
356
+ detectability.
357
  </p>
358
  </div>
359
 
website/src/pages/BioactivityScreening.tsx CHANGED
@@ -72,7 +72,7 @@ const PEPTIDE_COLUMNS: Column<PeptideView>[] = [
72
  sortable: true,
73
  render: (r) =>
74
  r.igeContains ? (
75
- <span className="badge badge-warn" title="The peptide equals or fully contains a documented linear IgE epitope (IEDB) β€” a potential allergenicity concern.">
76
  contains
77
  </span>
78
  ) : (
@@ -106,7 +106,7 @@ function LiveBadge({ live }: { live: boolean }) {
106
  title={
107
  live
108
  ? 'Matched against the HydroPD bioactivity/allergen master database (server-side).'
109
- : 'Backend unavailable β€” screening needs the server; no results computed offline.'
110
  }
111
  >
112
  {live ? 'Live screening' : 'Offline (backend unavailable)'}
@@ -196,17 +196,15 @@ export default function BioactivityScreening() {
196
  <div className="eyebrow">Tool</div>
197
  <h1>Bioactivity &amp; Allergen Screening</h1>
198
  <p className="lead">
199
- Screen sequences against HydroPD's centralized master database (10 bioactivity
200
- databases, ~58k peptides, plus IgE epitopes and recognized-allergen proteins).
201
- Two match types: <strong>bioactivity, cytotoxicity, and allergen origin are
202
- exact whole-sequence matches</strong> (I/L-folded), while the{' '}
203
- <strong>IgE-epitope check is a β€œcontains” match</strong> β€” the peptide equals or
204
- fully contains a documented linear epitope.
205
  </p>
206
  </div>
207
 
208
  {/* Peptide bioactivity + IgE (Q2) */}
209
- <Card title="1 Β· Screen peptides β€” bioactivity, cytotoxicity &amp; IgE epitopes">
210
  <SequenceInput
211
  label="Peptide sequences"
212
  value={pepInput}
@@ -287,11 +285,11 @@ export default function BioactivityScreening() {
287
  </Card>
288
 
289
  {/* Protein allergen origin (Q1) */}
290
- <Card title="2 Β· Screen proteins β€” allergen origin">
291
  <p className="muted" style={{ marginTop: 0, fontSize: '0.86rem' }}>
292
- A bare peptide can't answer this β€” allergen origin is a protein-level question.
293
- Paste full protein sequences (or FASTA) to check for an <strong>exact
294
- whole-protein match</strong> against recognized allergens (WHO/IUIS βˆͺ AllergenOnline).
295
  </p>
296
  <SequenceInput
297
  label="Protein sequences"
 
72
  sortable: true,
73
  render: (r) =>
74
  r.igeContains ? (
75
+ <span className="badge badge-warn" title="Holds a documented linear IgE epitope (IEDB). Potential allergenicity concern.">
76
  contains
77
  </span>
78
  ) : (
 
106
  title={
107
  live
108
  ? 'Matched against the HydroPD bioactivity/allergen master database (server-side).'
109
+ : 'Backend unavailable. Screening runs on the server.'
110
  }
111
  >
112
  {live ? 'Live screening' : 'Offline (backend unavailable)'}
 
196
  <div className="eyebrow">Tool</div>
197
  <h1>Bioactivity &amp; Allergen Screening</h1>
198
  <p className="lead">
199
+ Check sequences against 10 bioactivity databases (~58k peptides) plus IgE epitopes
200
+ and recognized allergens. Bioactivity, cytotoxicity, and allergen origin use{' '}
201
+ <strong>exact matches</strong>. The IgE check uses a <strong>contains match</strong>
202
+ {' '}(the peptide holds a known epitope).
 
 
203
  </p>
204
  </div>
205
 
206
  {/* Peptide bioactivity + IgE (Q2) */}
207
+ <Card title="1 Β· Peptides: bioactivity, cytotoxicity & IgE">
208
  <SequenceInput
209
  label="Peptide sequences"
210
  value={pepInput}
 
285
  </Card>
286
 
287
  {/* Protein allergen origin (Q1) */}
288
+ <Card title="2 Β· Proteins: allergen origin">
289
  <p className="muted" style={{ marginTop: 0, fontSize: '0.86rem' }}>
290
+ Allergen origin is a protein-level question, so paste full protein sequences (or FASTA).
291
+ We check for an <strong>exact match</strong> against recognized allergens (WHO/IUIS and
292
+ AllergenOnline).
293
  </p>
294
  <SequenceInput
295
  label="Protein sequences"
website/src/pages/Data.tsx CHANGED
@@ -57,7 +57,7 @@ function Computational() {
57
  <div>
58
  <Card
59
  title="Download datasets"
60
- subtitle="Raw peptidomics tables + the literature workbook. Everything here reflects the current HydroPD revamp (Steps 0–6)."
61
  >
62
  <DownloadCard
63
  title="Raw data bundle (H1–H13)"
@@ -187,7 +187,7 @@ function Experimentalist() {
187
  <div>
188
  <Card
189
  title="What data to generate & retain"
190
- subtitle="Producing compositional / peptidomics data? This is the HydroPD reporting schema β€” the fields to capture, in two tiers: MINIMUM (enough to interpret + model) and IDEAL (report everything)."
191
  actions={
192
  <a
193
  className="btn btn-secondary btn-sm"
@@ -243,7 +243,7 @@ function Experimentalist() {
243
 
244
  <Card
245
  title="Where new data is most needed"
246
- subtitle="High-value raw materials for cultivated-meat media that still lack usable peptidomics data β€” the best places to generate it."
247
  actions={
248
  <div className="segmented" style={{ padding: 2 }}>
249
  <button
@@ -263,10 +263,8 @@ function Experimentalist() {
263
  </div>
264
  }
265
  >
266
- <p style={{ marginTop: 0 }}>
267
- High-value raw materials for cultivated-meat media that lack usable
268
- peptidomics data β€” the most useful places to generate new data. Sorted by{' '}
269
- <strong>{gapSort === 'papers' ? 'fewest papers found' : 'CCM priority'}</strong>.
270
  </p>
271
  <div className="table-wrap">
272
  <table className="table">
@@ -310,10 +308,8 @@ function Experimentalist() {
310
  </table>
311
  </div>
312
  <p className="muted" style={{ fontSize: '0.78rem', marginTop: 10, marginBottom: 0 }}>
313
- {dataGaps.rawMaterials.filter((r) => r.status === 'none').length} raw
314
- materials returned <strong>zero papers</strong> in the literature search
315
- (e.g. Canola is <em>not</em> among them β€” Brassica napus has 1 found paper
316
- but no usable data yet).
317
  </p>
318
  </Card>
319
 
@@ -394,8 +390,8 @@ export default function Data() {
394
  <div className="eyebrow">Data</div>
395
  <h1>Data</h1>
396
  <p className="lead">
397
- Download the datasets behind HydroPD, review the literature-search
398
- landscape, and see which raw-material data gaps are most worth filling.
399
  </p>
400
  </div>
401
 
 
57
  <div>
58
  <Card
59
  title="Download datasets"
60
+ subtitle="Raw peptidomics tables and the literature workbook."
61
  >
62
  <DownloadCard
63
  title="Raw data bundle (H1–H13)"
 
187
  <div>
188
  <Card
189
  title="What data to generate & retain"
190
+ subtitle="Making peptidomics data? Capture these fields. Two tiers: MINIMUM to model, IDEAL to report everything."
191
  actions={
192
  <a
193
  className="btn btn-secondary btn-sm"
 
243
 
244
  <Card
245
  title="Where new data is most needed"
246
+ subtitle="Raw materials that lack usable peptidomics data. The best places to generate it."
247
  actions={
248
  <div className="segmented" style={{ padding: 2 }}>
249
  <button
 
263
  </div>
264
  }
265
  >
266
+ <p className="muted" style={{ marginTop: 0, fontSize: '0.84rem' }}>
267
+ Sorted by <strong>{gapSort === 'papers' ? 'fewest papers found' : 'CCM priority'}</strong>.
 
 
268
  </p>
269
  <div className="table-wrap">
270
  <table className="table">
 
308
  </table>
309
  </div>
310
  <p className="muted" style={{ fontSize: '0.78rem', marginTop: 10, marginBottom: 0 }}>
311
+ {dataGaps.rawMaterials.filter((r) => r.status === 'none').length} raw materials returned{' '}
312
+ <strong>zero papers</strong> in the search.
 
 
313
  </p>
314
  </Card>
315
 
 
390
  <div className="eyebrow">Data</div>
391
  <h1>Data</h1>
392
  <p className="lead">
393
+ Download the datasets, browse the literature landscape, and see which data
394
+ gaps are worth filling.
395
  </p>
396
  </div>
397
 
website/src/pages/DetectabilityPrediction.tsx CHANGED
@@ -41,11 +41,11 @@ const COLUMNS: Column<DetectabilityRow>[] = [
41
  sortable: true,
42
  render: (r) =>
43
  r.inTraining === 'positive' ? (
44
- <span className="badge badge-warn" title="This peptide was a detected (positive) example in this model's training set β€” the score may reflect memorisation, not generalisation.">
45
  Train⁺
46
  </span>
47
  ) : r.inTraining === 'negative' ? (
48
- <span className="badge badge-warn" title="This peptide was an undetected (negative) example in this model's training set β€” the score may reflect memorisation, not generalisation.">
49
  Train⁻
50
  </span>
51
  ) : (
@@ -86,10 +86,8 @@ export default function DetectabilityPrediction() {
86
  <div className="eyebrow">Tool</div>
87
  <h1>Detectability Prediction</h1>
88
  <p className="lead">
89
- Paste peptide sequences and pick one of the 30 trained context-specific
90
- models (species + enzyme). Describe your conditions to auto-rank the
91
- best-matched model, and any peptide that was in the model's training set is
92
- flagged.
93
  </p>
94
  </div>
95
 
@@ -158,7 +156,7 @@ export default function DetectabilityPrediction() {
158
  title={
159
  live
160
  ? 'Scores computed by the model (server-side inference).'
161
- : 'Backend unavailable β€” showing illustrative offline scores.'
162
  }
163
  >
164
  {live ? 'Live inference' : 'Offline preview'}
 
41
  sortable: true,
42
  render: (r) =>
43
  r.inTraining === 'positive' ? (
44
+ <span className="badge badge-warn" title="Detected (positive) example in this model's training set. The score may reflect memorisation.">
45
  Train⁺
46
  </span>
47
  ) : r.inTraining === 'negative' ? (
48
+ <span className="badge badge-warn" title="Undetected (negative) example in this model's training set. The score may reflect memorisation.">
49
  Train⁻
50
  </span>
51
  ) : (
 
86
  <div className="eyebrow">Tool</div>
87
  <h1>Detectability Prediction</h1>
88
  <p className="lead">
89
+ Paste peptides and pick a model. Describe your conditions to auto-rank the
90
+ best fit, or choose one yourself. Peptides seen during training are flagged.
 
 
91
  </p>
92
  </div>
93
 
 
156
  title={
157
  live
158
  ? 'Scores computed by the model (server-side inference).'
159
+ : 'Backend unavailable. Showing illustrative offline scores.'
160
  }
161
  >
162
  {live ? 'Live inference' : 'Offline preview'}
website/src/pages/DetectabilityTraining.tsx CHANGED
@@ -63,9 +63,8 @@ export default function DetectabilityTraining() {
63
  <div className="eyebrow">Tool</div>
64
  <h1>Train a Detectability Model</h1>
65
  <p className="lead">
66
- Provide detected (positive) peptides and a species tax ID, choose model
67
- specifications or the recommended defaults, and train a context-specific
68
- detectability model following the HydroPD Step-4 protocol.
69
  </p>
70
  </div>
71
 
@@ -105,7 +104,7 @@ export default function DetectabilityTraining() {
105
  >
106
  {FEATURE_SET_OPTIONS.map((o) => (
107
  <option key={o.id} value={o.id}>
108
- {o.label} β€” {o.desc}
109
  </option>
110
  ))}
111
  </select>
@@ -117,7 +116,7 @@ export default function DetectabilityTraining() {
117
  >
118
  {CLASSIFIER_OPTIONS.map((o) => (
119
  <option key={o.id} value={o.id}>
120
- {o.label} β€” {o.desc}
121
  </option>
122
  ))}
123
  </select>
@@ -129,7 +128,7 @@ export default function DetectabilityTraining() {
129
  >
130
  {SPLIT_OPTIONS.map((o) => (
131
  <option key={o.id} value={o.id}>
132
- {o.label} β€” {o.desc}
133
  </option>
134
  ))}
135
  </select>
@@ -188,8 +187,8 @@ export default function DetectabilityTraining() {
188
  <>
189
  <p className="muted" style={{ fontSize: '0.8rem', marginTop: 0 }}>
190
  {live
191
- ? '● Trained on the backend β€” real Step 2–5 pipeline (assign β†’ k-mer negatives β†’ protein-grouped CV).'
192
- : 'β—‹ Offline preview (illustrative numbers) β€” the training backend is not reachable.'}
193
  </p>
194
  {errorMsg && (
195
  <p
 
63
  <div className="eyebrow">Tool</div>
64
  <h1>Train a Detectability Model</h1>
65
  <p className="lead">
66
+ Give detected peptides and a species tax ID, pick your specs or use the
67
+ defaults, and train a model. Then download the model and processed data.
 
68
  </p>
69
  </div>
70
 
 
104
  >
105
  {FEATURE_SET_OPTIONS.map((o) => (
106
  <option key={o.id} value={o.id}>
107
+ {o.label} Β· {o.desc}
108
  </option>
109
  ))}
110
  </select>
 
116
  >
117
  {CLASSIFIER_OPTIONS.map((o) => (
118
  <option key={o.id} value={o.id}>
119
+ {o.label} Β· {o.desc}
120
  </option>
121
  ))}
122
  </select>
 
128
  >
129
  {SPLIT_OPTIONS.map((o) => (
130
  <option key={o.id} value={o.id}>
131
+ {o.label} Β· {o.desc}
132
  </option>
133
  ))}
134
  </select>
 
187
  <>
188
  <p className="muted" style={{ fontSize: '0.8rem', marginTop: 0 }}>
189
  {live
190
+ ? '● Trained on the server. Real pipeline: assign proteins, sample negatives, protein-grouped CV.'
191
+ : 'β—‹ Offline preview with illustrative numbers. The training backend is not reachable.'}
192
  </p>
193
  {errorMsg && (
194
  <p
website/src/pages/Home.tsx CHANGED
@@ -5,25 +5,31 @@ const TOOLS = [
5
  to: '/detectability',
6
  icon: 'πŸ“ˆ',
7
  title: 'Detectability Prediction',
8
- desc: 'Score peptides for MS detectability using one of 30 context-specific trained models.',
 
 
 
 
 
 
9
  },
10
  {
11
  to: '/training',
12
  icon: 'πŸ§ͺ',
13
  title: 'Train a Model',
14
- desc: 'Train a detectability model from your own detected peptides and species.',
15
  },
16
  {
17
  to: '/benchmarking',
18
  icon: 'πŸ†',
19
  title: 'Benchmarking',
20
- desc: 'Leaderboard of the 30 trained models and cross-model analysis of what works.',
21
  },
22
  {
23
  to: '/data',
24
  icon: 'πŸ—„οΈ',
25
  title: 'Data',
26
- desc: 'Download the raw datasets, review the literature-search summary, and see data gaps to fill.',
27
  },
28
  ]
29
 
@@ -36,9 +42,8 @@ export default function Home() {
36
  </div>
37
  <h1>HydroPD</h1>
38
  <p>
39
- Machine-learning tools for mass-spectrometry detectability of peptides
40
- from non-animal food-protein hydrolysates β€” built to support
41
- cell-culture media optimization for cultivated meat.
42
  </p>
43
  </div>
44
 
 
5
  to: '/detectability',
6
  icon: 'πŸ“ˆ',
7
  title: 'Detectability Prediction',
8
+ desc: 'Score your peptides against one of 30 species-specific models.',
9
+ },
10
+ {
11
+ to: '/bioactivity',
12
+ icon: '🧬',
13
+ title: 'Bioactivity Screening',
14
+ desc: 'Check peptides for known bioactivity, cytotoxicity, and allergen origin.',
15
  },
16
  {
17
  to: '/training',
18
  icon: 'πŸ§ͺ',
19
  title: 'Train a Model',
20
+ desc: 'Train a model on your own peptides and species, then download it.',
21
  },
22
  {
23
  to: '/benchmarking',
24
  icon: 'πŸ†',
25
  title: 'Benchmarking',
26
+ desc: 'Compare model types and see what drives performance.',
27
  },
28
  {
29
  to: '/data',
30
  icon: 'πŸ—„οΈ',
31
  title: 'Data',
32
+ desc: 'Download datasets, browse the literature landscape, and find gaps to fill.',
33
  },
34
  ]
35
 
 
42
  </div>
43
  <h1>HydroPD</h1>
44
  <p>
45
+ Predict which peptides show up in LC-MS/MS. Built for non-animal protein
46
+ hydrolysates used in cultivated-meat media.
 
47
  </p>
48
  </div>
49