Yeepee β€” Huawei TechArena 2026 CTR (Phase 1)

Private team repo. LightGBM click-through-rate model for the Huawei TechArena 2026 Ireland CTR challenge.

No competition data is included β€” no train/evaluation files, feature caches, parquet/duckdb, or row-level predictions/submissions. Only code, logs, metrics, charts and LightGBM model dumps.

Last sync: 2026-10-29 07:40 GMT Β· 2485 files.

Overview

Team Yeepee, Huawei TechArena 2026 (Ireland), Phase 1 CTR challenge. Each event shows 10 candidate items, with at most one click; each row carries up to 20 prior clicks of the user (including warm-up). Submissions are a click probability per row and are ranked by global ROC AUC over all rows (not per event). The solution has to run on a laptop CPU (no GPU).

Status: best submission is submission_v3 β€” 0.788757 public AUC (23 Oct 2026), 0.7775 local validation. Phase 1 is still open; the code here is a work in progress.

Model

  • LightGBM binary classifier (lr 0.05, 63 leaves, 400 rounds), 325 features in v3 (the earlier v3/ stand-alone pipeline used 164; see v3/out/final_info.json).
  • 3-seed average of predicted probabilities (plain mean, no per-event normalisation).
  • Training rows: the first event per user in [Ck, Ck+1d) for six cutoff folds Ck = 21–26 Jan (about 2.1M rows), with every statistic frozen at Ck. Evaluation features are frozen at 27 Jan.
  • Runs on a laptop-class CPU; no GPU.

Feature families

  • SVD item embeddings of the training co-click graph (k = 16 / 32 / 64, plus 128 for some centroid features).
  • History-cosine similarity: candidate vs the user's click-history centroid (plain, recency-weighted, contrastive, item-side variants).
  • Within-event normalisation: z-score and rank of key features across the 10 candidates of the same event.
  • History-match counts: how many of the user's prior clicks match / co-occur with the candidate.
  • User CTR and user-cluster CTR from training labels before the cutoff.
  • Co-occurrence / transition statistics between history items and candidates (training data only).
  • Ridge taste vectors: per-user ridge regression on frozen SVD-k64 item vectors (v2work/extra2.py).
  • User-state features (activity counts, history length, etc.). Time/gap features are dropped in v3 (notime).

Validation protocol

  • Time-based split: fit on folds before the validation cutoff; validate on the first event per user after the cutoff (main cutoff 25 Jan, check cutoff 26 Jan).
  • Label statistics frozen at the cutoff (CTR, co-click graph, SVD/MF embeddings use only labels before it).
  • Whole events kept together (all 10 candidates in the same split).
  • Metric is global ROC AUC, plus segment AUCs (warm / history-only / empty-history; stale β‰₯ 1 day vs fresher) and event-level vs within-event AUC.
  • Leak checks in v3/out/leakcheck.jsonl.

Data policy

  • No aggregates over the unlabelled evaluation rows. Every global / item-level statistic (popularity, co-occurrence, transitions, SVD factors, centroids, clusters) uses training data only.
  • Each evaluation row's own history is used only for that row's own user features.
  • submission_v2 was withdrawn because it pooled evaluation-row histories into item statistics.

Version history

version local AUC (cutoff 25 Jan) public AUC notes
starter 0.611 β€” competition starter baseline (v3/out/baselines.json)
v2 0.762 β€” superseded / not to be used β€” item stats pooled evaluation-row histories
v3 0.7775 0.788757 (23 Oct 2026) clean: training data + each row's own history only; 325 features, 3 seeds

Limitations

  • Empty-history users are weak (AUC about 0.56); history-only users about 0.72 vs about 0.78 for warm users.
  • Stale rows (β‰₯ 1 day stale) score lower (about 0.758 vs 0.782 at cutoff 25 Jan) and make up a larger share of test than of local validation.
  • Event-level AUC (which events get any click) is low (about 0.61–0.65); within-event ranking is about 0.76–0.78.
  • No competition data is in this repo, so nothing here can be re-run without the organisers' files.

Experiments that did not help (v2work/screen_results.jsonl)

Screening runs on a 25% user sample, 1 seed; AUC = best point of the 100–400-round curve. Ξ” is against the base run at the same cutoff. A new submission needs β‰₯ +0.002 locally.

