Skip to main content

A framework for characterizing and predicting pairwise comparisons using user clustering and matrix completion

Project description

Pairwise Comparison Framework

PyPI version Python License: MIT

A Python framework for clustering users based on their pairwise comparison patterns and predicting missing comparisons via matrix completion.

This project was developed as part of a final thesis (TCC) at the Escola Politécnica, Universidade Federal do Rio de Janeiro (UFRJ).

Overview

The framework operates in two stages:

  1. Clustering (Stage 1): Each user's pairwise comparisons are modeled as a weighted directed graph. Shortest-path-length matrices serve as structural preference signatures, a custom distance metric measures user similarity, and MDS + K-Means produces the final clusters.

  2. Prediction (Stage 2): A sparse comparison matrix is built from all users' data. Matrix completion (Iterative SVD or KNN) fills in missing entries. Applying completion within each cluster improves prediction accuracy over a global model.

Installation

Requires Python 3.13+.

pip install pairwise-comparison-framework

Or with uv:

uv add pairwise-comparison-framework

For local development:

git clone https://github.com/henchaves/pairwise-comparison-framework.git
cd pairwise-comparison-framework
uv sync

Quick Start

Clustering

import pairwise_comparison_framework as pcf

clusterizer = pcf.Clusterizer()
clusterizer.load_data("data/sample/comparisons.json", "data/sample/labels.json")

# Visualize a user's preference graph
clusterizer.plot_graph("user_id", with_labels=True)

# Get item rankings via PageRank
clusterizer.get_ranking("user_id", with_labels=True)

# Cluster users
clusters = clusterizer.get_user_clusters(n_clusters=3)

# Assess cluster quality
clusterizer.get_silhouette_scores(n_clusters=3)
clusterizer.get_elbow_data(max_clusters=10)
clusterizer.plot_clusters(n_clusters=3)

Prediction

# Iterative SVD (default)
predictor = pcf.Predictor(impute_method="svd", impute_rank=1)
predictor.load_data("data/sample/comparisons.json", "data/sample/labels.json")

# Or KNN imputation
predictor = pcf.Predictor(impute_method="knn", impute_k=5)
predictor.load_data("data/sample/comparisons.json", "data/sample/labels.json")

# Predict missing comparisons
completed_matrix = predictor.predict()

# Controlled evaluation: global vs per-cluster
results = predictor.evaluate_global_vs_clusters(
    clusters, n_rounds=50, test_size=0.2
)

Data Format

Comparisons (comparisons.json)

A JSON array of user comparison records. Each comparison score answers "How much more preferred is the first item over the second?":

  • 2: first item much more preferred
  • 1: first item more preferred
  • 0: equally preferred (tie)
  • -1: second item more preferred
  • -2: second item much more preferred
[
  {
    "user_id": "user_01",
    "comparisons": [
      {
        "first_item_id": "item_01",
        "second_item_id": "item_02",
        "score": 2
      }
    ]
  }
]

Labels (labels.json, optional)

A JSON array mapping item IDs to human-readable names:

[
  {
    "item_id": "item_01",
    "label": "Oranges"
  }
]

Notebooks

Notebook Description
notebooks/clustering.ipynb Clustering pipeline demo with sample data
notebooks/prediction.ipynb Prediction pipeline demo with sample data
notebooks/epfl_analysis.ipynb Full analysis on the EPFL food preference dataset (private dataset, not included)

Project Structure

pairwise-comparison-framework/
├── src/pairwise_comparison_framework/
│   ├── __init__.py          # Exports Clusterizer, Predictor
│   ├── _base.py             # Shared data loading logic
│   ├── models/              # Pydantic data models
│   ├── clusterizer/         # Stage 1: clustering pipeline
│   └── predictor/           # Stage 2: prediction pipeline
├── data/
│   └── sample/              # Small sample dataset (wine preferences)
└── notebooks/               # Jupyter notebooks

License

This project is licensed under the MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pairwise_comparison_framework-1.0.1.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pairwise_comparison_framework-1.0.1-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

File details

Details for the file pairwise_comparison_framework-1.0.1.tar.gz.

File metadata

  • Download URL: pairwise_comparison_framework-1.0.1.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pairwise_comparison_framework-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f6f749790e15e4cf0346c749f25c303c7567ce0fd71fbe77ef6f37e32df0a698
MD5 90c5556b68cae360dd532d85c2cab2f6
BLAKE2b-256 6249490e3bb213339e3b946997b6ca6887c7339026c4d59c608a73bb8f160c6e

See more details on using hashes here.

File details

Details for the file pairwise_comparison_framework-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pairwise_comparison_framework-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 19.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pairwise_comparison_framework-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b2e8e3006bbc35bdda21356c9685fe29bd20fe67bdf7c52dbee198c1f1468692
MD5 f9b6ead7ea7e41f043402492e21e6971
BLAKE2b-256 0912a2009694cf8706c2caa2eb6e0795c09a04d8aa7261a085ca4038f918bb52

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page