Iterative Positioning via Logistic Regression Embedding
Project description
IXPLORE
Iterative Positioning via Logistic Regression Embedding: A Python package for embedding users and items of political questionnaires in a shared 2D latent space.
IXPLORE jointly learns a posterior distribution for each user and a logistic regression model for each question. This can be used to visualize the political landscpae in a two dimensional, interpretable space. In inference, it can be used for missing value imputation and answer prediction.
Features
- User Embedding: Compute posterior distributions over user positions using observed reactions
- Item Models: Define decision boundaries in the latent space for each item by learning logistic regression models
- Iterative Refinement: Jointly optimize user embeddings and item models through iterative updates
- Flexible Initialization: Initialize embeddings via PCA, random values, or load pretrained embeddings
- Missing Data Handling: Robust to missing values in the user-item reaction matrix
- Answer Imputation: Predict missing answers based on learned user positions
- New User Embedding: Embed new users based on their responses and obtain optimal positions with uncertainty quantification
- Visualization Tools: Built-in plotting functions for embeddings, posteriors, and item decision boundaries
Installation
pip install ixplore
Or install from source:
git clone https://github.com/fybach/ixplore.git
cd ixplore
pip install -e .
Quick Start
import pandas as pd
from ixplore import IXPLORE
# Load reaction data (users × items matrix, values in [0, 1])
reactions = pd.read_csv('../data/synthetic_reactions.csv', index_col=0)
# Initialize and fit the model
model = IXPLORE(reactions, pca_initialization=True)
# Get user embeddings
embedding = model.get_embedding() # User positions (N × 2)
parameters = model.get_item_parameters() # Item parameters (K × 3)
# Embed a new user based on their answers
new_user_answers = pd.Series({'Q1': 0.8, 'Q2': 0.2, 'Q3': 0.6}, name='new_user')
position = model.embed_new_user(new_user_answers)
# Predict all answers for a user
predicted = model.predict_all_answers(new_user_answers)
Usage
Custom Configuration
import numpy as np
model = IXPLORE(
reactions,
prior_mean=np.array([0, 0]), # Prior center
prior_cov=np.array([[0.1, 0], [0, 0.1]]), # Prior covariance
sampling_resolution=200, # Grid resolution for posteriors
xlimits=(-1, 1), # X-axis bounds
ylimits=(-1, 1), # Y-axis bounds
pca_initialization=True, # Initialize with PCA
random_state=17 # For reproducibility
)
Loading Pretrained Models
# Load pretrained embedding and model parameters
model = IXPLORE(
reactions,
pretrained_embedding='../data/synthetic_embedding.csv',
)
Visualization
from ixplore.visualization import plot_embedding, plot_overview
# Plot user embeddings
plot_embedding(model.get_embedding(), colors='blue')
# Plot comprehensive overview
plot_overview(model, n=0, q='Q1', colors=user_colors)
API Reference
IXPLORE Class
Constructor Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
reactions |
pd.DataFrame | required | User-item reaction matrix (users as index, items as columns) |
prior_mean |
np.ndarray | [0, 0] | Mean of the prior distribution |
prior_cov |
np.ndarray | [[0.1, 0], [0, 0.1]] | Covariance of the prior distribution |
sampling_resolution |
int | 200 | Grid resolution for posterior computation |
xlimits |
tuple | (-1, 1) | X-axis limits of the latent space |
ylimits |
tuple | (-1, 1) | Y-axis limits of the latent space |
pca_initialization |
bool | True | Initialize embeddings with PCA |
random_state |
int | 0 | Random seed for reproducibility |
Key Methods
| Method | Description |
|---|---|
iterate(n_iterations) |
Run n iterations of posterior fitting and model updating |
fit_posteriors() |
Compute posterior distributions for all users |
fit_models() |
Fit logistic regression models for all items |
get_embedding() |
Return current user embeddings as DataFrame |
get_item_parameters() |
Return item model parameters |
embed_new_user(answers) |
Embed a new user given their answers |
predict_all_answers(answers) |
Predict answers for all items given partial answers |
impute_remaining_answers(answers) |
Impute missing answers for a user |
evaluate() |
Return MAE and accuracy on training data |
Dependencies
- numpy
- pandas
- scikit-learn
- scipy
- matplotlib
License
This project is licensed under the MIT License - see the LICENSE file for details.
Citation
If you use IXPLORE in your research, please cite:
@software{bachmann2026ixplore,
author = {Bachmann, Fynn},
title = {IXPLORE: Iterative Positioning via Logistic Regression Embedding},
year = {2026},
publisher = {GitHub},
url = {https://github.com/fybach/ixplore}
}
Or in text format:
Bachmann, F. (2026). IXPLORE: Iterative Positioning via Logistic Regression Embedding. GitHub. https://github.com/fybach/ixplore
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ixplore-0.1.0.tar.gz.
File metadata
- Download URL: ixplore-0.1.0.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13231a3b369b81da37e002994f589f786fb63cb21ccfdd007eb3134a6517ec9b
|
|
| MD5 |
c7fe28be253f46f32f8163155751e352
|
|
| BLAKE2b-256 |
0b86d68200e87dd66af5417011dc2128d3489f6061d7d16eb5e3404b8cce3c04
|
File details
Details for the file ixplore-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ixplore-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bc7dc22c045715787e26440ea9516d5778baf66db932ede4f61aa0a40e4ac43
|
|
| MD5 |
1d9e16feb91ecf33986ee5a6ec870f43
|
|
| BLAKE2b-256 |
69d8188ac75cd1370fc8a19d3d4f62d609b287853cc645cc7ef91bb961ebbb1f
|