Swing algorithm
Swing is an item-to-item (I2I) recommendation algorithm developed by Alibaba. It generates I2I indexes that power product recommendations in e-commerce, content, and advertising scenarios.
How it works
Traditional similarity algorithms — common neighbors, Adamic/Adar, cosine similarity, Jaccard similarity, cosine, and Rooted PageRank — measure node proximity directly. Swing takes a different approach: it considers the full graph structure and extends similarity calculation to two-hop nodes in a high-dimensional graph, making it anti-noise and significantly more accurate than traditional collaborative filtering algorithms.
For example, Swing can identify items that users frequently browse together during a shopping session — even when the co-occurrence signal is sparse — and surface them as recommendations on product detail pages.
Swing I2I indexes are used in recommendation scenarios on Taobao (mobile and PC) and in advertising services across TTPOD and Alimama.
Prerequisites
Before you begin, make sure you have:
An active PAI project with access to
algo_publicA MaxCompute table containing user click sequences
Permissions to create and write MaxCompute tables
Set up input and output tables
Input table
The input table stores user click sequences. Create it with the following schema:
CREATE TABLE IF NOT EXISTS swing_test_input
(
user_id BIGINT,
item_list STRING -- Mandatory. Contains the items clicked by a user, ordered from earliest to most recent.
)
LIFECYCLE 7;The item_list field is a semicolon-delimited string. Each item entry contains at least three sub-fields:
| Sub-field | Default position | Type | Description |
|---|---|---|---|
item_id | 0 (fixed, must be first) | Numeric | Item identifier. Must be a numeric type. |
norm | 1 (configurable via pos_norm) | Integer | Recent popularity (number of clicks). Set to 1 for all items if not used. |
timestamp | 2 (configurable via pos_time) | String | Click time in %Y%m%d%H%M%S format. Set to the same value for all items if not used. |
Example `item_list` value:
1001,5,20250809120000;1002,3,20250809130000;1003,10,20250809140000Items must be listed from earliest to most recent click time.
item_id must be a numeric type.Output table
The output table stores the I2I index. Create it with the following schema:
CREATE TABLE IF NOT EXISTS swing_test_result
(
item_id BIGINT COMMENT 'Anchor item ID',
item_list STRING COMMENT 'List of similar items'
)
LIFECYCLE 7;The item_list column uses the format:
item_id1,score1,coccur1,ori_score1;item_id2,score2,coccur2,ori_score2| Sub-field | Description |
|---|---|
item_id | ID of a similar item |
score | Normalized similarity score (max-value normalization applied) |
coccur | Number of co-occurrences between the anchor item and this item |
ori_score | Original (unnormalized) similarity score |
Run the PAI command
Submit the Swing job using the PAI command:
pai -name swing_rec_ext
-project algo_public
-DinputTable='swing_test_input/ds=20250809'
-DoutputTable='swing_test_result/ds=20250809'
-DmaxClickPerUser='500'
-DmaxUserPerItem='600'
-Dtopk='100'
-Dalpha1='5'
-Dalpha2='1'
-Dbeta='0.3'Use / to concatenate the table name and partition value for inputTable and outputTable.
Algorithm parameters
| Parameter | Description | Type | Default |
|---|---|---|---|
inputTable | Input table containing user click sequences. Supports both partitioned and non-partitioned tables. | String | — |
outputTable | Output table for the I2I index. Supports both partitioned and non-partitioned tables. | String | — |
maxClickPerUser | Maximum number of items retained per user's click sequence. If the sequence is longer, only the most recent items are kept. Lower values reduce noise from long-tail behavior; higher values capture broader user interests. | Integer | 600 |
maxTimeSpan | Maximum number of days between two clicks for the two items to be considered neighbors. Set to 1 to focus on short-term co-occurrences; increase for longer browsing sessions. | Integer | 1 |
maxUserPerItem | Number of users sampled per item for k-nearest neighbor calculation. Higher values improve accuracy at the cost of compute time. | Integer | 700 |
topk | Number of nearest neighbors to retain for each trigger item in the output. | Integer | 200 |
alpha1 | Controls the weight assigned to users with long click histories. Increasing alpha1 reduces the influence of highly active users. See Formula. | Integer | 5 |
alpha2 | Controls the penalty for user pairs with many items in common. Increasing alpha2 reduces the similarity score when two users share many items. See Formula. | Integer | 1 |
beta | Exponent that adjusts the smoothing effect of alpha1. Values closer to 0 reduce the dampening effect on active users; values closer to 1 increase it. See Formula. | Real number | 0.3 |
pos_time | Zero-based index of the timestamp sub-field within each item entry in item_list. | Integer | 2 |
pos_norm | Zero-based index of the norm (item popularity) sub-field within each item entry in item_list. | Integer | 1 |
Formula
Swing computes item similarity using the following formula:
$$sim(i,j) = \sum_{u \in U(i) \cap U(j)} \sum_{\substack{v \in U(i) \cap U(j) \\ v \neq u}} \frac{1}{(|I(u)|+\alpha_1)^\beta \cdot (|I(v)|+\alpha_1)^\beta} \cdot \frac{1}{|I(u) \cap I(v)| + \alpha_2} \cdot \frac{1}{N_j}$$
Where:
| Symbol | Description |
|---|---|
| $U(i)$ | Set of users who clicked item $i$ |
| $I(u)$ | Set of items clicked by user $u$ |
| $N_j$ | Normalization factor for item $j$ |
| $\alpha_1$ | Dampens the contribution of users with long click histories |
| $\alpha_2$ | Penalizes user pairs that share many common items |
| $\beta$ | Exponent controlling the smoothing effect of $\alpha_1$ |