cutoff tag what n_feats global AUC Ξ” vs base event AUC within-event AUC empty-history stale β‰₯1d
25 base reference (v3 feature set) 325 0.77286 +0.00000 0.6118 0.7609 0.5499 0.7518
25 ev + OOF event-level P(click) feature 327 0.77315 +0.00029 0.6129 0.7615 0.5416 0.7534
26 base reference (v3 feature set) 325 0.78965 +0.00000 0.6183 0.7787 0.5300 β€”
26 ev + OOF event-level P(click) feature 327 0.78940 -0.00025 0.6187 0.7786 0.5286 β€”
25 lr lambdarank objective 325 0.76349 -0.00937 0.5756 0.7529 0.5078 0.7388
25 dropcum drop cumulative-count features 308 0.77183 -0.00103 0.6106 0.7599 0.5476 0.7509
26 dropcum drop cumulative-count features 308 0.78938 -0.00027 0.6177 0.7781 0.5295 β€”
25 e_notime fold scheme e, no time features 325 0.77296 +0.00010 0.6118 0.7617 0.5321 0.7502
25 e_stale fold scheme e + stale-like rows 326 0.77356 +0.00070 0.6104 0.7618 0.5333 0.7516
25 fe_stale fold schemes f+e + stale-like rows 326 0.77354 +0.00068 0.6131 0.7622 0.5419 0.7531
25 f_stale fold scheme f + stale-like rows 326 0.77286 +0.00000 0.6117 0.7610 0.5362 0.7519
26 e_notime fold scheme e, no time features 325 0.78938 -0.00027 0.6164 0.7789 0.5502 β€”
26 e_stale fold scheme e + stale-like rows 326 0.78956 -0.00009 0.6160 0.7786 0.5338 β€”
26 fe_stale fold schemes f+e + stale-like rows 326 0.78954 -0.00011 0.6170 0.7785 0.5345 β€”
26 f_stale fold scheme f + stale-like rows 326 0.78934 -0.00031 0.6168 0.7783 0.5476 β€”
25 rc + repeat-click features 352 0.77287 +0.00001 0.6103 0.7615 0.5202 0.7530
26 rc + repeat-click features 352 0.78901 -0.00064 0.6174 0.7784 0.5285 β€”
25 fe_stale_rc stale folds + repeat-click 353 0.77317 +0.00031 0.6115 0.7627 0.5423 0.7530
26 fe_stale_rc stale folds + repeat-click 353 0.78935 -0.00030 0.6171 0.7782 0.5286 β€”
25 fe_stale_rc_cv stale folds + repeat-click + co-visitation 372 0.77312 +0.00026 0.6118 0.7616 0.5372 0.7520
26 fe_stale_rc_cv stale folds + repeat-click + co-visitation 372 0.78866 -0.00099 0.6159 0.7781 0.5315 β€”
25 gap_base 325 0.76958 -0.00328 0.6110 0.7576 0.5597 0.7494
26 gap_base 325 0.78377 -0.00588 0.6144 0.7728 0.5366 β€”
25 i_usfix 325 0.77274 -0.00012 0.6126 0.7613 0.5332 0.7520
25 gap_usfix 325 0.76979 -0.00307 0.6095 0.7573 0.5479 0.7497
26 i_usfix 325 0.78970 +0.00005 0.6180 0.7790 0.5367 β€”
26 gap_usfix 325 0.78350 -0.00615 0.6131 0.7724 0.5214 β€”
25 i_notr 316 0.77267 -0.00019 0.6127 0.7605 0.5271 0.7512
25 gap_notr 316 0.76939 -0.00347 0.6111 0.7576 0.5462 0.7484
26 i_notr 316 0.79037 +0.00072 0.6182 0.7796 0.5331 β€”
26 gap_notr 316 0.78382 -0.00583 0.6111 0.7733 0.5344 β€”
25 i_share 328 0.77223 -0.00063 0.6118 0.7604 0.5403 0.7508
25 gap_share 328 0.76926 -0.00360 0.6103 0.7576 0.5348 0.7486
26 i_share 328 0.78921 -0.00044 0.6160 0.7783 0.5251 β€”
26 gap_share 328 0.78432 -0.00533 0.6147 0.7739 0.5103 β€”
25 i_hs 333 0.77267 -0.00019 0.6120 0.7609 0.5577 0.7523
25 gap_hs 333 0.76932 -0.00354 0.6098 0.7573 0.5601 0.7476
26 i_hs 333 0.78916 -0.00049 0.6176 0.7781 0.5460 β€”
26 gap_hs 333 0.78336 -0.00629 0.6123 0.7716 0.5059 β€”
25 c_usfix_notr 316 0.77260 -0.00026 0.6119 0.7608 0.5360 0.7516
25 gap_c_usfix_notr 316 0.76986 -0.00300 0.6109 0.7575 0.5391 0.7480
26 c_usfix_notr 316 0.78980 +0.00015 0.6161 0.7793 0.5320 β€”
26 gap_c_usfix_notr 316 0.78352 -0.00613 0.6145 0.7728 0.5283 β€”
25 base_seed1 325 0.77298 +0.00012 0.6113 0.7613 0.5457 0.7512
25 gap_base_seed1 325 0.76972 -0.00314 0.6103 0.7579 0.5502 0.7494
26 base_seed1 325 0.78937 -0.00028 0.6165 0.7777 0.5167 β€”
26 gap_base_seed1 325 0.78349 -0.00616 0.6115 0.7716 0.5409 β€”
25 i_lr12 328 0.79146 +0.01860 0.6211 0.7803 0.5288 0.7736
25 gap_lr12 328 0.78908 +0.01622 0.6149 0.7766 0.5232 0.7705
26 i_lr12 328 0.80298 +0.01333 0.6235 0.7924 0.5316 β€”
26 gap_lr12 328 0.79821 +0.00856 0.6168 0.7865 0.5097 β€”
25 i_lrall 334 0.79468 +0.02182 0.6201 0.7837 0.5211 0.7765
25 i_lr10 328 0.79367 +0.02081 0.6160 0.7809 0.5147 0.7733
26 i_lrall 334 0.80615 +0.01650 0.6240 0.7961 0.5375 β€”
26 i_lr10 328 0.80616 +0.01651 0.6238 0.7953 0.5225 β€”
25 i_lr2all 379 0.79734 +0.02448 0.6204 0.7866 0.5267 0.7779
25 i_lr2_1012c 336 0.79656 +0.02370 0.6199 0.7851 0.5296 0.7767
25 i_lr2_81012 308 0.79348 +0.02062 0.6181 0.7821 0.5368 0.7749
26 i_lr2all 379 0.80834 +0.01869 0.6256 0.7978 0.5148 β€”
26 i_lr2_1012c 336 0.80727 +0.01762 0.6225 0.7968 0.5111 β€”
26 i_lr2_81012 308 0.80496 +0.01531 0.6258 0.7949 0.5085 β€”
25 gap_lr2all 379 0.79579 +0.02293 0.6190 0.7841 0.5449 0.7753
25 gap_lrall 334 0.79237 +0.01951 0.6172 0.7808 0.5291 0.7737
26 gap_lr2all 379 0.80490 +0.01525 0.6211 0.7928 0.4951 β€”
26 gap_lrall 334 0.80196 +0.01231 0.6196 0.7904 0.4982 β€”
25 v7_AB 387 0.80842 +0.03556 0.6193 0.7965 0.5390 0.7918
25 v7_A 382 0.80246 +0.02960 0.6228 0.7911 0.5236 0.7844
25 v7_B 384 0.80842 +0.03556 0.6160 0.7962 0.5163 0.7919
26 v7_AB 387 0.81854 +0.02889 0.6230 0.8080 0.5078 β€”
26 v7_A 382 0.81220 +0.02255 0.6282 0.8016 0.5098 β€”
26 v7_B 384 0.81814 +0.02849 0.6229 0.8074 0.5197 β€”
25 gap_v7_AB 387 0.80754 +0.03468 0.6190 0.7950 0.5169 0.7895
25 gap_v7_A 382 0.80059 +0.02773 0.6197 0.7886 0.5411 0.7827
25 gap_v7_B 384 0.80738 +0.03452 0.6152 0.7950 0.5496 0.7901
26 gap_v7_AB 387 0.81625 +0.02660 0.6234 0.8042 0.5049 β€”
26 gap_v7_A 382 0.80897 +0.01932 0.6236 0.7965 0.4926 β€”
26 gap_v7_B 384 0.81618 +0.02653 0.6203 0.8047 0.5150 β€”
25 xAn_lr2 410 0.79933 +0.02647 0.6213 0.7883 0.5091 0.7787
25 xAn_v7 418 0.80870 +0.03584 0.6181 0.7965 0.5143 0.7915
26 xAn_lr2 410 0.81069 +0.02104 0.6257 0.7991 0.5061 β€”
26 xAn_v7 418 0.81891 +0.02926 0.6225 0.8078 0.5238 β€”
25 gap_xAn_lr2 410 0.79760 +0.02474 0.6199 0.7859 0.4990 0.7776
25 gap_xAn_v7 418 0.80785 +0.03499 0.6162 0.7955 0.5431 0.7898
26 gap_xAn_lr2 410 0.80726 +0.01761 0.6216 0.7955 0.4764 β€”
26 gap_xAn_v7 418 0.81652 +0.02687 0.6180 0.8037 0.5021 β€”

