← Back to list

Riding the Quantum Range: Teaching a Single Qubit to Predict Your Paycheck

Well then. Last month my focus quietly wandered off and landed straight into March Madness. For the uninitiated, it is that college…

Sidd · 2026-04-21 22:24 · 1 claps · 12.6 min read paywalled
#quantum-computing #quantum-machine-learning #machine-learning
Open on Medium ↗
Wiki topics: ML · Machine Learning EDU · Education & Learning 🔧 · Data Engineering ⚛️ · Physics ⏱️ · Productivity 📊 · Economic Policy 🏀 · Basketball

Riding the Quantum Range: Teaching a Single Qubit to Predict Your Paycheck

Ref: https://qxplore.binossusai.com

Ref: https://qxplore.binossusai.com

Well then. Last month my focus quietly wandered off and landed straight into March Madness. For the uninitiated, it is that college basketball prediction ritual where fans build something called brackets and then emotionally commit to them. I somehow got voluntold to do this with a few colleagues. Exciting!! yes. Dangerous, also yes. The fun part is that there is an absurd amount of data floating around on the internet about teams, players, stats, histories and probably even what they had for their breakfast.

Here is the tricky bit though. Not everyone actually knows the fine print of the game or the teams. And even if they do, everyone has a favorite e.s.p. in this nation. Surprisingly, people do not always let their favorite team drive their prediction because deep down they know this is not a loyalty contest. It is a prediction game. A game of luck. In case if money enters the chat, a polite form of gambling with spreadsheets.

Prediction itself is nothing new. Humans have been doing it forever from reading stars to reading vibes. Sometimes it is intuition. Sometimes it is data. This whole thing reminded me of an experiment I once ran on the very famous Titanic dataset. You know the one. Predicting who made it back to shore using features like gender, class, age, and so on. Plenty of machine learning algorithms were eager to help. Naive Bayes showed up. Even a coin toss style classifier had opinions. This will be mindblowing; Do you know what actually gave the best accuracy? Guess! The answer is: None of those. The winner was the brutally honest classifier that predicted everyone did not survive. One hundred percent commitment. You dont believe me!! I am so offended! Well! I dont! Just kidding. Let me tell you Why did it work? It worked because more than eighty percent of passengers, regardless of class, gender, or age, did not make it back. Cold Atlantic Ocean at probably 1AM in the morning. The classification was also cold, efficient, slightly depressing but interesting, right?

That result plants a dangerous thought. Maybe there is no point in fancy prediction algorithms that require expertise, tuning, and emotional investment. I get why someone would think that. I thought the same thing when I first saw those results and questioned several life decisions shortly after.

Just when I was feeling intellectually secure, one of my colleagues casually dropped a bomb. They picked the winner of each match by comparing mascots. Whichever mascot looked more adorable advanced. No stats. No history. Just vibes and cuteness of team mascots. That colleague proceeded to win the entire bracket challenge. At that point, I seriously considered adding mascot adorability as a feature in my next model.

That little epiphany pushed me toward the next idea. What if I try the same experiment on a different dataset? Because surely lightning cannot strike twice. Or can it.

The Problem I Was Wrangling

This is one of the questions that keeps economists up at night and machine learning engineers awake out of sheer stubbornness: can you predict whether someone earns more than $50,000 a year from 14 census features which are age, education, occupation, hours worked per week, and a handful of others? The UCI Adult Census Income dataset, pulled straight from the 1994 US Census Bureau database, has been a benchmark punching bag for classifiers for decades. It is well-understood and nicely dirty with missing values disguised as ?, and of-course delightfully imbalanced.

I wasn’t trying to just to run a logistic regression and call it a day. I wanted to know something more specific regarding What would happen after stuffing a 14-dimensional classical feature vector into a single qubit using a QuantumCircuit with one Ry gate and then have the audacity to call it a classifier? Is a quantum circuit(even a laughably shallow one) capable of learning anything meaningful from census data!! Or does it just get bucked off the saddle the moment the data gets complicated? I had to find out.

Spoilers first:

  • Random Cladsifier hit 51% accuracy on the UCI Adult Income dataset — exactly what a coin toss deserves.
  • The bias-weighted “hypocrite” classifier exploiting the 75/25 class imbalance jumped to 75% without learning a single meaningful pattern.
  • Single qubit Parametric Quantum Circuit (PQC) encoding 14 features into a single Ry rotation angle clocked 71% overall accuracy including 78% precision on the majority class. Though it nearly fell off the horse on the minority class with only a 27% recall for >50K earners

Subtracting the Chalkboard Panic from the Science

Before we talk quantum, let’s talk about the hostility which is in this scenario is class imbalance. In my training set of 24,612 samples (after cleaning) approximately 75% of individuals earned ≤$50K and 25% earned >$50K.

This is the kind of landscape that makes naive models look deceptively brilliant. A classifier that does nothing but shout “poor!” at every single data point achieves 75% accuracy without ever breaking a sweat. That is definitely not intelligence but kind of a a broken clock being right twice a day.

A classifier that does nothing but shout “poor!” at every single data point achieves 75% accuracy without ever breaking a sweat. That is definitely not intelligence but kind of a a broken clock being right twice a day.

Now, let’s talk about the quantum side of the corral. A Parametric Quantum Circuit (PQC) is the quantum analog of a neural network layer which is basically a circuit with tunable gate parameters that can be optimized against a loss function. In this experiment, I kept the circuit as minimal as physically possible with one qubit, one classical bit and one Ry rotation gate. The Ry(θ) gate rotates the qubit state on the Bloch sphere around the Y-axis by angle θ. At θ = 0, the qubit stays in state |0⟩. At θ = π, it flips to |1⟩. Anywhere in between and you’re in superposition which means the qubit is genuinely both 0 and 1 simultaneously until any measurement collapses it.

The Ry gate is basically a member of the continuous rotation family, defined as Ry(θ) = exp(-iθY/2), where Y is the Pauli-Y matrix. This means it maps naturally to probability amplitudes which is exactly why it’s the workhorse of variational quantum eigensolvers (VQE) and QAOA ansatz designs. The fact that I am abusing it as a binary income predictor would make a quantum chemist wince but science is about exploration.

The real innovation in quantum machine learning is the feature map and the strategy for encoding classical data into quantum states. I was reading this somewhere that in 2019, Havlíček et al. showed in nature that quantum kernel methods using feature maps that are hard to simulate classically could in principle provide quantum advantage for machine learning. My single-angle encoding strategy is about as far from that as a rickety fence is from the Hoover Dam but it’s a meaningful starting point for understanding why encoding strategy is the whole game.

How I Set Up the Ranch (Implementation)

I pulled the adult.csv dataset via kagglehub and loaded it into a pandas DataFrame (32,561 rows and 15 columns with the usual frontier chaos of missing values hiding as ? in workclass, occupation, and native.country.

Colab Notebook

The data cleaning pipeline was pragmatic(I like to think that) I dropped rows where workclass was missing (those missing values felt too structural to impute honestly), and used mode imputation from the training set for occupation and native.country. Critically, I fit the mode on train only and applied it to test (no data leakage allowed!).

import pandas as pd
from sklearn.model_selection import train_test_split

# Split the DataFrame into training and testing sets
# Using a 80/20 split, with a random state for reproducibility
train, test = train_test_split(df, test_size=0.2, random_state=42)

After an 80/20 train-test split with random_state=42, I ran LabelEncoder across all object-type columns which includes workclass, education, marital.status, occupation, relationship, race, sex, native.country and the target income.

Shape of training data: (26048, 15)
Shape of test data: (6513, 15)

Before letting my model make any serious life decisions, I had to make sure all the features were playing fair. Some of them were clearly overachievers showing up with big numbers and intimidating the rest. THe best equalizer for this purpose is definitely MinMaxScaler. It politely but firmly told every feature to calm down and fit within the [0, 1] range. All 14 features complied without protest and were neatly scaled to values between 0.0 and 1.0 in the training data. No feature felt superior, no feature felt left out. Just a perfectly normalized and well behaved dataset ready for judgment.

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

# 'fit' learns the min and max values for each feature in the training data.
scaler.fit(train[numerical_cols])

# 'transform' applies the scaling to the training and testing data.
train[numerical_cols] = scaler.transform(train[numerical_cols])
test[numerical_cols] = scaler.transform(test[numerical_cols])

Before riding into quantum territory, I established two classical baselines:

Baseline 1: Pure Random Classifier

def classify(input_dummy):
  return random.randint(0, 1)

Ran it against all 24,612 training samples.

Got 12,436 correct predictions out of 24,612–51% accuracy. Exactly what the laws of probability ordered. A coin toss with extra steps.

12436 correct predictions out of 24612, Accuracy 51 %

Baseline 2: Weighted Hypocrite Classifier:

def classify_hypocrite_weighted(adult, weight):
  # The formula ensures the result is between 0 and 1 before rounding
  # and the weight biases this value.
  return round(min(1, max(0, weight * 0.5 + random.uniform(0,1))))

With bias_weight = -1, the expression (-1 * 0.5) + random.uniform(0, 1) produces values between -0.5 and 0.5, which round() mostly maps to 0. This makes the classifier systematically predict the majority class.

Result: 18,457 correct out of 24,612 which has 75% accuracy. Impressive number. Zero intelligence. The hypocrite earned its name.

18457 correct predictions out of 24612, Accuracy 75 %

If you are looking at this carefully I am sure you must be asking: “Why it’s Working with Higher Accuracy (75%)”. You will be surprised, there are more than few ways to answer your coonundrum:

  1. Class Imbalance: Approximately 75% of the individuals in the training data have an ‘income’ of 0.0 (which I infer means <=50K), while only about 25% have an ‘income’ of 1.0 (>50K). This is a significant class imbalance.

2. Weighted Hypocrite Classifier’s Bias: The ‘Weighted Hypocrite Classifier’ was configured with a bias_weight of -1. Let’s break down its #classify_hypocrite_weighted function:

weight 0.5 becomes -1 0.5 = -0.5. random.uniform(0,1) which adds a random value between 0 and 1 to this -0.5. This means the value before rounding will generally fall between -0.5 and 0.5. When you round() these numbers the values from -0.5 up to 0.499…. will all round to 0. Only 0.5 itself would round to 1. This heavily biases the classifier to predict 0 in most cases. That’s what bias means! I know right! Essentially, this classifier is designed to mostly predict the 0 class.

3. Exploiting the Majority Class: Because the model is heavily biased towards predicting 0, and 0 is the actual outcome for 75% of the data, the classifier correctly predicts the majority class a large proportion of the time. This directly leads to its 75% accuracy. It’s essentially saying, “Most people make <=50K, so I’ll just guess that most of the time.” This strategy is effective for overall accuracy in imbalanced datasets but doesn’t necessarily mean the model has learned any meaningful patterns to distinguish between the two income groups.

The high accuracy of 75% is a direct consequence of the classifier’s strong bias towards predicting the majority class (<=50K), which makes up 75% of the data. While this gives a seemingly good accuracy number, it highlights the challenge of evaluating models on imbalanced datasets, as a high overall accuracy might mask poor performance on the minority class. This serves as a valuable baseline to understand that any more complex model we build should not just match, but significantly surpass this ‘majority-class-guessing’ performance, especially for predicting the less frequent >50K income group.

Parametrized Quantum Circuit

a random circuit achieving Bell state

a random circuit achieving Bell state

Now, this is the time I will introduce the quantum circuit. My pqc_classify function encodes a row of train_features — a 14-dimensional vector of MinMax-scaled values into a single rotation angle:

def quantum_pqc_classify(backend, feature_vector):
  # 'feature_vector' will be a pandas Series corresponding to one row of train_features.
  # For a 1-qubit QPQC, we need to encode the entire feature vector into a single parameter.
  # A simple (though not optimal) way is to sum the features and scale this sum to a rotation angle.
  # Assuming features are scaled between 0 and 1, the sum will be between 0 and num_features.
  # We map this sum to an angle between 0 and pi for an Ry gate.
  num_features = len(feature_vector) # Get the number of features for scaling
  scaled_sum_features = feature_vector.sum() # Sum all feature values in the row

  # Normalize the sum to be between 0 and 1, then scale to an angle between 0 and pi.
  # This mapping is arbitrary and can be optimized.
  rotation_angle = scaled_sum_features * (np.pi / num_features) if num_features > 0 else 0

  qc = QuantumCircuit(1, 1)
  qc.ry(rotation_angle, 0) # Apply Y-rotation based on the encoded feature
  qc.measure(0, 0) # Measure qubit 0 into classical bit 0

  job = backend.run(qc)
  result = job.result()
  counts = result.get_counts()
  # Extract the dominant outcome (0 or 1) and return it as an int
  # max(counts, key=counts.get) gives the key ('0' or '1') with the highest count
  return int(max(counts, key=counts.get))

Since all 14 features are scaled to [0, 1], their sum falls between 0 and 14. Dividing by num_features (14) and multiplying by π maps that sum to an angle between 0 and π. I then built a fresh QuantumCircuit(1, 1) per sample, apply qc.ry(rotation_angle, 0) and measure into the classical bit. I ran it on AerSimulator, and return int(max(counts, key=counts.get)) which will output the dominant measurement outcome. Brutally simple. But it runs.

I also initialized a single qubit to state [0, 1] (pure |1⟩) and confirmed the statevector via result.get_statevector() before moving on to the superposition test with initial_state = [1/sqrt(2), 1/sqrt(2)] — which produced the expected roughly 50/50 measurement counts histogram between |0⟩ and |1⟩. The quantum machinery was working correctly. Now I just had to point it at something useful.

Results: What the Dust Settled On

Running pqc_classify across all 24,612 training samples took close to two minutes on Colab. That’s about 5 milliseconds per sample with each one spawning a full quantum circuit, compiling it for AerSimulator and executing the circuit. For production, this would be an absolute disaster but in this scenario for a research proof of concept, it’s the price of admission.

Here’s what the classification_report spat out:

Overall accuracy: 71%. Which sounds decent until I realized the brain-dead hypocrite hit 75%. On the surface, the PQC looks like it lost a horse race to a loaded coin.

Though, here’s where it gets genuinely interesting. The random classifier produced 78% precision on the majority class (income = 0.0) while simultaneously achieving 86% recall which means it was actually finding the ≤$50K earners, not just accidentally stumbling on them. Meanwhile, for the minority class (income = 1.0), precision was 39% and recall was a rough 27%. F1 of 0.32 for the >$50K class tells the honest story: the single-angle Ry encoding is not capturing the complexity needed to distinguish high earners from the crowd.

And that’s exactly what I expected and exactly why it matters that we measured it. The failure mode is instructive. When all 14 features collapse into a single scalar sum that then maps to one rotation angle, you’re throwing away almost all the information that makes individual samples distinguishable. A person with high education, high capital gains, and many hours worked per week will have a similar feature sum to someone with moderate values across the board. The Ry gate cannot know the difference. It’s like trying to describe a landscape by its total elevation — you lose every mountain and every valley.

What genuinely surprised me is the the PQC did beat the pure random classifier by a meaningful margin (71% vs. 51%), and it achieved that without any training or parameter optimization. The rotation angle encoding, crude as it is, creates enough signal to do better than chance. That’s not nothing. The Ry gate is quietly doing the right thing for the majority class. When the feature sum is small, the rotation stays near 0 and the qubit measures as |0⟩. The problem is entirely in the encoding, not in the quantum hardware.

PQC did beat the pure random classifier by a meaningful margin (71% vs. 51%). The problem is entirely in the encoding, not in the quantum hardware.

🤠 Time for a nice cowboy wisdom: A biased coin beats a fair coin when the trail is lopsided but only a trained circuit will get you all the way to the other side of the canyon.

I can keep going but lets conclude this experiment till here

A 1-qubit PQC with no trainable parameters and a sum-to-angle feature encoding is not a serious quantum machine learning model. It is a proof-of-concept canoe on a river that requires a battleship. It underperformed a biased random guesser by 4% points overall, and it nearly ignored a quarter of the dataset by failing to recall >$50K earners but I am not embarrassed about running it besides I am energized by what it revealed. The quantum infrastructure worked perfectly. AerSimulator executed 24,612 quantum circuits without breaking a sweat (well, in two minutes of wall time, but still!!). The Ry gate encoded meaningful signal. The real bottleneck is the encoding strategy which means the fix is architectural and not fundamental. Quantum Machine Learning isn’t limited by the understanding and manipulating just the qubits but actually limited by our creativity in mapping classical data into quantum state space.

Still need to figure out when quantum circuits genuinely beat classical models and under what conditions. This experiment is a brutally honest data point in that conversation. If we are going to put a quantum circuit on the census data, we better bring a feature map worth its salt because the data doesn’t care how exotic your hardware is. It only cares whether you can separate signal from noise.

The qubit is willing. Now we just need a better saddle. Mic drip!! :)


메타데이터
post_id
4b1e1b8ffabe
slug
riding-the-quantum-range-teaching-a-single-qubit-to-predict-your-paycheck-4b1e1b8ffabe
url
https://medium.com/@siddharthuncc/riding-the-quantum-range-teaching-a-single-qubit-to-predict-your-paycheck-4b1e1b8ffabe
canonical_url
https://medium.com/@siddharthuncc/riding-the-quantum-range-teaching-a-single-qubit-to-predict-your-paycheck-4b1e1b8ffabe
author_url
https://medium.com/@siddharthuncc
status
ok
fetched_at
2026-06-09 15:37:30