Machine learning models are powerful, but sometimes they produce predictions that break human intuition.
Imagine this: you’re predicting house prices. A 2,000 sq. ft. house is predicted cheaper than a 1,500 sq. ft. home. Sounds unsuitable, right?
That is where monotonicity constraints step in. They be certain that models follow the logical business rules we expect.
Let’s follow two colleagues, Alan and Aida, on their journey to find why monotonicity matters in machine learning.
The Story: Alan & Aida’s Discovery
Alan is a practical engineer. Aida is a principled scientist. Together, they’re constructing a house price prediction model.
Alan proudly shows Aida his model results:
“Look! R² is great, the error is low. We’re able to deploy!”
Aida takes the model out for testing:
- For a house with 1500 sq ft → Model predicts $300,000
- For a house with 2000 sq ft → Model predicts $280,000 😮
Aida frowns as she looks on the predictions:
“Wait a second… Why is that this 2,000 sq. ft. home predicted cheaper than a 1,500 sq. ft. home? That doesn’t make sense.”
Alan shrugs:
“That’s since the model found noise within the training data. It’s not at all times logical. But, the accuracy is sweet overall. Isn’t that enough?”
Aida shakes her head:
“Not likely. A trustworthy model must not only be accurate but in addition follow logic people can trust. Customers won’t trust us if greater homes sometimes look cheaper. We’d like a guarantee. This can be a monotonicity problem.”
And similar to that, Alan learns his next big ML lesson: metrics aren’t every little thing.
What’s Monotonicity in ML?
Aida explains:
“Monotonicity means predictions move in a consistent direction as inputs change. It’s like telling the model: as square footage goes up, price should never go down. We call it Monotone increasing. Or, as one other example, as a house age gets older, predicted prices mustn’t go up. We call this Monotone decreasing.”
Alan concludes that:
“So monotonicity here matters since it:
- Aligns with business logic, and
- Improves trust & interpretability.”
Aida nodded:
- “Yes, Plus, it helps meet fairness & regulatory expectations.”
Visualizing the Problem
Aida creates a toy dataset in Pandas to point out the issue:
import pandas as pd
# Example toy dataset
data = pd.DataFrame({
"sqft": [1200, 1500, 1800, 2000, 2200, 2250],
"predicted_price": [250000, 270000, 260000, 280000, 290000, 285000] # Notice dip at 1800 sqft and 2250 sqft
})
# Sort by sqft
data_sorted = data.sort_values("sqft")
# Check differences in goal
data_sorted["price_diff"] = data_sorted["predicted_price"].diff()
# Find monotonicity violations (where price decreases as sqft increases)
violations = data_sorted[data_sorted["price_diff"] < 0]
print("Monotonicity violations:n", violations)
Monotonicity violations:
sqft price price_diff
2 1800 260000 -10000.0
5 2250 285000 -5000.0
After which she plots the violations:
import matplotlib.pyplot as plt
plt.figure(figsize=(7,5))
plt.plot(data["sqft"], data["predicted_price"], marker="o", linestyle="-.", color="steelblue", label="Predicted Price")
# Highlight the dips
for sqft, price, price_diff in violations.values:
plt.scatter(sqft, price, color="red", zorder=5)
plt.text(x=sqft, y=price-3000, s="Dip!", color="red", ha="center")
# Labels and title
plt.title("Predicted House Prices vs. Square Footage")
plt.xlabel("Square Footage (sqft)")
plt.ylabel("Predicted Price ($)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.legend()
Aida points to the Dips: “Here’s the issue: 1,800 sq. ft. is priced lower than 1,500 sq. ft. and a couple of,250 sq. ft. is priced lower than 2,200 sq. ft.”
Fixing It with Monotonicity Constraints in XGBoost
Alan retrains the model and sets a monotonic increasing constraint on and monotonic decreasing constraint on .
This forces the model to at all times
- increase (or stay the identical) when increases given all other features are fixed.
- decrease (or stay the identical) when house age increases given all other features are fixed.
He uses XGBoost that makes it easy to implement monotonicity:
import xgboost as xgb
from sklearn.model_selection import train_test_split
df = pd.DataFrame({
"sqft": [1200, 1500, 1800, 2000, 2200],
"house_age": [30, 20, 15, 10, 5],
"price": [250000, 270000, 280000, 320000, 350000]
})
X = df[["sqft", "house_age"]]
y = df["price"]
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, random_state=42)
monotone_constraints = {
"sqft": 1, # Monotone increasing
"house_age": -1 # Monotone decreasing
}
model = xgb.XGBRegressor(
monotone_constraints=monotone_constraints,
n_estimators=200,
learning_rate=0.1,
max_depth=4,
random_state=42
)
model.fit(X_train, y_train)
print(X_test)
print("Predicted price:", model.predict(X_test.values))
sqft house_age
1 1500 20
Predicted price: [250000.84]
Alan hands over the brand new model to Aida. “Now the model respects domain knowledge. Predictions for larger houses won't ever dip below smaller ones.”
Aida tests the model again:
- 1500 sq ft → $300,000
- 2000 sq ft → $350,000
- 2500 sq ft → $400,000
Now she sees a smoother plot of house prices vs square footage.
import matplotlib.pyplot as plt
data2 = pd.DataFrame({
"sqft": [1200, 1500, 1800, 2000, 2200, 2250],
"predicted_price": [250000, 270000, 275000, 280000, 290000, 292000]
})
plt.figure(figsize=(7,5))
plt.plot(data2["sqft"], data2["predicted_price"], marker="o",
linestyle="-.", color="green", label="Predicted Price")
plt.title("Monotonic Predicted House Prices vs. Square Footage")
plt.xlabel("Square Footage (sqft)")
plt.ylabel("Predicted Price ($)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.legend()

Aida: “Perfect! When homes are of the identical age, a bigger size consistently results in a better or equal price. Conversely, homes of the identical square footage will at all times be priced lower in the event that they are older.”
Alan: “Yes — we gave the model that align with domain knowledge.”
Real-World Examples
Alan: what other domains can profit from monotonicity constraints?
Aida: Anywhere customers or money are involved, monotonicity can impact trust. Some domains where monotonicity really matters are:
- House pricing → Larger homes mustn't be priced lower.
- Loan approvals → Higher income mustn't reduce approval probability.
- Credit scoring → Longer repayment history mustn't lower the rating.
- Customer lifetime value (CLV) → More purchases shouldn’t lower CLV predictions.
- Insurance pricing → More coverage mustn't reduce the premium.
Takeaways
- Accuracy alone doesn’t guarantee trustworthiness.
- Monotonicity ensures predictions align with common sense and business rules.
- Customers, regulators, and stakeholders are more likely to just accept and use models which can be each accurate and logical.
As Aida reminds Alan:
“Make models not only smart, but sensible.”
Closing Thoughts
Next time you construct a model, don’t just ask: Also ask:
Monotonicity constraints are one in every of many tools for designing trustworthy ML models — alongside explainability, fairness constraints, and transparency.
. . .
Thanks for reading! I often share insights on practical AI/ML techniques—let’s connect on LinkedIn for those who’d wish to proceed the conversation.