Event Γ— item decomposition (v2work/posthoc_B3.json)

Separate event-level model p_event (does the event get any click), combined with the item model as p_event Γ— softmax(item) or logit(p_event) + Ξ±Β·item_logit over Ξ± ∈ {0.5…3}. Best combination vs the plain item model:

cutoff item model p_event only best combination its global AUC
25 0.77174 0.55818 b_pev_x_softmax 0.77151
26 0.78921 0.56130 b_pev_x_softmax 0.78913

No combination beat the plain item model: its scores already carry the event-level signal.

Auto-generated results

v2 combo runs (v2work/combo_results.jsonl)

cut variant n_feats best iter AUC all AUC warm AUC history-only AUC empty-history
25 base 276 300 0.7617 0.7636 0.7139 0.5505
25 notime 268 450 0.7620 0.7638 0.7154 0.5608
25 notime_x 306 450 0.7738 0.7758 0.7199 0.5757
25 notime 268 400 0.7617 0.7635 0.7148 0.5527
25 notime_x2 325 350 0.7754 0.7774 0.7224 0.5538
25 notime 325 400 0.7772 0.7793 0.7230 0.5602
25 notime_eft_ne 325 300 0.7775 0.7795 0.7243 0.5662

Repo layout

  • v2work/ β€” main pipeline behind v3: prep.py, v3fold.py / v3feat_ne.py (v3 features), build_folds.py / feats.py (v2 features), extra.py (similarity extras), extra2.py (ridge taste vectors, user state), combo.py (train / validate / final fit), write_sub.py; results combo_results.jsonl, screen_results.jsonl, event_results.jsonl, posthoc_B3.json; seed models final_model_s*.txt; out/solution_v3.py (driver), out/submission_log.csv; ens/ ensemble runs.
  • v3/ β€” stand-alone pipeline (prep.py, features.py, train.py, metric.py, segments.py, validate_submission.py), results in v3/out/, LightGBM dumps *.txt.
  • v4/ β€” staleness-aware protocol experiments.
  • research/ β€” AUC improvement notes; charts/ β€” training/profile charts.

How to reproduce

You need the competition files (train.zip, evaluation.zip), which are not included.

# unpack competition data into /workspace/huawei/data, then:
python v2work/out/solution_v3.py             # features -> 3-seed final fit -> v2work/out/submission_v3.csv
python v2work/out/solution_v3.py --validate  # also runs the cutoff-25 validation (combo.py val 25 notime)
python v3/validate_submission.py v2work/out/submission_v3.csv   # format check

Paths in the scripts assume /workspace/huawei. The driver runs, in order: prep.py, v3fold.py, build_folds.py c25/c26, extra.py, extra2.py, XF=1 XF2=1 combo.py final 400 3 notime, write_sub.py.

License

license: other. The code and model files are the team's competition work. The competition data and its terms belong to the Huawei TechArena 2026 organisers, and the competition rules apply to any use. The data is not redistributed here.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Evaluation results

  • ROC AUC, local validation (cutoff 25 Jan, first event per user after cutoff) on Huawei TechArena 2026 Phase 1 (private competition data, not included)
    self-reported
    0.777
  • ROC AUC, public leaderboard (submission_v3, 23 Oct 2026) on Huawei TechArena 2026 Phase 1 (private competition data, not included)
    self-reported
    0.789