Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save wojtyniak/cf93e5dd4da6a3cb2b3a65805ae453e9 to your computer and use it in GitHub Desktop.

Select an option

Save wojtyniak/cf93e5dd4da6a3cb2b3a65805ae453e9 to your computer and use it in GitHub Desktop.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Social-Textual Search and Ranking\n",
"\n",
"**Paper:** Social-Textual Search and Ranking \n",
"**Authors:** Ali Khodaei, Cyrus Shahabi\n",
"\n",
"## Overview\n",
"\n",
"This notebook implements the social-textual search and ranking system described in the paper. The system combines:\n",
"- **Social relevance**: Based on user relationships, user importance, and user actions\n",
"- **Textual relevance**: Based on traditional tf-idf keyword matching\n",
"\n",
"The paper proposes a novel ranking method that integrates social network information with textual content to improve search results in social media platforms.\n",
"\n",
"## Workflows Implemented\n",
"\n",
"1. **Socio-textual relevance ranking (sotext)** - Primary contribution\n",
"2. **Binary social ranking (socBinary)** - Baseline with binary user actions\n",
"3. **Binary socio-textual ranking (sotextBinary)** - Baseline\n",
"4. **Social-only ranking (soc)** - Baseline\n",
"5. **Textual-only ranking (text)** - Baseline (traditional tf-idf)\n",
"6. **Evaluation with varying k, alpha, and delta parameters**\n",
"\n",
"## Resource Constraints\n",
"\n",
"This notebook is designed to run with:\n",
"- **Memory**: 4GB RAM maximum\n",
"- **Runtime**: 5-10 minutes (small-scale demonstration)\n",
"- **Purpose**: Educational overview of the methods\n",
"\n",
"We use small synthetic datasets to demonstrate the algorithms. For full-scale experiments (as in the paper with Last.fm dataset: 3148 users, 30520 tracks, 12565 tags), you would need to run on a more powerful infrastructure."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Setup and Dependencies\n",
"\n",
"Install required libraries for graph processing, numerical computation, and visualization."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[37m⠋\u001b[0m \u001b[2mResolving dependencies... \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mResolving dependencies... \u001b[0m\r",
"\u001b[2K\u001b[37m⠋\u001b[0m \u001b[2mResolving dependencies... \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mResolving dependencies... \u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mnumpy==2.4.2 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mscipy==1.17.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mnetworkx==3.6.1 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mscikit-learn==1.8.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mmatplotlib==3.10.8 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mpandas==3.0.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mnumpy==2.4.2 \u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mnumpy==2.4.2 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mjoblib==1.5.3 \u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mthreadpoolctl==3.6.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mcontourpy==1.3.3 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mcycler==0.12.1 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mfonttools==4.61.1 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mkiwisolver==1.4.9 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mpackaging==25.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mpillow==12.1.1 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mpyparsing==3.3.2 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2mpython-dateutil==2.9.0.post0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2msix==1.17.0 \u001b[0m\r",
"\u001b[2K\u001b[37m⠹\u001b[0m \u001b[2m \u001b[0m\r",
"\u001b[2K\u001b[2mResolved \u001b[1m17 packages\u001b[0m \u001b[2min 256ms\u001b[0m\u001b[0m\r\n",
"\u001b[37m⠋\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/0) \r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/0) \r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14) \r",
"\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 0 B/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mthreadpoolctl \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 14.90 KiB/18.20 KiB\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 14.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.88 KiB/301.83 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 30.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 30.88 KiB/301.83 KiB\r\n",
"\u001b[2mcontourpy \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 14.91 KiB/354.35 KiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 78.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 75.49 KiB/301.83 KiB\r\n",
"\u001b[2mcontourpy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 30.91 KiB/354.35 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 32.00 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 3.25 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.91 KiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.90 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 30.91 KiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 14.88 KiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 30.91 KiB/33.36 MiB \u001b[12A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[12A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mpyparsing \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 94.88 KiB/119.90 KiB\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 107.38 KiB/301.83 KiB\r\n",
"\u001b[2mcontourpy \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 62.91 KiB/354.35 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 62.91 KiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 60.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 46.91 KiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 35.25 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 46.91 KiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 46.90 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 62.80 KiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 39.13 KiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 62.91 KiB/33.36 MiB \u001b[12A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[12A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 139.49 KiB/301.83 KiB\r\n",
"\u001b[2mcontourpy \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 78.80 KiB/354.35 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 77.16 KiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 76.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 75.58 KiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 67.25 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 66.08 KiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 77.27 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 76.56 KiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 62.60 KiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 78.74 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[11A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[11A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 187.49 KiB/301.83 KiB\r\n",
"\u001b[2mcontourpy \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 338.80 KiB/354.35 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 707.71 KiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 172.61 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 575.58 KiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 195.25 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 236.73 KiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 301.27 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 668.46 KiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 175.83 KiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 238.74 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[11A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[11A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 251.38 KiB/301.83 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 1.04 MiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 236.61 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 1.02 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 238.61 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 1.03 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 397.27 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 1.04 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 1.01 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 334.74 KiB/33.36 MiB \u001b[10A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[10A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 251.38 KiB/301.83 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 1.14 MiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 252.61 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 1.07 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 238.61 KiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 1.14 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 397.27 KiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 1.15 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 1.13 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 334.74 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[10A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[10A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 271.49 KiB/301.83 KiB\r\n",
"\u001b[2mkiwisolver \u001b[0m \u001b[32m------------------------------\u001b[30m\u001b[2m\u001b[0m\u001b[0m 1.41 MiB/1.41 MiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 315.59 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 1.57 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 1.37 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 1.34 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 1.06 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 1.48 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 1.56 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 383.08 KiB/33.36 MiB \u001b[10A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[10A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mjoblib \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 287.49 KiB/301.83 KiB\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 315.59 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 1.59 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 1.48 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 1.40 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 1.13 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 1.60 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 1.57 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 398.74 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[9A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[9A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 380.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m------------\u001b[30m\u001b[2m------------------\u001b[0m\u001b[0m 2.01 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 1.92 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 2.02 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 1.46 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 2.04 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 2.01 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 496.26 KiB/33.36 MiB \u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 380.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 2.04 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 1.98 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 2.04 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 1.46 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 2.08 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 2.03 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 512.26 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 494.12 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m---------------\u001b[30m\u001b[2m---------------\u001b[0m\u001b[0m 2.48 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 2.40 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 2.40 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 1.84 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 2.55 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 2.47 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m\u001b[30m\u001b[2m------------------------------\u001b[0m\u001b[0m 894.64 KiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 636.50 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m----------------\u001b[30m\u001b[2m--------------\u001b[0m\u001b[0m 2.62 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m------------\u001b[30m\u001b[2m------------------\u001b[0m\u001b[0m 2.71 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 2.87 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 2.26 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 2.86 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 2.77 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-\u001b[30m\u001b[2m-----------------------------\u001b[0m\u001b[0m 2.02 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠹\u001b[0m \u001b[2mPreparing packages...\u001b[0m (4/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 908.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 3.06 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 3.24 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.13 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 2.32 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 3.39 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 3.28 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 2.30 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠸\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 988.71 KiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 3.58 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m----------------\u001b[30m\u001b[2m--------------\u001b[0m\u001b[0m 3.66 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.27 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 2.52 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.82 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 3.67 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m--\u001b[30m\u001b[2m----------------------------\u001b[0m\u001b[0m 3.01 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠸\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m---------------\u001b[30m\u001b[2m---------------\u001b[0m\u001b[0m 1.03 MiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 3.64 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 3.93 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 4.14 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 2.94 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 4.12 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 3.81 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 3.77 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠸\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 1.18 MiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 3.80 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 4.44 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----------------\u001b[30m\u001b[2m--------------\u001b[0m\u001b[0m 4.62 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 3.09 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 4.59 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 4.03 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.04 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠸\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 1.62 MiB/1.97 MiB\r\n",
"\u001b[2mfonttools \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 4.56 MiB/4.70 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m---------------------\u001b[30m\u001b[2m---------\u001b[0m\u001b[0m 4.78 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 4.97 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.17 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 4.97 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 4.47 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.07 MiB/33.36 MiB \u001b[8A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[8A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 1.69 MiB/1.97 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 5.36 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 5.45 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.31 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m---------------\u001b[30m\u001b[2m---------------\u001b[0m\u001b[0m 5.51 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 4.73 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.09 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[7A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[7A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 1.71 MiB/1.97 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 5.44 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 5.53 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 3.37 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------\u001b[30m\u001b[2m--------------\u001b[0m\u001b[0m 5.58 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 4.75 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.09 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[7A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[7A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mnetworkx \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 1.90 MiB/1.97 MiB\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 5.81 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m---------------------\u001b[30m\u001b[2m---------\u001b[0m\u001b[0m 5.92 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 4.07 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 5.93 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 4.89 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.15 MiB/33.36 MiB \u001b[7A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[7A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 5.86 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m---------------------\u001b[30m\u001b[2m---------\u001b[0m\u001b[0m 6.03 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 4.14 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 6.03 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 4.90 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---\u001b[30m\u001b[2m---------------------------\u001b[0m\u001b[0m 4.17 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[6A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[6A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m---------------------------\u001b[30m\u001b[2m---\u001b[0m\u001b[0m 6.23 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 6.32 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 4.82 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 6.16 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 4.95 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m----\u001b[30m\u001b[2m--------------------------\u001b[0m\u001b[0m 5.49 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[6A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[6A\u001b[37m⠼\u001b[0m \u001b[2mPreparing packages...\u001b[0m (6/14)\r\n",
"\u001b[2mpillow \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 6.71 MiB/6.71 MiB\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 6.92 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 5.18 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 6.48 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 4.97 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 6.24 MiB/33.36 MiB \u001b[6A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[6A\u001b[37m⠴\u001b[0m \u001b[2mPreparing packages...\u001b[0m (8/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 6.92 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 5.25 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 6.55 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 4.97 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 6.31 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠴\u001b[0m \u001b[2mPreparing packages...\u001b[0m (8/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 7.12 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------------------\u001b[30m\u001b[2m----------\u001b[0m\u001b[0m 5.91 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 6.85 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 5.21 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----\u001b[30m\u001b[2m-------------------------\u001b[0m\u001b[0m 6.65 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠴\u001b[0m \u001b[2mPreparing packages...\u001b[0m (8/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m---------------------------\u001b[30m\u001b[2m---\u001b[0m\u001b[0m 7.54 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 6.66 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m--------------------\u001b[30m\u001b[2m----------\u001b[0m\u001b[0m 7.22 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 5.45 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m------\u001b[30m\u001b[2m------------------------\u001b[0m\u001b[0m 7.54 MiB/33.36 MiB \u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠴\u001b[0m \u001b[2mPreparing packages...\u001b[0m (8/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m---------------------------\u001b[30m\u001b[2m---\u001b[0m\u001b[0m 7.73 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 7.37 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m---------------------\u001b[30m\u001b[2m---------\u001b[0m\u001b[0m 7.53 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 5.87 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-------\u001b[30m\u001b[2m-----------------------\u001b[0m\u001b[0m 8.25 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠴\u001b[0m \u001b[2mPreparing packages...\u001b[0m (8/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 8.02 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 7.97 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 7.69 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m------------\u001b[30m\u001b[2m------------------\u001b[0m\u001b[0m 6.66 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m--------\u001b[30m\u001b[2m----------------------\u001b[0m\u001b[0m 9.04 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mmatplotlib \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 8.24 MiB/8.31 MiB\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 8.34 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 7.76 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 7.35 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 10.25 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[5A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[5A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mscikit-learn \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 8.40 MiB/8.49 MiB\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 7.78 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 7.39 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 10.28 MiB/33.36 MiB \u001b[4A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[4A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 7.90 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 7.42 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---------\u001b[30m\u001b[2m---------------------\u001b[0m\u001b[0m 10.58 MiB/33.36 MiB \u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 8.07 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 7.47 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m----------\u001b[30m\u001b[2m--------------------\u001b[0m\u001b[0m 11.19 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 8.21 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 9.41 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----------\u001b[30m\u001b[2m-------------------\u001b[0m\u001b[0m 12.67 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠦\u001b[0m \u001b[2mPreparing packages...\u001b[0m (9/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 8.32 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 11.98 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m------------\u001b[30m\u001b[2m------------------\u001b[0m\u001b[0m 13.72 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠧\u001b[0m \u001b[2mPreparing packages...\u001b[0m (11/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m------------------------\u001b[30m\u001b[2m------\u001b[0m\u001b[0m 8.56 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 14.18 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-------------\u001b[30m\u001b[2m-----------------\u001b[0m\u001b[0m 14.74 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠧\u001b[0m \u001b[2mPreparing packages...\u001b[0m (11/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 8.70 MiB/10.36 MiB\r\n",
"\u001b[2mnumpy \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 15.76 MiB/15.84 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m--------------\u001b[30m\u001b[2m----------------\u001b[0m\u001b[0m 16.33 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[3A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[3A\u001b[37m⠧\u001b[0m \u001b[2mPreparing packages...\u001b[0m (11/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 8.74 MiB/10.36 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 19.10 MiB/33.36 MiB \u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠧\u001b[0m \u001b[2mPreparing packages...\u001b[0m (11/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 8.99 MiB/10.36 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----------------\u001b[30m\u001b[2m-------------\u001b[0m\u001b[0m 19.22 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mpandas \u001b[0m \u001b[32m----------------------------\u001b[30m\u001b[2m--\u001b[0m\u001b[0m 9.78 MiB/10.36 MiB\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m------------------\u001b[30m\u001b[2m------------\u001b[0m\u001b[0m 20.09 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[2A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 21.90 MiB/33.36 MiB \u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-------------------\u001b[30m\u001b[2m-----------\u001b[0m\u001b[0m 22.00 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---------------------\u001b[30m\u001b[2m---------\u001b[0m\u001b[0m 23.53 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m----------------------\u001b[30m\u001b[2m--------\u001b[0m\u001b[0m 25.02 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠇\u001b[0m \u001b[2mPreparing packages...\u001b[0m (12/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----------------------\u001b[30m\u001b[2m-------\u001b[0m\u001b[0m 26.47 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠋\u001b[0m \u001b[2mPreparing packages...\u001b[0m (13/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-------------------------\u001b[30m\u001b[2m-----\u001b[0m\u001b[0m 27.98 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠋\u001b[0m \u001b[2mPreparing packages...\u001b[0m (13/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m--------------------------\u001b[30m\u001b[2m----\u001b[0m\u001b[0m 29.40 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠋\u001b[0m \u001b[2mPreparing packages...\u001b[0m (13/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m---------------------------\u001b[30m\u001b[2m---\u001b[0m\u001b[0m 30.92 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (13/14)\r\n",
"\u001b[2mscipy \u001b[0m \u001b[32m-----------------------------\u001b[30m\u001b[2m-\u001b[0m\u001b[0m 32.42 MiB/33.36 MiB "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1A\r",
"\u001b[2K\u001b[1B\r",
"\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (13/14) \r",
"\u001b[2K\u001b[2mPrepared \u001b[1m14 packages\u001b[0m \u001b[2min 1.83s\u001b[0m\u001b[0m\r\n",
"░░░░░░░░░░░░░░░░░░░░ [0/0] \u001b[2mInstalling wheels... \u001b[0m\r",
"\u001b[2K░░░░░░░░░░░░░░░░░░░░ [0/14] \u001b[2mInstalling wheels... \u001b[0m\r",
"\u001b[2K░░░░░░░░░░░░░░░░░░░░ [0/14] \u001b[2mthreadpoolctl==3.6.0 \u001b[0m\r",
"\u001b[2K█░░░░░░░░░░░░░░░░░░░ [1/14] \u001b[2mthreadpoolctl==3.6.0 \u001b[0m\r",
"\u001b[2K█░░░░░░░░░░░░░░░░░░░ [1/14] \u001b[2mcontourpy==1.3.3 \u001b[0m\r",
"\u001b[2K██░░░░░░░░░░░░░░░░░░ [2/14] \u001b[2mcontourpy==1.3.3 \u001b[0m\r",
"\u001b[2K██░░░░░░░░░░░░░░░░░░ [2/14] \u001b[2mcycler==0.12.1 \u001b[0m\r",
"\u001b[2K████░░░░░░░░░░░░░░░░ [3/14] \u001b[2mcycler==0.12.1 \u001b[0m\r",
"\u001b[2K████░░░░░░░░░░░░░░░░ [3/14] \u001b[2mkiwisolver==1.4.9 \u001b[0m\r",
"\u001b[2K█████░░░░░░░░░░░░░░░ [4/14] \u001b[2mkiwisolver==1.4.9 \u001b[0m\r",
"\u001b[2K█████░░░░░░░░░░░░░░░ [4/14] \u001b[2mpyparsing==3.3.2 \u001b[0m\r",
"\u001b[2K███████░░░░░░░░░░░░░ [5/14] \u001b[2mpyparsing==3.3.2 \u001b[0m\r",
"\u001b[2K███████░░░░░░░░░░░░░ [5/14] \u001b[2mjoblib==1.5.3 \u001b[0m\r",
"\u001b[2K████████░░░░░░░░░░░░ [6/14] \u001b[2mjoblib==1.5.3 \u001b[0m\r",
"\u001b[2K████████░░░░░░░░░░░░ [6/14] \u001b[2mpillow==12.1.1 \u001b[0m\r",
"\u001b[2K██████████░░░░░░░░░░ [7/14] \u001b[2mpillow==12.1.1 \u001b[0m\r",
"\u001b[2K██████████░░░░░░░░░░ [7/14] \u001b[2mnetworkx==3.6.1 \u001b[0m\r",
"\u001b[2K███████████░░░░░░░░░ [8/14] \u001b[2mnetworkx==3.6.1 \u001b[0m\r",
"\u001b[2K███████████░░░░░░░░░ [8/14] \u001b[2mfonttools==4.61.1 \u001b[0m\r",
"\u001b[2K████████████░░░░░░░░ [9/14] \u001b[2mfonttools==4.61.1 \u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\r",
"\u001b[2K██████████████████░░ [13/14] \u001b[2mpandas==3.0.0 \u001b[0m\r",
"\u001b[2K\u001b[2mInstalled \u001b[1m14 packages\u001b[0m \u001b[2min 50ms\u001b[0m\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mcontourpy\u001b[0m\u001b[2m==1.3.3\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mcycler\u001b[0m\u001b[2m==0.12.1\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mfonttools\u001b[0m\u001b[2m==4.61.1\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mjoblib\u001b[0m\u001b[2m==1.5.3\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mkiwisolver\u001b[0m\u001b[2m==1.4.9\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mmatplotlib\u001b[0m\u001b[2m==3.10.8\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mnetworkx\u001b[0m\u001b[2m==3.6.1\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mnumpy\u001b[0m\u001b[2m==2.4.2\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mpandas\u001b[0m\u001b[2m==3.0.0\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mpillow\u001b[0m\u001b[2m==12.1.1\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mpyparsing\u001b[0m\u001b[2m==3.3.2\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mscikit-learn\u001b[0m\u001b[2m==1.8.0\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mscipy\u001b[0m\u001b[2m==1.17.0\u001b[0m\r\n",
" \u001b[32m+\u001b[39m \u001b[1mthreadpoolctl\u001b[0m\u001b[2m==3.6.0\u001b[0m\r\n"
]
}
],
"source": [
"!uv pip install numpy scipy networkx scikit-learn matplotlib pandas"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Libraries imported successfully!\n"
]
}
],
"source": [
"import numpy as np\n",
"import networkx as nx\n",
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
"from sklearn.metrics.pairwise import cosine_similarity\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"from collections import defaultdict\n",
"import random\n",
"from typing import Dict, List, Tuple, Set\n",
"import warnings\n",
"warnings.filterwarnings('ignore')\n",
"\n",
"# Set random seeds for reproducibility\n",
"np.random.seed(42)\n",
"random.seed(42)\n",
"\n",
"print(\"Libraries imported successfully!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Generate Synthetic Dataset\n",
"\n",
"Since we're demonstrating the algorithm with resource constraints, we'll generate a small synthetic dataset that mimics the Last.fm structure:\n",
"- Users with friendship relationships\n",
"- Tracks (music items) with tags (keywords)\n",
"- User-track interactions (playcounts)\n",
"\n",
"**For production**: Replace this with the actual Last.fm dataset (3148 users, 30520 tracks, 12565 tags) or your own social media dataset."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generating synthetic dataset:\n",
" Users: 100\n",
" Tracks: 500\n",
" Tags: 100\n",
" Target sparsity: 0.05\n"
]
}
],
"source": [
"# Small-scale dataset parameters (for demonstration)\n",
"NUM_USERS = 100 # Paper uses 3148 users\n",
"NUM_TRACKS = 500 # Paper uses 30520 tracks\n",
"NUM_TAGS = 100 # Paper uses 12565 tags\n",
"AVG_FRIENDS = 10 # Average number of friends per user\n",
"AVG_TAGS_PER_TRACK = 3\n",
"SPARSITY = 0.05 # Fraction of user-track interactions\n",
"\n",
"print(f\"Generating synthetic dataset:\")\n",
"print(f\" Users: {NUM_USERS}\")\n",
"print(f\" Tracks: {NUM_TRACKS}\")\n",
"print(f\" Tags: {NUM_TAGS}\")\n",
"print(f\" Target sparsity: {SPARSITY}\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated 100 unique tags\n",
"Sample tags: ['rock', 'upbeat-rock', 'mellow-rock', 'energetic-rock', 'pop', 'upbeat-pop', 'mellow-pop', 'energetic-pop', 'jazz', 'upbeat-jazz']\n"
]
}
],
"source": [
"# Generate tag vocabulary\n",
"tag_categories = ['rock', 'pop', 'jazz', 'classical', 'electronic', 'metal', 'folk', 'indie', \n",
" 'blues', 'country', 'hip-hop', 'rap', 'alternative', 'punk', 'soul']\n",
"tag_modifiers = ['upbeat', 'mellow', 'energetic', 'calm', 'aggressive', 'melodic', 'ambient']\n",
"\n",
"all_tags = []\n",
"for cat in tag_categories:\n",
" all_tags.append(cat)\n",
" for mod in tag_modifiers[:3]: # Limit combinations\n",
" all_tags.append(f\"{mod}-{cat}\")\n",
"\n",
"# Ensure we have exactly NUM_TAGS\n",
"all_tags = all_tags[:NUM_TAGS] if len(all_tags) >= NUM_TAGS else all_tags + [f\"tag_{i}\" for i in range(NUM_TAGS - len(all_tags))]\n",
"\n",
"print(f\"Generated {len(all_tags)} unique tags\")\n",
"print(f\"Sample tags: {all_tags[:10]}\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Social network generated:\n",
" Nodes (users): 100\n",
" Edges (friendships): 500\n",
" Average degree: 10.00\n",
" Network diameter: 5\n",
" Average clustering coefficient: 0.505\n"
]
}
],
"source": [
"# Generate social network graph (friendship relationships)\n",
"# Using Watts-Strogatz small-world network (realistic for social networks)\n",
"G = nx.connected_watts_strogatz_graph(n=NUM_USERS, k=AVG_FRIENDS, p=0.1, seed=42)\n",
"\n",
"print(f\"Social network generated:\")\n",
"print(f\" Nodes (users): {G.number_of_nodes()}\")\n",
"print(f\" Edges (friendships): {G.number_of_edges()}\")\n",
"print(f\" Average degree: {sum(dict(G.degree()).values()) / G.number_of_nodes():.2f}\")\n",
"print(f\" Network diameter: {nx.diameter(G)}\")\n",
"print(f\" Average clustering coefficient: {nx.average_clustering(G):.3f}\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated 500 tracks\n",
"Sample track: {'id': 0, 'name': 'Track_0', 'tags': {np.str_('tag_10'), np.str_('tag_23'), np.str_('upbeat-punk')}}\n"
]
}
],
"source": [
"# Generate tracks with tags\n",
"tracks = {}\n",
"for track_id in range(NUM_TRACKS):\n",
" # Each track has 1-5 tags\n",
" num_tags = np.random.randint(1, min(6, AVG_TAGS_PER_TRACK + 2))\n",
" track_tags = set(np.random.choice(all_tags, size=num_tags, replace=False))\n",
" tracks[track_id] = {\n",
" 'id': track_id,\n",
" 'name': f\"Track_{track_id}\",\n",
" 'tags': track_tags\n",
" }\n",
"\n",
"print(f\"Generated {len(tracks)} tracks\")\n",
"print(f\"Sample track: {tracks[0]}\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated playcount data:\n",
" Total user-track interactions: 2428\n",
" Total playcounts: 5873\n",
" Users with playcounts: 100\n",
" Sparsity: 0.0486\n"
]
}
],
"source": [
"# Generate user-track interactions (playcounts)\n",
"# Sparse matrix: most users haven't listened to most tracks\n",
"playcounts = defaultdict(lambda: defaultdict(int))\n",
"\n",
"# Generate interactions\n",
"num_interactions = int(NUM_USERS * NUM_TRACKS * SPARSITY)\n",
"for _ in range(num_interactions):\n",
" user_id = np.random.randint(0, NUM_USERS)\n",
" track_id = np.random.randint(0, NUM_TRACKS)\n",
" # Playcount follows power law (some tracks played much more)\n",
" playcount = int(np.random.pareto(a=1.5) + 1)\n",
" playcounts[user_id][track_id] = max(playcounts[user_id][track_id], playcount)\n",
"\n",
"# Calculate statistics\n",
"total_playcounts = sum(sum(user_plays.values()) for user_plays in playcounts.values())\n",
"users_with_plays = len(playcounts)\n",
"\n",
"print(f\"Generated playcount data:\")\n",
"print(f\" Total user-track interactions: {len([(u, t) for u in playcounts for t in playcounts[u]])}\")\n",
"print(f\" Total playcounts: {total_playcounts}\")\n",
"print(f\" Users with playcounts: {users_with_plays}\")\n",
"print(f\" Sparsity: {len([(u, t) for u in playcounts for t in playcounts[u]]) / (NUM_USERS * NUM_TRACKS):.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Core Functions: User Relatedness, Weight, and Action\n",
"\n",
"These are the three key components of social relevance as described in Section 4 of the paper:\n",
"\n",
"1. **User Relatedness Function (urf)**: Measures how related two users are based on their distance in the social network\n",
"2. **User Weight Function (uwf)**: Quantifies the global importance of a user (using degree centrality)\n",
"3. **User Action Function (uaf)**: Captures how relevant a user's actions on an object are"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"User relatedness urf(0, 1) = 1.000\n"
]
}
],
"source": [
"def compute_user_relatedness(G: nx.Graph, user_i: int, user_j: int, delta: int = 2) -> float:\n",
" \"\"\"\n",
" Compute User Relatedness Function (urf) as described in paper Section 4.1.\n",
" \n",
" urf(ui, uj) = 1 / dist(ui, uj) if dist <= delta, else 0\n",
" \n",
" Args:\n",
" G: Social network graph\n",
" user_i: First user ID\n",
" user_j: Second user ID\n",
" delta: Maximum distance threshold (default=2)\n",
" \n",
" Returns:\n",
" Relatedness score (0 to 1)\n",
" \"\"\"\n",
" if user_i == user_j:\n",
" return 1.0\n",
" \n",
" try:\n",
" distance = nx.shortest_path_length(G, source=user_i, target=user_j)\n",
" if distance <= delta:\n",
" return 1.0 / distance\n",
" else:\n",
" return 0.0\n",
" except nx.NetworkXNoPath:\n",
" return 0.0\n",
"\n",
"# Test the function\n",
"test_urf = compute_user_relatedness(G, 0, 1, delta=2)\n",
"print(f\"User relatedness urf(0, 1) = {test_urf:.3f}\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Computed weights for 100 users\n",
"Sample weights: [(0, 0.10101010101010101), (1, 0.09090909090909091), (2, 0.10101010101010101), (3, 0.1111111111111111), (4, 0.10101010101010101)]\n",
"Weight range: [0.0707, 0.1212]\n"
]
}
],
"source": [
"def compute_user_weights(G: nx.Graph) -> Dict[int, float]:\n",
" \"\"\"\n",
" Compute User Weight Function (uwf) for all users as described in paper Section 4.1.\n",
" \n",
" uwf(ui) = deg(ui) / (m - 1)\n",
" \n",
" where deg(ui) is the degree (number of friends) and m is total number of users.\n",
" \n",
" Args:\n",
" G: Social network graph\n",
" \n",
" Returns:\n",
" Dictionary mapping user_id to weight score\n",
" \"\"\"\n",
" m = G.number_of_nodes()\n",
" weights = {}\n",
" \n",
" for node in G.nodes():\n",
" degree = G.degree(node)\n",
" weights[node] = degree / (m - 1) if m > 1 else 0.0\n",
" \n",
" return weights\n",
"\n",
"# Compute weights for all users\n",
"user_weights = compute_user_weights(G)\n",
"print(f\"Computed weights for {len(user_weights)} users\")\n",
"print(f\"Sample weights: {list(user_weights.items())[:5]}\")\n",
"print(f\"Weight range: [{min(user_weights.values()):.4f}, {max(user_weights.values()):.4f}]\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"User action uaf(0, 123) = 0.143 (normalized), 1.0 (binary)\n"
]
}
],
"source": [
"def compute_user_action(user_id: int, track_id: int, playcounts: dict, binary: bool = False) -> float:\n",
" \"\"\"\n",
" Compute User Action Function (uaf) as described in paper Section 4.1.\n",
" \n",
" uaf(ui, ok) = playcount(ui, ok) / max_playcount(ui) (normalized)\n",
" \n",
" or uaf(ui, ok) = 1 if playcount > 0, else 0 (binary version)\n",
" \n",
" Args:\n",
" user_id: User ID\n",
" track_id: Track ID\n",
" playcounts: Playcount data structure\n",
" binary: If True, use binary version (0 or 1)\n",
" \n",
" Returns:\n",
" User action score (0 to 1)\n",
" \"\"\"\n",
" if user_id not in playcounts or track_id not in playcounts[user_id]:\n",
" return 0.0\n",
" \n",
" if binary:\n",
" return 1.0 if playcounts[user_id][track_id] > 0 else 0.0\n",
" else:\n",
" user_playcounts = playcounts[user_id]\n",
" if not user_playcounts:\n",
" return 0.0\n",
" max_playcount = max(user_playcounts.values())\n",
" return playcounts[user_id][track_id] / max_playcount if max_playcount > 0 else 0.0\n",
"\n",
"# Test the function\n",
"if 0 in playcounts and len(playcounts[0]) > 0:\n",
" test_track = list(playcounts[0].keys())[0]\n",
" test_uaf = compute_user_action(0, test_track, playcounts, binary=False)\n",
" test_uaf_binary = compute_user_action(0, test_track, playcounts, binary=True)\n",
" print(f\"User action uaf(0, {test_track}) = {test_uaf:.3f} (normalized), {test_uaf_binary:.1f} (binary)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Social Relevance Computation\n",
"\n",
"Social relevance combines the three functions above to compute how socially relevant an object (track) is to a query (user + keywords).\n",
"\n",
"As described in Section 4.1:\n",
"\n",
"$$socRel(o, q) = \\sum_{v_i \\in U_o} urf(u_q, v_i) \\times uaf(v_i, o) \\times uwf(v_i)$$\n",
"\n",
"where $U_o$ is the set of users who have performed actions on object $o$."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Social relevance for user 0, track 0: 0.0089\n"
]
}
],
"source": [
"def compute_social_relevance(query_user: int, track_id: int, G: nx.Graph, \n",
" playcounts: dict, user_weights: dict, \n",
" delta: int = 2, binary: bool = False) -> float:\n",
" \"\"\"\n",
" Compute social relevance score as described in paper Section 4.1.\n",
" \n",
" socRel(o, q) = sum over all users vi who interacted with object o of:\n",
" urf(query_user, vi) × uaf(vi, o) × uwf(vi)\n",
" \n",
" Args:\n",
" query_user: The user issuing the query\n",
" track_id: The track/object being scored\n",
" G: Social network graph\n",
" playcounts: User-track interaction data\n",
" user_weights: Pre-computed user weights (uwf)\n",
" delta: Distance threshold for user relatedness\n",
" binary: Use binary user action function\n",
" \n",
" Returns:\n",
" Social relevance score\n",
" \"\"\"\n",
" social_score = 0.0\n",
" \n",
" # Find all users who have interacted with this track\n",
" users_with_track = [u for u in playcounts if track_id in playcounts[u]]\n",
" \n",
" for user_i in users_with_track:\n",
" # Compute each component\n",
" urf = compute_user_relatedness(G, query_user, user_i, delta)\n",
" uaf = compute_user_action(user_i, track_id, playcounts, binary)\n",
" uwf = user_weights.get(user_i, 0.0)\n",
" \n",
" # Aggregate\n",
" social_score += urf * uaf * uwf\n",
" \n",
" return social_score\n",
"\n",
"# Test social relevance computation\n",
"test_social_score = compute_social_relevance(0, 0, G, playcounts, user_weights, delta=2, binary=False)\n",
"print(f\"Social relevance for user 0, track 0: {test_social_score:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Textual Relevance Computation (TF-IDF)\n",
"\n",
"Textual relevance uses the standard tf-idf (term frequency-inverse document frequency) model as described in Section 4.2.\n",
"\n",
"$$texRel(o, q) = \\sum_{t_j \\in K_q} tf(o, t_j) \\times idf(t_j)$$\n",
"\n",
"where $K_q$ is the set of query keywords (tags)."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"TF-IDF matrix shape: (500, 59)\n",
"Vocabulary size: 59\n",
"Sample vocabulary: [('tag_10', 20), ('tag_23', 34), ('upbeat', 58), ('punk', 14), ('country', 3), ('tag_5', 53), ('tag_19', 29), ('alternative', 0), ('tag_39', 51), ('mellow', 11)]\n"
]
}
],
"source": [
"# Build textual corpus for TF-IDF\n",
"track_ids = list(tracks.keys())\n",
"track_documents = [' '.join(tracks[tid]['tags']) for tid in track_ids]\n",
"\n",
"# Create TF-IDF vectorizer\n",
"tfidf_vectorizer = TfidfVectorizer()\n",
"tfidf_matrix = tfidf_vectorizer.fit_transform(track_documents)\n",
"\n",
"print(f\"TF-IDF matrix shape: {tfidf_matrix.shape}\")\n",
"print(f\"Vocabulary size: {len(tfidf_vectorizer.vocabulary_)}\")\n",
"print(f\"Sample vocabulary: {list(tfidf_vectorizer.vocabulary_.items())[:10]}\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Textual relevance for query ['rock', 'pop'], track 0: 0.0000\n"
]
}
],
"source": [
"def compute_textual_relevance(query_keywords: List[str], track_id: int, \n",
" track_ids: List[int], tfidf_matrix, \n",
" tfidf_vectorizer) -> float:\n",
" \"\"\"\n",
" Compute textual relevance using TF-IDF as described in paper Section 4.2.\n",
" \n",
" texRel(o, q) = sum over keywords tj in query of: tf(o, tj) × idf(tj)\n",
" \n",
" Args:\n",
" query_keywords: List of keyword strings in the query\n",
" track_id: Track ID to score\n",
" track_ids: Ordered list of track IDs (for indexing into tfidf_matrix)\n",
" tfidf_matrix: Pre-computed TF-IDF matrix\n",
" tfidf_vectorizer: Fitted TF-IDF vectorizer\n",
" \n",
" Returns:\n",
" Textual relevance score\n",
" \"\"\"\n",
" # Transform query to TF-IDF vector\n",
" query_text = ' '.join(query_keywords)\n",
" query_vector = tfidf_vectorizer.transform([query_text])\n",
" \n",
" # Get track's TF-IDF vector\n",
" track_index = track_ids.index(track_id)\n",
" track_vector = tfidf_matrix[track_index]\n",
" \n",
" # Compute cosine similarity (equivalent to dot product for normalized vectors)\n",
" similarity = cosine_similarity(query_vector, track_vector)[0, 0]\n",
" \n",
" return similarity\n",
"\n",
"# Test textual relevance\n",
"test_query_keywords = ['rock', 'pop']\n",
"test_text_score = compute_textual_relevance(test_query_keywords, 0, track_ids, tfidf_matrix, tfidf_vectorizer)\n",
"print(f\"Textual relevance for query {test_query_keywords}, track 0: {test_text_score:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Socio-Textual Relevance (Main Contribution)\n",
"\n",
"The main contribution of the paper is combining social and textual relevance using a weighted sum controlled by parameter $\\alpha$:\n",
"\n",
"$$stRel(o, q) = \\alpha \\times socRel(o, q) + (1 - \\alpha) \\times texRel(o, q)$$\n",
"\n",
"where:\n",
"- $\\alpha = 0$: Pure social ranking\n",
"- $\\alpha = 1$: Pure textual ranking\n",
"- $\\alpha = 0.5$: Equal weight to social and textual"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Socio-textual relevance (alpha=0.5): 0.0044\n",
" Social component: 0.0089\n",
" Textual component: 0.0000\n"
]
}
],
"source": [
"def compute_socio_textual_relevance(social_score: float, textual_score: float, alpha: float = 0.5) -> float:\n",
" \"\"\"\n",
" Combine social and textual relevance as described in paper Section 4.\n",
" \n",
" stRel(o, q) = α × socRel(o, q) + (1 - α) × texRel(o, q)\n",
" \n",
" Args:\n",
" social_score: Social relevance score\n",
" textual_score: Textual relevance score\n",
" alpha: Weight parameter (0 to 1)\n",
" - alpha=0: pure social\n",
" - alpha=1: pure textual\n",
" - alpha=0.5: equal weight\n",
" \n",
" Returns:\n",
" Combined socio-textual relevance score\n",
" \"\"\"\n",
" return alpha * social_score + (1 - alpha) * textual_score\n",
"\n",
"# Test combined score\n",
"test_combined = compute_socio_textual_relevance(test_social_score, test_text_score, alpha=0.5)\n",
"print(f\"Socio-textual relevance (alpha=0.5): {test_combined:.4f}\")\n",
"print(f\" Social component: {test_social_score:.4f}\")\n",
"print(f\" Textual component: {test_text_score:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. Complete Ranking System\n",
"\n",
"Now we implement the complete ranking system that:\n",
"1. Takes a query (user + keywords)\n",
"2. Computes relevance scores for all tracks\n",
"3. Returns top-k ranked results\n",
"\n",
"We implement all five approaches tested in the paper:\n",
"- **soc**: Social-only ranking\n",
"- **text**: Textual-only ranking (traditional tf-idf)\n",
"- **sotext**: Socio-textual ranking (main contribution)\n",
"- **socBinary**: Social ranking with binary user actions\n",
"- **sotextBinary**: Socio-textual ranking with binary user actions"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ranking system implemented successfully!\n"
]
}
],
"source": [
"def rank_tracks(query_user: int, query_keywords: List[str], \n",
" tracks: dict, G: nx.Graph, playcounts: dict, \n",
" user_weights: dict, track_ids: List[int],\n",
" tfidf_matrix, tfidf_vectorizer,\n",
" approach: str = 'sotext', alpha: float = 0.5, \n",
" delta: int = 2, k: int = 10) -> List[Tuple[int, float]]:\n",
" \"\"\"\n",
" Rank tracks according to specified approach.\n",
" \n",
" Args:\n",
" query_user: User issuing the query\n",
" query_keywords: List of keyword strings\n",
" tracks: Track data\n",
" G: Social network graph\n",
" playcounts: User-track interactions\n",
" user_weights: Pre-computed user weights\n",
" track_ids: Ordered list of track IDs\n",
" tfidf_matrix: TF-IDF matrix\n",
" tfidf_vectorizer: TF-IDF vectorizer\n",
" approach: 'soc', 'text', 'sotext', 'socBinary', 'sotextBinary'\n",
" alpha: Weight for social vs textual (used in sotext/sotextBinary)\n",
" delta: Distance threshold for user relatedness\n",
" k: Number of top results to return\n",
" \n",
" Returns:\n",
" List of (track_id, score) tuples, sorted by descending score\n",
" \"\"\"\n",
" scores = []\n",
" \n",
" # Filter to textually relevant tracks (for text-based approaches)\n",
" if approach in ['text', 'sotext', 'sotextBinary']:\n",
" # A track is textually relevant if it shares at least one tag with query\n",
" query_keywords_set = set(query_keywords)\n",
" candidate_tracks = [tid for tid in track_ids \n",
" if len(tracks[tid]['tags'].intersection(query_keywords_set)) > 0]\n",
" else:\n",
" # For pure social approaches, consider all tracks\n",
" candidate_tracks = track_ids\n",
" \n",
" # Compute scores for each candidate track\n",
" for track_id in candidate_tracks:\n",
" if approach == 'soc':\n",
" # Pure social ranking\n",
" score = compute_social_relevance(query_user, track_id, G, playcounts, \n",
" user_weights, delta, binary=False)\n",
" \n",
" elif approach == 'socBinary':\n",
" # Social ranking with binary actions\n",
" score = compute_social_relevance(query_user, track_id, G, playcounts, \n",
" user_weights, delta, binary=True)\n",
" \n",
" elif approach == 'text':\n",
" # Pure textual ranking\n",
" score = compute_textual_relevance(query_keywords, track_id, track_ids, \n",
" tfidf_matrix, tfidf_vectorizer)\n",
" \n",
" elif approach == 'sotext':\n",
" # Socio-textual ranking (main contribution)\n",
" social_score = compute_social_relevance(query_user, track_id, G, playcounts, \n",
" user_weights, delta, binary=False)\n",
" textual_score = compute_textual_relevance(query_keywords, track_id, track_ids, \n",
" tfidf_matrix, tfidf_vectorizer)\n",
" score = compute_socio_textual_relevance(social_score, textual_score, alpha)\n",
" \n",
" elif approach == 'sotextBinary':\n",
" # Socio-textual ranking with binary actions\n",
" social_score = compute_social_relevance(query_user, track_id, G, playcounts, \n",
" user_weights, delta, binary=True)\n",
" textual_score = compute_textual_relevance(query_keywords, track_id, track_ids, \n",
" tfidf_matrix, tfidf_vectorizer)\n",
" score = compute_socio_textual_relevance(social_score, textual_score, alpha)\n",
" \n",
" else:\n",
" raise ValueError(f\"Unknown approach: {approach}\")\n",
" \n",
" scores.append((track_id, score))\n",
" \n",
" # Sort by score (descending) and return top-k\n",
" scores.sort(key=lambda x: x[1], reverse=True)\n",
" return scores[:k]\n",
"\n",
"print(\"Ranking system implemented successfully!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. Example Query and Ranking\n",
"\n",
"Let's run an example query and compare results from all five approaches."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Example Query:\n",
" User: 0\n",
" Keywords: ['rock']\n",
" Top-k: 10\n",
"\n",
"\n",
"SOC Ranking:\n",
"Rank | Track ID | Score | Tags\n",
"------------------------------------------------------------\n",
" 1 | 27 | 0.1490 | energetic-pop, energetic-jazz\n",
" 2 | 229 | 0.1352 | electronic, upbeat-hip-hop\n",
" 3 | 82 | 0.1332 | energetic-rock, tag_21\n",
" 4 | 5 | 0.1325 | upbeat-metal, mellow-classical\n",
" 5 | 307 | 0.1206 | tag_10, energetic-folk, upbeat-indie\n",
"\n",
"TEXT Ranking:\n",
"Rank | Track ID | Score | Tags\n",
"------------------------------------------------------------\n",
" 1 | 430 | 0.7880 | tag_32, mellow-rock, rock\n",
" 2 | 129 | 0.6959 | energetic-rock, upbeat-country, tag_24\n",
" 3 | 332 | 0.5090 | energetic-metal, upbeat-electronic, rock\n",
" 4 | 474 | 0.4928 | classical, tag_8, rock\n",
" 5 | 269 | 0.4913 | tag_22, rock, jazz\n",
"\n",
"SOTEXT Ranking:\n",
"Rank | Track ID | Score | Tags\n",
"------------------------------------------------------------\n",
" 1 | 430 | 0.4091 | tag_32, mellow-rock, rock\n",
" 2 | 129 | 0.3480 | energetic-rock, upbeat-country, tag_24\n",
" 3 | 332 | 0.2597 | energetic-metal, upbeat-electronic, rock\n",
" 4 | 474 | 0.2534 | classical, tag_8, rock\n",
" 5 | 392 | 0.2507 | tag_10, rap, rock\n",
"\n",
"SOCBINARY Ranking:\n",
"Rank | Track ID | Score | Tags\n",
"------------------------------------------------------------\n",
" 1 | 229 | 0.4545 | electronic, upbeat-hip-hop\n",
" 2 | 254 | 0.4242 | mellow-soul\n",
" 3 | 5 | 0.3990 | upbeat-metal, mellow-classical\n",
" 4 | 443 | 0.3838 | upbeat-blues, energetic-punk, upbeat-rock\n",
" 5 | 477 | 0.3586 | energetic-metal, energetic-punk, tag_11\n",
"\n",
"SOTEXTBINARY Ranking:\n",
"Rank | Track ID | Score | Tags\n",
"------------------------------------------------------------\n",
" 1 | 430 | 0.5102 | tag_32, mellow-rock, rock\n",
" 2 | 129 | 0.3480 | energetic-rock, upbeat-country, tag_24\n",
" 3 | 392 | 0.3459 | tag_10, rap, rock\n",
" 4 | 332 | 0.3075 | energetic-metal, upbeat-electronic, rock\n",
" 5 | 474 | 0.2742 | classical, tag_8, rock\n"
]
}
],
"source": [
"# Create example query\n",
"example_user = 0\n",
"example_keywords = ['rock'] # Query for rock music\n",
"top_k = 10\n",
"\n",
"print(f\"Example Query:\")\n",
"print(f\" User: {example_user}\")\n",
"print(f\" Keywords: {example_keywords}\")\n",
"print(f\" Top-k: {top_k}\")\n",
"print()\n",
"\n",
"# Run all five approaches\n",
"approaches = ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']\n",
"results = {}\n",
"\n",
"for approach in approaches:\n",
" ranked_tracks = rank_tracks(\n",
" query_user=example_user,\n",
" query_keywords=example_keywords,\n",
" tracks=tracks,\n",
" G=G,\n",
" playcounts=playcounts,\n",
" user_weights=user_weights,\n",
" track_ids=track_ids,\n",
" tfidf_matrix=tfidf_matrix,\n",
" tfidf_vectorizer=tfidf_vectorizer,\n",
" approach=approach,\n",
" alpha=0.5,\n",
" delta=2,\n",
" k=top_k\n",
" )\n",
" results[approach] = ranked_tracks\n",
"\n",
"# Display results\n",
"for approach in approaches:\n",
" print(f\"\\n{approach.upper()} Ranking:\")\n",
" print(\"Rank | Track ID | Score | Tags\")\n",
" print(\"-\" * 60)\n",
" for rank, (track_id, score) in enumerate(results[approach][:5], 1):\n",
" tags_str = ', '.join(list(tracks[track_id]['tags'])[:3])\n",
" print(f\"{rank:4d} | {track_id:8d} | {score:8.4f} | {tags_str}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 9. Evaluation: Normalized Discounted Cumulative Gain (nDCG)\n",
"\n",
"The paper evaluates ranking quality using nDCG metric (Section 5). nDCG measures how well the ranking matches the ideal ranking based on user playcounts.\n",
"\n",
"$$DCG@k = \\sum_{i=1}^{k} \\frac{rel_i}{\\log_2(i+1)}$$\n",
"\n",
"$$nDCG@k = \\frac{DCG@k}{IDCG@k}$$\n",
"\n",
"where $rel_i$ is the relevance (playcount) of the item at position $i$, and IDCG is the ideal DCG (ranking by playcount)."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Example nDCG@5 for 'sotext' approach: 0.0745\n"
]
}
],
"source": [
"def compute_dcg(ranked_items: List[int], relevances: Dict[int, float], k: int) -> float:\n",
" \"\"\"\n",
" Compute Discounted Cumulative Gain at k.\n",
" \n",
" DCG@k = sum over i=1 to k of: rel_i / log2(i + 1)\n",
" \n",
" Args:\n",
" ranked_items: List of item IDs in ranked order\n",
" relevances: Dictionary mapping item_id to relevance score\n",
" k: Number of top items to consider\n",
" \n",
" Returns:\n",
" DCG score\n",
" \"\"\"\n",
" dcg = 0.0\n",
" for i, item_id in enumerate(ranked_items[:k], 1):\n",
" rel = relevances.get(item_id, 0.0)\n",
" dcg += rel / np.log2(i + 1)\n",
" return dcg\n",
"\n",
"def compute_ndcg(ranked_items: List[int], relevances: Dict[int, float], k: int) -> float:\n",
" \"\"\"\n",
" Compute Normalized Discounted Cumulative Gain at k.\n",
" \n",
" nDCG@k = DCG@k / IDCG@k\n",
" \n",
" Args:\n",
" ranked_items: List of item IDs in ranked order\n",
" relevances: Dictionary mapping item_id to relevance score\n",
" k: Number of top items to consider\n",
" \n",
" Returns:\n",
" nDCG score (0 to 1)\n",
" \"\"\"\n",
" # Compute DCG for the ranking\n",
" dcg = compute_dcg(ranked_items, relevances, k)\n",
" \n",
" # Compute IDCG (ideal ranking by relevance)\n",
" ideal_items = sorted(relevances.keys(), key=lambda x: relevances[x], reverse=True)\n",
" idcg = compute_dcg(ideal_items, relevances, k)\n",
" \n",
" # Normalize\n",
" if idcg == 0:\n",
" return 0.0\n",
" return dcg / idcg\n",
"\n",
"# Test nDCG computation\n",
"# For ground truth, use the querying user's playcounts as relevance\n",
"test_relevances = playcounts.get(example_user, {})\n",
"if test_relevances:\n",
" test_ranking = [track_id for track_id, _ in results['sotext']]\n",
" test_ndcg = compute_ndcg(test_ranking, test_relevances, k=5)\n",
" print(f\"Example nDCG@5 for 'sotext' approach: {test_ndcg:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 10. Experiment: Varying Alpha Parameter\n",
"\n",
"As described in Section 5.1.3, we evaluate how the choice of $\\alpha$ (weight between social and textual) affects ranking quality."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated 20 test queries\n",
"Sample query: User=81, Keywords=['mellow-classical']\n"
]
}
],
"source": [
"# Generate test queries (small set for demonstration)\n",
"num_test_queries = 20 # Paper uses 100 queries\n",
"test_queries = []\n",
"\n",
"# Select users with enough friends and playcount data\n",
"eligible_users = [u for u in G.nodes() if G.degree(u) >= 4 and u in playcounts]\n",
"\n",
"for _ in range(num_test_queries):\n",
" if not eligible_users:\n",
" break\n",
" query_user = random.choice(eligible_users)\n",
" query_keyword = random.choice(all_tags)\n",
" \n",
" # Check if there are textually relevant tracks\n",
" relevant_tracks = [tid for tid in track_ids if query_keyword in tracks[tid]['tags']]\n",
" if len(relevant_tracks) > 0:\n",
" test_queries.append((query_user, [query_keyword]))\n",
"\n",
"print(f\"Generated {len(test_queries)} test queries\")\n",
"print(f\"Sample query: User={test_queries[0][0]}, Keywords={test_queries[0][1]}\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running evaluation with varying alpha...\n",
" Queries: 20\n",
" Alpha values: [0.0, 0.25, 0.5, 0.75, 1.0]\n",
" k=5, delta=2\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluation complete!\n"
]
}
],
"source": [
"# Evaluate nDCG for different alpha values\n",
"alpha_values = [0.0, 0.25, 0.5, 0.75, 1.0]\n",
"k_eval = 5\n",
"delta_eval = 2\n",
"\n",
"ndcg_results = {approach: [] for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']}\n",
"\n",
"print(f\"Running evaluation with varying alpha...\")\n",
"print(f\" Queries: {len(test_queries)}\")\n",
"print(f\" Alpha values: {alpha_values}\")\n",
"print(f\" k={k_eval}, delta={delta_eval}\")\n",
"\n",
"for alpha in alpha_values:\n",
" alpha_ndcg = {approach: [] for approach in ndcg_results.keys()}\n",
" \n",
" for query_user, query_keywords in test_queries:\n",
" # Ground truth: user's playcounts\n",
" relevances = playcounts.get(query_user, {})\n",
" if not relevances:\n",
" continue\n",
" \n",
" # Evaluate each approach\n",
" for approach in ndcg_results.keys():\n",
" # For non-alpha approaches, only compute once\n",
" if approach in ['soc', 'socBinary'] and alpha != 0.0:\n",
" continue\n",
" if approach == 'text' and alpha != 1.0:\n",
" continue\n",
" \n",
" ranked = rank_tracks(\n",
" query_user=query_user,\n",
" query_keywords=query_keywords,\n",
" tracks=tracks,\n",
" G=G,\n",
" playcounts=playcounts,\n",
" user_weights=user_weights,\n",
" track_ids=track_ids,\n",
" tfidf_matrix=tfidf_matrix,\n",
" tfidf_vectorizer=tfidf_vectorizer,\n",
" approach=approach,\n",
" alpha=alpha,\n",
" delta=delta_eval,\n",
" k=k_eval\n",
" )\n",
" \n",
" ranked_ids = [tid for tid, _ in ranked]\n",
" ndcg = compute_ndcg(ranked_ids, relevances, k_eval)\n",
" alpha_ndcg[approach].append(ndcg)\n",
" \n",
" # Average nDCG for this alpha\n",
" for approach in ndcg_results.keys():\n",
" if alpha_ndcg[approach]:\n",
" avg_ndcg = np.mean(alpha_ndcg[approach])\n",
" ndcg_results[approach].append(avg_ndcg)\n",
" elif approach in ['soc', 'socBinary']:\n",
" # Replicate score for all alphas (doesn't use alpha)\n",
" if ndcg_results[approach]:\n",
" ndcg_results[approach].append(ndcg_results[approach][0])\n",
" elif approach == 'text':\n",
" # Replicate score for all alphas (doesn't use alpha)\n",
" if ndcg_results[approach]:\n",
" ndcg_results[approach].append(ndcg_results[approach][0])\n",
"\n",
"print(\"Evaluation complete!\")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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XXfdpU2bNqlPnz6SpG+++UZPPPGE9u3bpylTptj1X7BggRYuXKgePXqoXbt2WrFihWbPnq09e/bo119/telbnFwrLpPJpOPHj2vEiBG66aabdMstt6hixYr6+++/tWDBAv30009asWKFWrVqZbfvV199pcWLF+u2227To48+qvT0dEkq9njffvutFi9erF69eql9+/ZauHChXn75ZRmGIX9/f7388su6/fbb1bFjR33zzTd65plnFBISYvM5MgxD9957rz7//HPVrVtX99xzjzw9PRUfH6+hQ4dq+/btmjx5siRZv+havny5Bg0aZC22z//SbM+ePerYsaMOHDigbt26qVevXkpJSdE333yjn3/+WYmJiWrTpo3N88jKylLnzp11+vRp9ezZU+7u7goJCbmctwkALs0AALiMvXv3GpKMmJgYu22vvvqqIcm49dZb7bb9/fffdm2HDh0ywsLCjLp169q0L1261JBkSDK++OILm20DBgwwJBmff/65TbskIyoqyjAMwzh16pTRrVs3Q5IxceJEu+MOGjTIkGTs3bu32Mc8ceKEUaFCBaN8+fLGn3/+aW3PyckxOnfubEgyIiIi7I5dkBo1ahiSjL/++uui/TIyMgx3d3fDx8fHyMvLMwzjf+/HoEGDCtzn/NclX1JSkpGbm2vTZrFYjPvvv9+QZPz6668226KioowL/znOf73GjRtn0x4REVHo8540aZIhyZg1a5ZNe05OjlGlShUjODjYyM7OLnDf8914442Gm5ubcejQIZv2Y8eOGZ6enkbLli2tbbGxsYYkY/78+XbjHD169JLHOj/GkJAQIyAgwDh79qxhGIYxc+ZMQ5IxZswYu/6FvS/5r2X9+vWNkydPWttPnjxp1K9f3zCZTMb69eut7XFxcYYkw93d3eZ9yc3NNTp27GhIMlavXm1zjKLk2sVEREQYXl5edu0JCQmGyWQyypcvb2RkZBiZmZnGgQMH7Ppt3brVqFChghEdHW3Tnv+czGazER8fb7dfccfz8PAw1q1bZ21PT083goODjXLlyhmhoaHGnj17rNv2799veHp6GpGRkTZjffDBB4YkY8iQITafxaysLKNHjx6GJGPDhg3W9nHjxhmSjKVLl9rFaxiG0a5dO8PNzc1YtGiRTfuuXbsMX19fu+NHRERY/75mZGQUOCYAOAPTywHABe3evVvjx4/X+PHj9fTTT6tz58567rnnFBISUuC0zYLOBFapUkV9+vTRX3/9paSkJLvtHTp0UL9+/Wza7r//fknnzkgX5OjRo+rcubMSExM1c+ZMPfvss0V6Xo4e87vvvtPp06c1dOhQ1a1b19ru7u6ul19+uUjHPHLkiCQpPDz8ov18fHwUGBios2fP6sSJE0U6xvmqV68uNzc3m7bzV+NOSEgo9tgXM2TIEHl6emrGjBk27QsXLtThw4c1aNAgh2YHDBgwQHl5efr8889t2ufOnavs7GzrAn/nK2gGQWBgoMOx//DDD0pOTlbfvn2tsx3uvPNOlStXTrNmzSryyvIvvPCC/P39rY/9/f01ZswYGYahjz/+2K7/Pffco/bt21sfu7m5adCgQZLsc6E4uVaY3Nxca54///zzuvPOO9W9e3cZhqGXXnpJPj4+8vLyKnBRwuuuu06dOnXSihUrCrxs4fbbb1d0dLRde3HHu++++2zOgPv6+uq2225TRkaGHnnkEdWqVcu6LTw8XDfeeKO2b9+u3Nxca/vbb7+t8uXL65133rH5LHp6elovR7jwc1eYTZs2adWqVRo0aJDdZRP16tXTsGHDrDNoLvT6668XOusFAJyB6eUA4IL27NljvZ4xX2hoqH755RfVqVPHrv/ff/+tiRMnasmSJTp48KCysrJsth86dEgRERE2bS1atLAbp1q1apKkkydP2m1LTk5W+/bt9c8//+jbb79Vjx49ivq0HD7m77//Lkm68cYb7fq3adOmwCn2Jelybh+WnZ2tt99+W1988YV27typ06dP21xLfOjQoZII0U5QUJB69+5tPW7+Qmz5RfgDDzzg0Dh33XWXnnjiCX3yySeKjY21tn/66adyd3dX//79bfpOmzZNd9xxh/r166euXbuqQ4cORV65Pj/G86ci+/r6qlevXpozZ45+/vln3XzzzQ6Pd9NNNxXaVtB1y0XJheLkWmHy8vKseW42m1WxYkV17txZjz32mHr27Gntt3nzZr3++uv69ddfdeTIEbui+OjRo3aLF7Zu3brQ4xZnvKZNm9qNk9+nsG15eXlKTk5W1apVlZGRoT/++ENhYWGaNGmSXf/8GHbu3Flo3Odbs2aNpHN/lwq6n33+ODt37tT1119vbff29lZkZKRDxwCAkkLRDQAuKCYmRosWLZIkpaam6uOPP9aoUaPUs2dPrVu3ThUqVLD23b17t1q3bq309HR16tRJPXr0kJ+fn8xms5YtW6bly5fbFQaS5OfnZ9eWX8zm5eXZbTt8+LDS09NVp04du+skHeXoMfOvPw0ODrbrbzabi3QrrdDQUO3bt0///PNPgV9Y5Dt79qyOHTtmXYypuO688059//33qlevnvr166fg4GB5eHjo5MmTevPNNwt8L0rKQw89pC+++EIzZszQ5MmTdejQIf3000+KiopSvXr1HBojICBAt912m7755htt375djRo10p49e7Rq1SrdcsstNu9JmzZttGzZMr366quaM2eO9fr5Vq1aadKkSerUqdMlj3fo0CEtWrRItWrVsvuSZeDAgZozZ45mzpxZpKK7oGt089vS0tLstjn6uSxurhXGy8tLmZmZF+2zatUqde7cWdK5Rdbq1q2rChUqyGQyaf78+fr9998LPGZh1ykXd7yLvUYX25ZfTJ84cUKGYejgwYN2Xyie78yZM4VuO9/x48clnZvJsXDhQofHCw4Odmj9CQAoSRTdAODigoKC9NRTTyktLU0vv/yyxowZY11QS5L+85//6MSJE/rkk0/spv4+/PDDJXZ7saZNm2rQoEF64IEH1KlTJy1ZssRpCxDl/098SkqK3TaLxaKjR486fDa1Xbt22rdvnxITEy9adC9fvly5ubm67rrrrP9Tnn/rsPOnyOYrqHhbv369vv/+e8XExGjhwoU208zXrFmjN99806GYi6tjx45q0KCBZs+erVdffVVxcXHKy8u75AJqFxowYIC++eYbffLJJ5o4caI+/fRTa/uFbrrpJv300086e/as1q5dq++//17vvvuubr31Vm3dutVm2nFBZs2apby8PP3999+FFkMLFizQ0aNHHf4yJDk5WdWrV7drk2Qz7byorlSune+VV15RVlaWfvnlF7svJdasWWOdFXKhwl7L4o53ufJzukWLFtqwYUOJjTd9+nQNHz7c4f0ouAGUBq7pBoAy4rnnnlNYWJjeffddm1ts7dmzR5LsVk02DEMrV64s0RiGDBmiuLg47dy5U506dbIWMiWtSZMmklRg/OvWrSuwCC5M/jXjU6dOLfSsomEYmjhxoiTbKc75KyUfPHjQbp+Cpinnvxe33nqr3XXdv/zyi8MxF8bNza3AWQjne/DBB5Wamqr58+dr5syZqlixonUVb0fdcsstCgwM1Jw5c2SxWPTZZ5/J19f3oitz+/j4qGPHjpoyZYqee+45nT17VvHx8Rc9jvHv7aOkc6tVDx061O6nXbt2ys7Otq6c7oiCXuv8tmbNmjk8zoWuZK6df8xKlSrZFcgZGRnauHFjqY/nKF9fXzVs2FA7duwo8PKVguTnUEGf+fzZNqtXry6xGAHAWSi6AaCM8PHx0ahRo5STk6OXXnrJ2p5//eiFtzZ67bXXClxE6HINHDhQs2bN0q5du9SxY0frQmUl6fbbb1eFChX00UcfWQsd6dwZ5xdeeKFIY3Xp0kV33nmn/vzzT9111112Z6izsrL0yCOPaMWKFYqIiNCQIUOs2/z8/FS/fn39+uuv2r17t7X91KlTGj16tN2xCnsvtm3bZi3qL0elSpV09OjRi05JHjRokLy9vTVy5Ej9/fffGjBgwEVv/1YQDw8P9evXT/v379frr7+uv/76S3369LFbfGr16tUFxpL/Zcyljrt8+XLt2bNHHTp0UFxcnGbMmGH3k1+UF+We3S+99JLN+5w/S8RkMlkXSCuOK51r+cc8ceKEtm3bZm3Ly8vTU089pdTU1FIfryieeOIJZWRkaNiwYQVOI9+7d6/NF4qVKlWSJP3zzz92fVu3bq02bdro888/19y5c+22WywWp8w8AIDiYHo5AJQhDz74oCZNmqTZs2frueeeU+3atfXwww8rLi5Offr00V133aXAwECtWbNGGzdu1K233nrR6x2La8CAATKbzRo0aJD1fsoXLrx0OQICAjR16lQ9+OCDatGihe6++27rfbq9vLwUFhZmnfrtiFmzZikzM1Pff/+9atWqpVtvvVXh4eFKTU3Vjz/+qIMHDyogIEDfffedKlasaLPvk08+qQcffFBt27ZV3759ZbFY9NNPPxV4L+PWrVurdevW+vLLL3X48GHdcMMN2r9/vxYsWKBbb71VX3/99WW9Lp07d9aGDRt0880366abbpKnp6c6dOigDh06WPtUqlRJffv2tZ4ZLurU8nwDBgzQu+++q7Fjx1ofX2jSpElaunSpOnTooJo1a8rb21sbN25UYmKiatWqpTvuuOOix8gvpM//ouNC9evXV7t27bRq1SqtXbvWofUE6tWrp+uvv97mPt0HDhxQbGysWrZsecn9C1Maufb4449r8eLFuvHGG3XXXXfJ29tby5Yt08GDB9WxY0ctW7asVMcrioceekhr1qzRxx9/rJUrVyo6OlphYWFKTk7Wzp07tXbtWs2ZM8d6T+5OnTrJZDLpueee07Zt2+Tv76+AgADrdPLPP/9cnTp10t13361p06apefPm8vHx0f79+7V69WqlpqZe8pp5ALgSONMNAGWIt7e3Ro8erdzcXOtiRM2aNdPixYvVvHlzzZs3TzNnzlRAQIBWrlx5WQXGpdx777365JNPtHv3bnXq1KnEV+UeNmyYvvrqK9WqVUuzZs3SrFmzdMMNN2jx4sVKT08vcPGmwpQvX17ff/+9vvnmG7Vr106LFy/WpEmT9OGHH+rgwYO67bbbtHPnTuu09gvjeOedd1SxYkXNmDFDP/30kwYPHlzgrY3c3Nz0ww8/6P7779eePXs0ffp0bd++XZMnT9brr79+Wa+HdO5WWMOGDdOuXbv06quv6oUXXtCSJUvs+uWfzb3hhhtsVm4uihtuuEF169ZVTk6OqlWrpo4dO9r1eeSRR9SrVy/99ddfmjVrlv773//q8OHDeu6557R27dqLvkdpaWn65ptvVL58ed15550XjSW/KHf0bPeXX36pe+65R/PmzdN///tflS9fXm+99ZYmT57s0P6FKY1cu+222/T111+rVq1a+vTTTzVnzhw1aNBA69atc3iVdGeOVxQmk0mzZs3S3Llzdd111+mHH37Q1KlTFR8fL29vb02ePNnmNmeNGjVSXFycKleurOnTp+uFF16weQ9r1qypTZs2acyYMTp9+rTi4uL0/vvva/PmzerQoYPDtx8DAGczGeffxwQAABe3e/du1a1bV3fddVeB00qLYuXKlerSpYtq1aqlFStWXNaq5a5k8uTJevrpp/XRRx9Zr2m/FnTs2FHLly8X/2sDAHAlnOkGALikEydO2N266OzZsxo5cqQkqVevXpd9jPbt22vGjBnasWOHYmJirLcqK8syMzP19ttvq2LFirr77rtLOxwAAK55XNMNAHBJy5cv19ChQ9WtWzdVr15dR48e1ZIlS7Rv3z517txZ/fr1K5Hj3HfffTIMw3ov6u7du5fIuFfar7/+quXLl+vnn39WUlKSJk6cqHLlypV2WAAAXPMougEALum6665T165dtXLlSs2fP1+SVKdOHb300kt66qmnirSQ2qUUtEhYWZOQkKAJEyaocuXKGjlypJ566qnSDgkAAIhrugEAAAAAcBqu6QYAAAAAwEkougEAAAAAcBKKbgBAmWIYhlq0aKFu3bqVdihlmslkKvDe22VBScQ+ePBgmUwm7du3r0RichU33XST2rRpU9phAADOQ9ENAChTZs+erY0bN+rFF1+0thmGoZ9++kmPPPKIGjduLH9/f5UrV05NmjTRq6++qszMzELH+/nnnxUVFSVfX1/5+fmpU6dOSkxMvBJPBS5m2bJlMplMGj9+fGmHIkk6ePCgpk2bZl3B39PTU6GhoerTp4/Wrl1b4D7jx4/XunXr9MUXX1zhaAEAhaHoBgCUGRaLRePHj9dNN92kG264wdqelZWlW265RXFxcQoLC9ODDz6ooUOH6uzZs3r++efVoUMHZWRk2I336aefqnv37tqxY4cGDx6sQYMGadu2beratau+/vrrK/nUrrgdO3Zo9uzZpR0GLmL69OkaOXKk/v77b3Xr1k1PPvmkbrzxRn333Xdq166d5s6da7dPly5d1Lx5c40bN06slQsAroFbhgEAyoyffvpJ+/bt0/PPP2/T7ubmppdfflmPPvqoKlasaG3PyclRnz599P333+udd97R008/bd124sQJPf7446pcubI2btyoatWqSZJGjRqlZs2a6ZFHHlFMTIx8fX2vzJO7who0aFDaIeASWrdurWXLlikqKsqm/ZdfflGXLl30yCOPqFevXvLy8rLZft999yk2NlZLlixRly5drmTIAIACcKYbAFBmxMXFyWQyqU+fPjbtHh4eev75520K7vz20aNHS5KWL19us+2rr77SyZMn9fjjj1sLbkmqVq2ahg8frqNHj+rbb791OLZff/1VUVFRKl++vAIDA9WvXz/9888/6tixo0wmk03fi11PPH78eJlMJi1btsxu24oVK9SjRw9VrlxZXl5eqlu3rsaMGWN3Fv/8adKrVq1St27dFBAQYBNHYddFZ2dna+rUqWrevLnKly8vX19f3XTTTVqwYIFd37S0NI0dO1aNGjVShQoV5Ofnpzp16mjQoEFKSkpy7IW7iBkzZuj666+Xt7e3wsPD9cwzz1z0UoFTp05p3Lhxuu666+Tj46OAgADFxMTo119/veSxxo8fr06dOkmSJkyYIJPJZP3Jf5/+/PNPPfPMM2revLkCAwPl7e2tevXq6dlnn9Xp06cv+/leqHfv3nYFt3Tuuu1OnTrpxIkT+uOPP+y29+3b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N2rNmjXq2rXrJWMqjoYNG8rPz08bNmxQTk5OkVbhNplMatiwoRo2bKiePXuqevXqWrBgQbGL7iZNmmjevHn65Zdf7L40+eWXX+z6t2rVSiaTSatXry7W8fLln5nPy8uz2/b333/LMAxFR0fbnT0uKCbpXNFdUDFemIiICLui+/yCu1+/fvrkk08cmkGwa9cueXh4cD92AHAB3KcbAFAmBAQEqHHjxtqwYYPNdbT5fvvtN3Xt2lW5ubn66aef1LZt24uOd9ddd8nf31/Tp0/XgQMHrO0HDhzQ22+/rcqVK+uOO+64ZFw33nijatasqR9++MHmftCGYei5554rsIDLLyQvvI/y119/bXc/cUl69NFH5e7urscff7zA236dPHmywGK9KNzd3fXII48oKSlJTz31VIGrj2/dutV6Rn/fvn0FTpvPPxN94Srh+fe8dsQ999wjNzc3TZ061WYGQXp6ul5++WW7/qGhobrrrru0atUqvfHGGzIMw67P2rVr7e5nfqH866AL+qIk/4z7qlWrbD5/Bw4cKPTLhcGDB8swDId/Lnw986eUz549W3379tWnn37qUMGdnZ2tTZs2qWXLlkwvBwAXwJluAECZcccdd2jcuHFas2aN2rVrZ20/fvy4unbtqpMnT6p79+6Kj49XfHy8zb4XTt2tWLGi3n77bQ0YMEDNmzdXv379JElz587VsWPHNHfuXIemcpvNZn3wwQe65ZZbFB0dbb1P95IlS3T48GE1btxYW7Zssdnn9ttvV+3atTVr1iz9888/atasmXbs2KElS5bolltu0Y8//mjT//rrr9e7776rRx55RPXr19ctt9yi2rVr69SpU/r777+1fPlyDR48+JLX+V7KhAkTtHHjRr311ltauHChOnTooODgYB08eFB//PGHfv/9d61evVrBwcHavHmzevfurdatW6tRo0YKDQ3VwYMHNX/+fJnNZo0cOdI6bn6R6ug13nXq1NHYsWM1btw4NW7cWHfddZfc3d31zTffqHHjxgXOdnj33Xe1a9cuPfPMM/rkk0/Utm1bBQQE6J9//rFeRnD48OGLFqENGjRQWFiYvvjiC3l5ealatWoymUx6/PHHVaVKFfXp00fffPONWrZsqS5duig5OVk//PCDunTpoj179hTx1b60F198UR9//LEqVKigevXqFfiFQ69evdS0aVObtl9+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/vprRUZGysfHR4GBgYqOjtaZM2dksVj04osvqlq1avLy8lLTpk21aNEim30PHDig/v37q1KlSipfvrxatmyptWvXWrebTCaFhoYqNDRUdevW1csvvyyz2awtW7ZY+1w4vdxkMmnGjBm64447VK5cOdWtW1cLFiywbs/Ly9PQoUNVs2ZN+fj4qH79+nrzzTdt4ho8eLB69eqlV155RWFhYWrQoIFefvllRUZG2j3/pk2b6oUXXrjcl/GKoegGAAAAgCIw8vKU/OpEyTAK2HiuLfnViU6Zan748GH1799f999/v3bs2KFly5apd+/eMgxDb775pqZMmaLJkydry5YtiomJUc+ePfXXX39Jkk6fPq2oqCgdPHhQCxYs0O+//65nnnlGFoulwGPl5eXp448/liQ1b978onFNmDBBd911l7Zs2aJbbrlF9957r44fPy5Jslgsqlatmr766itt375dY8eO1XPPPacvv/zSZozExETt2rVL8fHx+v777zV48GDt2LFD69evt/bZtGmTtmzZoiFDhhT7NbzSmF4OAAAAAP/a2+dO5R49etE+luxsWU6cKLyDYSj3yBH9eeNNMnt6XvKY7pUrq+Y3XzsU3+HDh5Wbm6vevXsrIiJCkqxngydPnqxRo0bp7rvvliRNmjRJS5cu1bRp0/TOO+9ozpw5Sk1N1fr161WpUiVJUp06dWzGT0tLU4UKFSRJZ8+elYeHhz744APVrl37onENHjxY/fv3lyS9+uqreuutt7Ru3Tp1795dHh4emjBhgrVvzZo1tXr1an355Ze66667rO3ly5fXjBkz5OnpKcMwlJubq5iYGMXFxalVq1aSpLi4OEVFRalWrVoOvV6ugKIbAAAAAP6Ve/SocpOTS2Qsy4kTKvgccvE1adJEXbp0UWRkpGJiYtStWzfdeeedcnNz06FDh9S+fXub/u3bt9fvv/8uSdq8ebOaNWtmLbgL4uvrq40bN0qSMjIylJCQoIcffliBgYHq0aNHofs1btzY+nv58uXl5+enlJQUa9s777yjmTNnav/+/Tp79qyys7PVtGlTmzEiIyPlecGXFA888ICGDh2qqVOnymw2a86cOfrPf/5z8RfJxVB0AwAAAMC/3CtXvmSfS57p/pe5YkWHz3Q7ys3NTfHx8Vq1apUWL16s6dOn6/nnn1d8fPwl9/Xx8blkH7PZbHP2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123GrV+/vj755BM988wzkqS4uDj17dvXGqMzUHQDAAAAwL8y0rPtpowX16UK8+Jo0qSJunTposjISMXExKhbt26688475ebmpkOHDql9+/Y2/du3b6/ff/+90PHOnDmjPXv2aOjQoRo2bJi1PTc313rNtSS1bdtWTz31lF566SWNGjVKN954o0Px1q9fXwsWLJAknTp1SnPnzlXfvn21dOlStWzZstD9GjdubP29SpUqkqSUlBQ1aNBAeXl5evXVV/Xll1/q4MGDys7OVlZWlsqVK2czRosWLezGfeCBB/TBBx/omWeeUXJysn766SctWbLEoedSXBTdAAAAAPCvcn6XXmzLkTPdkuRd3sPhM92OcnNzU3x8vFatWqXFixdr+vTpev755xUfH+/wGOc7ffq0JOnDDz9UmzZt7I6Vz2KxaOXKlXJzc9Pu3bsdHt/T01N16tSxPm7WrJnmz5+vadOm6dNPPy10Pw8PD+vvJpPJGoMkvfHGG3rzzTc1bdo0RUZGqnz58hoxYoSys21nKJQvX95u3IEDB+rZZ5/V6tWrtWrVKtWsWVM33XSTw8+nOCi6AQAAAOBfjkzztlgMzX5u1UXPiFeo6KUBr7ST2WwqyfAknStC27dvr/bt22vs2LGKiIhQYmKiwsLCtHLlSkVFRVn7rly50jrlOn/17ry8POv2kJAQhYWF6e+//9a9995b6DHfeOMN7dy5U8uXL1dMTIzi4uI0ZMiQQse9GDc3N509e7ZoT/o8K1eu1O2336777rtP0rli/M8//1SjRo0uuW9gYKB69eqluLg4rV692vocnImiGwAAAACKwGw26aZ+dbXo/a2F9rnxrrpOKbjXrl2rxMREdevWTcHBwVq7dq1SU1PVsGFDPf300xo3bpxq166tpk2bKi4uTps3b9Znn30mSQoODpaPj48WLVqkatWqydvbW/7+/powYYKeeOIJ+fv7q3v37srKytKGDRt04sQJxcbGatOmTRo7dqy+/vprtW/fXlOnTtX//d//KSoqSrVq1Sp0XOncNPUjR45I+t/08u3bt2vUqFHFfg3q1q2rr7/+WqtWrVLFihU1depUJScnO1R0S+emmN92223Ky8vToEGDih2Ho1xu9fJ33nlHNWrUkLe3t9q0aWO3At35tm3bpj59+qhGjRoymUyaNm2aXZ8Lb8huMpnUoEEDmz6Z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Rx55RHfeeaeaNGmiRx991BlxAwAAAADg8tyLuoOXl5d+/vlnDRo0SO+//74++OADuz6GYah79+6aPXu2vLy8SiRQAAAAAADKmiIX3ZIUGBioH374QevWrdN3332nnTt3Kj09XX5+fmrQoIF69OihG264oaRjBQAAAACgTClW0Z2vdevWat26dUnFAgAAAADAVeWyim5J2rFjh/bs2aNTp07J19dXderUUYMGDUoiNgAAAAAAyrRiF93vv/++XnnlFR08eNBuW3h4uMaMGaMHHnjgsoIDAAAAAKAsK1bR/dRTT2nq1KmqVKmS7r//fl1//fWqUKGCTp8+rT/++EPz58/XQw89pL/++kuTJk0q6ZgBAAAAACgTilx0r1u3TlOnTtUdd9yh2bNnq3z58nZ93nzzTd13332aPHmy+vbtq5YtW5ZIsAAAAAAAlCVFvk/3Rx99pCpVqmjOnDkFFtySVL58eX3++ecKCQnRRx99dNlBAgAAAABQFhW56F69erX69u17yftve3t7q2/fvlq5cmWxgwMAAAAAoCwrctH9zz//qGHDhg71bdSokf75558iBwUAAAAAwNWgyEV3enq6fH19HepboUIFnTp1qshBAQAAAABwNShy0W0YhkwmU5H6AwAAAABwLSrWLcMmT56szz///JL9CrqHNwAAAAAA14oiF93Vq1fX8ePHdfz4cYf7AwAAAABwLSpy0b1v3z4nhAEAAAAAwNWnWNPLC3L69GmdOHGiwGu4OdsNAAAAALgWXVbRnZmZqQkTJuijjz7SsWPHCu2Xl5d3OYcBAAAAAKBMuqyi+9FHH9XHH3+sXr166aabblLFihVLKi4AAAAAAMq8yyq6582bpwceeEDvv/9+ScUDAAAAAMBVo8j36T6fyWRS8+bNSyoWOJGRl6eMdeuUnZiojHXrZDDlHygQuQI4jnwBHEe+AI672vLlss5033777UpISNBDDz1UUvHACdIXL1byqxOVe+SIJOmMJPfQUIU8N1p+3bqVbnCACyFXAMeRL4DjyBfAcVdjvpiMgpYbd9CePXt01113qUWLFnrooYdUvXp1ubm52fWrVKnSZQVZFqSnp8vf319paWny8/Mr7XCs0hcv1sH/GyFd+DabTJKkqm9OK7MfXqAkkSuA48gXwHHkC+C4spYvjtaAl1V0m83/m51u+veFKMi1sHq5Kxbd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r0cIIY4cOSJGjhwp1Gq1CA0NFYsXLxbvvfeeACBycnIkxyYlJdm9d2NbXX366aciKipKKBQKh7YPS0tLE8OHDxeurq7C09NTTJkyRRw/flxSpiVbhu3bt0/MmTNH9OvXT3h5eQmlUinCw8PFrFmzRGZmpl35Dz74QPTu3VsolUoRFBQknnzySbutwYQQYu/evWLcuHHCw8NDaLVaMWDAAMk2Vo1tGbZx40YxYMAAodFoRI8ePcTSpUvF559/brclW0u2DGvs9yCEECtXrhQAxIoVK2xp//jHP8SQIUOEq6ur8PDwEP379xcvvviiuHjx4jXf29F7ymr48OECgHj00Ucbrdtnn30mevbsKdRqtejdu7dYsWJFoz8vR9uiEEJkZWWJhx56SAQEBAi1Wi2ioqLEnDlzRE1Nja1MeXm5mD9/vtDpdEKlUgl/f38xbNgw8dZbb4na2lpbuRMnTggAIi0trdH6ExF1NTIhOvCKLERE1CksXLgQixYtQn5+fodaGOmRRx7B77//jj179ji7Kk2aN28ePvnkE1RUVDS5qBVRVzJv3jx8//33OHToEHu6ieimwDndRETUZS1YsAAHDx60bQ/mbEajUfK6sLAQq1atwogRIxhw002hsLAQ//znP/HGG28w4CaimwbndBMRUZcVHh6O6upqZ1fDJi4uDqNHj0afPn2Qm5uLzz77DGVlZXjttdecXTWiduHn54eKigpnV4OIqF0x6CYiImonkyZNwrp16/CPf/wDMpkMgwcPxmeffYZRo0Y5u2pERETURjinm4iIiIiIiKiNcE43ERERERERURth0E1ERERERETURhh0ExEREREREbURBt1EREREREREbYRBNxEREREREVEbYdBNRERERERE1EYYdBMRERERERG1EQbdRERERERERG2EQTcRERERERFRG/l/aLWQ4JUE9n4AAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data",
"transient": {}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"nDCG@5 Results (varying alpha):\n",
"Alpha\tsoc\ttext\tsotext\tsocBinary\tsotextBinary\n",
"0.00\t0.1858\t0.0114\t0.0114\t0.0834\t0.0114\n",
"0.25\t0.1858\t-\t0.0114\t0.0834\t0.0114\n",
"0.50\t0.1858\t-\t0.0114\t0.0834\t0.0114\n",
"0.75\t0.1858\t-\t0.0427\t0.0834\t0.0269\n",
"1.00\t0.1858\t-\t0.0693\t0.0834\t0.0395\n"
]
}
],
"source": [
"# Plot nDCG vs Alpha\n",
"plt.figure(figsize=(10, 6))\n",
"\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if ndcg_results[approach]:\n",
" plt.plot(alpha_values[:len(ndcg_results[approach])], ndcg_results[approach], \n",
" marker='o', label=approach, linewidth=2)\n",
"\n",
"plt.xlabel('Alpha (Weight of Social Relevance)', fontsize=12)\n",
"plt.ylabel(f'nDCG@{k_eval}', fontsize=12)\n",
"plt.title(f'Ranking Quality vs Alpha Parameter\\n({len(test_queries)} queries, delta={delta_eval})', fontsize=14)\n",
"plt.legend(loc='best', fontsize=10)\n",
"plt.grid(True, alpha=0.3)\n",
"plt.xticks(alpha_values)\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Print numerical results\n",
"print(\"\\nnDCG@5 Results (varying alpha):\")\n",
"print(\"Alpha\", end=\"\")\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" print(f\"\\t{approach}\", end=\"\")\n",
"print()\n",
"for i, alpha in enumerate(alpha_values[:len(ndcg_results['sotext'])]):\n",
" print(f\"{alpha:.2f}\", end=\"\")\n",
" for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if i < len(ndcg_results[approach]):\n",
" print(f\"\\t{ndcg_results[approach][i]:.4f}\", end=\"\")\n",
" else:\n",
" print(\"\\t-\", end=\"\")\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 11. Experiment: Varying k (Top-k Results)\n",
"\n",
"As described in Section 5.1.1, we evaluate how the number of returned results (k) affects ranking quality."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running evaluation with varying k...\n",
" Queries: 20\n",
" k values: [1, 2, 5, 10, 20]\n",
" alpha=0.5, delta=2\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluation complete!\n"
]
}
],
"source": [
"# Evaluate nDCG for different k values\n",
"k_values = [1, 2, 5, 10, 20]\n",
"alpha_k = 0.5\n",
"delta_k = 2\n",
"\n",
"ndcg_by_k = {approach: [] for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']}\n",
"\n",
"print(f\"Running evaluation with varying k...\")\n",
"print(f\" Queries: {len(test_queries)}\")\n",
"print(f\" k values: {k_values}\")\n",
"print(f\" alpha={alpha_k}, delta={delta_k}\")\n",
"\n",
"for k_val in k_values:\n",
" k_ndcg = {approach: [] for approach in ndcg_by_k.keys()}\n",
" \n",
" for query_user, query_keywords in test_queries:\n",
" relevances = playcounts.get(query_user, {})\n",
" if not relevances:\n",
" continue\n",
" \n",
" for approach in ndcg_by_k.keys():\n",
" ranked = rank_tracks(\n",
" query_user=query_user,\n",
" query_keywords=query_keywords,\n",
" tracks=tracks,\n",
" G=G,\n",
" playcounts=playcounts,\n",
" user_weights=user_weights,\n",
" track_ids=track_ids,\n",
" tfidf_matrix=tfidf_matrix,\n",
" tfidf_vectorizer=tfidf_vectorizer,\n",
" approach=approach,\n",
" alpha=alpha_k,\n",
" delta=delta_k,\n",
" k=k_val\n",
" )\n",
" \n",
" ranked_ids = [tid for tid, _ in ranked]\n",
" ndcg = compute_ndcg(ranked_ids, relevances, k_val)\n",
" k_ndcg[approach].append(ndcg)\n",
" \n",
" for approach in ndcg_by_k.keys():\n",
" if k_ndcg[approach]:\n",
" ndcg_by_k[approach].append(np.mean(k_ndcg[approach]))\n",
"\n",
"print(\"Evaluation complete!\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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2aJWrVpCoVAIT09PMW7cOBEVFWXQVvu5efb1HxoaKgYPHiz8/PyEvb29kMvlwtPTU/Tp00fs3bvX6HWXLFkiAIhVq1aZXGtqaqr4+OOPRZUqVYRSqRQNGjQQK1euLPA1+uDBA/H+++8LPz8/oVQqhb29vahfv74YN26cCAkJ0WtrbMswIYRYu3at8Pf3F0ql0uD53759WwwYMEC4ubkJa2tr0apVK/HLL7+Y9L4pClO2iTO2faCvr69o2rRpidZCRFRWJELkmY9FRERmZfjw4di5cyfu3r1bqEXFykuHDh1w+PBhvMjfer755hu89957uHTpktGV5EsLP/cla+DAgTh58iTCw8OhUCjKu5xK7cCBA+jatSvWrVuHESNGlHc5RESFxnu6iYjM2Jw5c5Ceno5ly5aVdylkoiNHjuC1114r08BNJe+ff/7Bhx9+yMBdBoKDg9G0adPnbilGRFRR8Z5uIiIz5uPjg3Xr1hndcogqps2bN5d3CVQCoqKiyruEF0JCQgI6d+6M3r1767YXJCIyNwzdRERmbvDgweVdAhFRqXB2dja62BoRkTnhPd1EREREREREpYTzdIiIiIiIiIhKCUM3ERERERERUSnhPd0m0Gg0ePToEezs7CCRSMq7HCIiIiIiIipnQggkJyfD29u7wMUeGbpN8OjRI1SrVq28yyAiIiIiIqIK5v79+6hatWq+5xm6TWBnZwcg55Npb29fztUYp9FoEBsbCzc3N7PYUsPc6qXSwdcBUenh+4uIiMyZOXwfS0pKQrVq1XR5MT8M3SbQTim3t7ev0KE7IyMD9vb2FfZFmZe51Uulg68DotLD9xcREZkzc/o+9rxbkCt29URERERERERmjKGbiIiIiIiIqJQwdBMRERERERGVEoZuIiIiIiIiolLC0E1ERERERERUShi6iYiIiIiIiEoJQzcRERERERFRKWHoJiIiIiIiIiolDN1EREREREREpYShm4iIiIiIiKiUMHQTERERERERlRKGbiIiIiIiIqJSwtBNREREREREVEoYuomIiIiIiIhKCUM3ERERERERVRhqjcCJ2/HYdz0BJ27HQ60R5V1SscjLuwAiIiIiIiIiANhzORLB268iMjEj98gdeDlYYlbvBujeyKtcaysqjnQTERERERFRudtzORITNpzLE7hzRCVmYMKGc9hzObKcKisehm4i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qlatCqVSiaZNm2LPnj16j33w4AGGDRsGZ2dn2NjYoGXLljh58mSp1UpERERERGSOGLrLkVojELz9KoSRc9pjwduvQq0x1qJ4IiMjMWzYMIwZMwbXrl1DaGgo+vfvDyEElixZgoULF2LBggX4999/ERQUhNdeew23bt0CAKSkpCAwMBAPHz7Etm3bcPHiRXz88cfQaDQlXicREREREZE54/TyUtJ72T+ITc4ssE2mSo3Hadn5nhcAIhMz0HLOfijlsude09VWge3vvmJSfZGRkVCpVOjfvz98fHwAAP7+/gCABQsWYOrUqRg6dCgAYN68eTh06BAWL16M5cuXY9OmTYiNjcXp06fh7OwMAKhdu7ZJ1yUiIiIiInqRMHSXktjkTEQlZTy/oQlygnn+4VxLGB0zN65Jkybo3Lkz/P39ERQUhG7dumHgwIGQyWR49OgR2rZtq9e+bdu2uHjxIgDgwoULaNasmS5wExERERERkXEM3aXEzU753DbPG+nWcrK2MHmk21QymQz79+/HsWPHsG/fPixbtgwzZszA/v37n/tYKysrk69DRERERET0ImPoLiWmTPNWawRemXcQUYkZRseoJQA8HSzxz9ROz90+TAgBlUpVqBolEgnatm2Ltm3bYubMmfDx8UFISAi8vb1x9OhRBAYG6toePXoUAQEBAIDGjRtj9erVSEhI4Gg3ERERERFRAbiQWjmSSSWY1bsBgJyAnZf241m9G5TKft0nT57EF198gTNnzuDevXv4448/EBsbi/r16+Ojjz7CvHnzsHnzZty4cQPTpk3DhQsX8P777wMAhg0bBk9PT/Tt2xdHjx7F7du38fvvv+P48eMlXicREREREZE540h3OeveyAvfvdHcYJ9uz1Lep9ve3h5///03Fi9ejKSkJPj4+GDhwoXo0aMHgoKCkJiYiA8//BAxMTFo0KABtm3bBj8/PwCAQqHAvn378OGHH6Jnz55QqVRo0KABli9fXiq1EhERERERmSuJEKLk96OqZJKSkuDg4IDExETY29vrncvIyMCdO3fg6+sLS0vLIl9DrRE4dScBMckZcLezRICvc6FGuLXTy+VyOSSSkh8ZL2nmVm9xldTrpLLRaDSIiYmBu7s7pFJOvCEqSXx/ERGROTOH72MF5cS8ONJdQcikErxcy6W8yyAiIiIiIqISVDF/ZUBERERERERU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M5Nl1nt+f8ySmcwkmYRMZib5vF+vYTLn3rnznckMk+85555vcroO//XIJT2e0y2EgLOXPZaSJGHSpEmYNGkSlixZguHDh2P79u0oKCjA+++/H1CO6/333/dNufaea+1fCi43NxcFBQU4dOgQvv/973f5mGvWrMG+ffuwY8cOXHXVVdi4cSN+8IMfdHnc7qhUKrS3t/fqOft7//338d3vfhe33347AHcyvn//fowePbrH+2ZmZqKqqgobN27E7t27cdddd/U5DiIiIop/wm7vfpGwEPWcvSPPGKDyunJycteLhHVebTutY1RaSuSoM9GZYNIdRbIs4dKbR4Rcvdxr8k0jIlKve8+ePdi+fTumTZuGnJwc7Nmzx7dS+QMPPIClS5eivLwc48aNw8aNG7F371785S9/AQDk5OQgISEBW7duRVFREfR6PQwGA5YvX46f/vSnMBgMuOqqq2Cz2fDxxx/j9OnTmDdvHj799FMsWbIEW7ZswaRJk7BmzRrMnTsXU6dORVlZWZfHBdzT1Ovq6gB0TC//8ssvsXDhwj6/BiNGjMCWLVuwa9cupKenY+3ataivrw8r6QbcU8yvueYauFwuzJo1q89xEBERUWwQQkBpaek4vznEImEBU7X9pmuLgRx17lzPuXMiHTDqnApVWpp71FnNP/2JooGfvCgrPz8HV/1oTFCd7uR0HSbfFLk63ampqdi5cyfWrVsHs9mM4cOH44knnsDVV1+N6dOnw2QyYf78+TAajRg9ejRef/11jBgxAoC7fNdTTz2FFStWYMmSJbj00kuxY8cOzJkzB4mJiVizZg0eeOABJCUl4dxzz8XcuXNhtVpx++23484778S1114LIQTmzJmDrVu34r/+67+wc+fOLo8LAF988YXvnOzExESUl5fjt7/9Le64444+vwY///nPcejQIUyfPh2JiYm4++67UVVVBZPJFNb9KysrkZ+fj3POOQcFBQV9joOIiIj6l2K3d0zL9kuaOxYOC56q7TKZ4LJYBm7UOSUlcKp2V/WcO486JyRw1JkozkhCiPBX3xqizGYzDAYDTCZT0GrZVqsVtbW1KC0thV6v7/NjKIrAyQPNaDXbkJSqQ/6ItF6NcHunl6vV6rj4jzje4g2lpaUFhYWF2Lhxo2/F9q701/tksFEUBUajETk5OZDlntctIKLw8fNF8U4oinvU2Zc0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hKy9rdW6a29//zbW3iYiIiIiiiFMuoniCGtvExERERHFFybdRHGCtbeJiIiIiOIPk26iGCcUBU2//wManmLtbSIiIiKieMOkmyiGOYxGnFi4EG27P/C1sfY2EREREVH8YNJNFKNYe5uIiIiIKP7xL3eiGOOuvf0ETm3+o6+NtbeJiIiIiOITk26iGGI75Km9/RVrbxMRERERDQZMuoligBACpr+94q693d4OgLW3iYiIiIgGAybdRFHmslhQt2x5YO3t8nJ37e2zzopiZEREREREdKaYdBNFUeja2zcit3oRa28TEREREQ0CTLqJoqDL2tsrVyD1qquiHB0REREREfUXJt1EAyxk7e3zz0fh42ugKWTtbSIiIiKiwYRJN9EAYu1tIiIiIqKhhX/lEw2ALmtvr1mDpIkTohgZERERERFFEpNuoggLWXv7iiuQ/8jDrL1NRERERDTIMekmipAua28vfBDpt7H2NhERERHRUCBHO4BQnnnmGZSUlECv12PixIn48MMPu93/pZdewqhRo6DX63HuuefizTffDNh+5513QpKkgMtVXCGaIshlseDE/AU4+dBDvoRbW16OkpdeRMb3v8+Em4iIiIhoiIi5pPuFF17AvHnzsHTpUvzrX//C2LFjMX36dBiNxpD779q1C7feeitmz56NTz/9FFVVVaiqqsLnn38esN9VV12FkydP+i7PP//8QDwdGoLa9+5FbdX1MPt1/qTdeCNKX3oR+rPOimJkREREREQ00GIu6V67di1++MMf4q677sLo0aOxfv16JCYm4tlnnw25/69+9StcddVVeOCBB3D22Wdj5cqV+Na3voWnn346YD+dToe8vDzfJZ3n0lI/E4qCxt9twOHv3w7H8eMA3LW3C9c9ifyVKyAnJkY5QiIiIiIiGmgxlXTb7XZ88sknqKys9LXJsozKykrs3r075H12794dsD8ATJ8+PWj/HTt2ICcnB2eddRbuvfdeNDU19f8ToCHLUW/E0dmz0fDkk4DLBcBde7vs1VeQylMZiIiIiIiGrJhaSK2xsREulwu5ubkB7bm5udi3b1/I+9TV1YXcv66uznf7qquuwve+9z2UlpaipqYGixcvxtVXX43du3dDpVIFHdNms8Fms/lum81mAICiKFAUpc/PL5IURYEQImbj6yze4u1Oy3vvoW7xQ0G1tzPvvReSWj0o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",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data",
"transient": {}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"nDCG Results (varying k):\n",
"k\tsoc\ttext\tsotext\tsocBinary\tsotextBinary\n",
"1\t0.2167\t0.0181\t0.0181\t0.0221\t0.0181\n",
"2\t0.1916\t0.0159\t0.0159\t0.0267\t0.0159\n",
"5\t0.1858\t0.0114\t0.0114\t0.0834\t0.0114\n",
"10\t0.2286\t0.0271\t0.0281\t0.1052\t0.0292\n",
"20\t0.2716\t0.0241\t0.0257\t0.1231\t0.0257\n"
]
}
],
"source": [
"# Plot nDCG vs k\n",
"plt.figure(figsize=(10, 6))\n",
"\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if ndcg_by_k[approach]:\n",
" plt.plot(k_values[:len(ndcg_by_k[approach])], ndcg_by_k[approach], \n",
" marker='o', label=approach, linewidth=2)\n",
"\n",
"plt.xlabel('k (Number of Top Results)', fontsize=12)\n",
"plt.ylabel('nDCG@k', fontsize=12)\n",
"plt.title(f'Ranking Quality vs k Parameter\\n({len(test_queries)} queries, alpha={alpha_k}, delta={delta_k})', fontsize=14)\n",
"plt.legend(loc='best', fontsize=10)\n",
"plt.grid(True, alpha=0.3)\n",
"plt.xticks(k_values)\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Print numerical results\n",
"print(\"\\nnDCG Results (varying k):\")\n",
"print(\"k\", end=\"\")\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" print(f\"\\t{approach}\", end=\"\")\n",
"print()\n",
"for i, k_val in enumerate(k_values[:len(ndcg_by_k['sotext'])]):\n",
" print(f\"{k_val}\", end=\"\")\n",
" for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if i < len(ndcg_by_k[approach]):\n",
" print(f\"\\t{ndcg_by_k[approach][i]:.4f}\", end=\"\")\n",
" else:\n",
" print(\"\\t-\", end=\"\")\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 12. Experiment: Varying Delta (Distance Threshold)\n",
"\n",
"As described in Section 5.1.2, we evaluate how the distance threshold $\\delta$ (maximum social network distance) affects ranking quality."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running evaluation with varying delta...\n",
" Queries: 20\n",
" Delta values: [1, 2, 3, 4]\n",
" alpha=0.5, k=5\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluation complete!\n"
]
}
],
"source": [
"# Evaluate nDCG for different delta values\n",
"delta_values = [1, 2, 3, 4]\n",
"alpha_delta = 0.5\n",
"k_delta = 5\n",
"\n",
"ndcg_by_delta = {approach: [] for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']}\n",
"\n",
"print(f\"Running evaluation with varying delta...\")\n",
"print(f\" Queries: {len(test_queries)}\")\n",
"print(f\" Delta values: {delta_values}\")\n",
"print(f\" alpha={alpha_delta}, k={k_delta}\")\n",
"\n",
"for delta_val in delta_values:\n",
" delta_ndcg = {approach: [] for approach in ndcg_by_delta.keys()}\n",
" \n",
" for query_user, query_keywords in test_queries:\n",
" relevances = playcounts.get(query_user, {})\n",
" if not relevances:\n",
" continue\n",
" \n",
" for approach in ndcg_by_delta.keys():\n",
" ranked = rank_tracks(\n",
" query_user=query_user,\n",
" query_keywords=query_keywords,\n",
" tracks=tracks,\n",
" G=G,\n",
" playcounts=playcounts,\n",
" user_weights=user_weights,\n",
" track_ids=track_ids,\n",
" tfidf_matrix=tfidf_matrix,\n",
" tfidf_vectorizer=tfidf_vectorizer,\n",
" approach=approach,\n",
" alpha=alpha_delta,\n",
" delta=delta_val,\n",
" k=k_delta\n",
" )\n",
" \n",
" ranked_ids = [tid for tid, _ in ranked]\n",
" ndcg = compute_ndcg(ranked_ids, relevances, k_delta)\n",
" delta_ndcg[approach].append(ndcg)\n",
" \n",
" for approach in ndcg_by_delta.keys():\n",
" if delta_ndcg[approach]:\n",
" avg_ndcg = np.mean(delta_ndcg[approach])\n",
" ndcg_by_delta[approach].append(avg_ndcg)\n",
" elif approach == 'text':\n",
" # Text approach doesn't use delta, replicate score\n",
" if ndcg_by_delta[approach]:\n",
" ndcg_by_delta[approach].append(ndcg_by_delta[approach][0])\n",
"\n",
"print(\"Evaluation complete!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Plot nDCG vs delta\n",
"plt.figure(figsize=(10, 6))\n",
"\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if ndcg_by_delta[approach]:\n",
" plt.plot(delta_values[:len(ndcg_by_delta[approach])], ndcg_by_delta[approach], \n",
" marker='o', label=approach, linewidth=2)\n",
"\n",
"plt.xlabel('Delta (Distance Threshold)', fontsize=12)\n",
"plt.ylabel(f'nDCG@{k_delta}', fontsize=12)\n",
"plt.title(f'Ranking Quality vs Delta Parameter\\n({len(test_queries)} queries, alpha={alpha_delta}, k={k_delta})', fontsize=14)\n",
"plt.legend(loc='best', fontsize=10)\n",
"plt.grid(True, alpha=0.3)\n",
"plt.xticks(delta_values)\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Print numerical results\n",
"print(f\"\\nnDCG@{k_delta} Results (varying delta):\")\n",
"print(\"Delta\", end=\"\")\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" print(f\"\\t{approach}\", end=\"\")\n",
"print()\n",
"for i, delta_val in enumerate(delta_values[:len(ndcg_by_delta['sotext'])]):\n",
" print(f\"{delta_val}\", end=\"\")\n",
" for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" if i < len(ndcg_by_delta[approach]):\n",
" print(f\"\\t{ndcg_by_delta[approach][i]:.4f}\", end=\"\")\n",
" else:\n",
" print(\"\\t-\", end=\"\")\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 13. Summary and Conclusions\n",
"\n",
"### What We Implemented\n",
"\n",
"This notebook demonstrates the complete **social-textual search and ranking** system from the paper:\n",
"\n",
"1. **Core Components**:\n",
" - User Relatedness Function (urf): Based on social network distance\n",
" - User Weight Function (uwf): Based on degree centrality\n",
" - User Action Function (uaf): Based on normalized playcounts\n",
"\n",
"2. **Ranking Approaches**:\n",
" - **sotext**: Socio-textual ranking (main contribution)\n",
" - **soc**: Social-only ranking\n",
" - **text**: Textual-only ranking (traditional tf-idf)\n",
" - **socBinary**: Social ranking with binary actions\n",
" - **sotextBinary**: Socio-textual with binary actions\n",
"\n",
"3. **Evaluation**:\n",
" - nDCG metric for ranking quality\n",
" - Parameter sensitivity analysis (alpha, k, delta)\n",
"\n",
"### Key Findings (from our small-scale demonstration)\n",
"\n",
"The experiments show how different parameters affect ranking quality:\n",
"- **Alpha**: Controls balance between social and textual relevance\n",
"- **k**: Number of top results returned\n",
"- **Delta**: Social network distance threshold\n",
"\n",
"### Scaling to Full Experiments\n",
"\n",
"To run the full experiments as in the paper:\n",
"\n",
"1. **Data**: Use the actual Last.fm dataset (3148 users, 30520 tracks, 12565 tags)\n",
"2. **Queries**: Generate 100+ queries per experiment round\n",
"3. **Infrastructure**: Use a server with adequate RAM (16GB+) and CPU\n",
"4. **Optimization**: \n",
" - Pre-compute shortest paths for all user pairs\n",
" - Cache TF-IDF computations\n",
" - Parallelize query evaluation\n",
"5. **Expected runtime**: Full evaluation may take hours to days depending on hardware\n",
"\n",
"### Paper Citation\n",
"\n",
"If you use this implementation, please cite the original paper:\n",
"\n",
"```\n",
"Ali Khodaei and Cyrus Shahabi. \"Social-Textual Search and Ranking.\"\n",
"```\n",
"\n",
"### Next Steps for Researchers\n",
"\n",
"1. Replace synthetic data with real social media dataset\n",
"2. Experiment with different centrality measures for uwf (betweenness, closeness, PageRank)\n",
"3. Try alternative distance functions for urf (commute time, Katz centrality)\n",
"4. Extend to other domains (images, videos, documents)\n",
"5. Incorporate user feedback for personalization"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 14. Verification: Final Test\n",
"\n",
"Let's verify that all components work together correctly."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"============================================================\n",
"FINAL VERIFICATION\n",
"============================================================\n",
"\n",
"Query: User=5, Keywords=['rock', 'pop'], k=5\n",
"\n",
"✓ soc : Returned 5 results\n",
"✓ text : Returned 5 results\n",
"✓ sotext : Returned 5 results\n",
"✓ socBinary : Returned 5 results\n",
"✓ sotextBinary : Returned 5 results\n",
"\n",
"============================================================\n",
"VERIFICATION RESULT: 5/5 approaches working\n",
"============================================================\n",
"\n",
"✓✓✓ ALL TESTS PASSED! Notebook is ready to use. ✓✓✓\n"
]
}
],
"source": [
"print(\"=\" * 60)\n",
"print(\"FINAL VERIFICATION\")\n",
"print(\"=\" * 60)\n",
"\n",
"# Test all five ranking approaches\n",
"verification_user = 5\n",
"verification_keywords = ['rock', 'pop']\n",
"verification_k = 5\n",
"\n",
"print(f\"\\nQuery: User={verification_user}, Keywords={verification_keywords}, k={verification_k}\")\n",
"print()\n",
"\n",
"success_count = 0\n",
"for approach in ['soc', 'text', 'sotext', 'socBinary', 'sotextBinary']:\n",
" try:\n",
" results = rank_tracks(\n",
" query_user=verification_user,\n",
" query_keywords=verification_keywords,\n",
" tracks=tracks,\n",
" G=G,\n",
" playcounts=playcounts,\n",
" user_weights=user_weights,\n",
" track_ids=track_ids,\n",
" tfidf_matrix=tfidf_matrix,\n",
" tfidf_vectorizer=tfidf_vectorizer,\n",
" approach=approach,\n",
" alpha=0.5,\n",
" delta=2,\n",
" k=verification_k\n",
" )\n",
" print(f\"✓ {approach:15s}: Returned {len(results)} results\")\n",
" success_count += 1\n",
" except Exception as e:\n",
" print(f\"✗ {approach:15s}: FAILED - {str(e)}\")\n",
"\n",
"print()\n",
"print(\"=\" * 60)\n",
"print(f\"VERIFICATION RESULT: {success_count}/5 approaches working\")\n",
"print(\"=\" * 60)\n",
"\n",
"if success_count == 5:\n",
" print(\"\\n✓✓✓ ALL TESTS PASSED! Notebook is ready to use. ✓✓✓\")\n",
"else:\n",
" print(\"\\n⚠ WARNING: Some approaches failed. Please review errors above.\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment