# KDD Cup 2020 figure and implementation notes

## Sources and date

- [Original Chinese article](https://zhuanlan.zhihu.com/p/149424540). The author's archived page records publication on June 20, 2020 and an update on July 17, 2020. The blog post preserves the publication date. The archive does not establish a time zone, so no time or offset is invented.
- [Released solution snapshot](https://github.com/ChuanyuXue/KDDCUP-2020/tree/b675a1b01ba430845f9e23a466bc82501f57abb2).
- [Team description and method outline](https://github.com/ChuanyuXue/KDDCUP-2020/blob/b675a1b01ba430845f9e23a466bc82501f57abb2/README_CN.md). This identifies Challengers' results as first on A and sixth on B; these are leaderboard stages within the Debiasing Challenge, not victories in two separate KDD competition tracks.
- [Organizer's challenge page](https://tianchi.aliyun.com/competition/entrance/231785/introduction) and [organizer Q&A](https://tianchi.aliyun.com/forum/post/110939).

The post adapts the author's account and explains its methods. It does not report a new training run, new scores, or a reproduced benchmark.

## Figures

All four SVGs are drawn with vector shapes and editable text. None contains a copied, traced, or embedded raster image. Black outlines, white backgrounds, and hatching follow the blog's CIKM figures.

| Asset | Source concept | Redraw |
| --- | --- | --- |
| 01-pipeline.svg | Original pipeline figure | Combined retrieval feeds 1,000 candidates. Second-order similarities and SASRec feed ranking features. CatBoost and LightGBM lead to 50 items after popularity adjustment. |
| 02-data-split.svg | Original handwritten split figure | A clean sequence diagram with held-out targets. Widths are schematic, not observed durations. |
| 03-graph-walks.svg | Original four-panel graph-learning figure | New example sequences and a matching five-node graph. All displayed walks follow graph edges. The graph shows an undirected topology for illustration; the post explains the different DeepWalk and node2vec graph construction. The embedding cells are schematic and contain no model outputs. |
| 04-shared-neighbors.svg | Original common-neighbor figure | New graph layout showing three shared intermediates and extra neighbors. No experimental graph data is claimed. |

There are no empirical charts in the original article to reconstruct. Dataset downloads and model training are not needed to redraw these conceptual figures.

## Formula and implementation checks

The equations use consistent symbols and resolve typographical ambiguities in the Chinese write-up. Paths below are relative to the pinned solution repository.

- **Evaluation:** the evaluate_each_phase function in code/3_Recall/01_Recall-Wu-online.py uses one held-out next-click item. Its half subset includes targets whose degree is at or below the median of the target degrees for that phase, with ties included. A one-based rank gives 1/log2(r+1).
- **Splitting:** code/1_DataPreprocessing/01_Generate_Offline_Dataset_origin.py removes held-out user–item pairs from all phase files. The model-1 dataset repeats the process on the remaining history. The diagram expresses that sequence of holdouts, not a claim that every user has the same history length.
- **Item CF:** code/2_Similarity/01_itemCF_Mundane_online.py uses unique-user count for the source item's logarithmic term, user history length for the other logarithmic term, and click counts for the (n_i n_j)^0.2 term. Direction weight is 0.8 for an earlier destination and 1 for a later destination. Time gaps are scaled by 650000. The post factors embedding similarities out of the pair sum; those similarities depend only on the item pair.
- **Fusion:** the same script transforms cosine scores with 0.5*cosine+0.5, squares the node2vec term, and multiplies it by DeepWalk and text terms. Missing similarities default to 0.5. The stored scores are truncated to four decimal places; the article gives the underlying calculation.
- **Candidate scores:** the online similarity script considers 500 neighbors per history item and returns up to 1,000 candidates. It sums history contributions with popularity, position, and time weights. These are distinct from the strongest-path aggregation in the earlier CIKM solution.
- **Phase reuse:** the online similarity script shifts later released phases by a common time offset before combining them. This is a competition-data construction, not an assertion that later observations are available in a chronological live deployment.
- **Graph walks:** code/2_Similarity/deep_node_model.py uses uniform DeepWalk on an undirected graph and node2vec with p=2, q=0.5 on a directed weighted graph. Both use walk length 20, 80 walks per node, window size 10, and 128-dimensional embeddings. The optional degree-reweighting branch is not enabled by the shown entry points. Repeated graph edges are overwritten by the graph constructor, rather than summed; the article therefore does not reproduce the write-up's edge-sum formula as an exact implementation formula.
- **Second-order similarity:** code/2_Similarity/RA_Wu_online.py filters direct similarities at 0.005 and uses weighted strength, not unweighted degree, for its normalizations. Its neighbor search requires the source and intermediate node to be connected in both directions and the intermediate to connect to the destination. The post's intermediate set refers to this retained neighbor search. CN, RA, and AA outputs are thresholded and truncated before further use; HPI, HDI, and LHN1 derive from the retained CN values. The HPI denominator uses the strengths of the source and destination, resolving the inconsistent subscript in the original article.
- **Features:** feature_list.csv is an Excel workbook despite its suffix. Its 68 feature rows, excluding the target label, minus the ten named exclusions in Model_Online.py leave 58 features. The 23/18/11 group counts come from the author's write-up and describe feature construction before final selection. The repository contains phase-local counts as well as cumulative counts through each phase.
- **Sequential model:** code/3_NN/sas_rec.py scales the supplied 256-dimensional item features by 1/25 and assigns them to the embedding table. model2.py adds a user embedding to the sequence representation before its item dot product. The ranking feature scripts apply the sigmoid. Missing item vectors in ItemFeat2.py are filled using popularity-group means; the post does not repeat the original article's random-fill description.
- **Training:** code/5_Modeling/Model_Online.py creates six 1:5 positive-to-negative samples and averages six predictions in each model family. Its sample weighting emphasizes low-count items and low-count positives; the original article did not supply an ablation isolating those weights.
- **Ensemble:** the harmonic and geometric means use CatBoost:LightGBM weights of 6:4 and are added. The sum is a ranking score, not a calibrated probability.
- **Popularity adjustment:** Model_Online.py uses max(0.61, 1/log(n_i+2)) for positive cumulative counts through the query phase. This differs from the simpler 1/log(n_i+1) expression in the original write-up. The script treats zero or missing counts separately through its NaN handling, yielding the floor. Applying a common multiplier before this ensemble is algebraically equivalent to applying it after the sum.

## Rebuild

Run `python draw_figures.py` in this directory. Only the Python standard library is required. The script performs no downloads and does not run the competition code.
