From ea2354a365a557c1108947defe45817f3a8f72d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Tue, 16 Jun 2026 19:06:04 +0200 Subject: [PATCH 01/15] [#29] docs: add LICENSE (MIT) --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1e8a21a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Krzysztof Głowacz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From b12ffe29c30e97092a1c004be560772140dbaaa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Tue, 16 Jun 2026 20:31:57 +0200 Subject: [PATCH 02/15] [#29] docs(README): remove prek-related commands (for dev), add tagline and some badges --- README.md | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 35f726d..24b3395 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,13 @@ -# IMPACT (Intention-Modulated Personalized ACT-R) +# IMPACT -## Development +**I**ntention-**M**odulated **P**ersonalized **ACT**-R --- a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (SOTA) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline --- download through training --- runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU via Kaggle for speed though. -### Pre-commit Hooks +Built for my master's thesis at Wrocław University of Science and Technology. -[prek](https://prek.j178.dev/) (which is a "reimagined version of [pre-commit](https://pre-commit.com/), written in Rust") runs automated checks before every `git commit`. - -**Setup:** - -```bash -uv tool install prek # install prek (recommended way - using `uv tool` command) -prek install # install hooks into .git\hooks\pre-commit -``` - -Now every `git commit` will invoke `prek run` for the files **included in the commit**. If you ever want to undo this, run `prek uninstall`. - -If you want to manually execute all configured hooks on the files in your current git staging area, run: - -```bash -prek run -``` - -To target all files (the entire repository), add `--all-files` flag to the command: - -```bash -prek run --all-files -``` - -To bypass all hooks, add `--no-verify` flag to the `git commit` command: - -```bash -git commit --no-verify -m "your message" -``` +![CI](https://img.shields.io/badge/CI-passing-brightgreen) +![Ruff](https://img.shields.io/badge/lint-ruff-261230) +![mypy](https://img.shields.io/badge/types-mypy-blue) +![basedpyright](https://img.shields.io/badge/types-basedpyright-blue) +![uv](https://img.shields.io/badge/deps-uv-de5fe9) +![Python](https://img.shields.io/badge/python-3.12%2B-blue) +![License](https://img.shields.io/badge/license-MIT-lightgrey) From a231d29f04c3c90c7d78d4b58209d8dbbfa8379a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Tue, 16 Jun 2026 20:33:55 +0200 Subject: [PATCH 03/15] [#29] docs(README): replace '---' with — --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24b3395..adcfa5e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IMPACT -**I**ntention-**M**odulated **P**ersonalized **ACT**-R --- a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (SOTA) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline --- download through training --- runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU via Kaggle for speed though. +**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (SOTA) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU via Kaggle for speed though. Built for my master's thesis at Wrocław University of Science and Technology. From 0b8e699ad2f08156176c59aff7a294cacb54f6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Thu, 18 Jun 2026 19:04:30 +0200 Subject: [PATCH 04/15] [#29] docs(README): add/configure badges --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index adcfa5e..fc881a5 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ **I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (SOTA) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU via Kaggle for speed though. -Built for my master's thesis at Wrocław University of Science and Technology. +Built for master's thesis at Wrocław University of Science and Technology. -![CI](https://img.shields.io/badge/CI-passing-brightgreen) -![Ruff](https://img.shields.io/badge/lint-ruff-261230) -![mypy](https://img.shields.io/badge/types-mypy-blue) -![basedpyright](https://img.shields.io/badge/types-basedpyright-blue) -![uv](https://img.shields.io/badge/deps-uv-de5fe9) + +[![Actions status](https://github.com/Krisenberg/impact/workflows/CI/badge.svg)](https://github.com/Krisenberg/impact/actions) + ![Python](https://img.shields.io/badge/python-3.12%2B-blue) ![License](https://img.shields.io/badge/license-MIT-lightgrey) +[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) +[![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) From 676d2271d5077654c5662e40781f3af287d067b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Thu, 18 Jun 2026 19:26:25 +0200 Subject: [PATCH 05/15] [#29] feat(ci): consolidate both workflow files (lint, typecheck) into a single ci.yml file --- .github/workflows/{type-check.yml => ci.yml} | 17 ++++++++++-- .github/workflows/lint.yml | 29 -------------------- 2 files changed, 14 insertions(+), 32 deletions(-) rename .github/workflows/{type-check.yml => ci.yml} (81%) delete mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/type-check.yml b/.github/workflows/ci.yml similarity index 81% rename from .github/workflows/type-check.yml rename to .github/workflows/ci.yml index 892e723..f960880 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ --- -name: Type check +name: CI on: push: @@ -14,6 +14,19 @@ concurrency: cancel-in-progress: true jobs: + ruff: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Run Ruff check and format + uses: astral-sh/ruff-action@v3 + with: + version-file: pyproject.toml + - run: ruff check --no-fix + - run: ruff format --diff + mypy: runs-on: ubuntu-latest steps: @@ -28,7 +41,6 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - # Install a specific version of uv. version: "0.11.14" enable-cache: true @@ -52,7 +64,6 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - # Install a specific version of uv. version: "0.11.14" enable-cache: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index c0aff0c..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Lint - -on: - push: - branches: - - main - pull_request: - branches: - - main - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - ruff: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Run Ruff check and format - uses: astral-sh/ruff-action@v3 - with: - version-file: pyproject.toml - args: --version - - run: ruff check --no-fix - - run: ruff format --diff From 4758f536224daca38c9a0865075d1672e8992c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Thu, 18 Jun 2026 19:36:46 +0200 Subject: [PATCH 06/15] [#29] docs(README): fix badge with the CI/Actions status --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index fc881a5..09baf3b 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ Built for master's thesis at Wrocław University of Science and Technology. - -[![Actions status](https://github.com/Krisenberg/impact/workflows/CI/badge.svg)](https://github.com/Krisenberg/impact/actions) - +[![CI](https://github.com/Krisenberg/impact/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Krisenberg/impact/actions/workflows/ci.yml) ![Python](https://img.shields.io/badge/python-3.12%2B-blue) ![License](https://img.shields.io/badge/license-MIT-lightgrey) [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) From 7aa497e88356ce08b1f5a410ed6ce8ff05db67f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sat, 20 Jun 2026 17:23:20 +0200 Subject: [PATCH 07/15] [#29] docs(README): add IMPACT architecture diagram --- README.md | 6 + assets/impact_architecture.svg | 992 +++++++++++++++++++++++++++++++++ 2 files changed, 998 insertions(+) create mode 100644 assets/impact_architecture.svg diff --git a/README.md b/README.md index 09baf3b..c0e02df 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,9 @@ Built for master's thesis at Wrocław University of Science and Technology. [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) + +

+ IMPACT architecture: SASRec (session mean pooling + self-attention) and ACT-R (BLA+ memory signal) as independent pathways, merged at inference via a softmax-weighted late-fusion gate controlled by the hyperparameter alpha. +

diff --git a/assets/impact_architecture.svg b/assets/impact_architecture.svg new file mode 100644 index 0000000..f51cbdd --- /dev/null +++ b/assets/impact_architecture.svg @@ -0,0 +1,992 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 08b80d4cf88053f22adf36452b7a5fa6e4094376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 19:07:41 +0200 Subject: [PATCH 08/15] [#29] docs(README): add PyTorch badge, add more detailed project introduction explaining the trade-off and the problem that IMPACT resolved --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c0e02df..bcefc66 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,23 @@ Built for master's thesis at Wrocław University of Science and Technology. [![CI](https://github.com/Krisenberg/impact/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Krisenberg/impact/actions/workflows/ci.yml) -![Python](https://img.shields.io/badge/python-3.12%2B-blue) +![Python](https://img.shields.io/badge/python-3.12%2B-3776AB?logo=python&logoColor=white) +![PyTorch](https://img.shields.io/badge/PyTorch-2.x-EE4C2C?logo=pytorch&logoColor=white) ![License](https://img.shields.io/badge/license-MIT-lightgrey) [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) +Sequential recommender systems, such as SASRec, model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R**, a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the blend can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). + +ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. +

IMPACT architecture: SASRec (session mean pooling + self-attention) and ACT-R (BLA+ memory signal) as independent pathways, merged at inference via a softmax-weighted late-fusion gate controlled by the hyperparameter alpha.

+ +## License + +MIT — see [`LICENSE`](LICENSE). From 15c78e1a848bba3cdb5a64b04e937aa526c67edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 19:19:05 +0200 Subject: [PATCH 09/15] [#29] docs(README): add entry to references section to explicitly cite Yambda-5B paper --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bcefc66..6774526 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IMPACT -**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (SOTA) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU via Kaggle for speed though. +**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (established baseline) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset [[1]](#1). The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU for speed though. Built for master's thesis at Wrocław University of Science and Technology. @@ -12,9 +12,9 @@ Built for master's thesis at Wrocław University of Science and Technology. [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) -Sequential recommender systems, such as SASRec, model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R**, a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the blend can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). +Sequential recommender systems, such as SASRec, model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R**, a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the final "blend" can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). -ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. +Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[1]](#1) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before.

+## References + +[1] +Alexander Ploshkin et al., 2025. +Yambda-5B — A Large-Scale Multi-Modal Dataset for Ranking and Retrieval. +DOI: [10.1145/3705328.3748163](https://doi.org/10.1145/3705328.3748163) + ## License MIT — see [`LICENSE`](LICENSE). From 70d9dc58dd402eeb28dbdb6929f3e3943e3f4473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 19:24:50 +0200 Subject: [PATCH 10/15] [#29] docs(README): add references to SASRec and ACT-R papers --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6774526..dc9c158 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IMPACT -**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (established baseline) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset [[1]](#1). The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU for speed though. +**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (established baseline) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU for speed though. Built for master's thesis at Wrocław University of Science and Technology. @@ -12,9 +12,9 @@ Built for master's thesis at Wrocław University of Science and Technology. [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) -Sequential recommender systems, such as SASRec, model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R**, a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the final "blend" can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). +Sequential recommender systems, such as SASRec [[1]](#1), model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R** [[2]](#2), a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the final "blend" can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). -Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[1]](#1) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. +Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[3]](#3) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before.

[1] +Wang-Cheng Kang and Julian McAuley, 2018. +Self-Attentive Sequential Recommendation. +DOI: [10.48550/arXiv.1808.09781](https://doi.org/10.48550/arXiv.1808.09781) + +[2] +John R. Anderson et al., 2004. +Psychological Review 111.4. +DOI: [10.1037/0033-295X.111.4.1036](https://doi.org/10.1037/0033-295X.111.4.1036) + +[3] Alexander Ploshkin et al., 2025. Yambda-5B — A Large-Scale Multi-Modal Dataset for Ranking and Retrieval. DOI: [10.1145/3705328.3748163](https://doi.org/10.1145/3705328.3748163) From 8b07c5f68aff9dcfdfbe051b7cbff200fb126654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 19:44:28 +0200 Subject: [PATCH 11/15] [#29] docs(README): add citation note and CITATION.cff file --- CITATION.cff | 22 ++++++++++++++++++++++ README.md | 8 ++++++++ 2 files changed, 30 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..372480c --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,22 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +type: software +authors: + - family-names: Głowacz + given-names: Krzysztof + orcid: https://orcid.org/0009-0009-0914-7395 +title: "IMPACT: Intention-Modulated Personalized ACT-R" +abstract: "A hybrid sequential/cognitive-memory music recommender system extending SASRec + with a personalised popularity signal derived from the ACT-R cognitive architecture, + weighted by listen intentionality." +repository-code: "https://github.com/Krisenberg/impact" +url: "https://github.com/Krisenberg/impact" +date-released: 2026-06-15 +license: MIT +keywords: + - recommender-systems + - sequential-recommendation + - music-recommendation + - sasrec + - act-r + - cognitive-architecture diff --git a/README.md b/README.md index dc9c158..132b74b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,14 @@ Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), b width="860">

+## Citation + +The accompanying master's thesis is undergoing formal review and defence at Wrocław University of Science and Technology, and cannot be shared publicly yet. + +This repository serves as the primary citable artifact. It contains the complete implementation of IMPACT, together with the experimental pipelines, diagrams, and results required to reproduce the findings reported in the thesis. + +If you use this software, please cite it using the entry provided in [`CITATION.cff`](CITATION.cff). + ## References [1] From fad1752bf42c4cb0cdebb42d1b8ebc14b7524ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 20:29:16 +0200 Subject: [PATCH 12/15] [#29] docs(README): add results section (with tables and exact metric values) --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 132b74b..0389499 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,36 @@ Sequential recommender systems, such as SASRec [[1]](#1), model what a user want Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[3]](#3) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. +## Architecture + +The two pathways — SASRec and ACT-R — are fully decoupled and independent of each other. Fusion happens only at inference time, via a single hyperparameter alpha. +

- IMPACT architecture: SASRec (session mean pooling + self-attention) and ACT-R (BLA+ memory signal) as independent pathways, merged at inference via a softmax-weighted late-fusion gate controlled by the hyperparameter alpha.

+## Results + +Three configurations of IMPACT were evaluated on the held-out Yambda-5B test set: pure ACT-R (alpha = 0), the optimal (empirically found) hybrid (alpha = 0.4) and pure SASRec (alpha = 1). + +| Metric | ACT-R (alpha=0) | **IMPACT (alpha=0.4)** | SASRec (alpha=1) | +|---|---|---|---| +| NDCG@10 | 0.0894 | **0.0650** | 0.0304 | +| Recall@10 | 0.0805 | **0.0624** | 0.0258 | + +The results presented above, which use only overall metrics, tell a misleading story: ACT-R performs better than the hybrid with SASRec on both NDCG@10 and Recall@10, which might suggest that the SASRec component is unnecessary. To understand why ACT-R is superior and whether that superiority is desirable, the NDCG@10 metric is analysed along two dimensions — whether the recommended track is one the user already knows (*repetition*) or genuinely new to them (*exploration*), and whether the "knownness" is judged against the user's recent session window (*local*) or their entire listening history (global): + +| NDCG@10, decomposed | ACT-R (alpha=0) | **IMPACT (alpha=0.4)** | SASRec (alpha=1) | +|---|---|---|---| +| Repetition, local | 0.1445 | **0.1024** | 0.0444 | +| Exploration, local | 0.0138 | **0.0098** | 0.0070 | +| Repetition, global | 0.1004 | **0.0720** | 0.0328 | +| Exploration, global | 0.0000 | **0.0022** | 0.0035 | + +The NDCG@10 metric decomposition reveals the trade-off introduced earlier. ACT-R's accuracy advantage is entirely driven by repetition — it performs well because music consumption is repetitive by nature, and ACT-R is specifically designed to model such behaviour. However, the downside is that its global exploration score is 0.000, meaning it cannot recommend a track outside the user's listening history (which leads to a filtering bubble). SASRec is at the other extreme — it can recommend genuinely new content, but with only a fraction of ACT-R's accuracy. **IMPACT bridges this gap** by retaining most of ACT-R's repetition-driven accuracy while maintaining a non-zero exploration ability — the outcome the hybrid was designed to produce. + ## Citation The accompanying master's thesis is undergoing formal review and defence at Wrocław University of Science and Technology, and cannot be shared publicly yet. From cd1751ccfc9d862eff0e48880b5e1ef653d51a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Sun, 21 Jun 2026 22:20:28 +0200 Subject: [PATCH 13/15] [#29] docs(README): mention the statistical hypothesis testing (including interpretation and conclusions) to the results section --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0389499..408ef1f 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,16 @@ The results presented above, which use only overall metrics, tell a misleading s The NDCG@10 metric decomposition reveals the trade-off introduced earlier. ACT-R's accuracy advantage is entirely driven by repetition — it performs well because music consumption is repetitive by nature, and ACT-R is specifically designed to model such behaviour. However, the downside is that its global exploration score is 0.000, meaning it cannot recommend a track outside the user's listening history (which leads to a filtering bubble). SASRec is at the other extreme — it can recommend genuinely new content, but with only a fraction of ACT-R's accuracy. **IMPACT bridges this gap** by retaining most of ACT-R's repetition-driven accuracy while maintaining a non-zero exploration ability — the outcome the hybrid was designed to produce. +**Statistical significance.** To test whether the improvement is systematic rather than incidental, a Wilcoxon signed-rank test for paired data was applied to per-session NDCG@10 differences $d_i$ = NDCG@10(IMPACT) − NDCG@10(SASRec) across the full test set, under the following hypotheses: +- $H_0$: The median of $d_i$ is zero — IMPACT does not outperform SASRec systematically. +- $H_1$: The median of $d_i$ is positive — IMPACT systematically achieves a higher NDCG@10 than SASRec. + +The test rejected $H_0$ in favour of $H_1$ with a p-value $<< 0.001$ and an effect size r = 0.771 (Cohen's $d$ $\approx$ 2.42). + +Details that are worth stating explicitly: +- **Effect size scope:** an effect size of r = 0.771 describes the strength and consistency of the difference among the 5,960 pairs (26.8% of the test set) in which the two systems actually differed. For the remaining 73.2%, both models returned identical scores — predominantly NDCG@10 = 0 for both, which is typical in sparse recommendation settings. The effect is large where it exists, but not uniformly large across the full test set. +- **Direction:** of the 5,960 non-zero pairs, IMPACT outperformed SASRec in 5,182 cases (86.9%) and underperformed in 778 (13.1%) — a ratio of approximately 6.7:1 in favour of IMPACT, which is consistent with the one-sided hypothesis $H_1$. This could be understood like the following: **where introducing the personalised popularity signal changes the prediction at all, that change is nearly seven times more likely to help than to hurt.** + ## Citation The accompanying master's thesis is undergoing formal review and defence at Wrocław University of Science and Technology, and cannot be shared publicly yet. From 6cbb992457e07914f79aa3820955233c92d55202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Thu, 16 Jul 2026 19:01:45 +0200 Subject: [PATCH 14/15] [#29] docs(README): add alpha sweep plot, mention optimal alpha selection process (empirical), improve other sections (minor improvements, selected words change, etc.) --- README.md | 29 ++++++++++++++++++++--------- assets/alpha_sweep_plot.svg | 1 + 2 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 assets/alpha_sweep_plot.svg diff --git a/README.md b/README.md index 408ef1f..85800fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IMPACT -**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (established baseline) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — download through training — runs within 16GB of RAM with no GPU and no OOM; the reported results were trained on GPU for speed though. +**I**ntention-**M**odulated **P**ersonalized **ACT**-R — a hybrid sequential/cognitive-memory recommender system for music that beats SASRec (established baseline) by 114% NDCG@10 on the 4.8B-interaction Yambda-5B dataset. The full pipeline — dataset download, model training and system evaluation — runs within 16GB of RAM with no GPU and no OOM, though SASRec was trained on a GPU for speed. Built for master's thesis at Wrocław University of Science and Technology. @@ -12,23 +12,23 @@ Built for master's thesis at Wrocław University of Science and Technology. [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![basedpyright - checked](https://img.shields.io/endpoint?url=https://docs.basedpyright.com/latest/badge.json)](https://docs.basedpyright.com) -Sequential recommender systems, such as SASRec [[1]](#1), model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R** [[2]](#2), a cognitive architecture that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen or just passively served by the streaming platform. The two models operate and reason independently and are combined at inference time, so the final "blend" can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). +Sequential recommender systems, such as SASRec [[1]](#1), model what a user wants *right now*, within a short window of recent sessions. However, music listening is dominated by repetition — people return to their favourite tracks for months or even years — and this long-term signal is completely outside the scope of a short attention window. **IMPACT** adds it back in by using a personalised popularity signal derived from **ACT-R** [[2]](#2), a cognitive architecture from 1993 that models how human declarative memory strengthens and weakens with use. This signal is weighted by whether each listen was actively chosen by the user or just passively served by the streaming platform. The two models operate independently and are combined at inference time, so the final "blend" can be adjusted/retuned without retraining SASRec (ACT-R is purely deterministic either way). -Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** combines both capabilities, and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[3]](#3) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. +Experiments showed that ACT-R achieves the highest ranking accuracy (NDCG@10), but can only recommend tracks already present in the user's listening history — its global exploration score is exactly 0.000 by definition. SASRec can recommend novel, previously unheard tracks, but at substantially lower ranking accuracy. **IMPACT** is "the best of both worlds", and on the full-scale **Yambda-5B** dataset (4.8 billion interactions) [[3]](#3) **improves NDCG@10 by +114%** relative to SASRec, while still being able to recommend tracks that the user has never heard before. ## Architecture -The two pathways — SASRec and ACT-R — are fully decoupled and independent of each other. Fusion happens only at inference time, via a single hyperparameter alpha. +The two components — SASRec and ACT-R — are fully decoupled and independent of each other. Fusion happens only at inference time, via a hyperparameter alpha.

IMPACT architecture: SASRec (session mean pooling + self-attention) and ACT-R (BLA+ memory signal) as independent pathways, merged at inference via a softmax-weighted late-fusion gate controlled by the hyperparameter alpha.

## Results -Three configurations of IMPACT were evaluated on the held-out Yambda-5B test set: pure ACT-R (alpha = 0), the optimal (empirically found) hybrid (alpha = 0.4) and pure SASRec (alpha = 1). +Three configurations of IMPACT were evaluated on the held-out Yambda-5B test set: pure ACT-R, the optimal (empirically found) hybrid and pure SASRec. | Metric | ACT-R (alpha=0) | **IMPACT (alpha=0.4)** | SASRec (alpha=1) | |---|---|---|---| @@ -46,14 +46,25 @@ The results presented above, which use only overall metrics, tell a misleading s The NDCG@10 metric decomposition reveals the trade-off introduced earlier. ACT-R's accuracy advantage is entirely driven by repetition — it performs well because music consumption is repetitive by nature, and ACT-R is specifically designed to model such behaviour. However, the downside is that its global exploration score is 0.000, meaning it cannot recommend a track outside the user's listening history (which leads to a filtering bubble). SASRec is at the other extreme — it can recommend genuinely new content, but with only a fraction of ACT-R's accuracy. **IMPACT bridges this gap** by retaining most of ACT-R's repetition-driven accuracy while maintaining a non-zero exploration ability — the outcome the hybrid was designed to produce. -**Statistical significance.** To test whether the improvement is systematic rather than incidental, a Wilcoxon signed-rank test for paired data was applied to per-session NDCG@10 differences $d_i$ = NDCG@10(IMPACT) − NDCG@10(SASRec) across the full test set, under the following hypotheses: -- $H_0$: The median of $d_i$ is zero — IMPACT does not outperform SASRec systematically. +**Selecting alpha.** The three configurations evaluated above use $\alpha \in {0, 0.4, 1}$, but alpha is a continuous hyperparameter. To select the optimal value without overfitting to the held-out test set, all five NDCG@10 variants (overall + four decomposed) were swept across $\alpha \in [0, 1]$ in steps of 0.05 on the validation set of the smaller Yambda-50M variant (1% of the full dataset), used as a computational proxy. The found $\alpha_opt$ = 0.4 was then applied to the held-out Yambda-5B test set without further tuning. + +

+ Alpha sweep: all five NDCG@10 variants plotted against alpha from 0 to 1 (with a step of 0.05). Global exploration is exactly 0.000 for alpha = 0 and increases as SASRec's weight grows, while repetition-based and overall accuracy decline monotonically. +

+ +The plot makes the tradeoff clear: overall accuracy and repetition-based metrics decline monotonically as alpha increases, while global exploration is exactly 0.000 for small alpha values and only becomes non-zero once SASRec contributes enough weight to the fusion. $\alpha = 0.4$ is the point where the system recovers most of the exploration ability without sacrificing an unreasonable amount of the accuracy advantage that ACT-R provides. A pure ACT-R configuration ($\alpha = 0$) would score highest on every accuracy metric but would never recommend a track outside the user's history — it would always lead to a filter bubble by definition, regardless of the user's actual openness to new content. + +**Statistical significance.** To test whether the improvement is statistically significant, a Wilcoxon signed-rank test for paired data was applied to per-session NDCG@10 differences $d_i$ = NDCG@10(IMPACT) − NDCG@10(SASRec) across the full test set, under the following hypotheses: + +- $H_0$: The median of $d_i$ is zero — IMPACT does not outperform SASRec. - $H_1$: The median of $d_i$ is positive — IMPACT systematically achieves a higher NDCG@10 than SASRec. The test rejected $H_0$ in favour of $H_1$ with a p-value $<< 0.001$ and an effect size r = 0.771 (Cohen's $d$ $\approx$ 2.42). Details that are worth stating explicitly: -- **Effect size scope:** an effect size of r = 0.771 describes the strength and consistency of the difference among the 5,960 pairs (26.8% of the test set) in which the two systems actually differed. For the remaining 73.2%, both models returned identical scores — predominantly NDCG@10 = 0 for both, which is typical in sparse recommendation settings. The effect is large where it exists, but not uniformly large across the full test set. +- **Effect size scope:** an effect size of r = 0.771 describes the strength and consistency of the difference among the 5,960 pairs (26.8% of the test set) in which the two systems actually differed. For the remaining 73.2%, both models returned identical scores — predominantly NDCG@10 = 0 for both, which is typical in sparse recommendation scenarios. The effect is large where it exists, but not uniformly large across the full test set. - **Direction:** of the 5,960 non-zero pairs, IMPACT outperformed SASRec in 5,182 cases (86.9%) and underperformed in 778 (13.1%) — a ratio of approximately 6.7:1 in favour of IMPACT, which is consistent with the one-sided hypothesis $H_1$. This could be understood like the following: **where introducing the personalised popularity signal changes the prediction at all, that change is nearly seven times more likely to help than to hurt.** ## Citation diff --git a/assets/alpha_sweep_plot.svg b/assets/alpha_sweep_plot.svg new file mode 100644 index 0000000..9ef4322 --- /dev/null +++ b/assets/alpha_sweep_plot.svg @@ -0,0 +1 @@ +0.00.20.40.60.81.0α (0 = pure ACT-R, 1 = pure SASRec)0.060.080.100.120.14NDCG@10 (Overall & Repetition)0.08860.07470.05500.14310.12060.08990.10050.08220.0597α = 0.4NDCG@10 (Overall)Local RepetitionGlobal Repetition0.00.20.40.60.81.0α (0 = pure ACT-R, 1 = pure SASRec)0.0000.0020.0040.0060.0080.0100.0120.0140.0160.018NDCG@10 (Exploration)0.01700.01050.00630.00000.00200.0029α = 0.4Local ExplorationGlobal Exploration From 0af7ca01c629337fc0860675bc6b8f5c02f41be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20G=C5=82owacz?= Date: Thu, 16 Jul 2026 19:02:30 +0200 Subject: [PATCH 15/15] [#29] chore(.gitignore): update rules for the files/dirs to be git-ignored --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d333a7d..9ed19c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ .vscode data +final-artefacts logs /models/* notebooks/*.ipynb !notebooks/kaggle_grid_search.ipynb !notebooks/kaggle_sasrec_training.ipynb reports +tests # Created by https://www.toptal.com/developers/gitignore/api/python # Edit at https://www.toptal.com/developers/gitignore?templates=python