Overfitting vs Underfitting

Python · Machine Learning (Scikit-Learn)

Theory

An underfit model is too simple to capture the pattern, so it scores poorly on both training and test data (high bias): a depth-1 tree that asks only one question is an example. An overfit model is so flexible that it memorises noise in the training data, scoring near-perfect on training but clearly worse on test data (high variance): an unlimited-depth tree is the classic case. The goal is the middle, where the test score is highest and close to the training score.

The practical check is to compare train and test (or cross-validated) scores as complexity grows. A big gap means overfitting: simplify the model (smaller max_depth, larger min_samples_leaf, stronger regularisation such as a lower C), add more data or use an ensemble. Both scores low means underfitting: use a more flexible model or better features.

Why we use it

Generalising to new data is the whole point of a model. Recognising the two failure modes from train and test scores tells you whether to make the model simpler or more powerful, instead of guessing.

When to use it

Check train vs test scores every time you fit a model, and plot them across a complexity setting (depth, k, C) when tuning. Use cross-validation for the comparison when data is small, so one lucky split does not mislead you.

How it works

  1. Fit the model; compute train and test scores
  2. Are both scores low? Yes: Underfitting: more complex model or better features. No: Continue.
  3. Train much higher than test? Yes: Overfitting: simplify, regularise or add data. No: Good fit.
  4. Repeat across complexity settings (depth, k, C)
  5. Choose the setting with the best test / CV score

Syntax

train_score = model.score(X_train, y_train)
test_score = model.score(X_test, y_test)
# gap = train_score - test_score
from sklearn.model_selection import validation_curve

Example

for d in [1, 3, None]:
    t = DecisionTreeClassifier(max_depth=d).fit(X_train, y_train)
    print(d, t.score(X_train, y_train), t.score(X_test, y_test))

Key points

Python topics

Getting Started

Variables & Data Types

Operators

Strings

Lists

Tuples

Sets

Dictionaries

Control Flow

Loops

Functions & OOP

Working with Data

Tooling & Errors

File Handling

Exception Handling

NumPy Library

Pandas Basics

Data Cleaning

Combining DataFrames (SQL Joins & Unions)

GroupBy & SQL-Style Analytics

Reshaping & Workflow

Data Visualization

Machine Learning (Scikit-Learn)

Advanced Python & AI

T
Tech Town
Log InSign Up Free
Home SQL Python DSA Power BI Snowflake Databricks Spark Gen AI Practice Problems Contest Blog

Python for Data Analysts

From basics to business insights — the complete step-by-step Python roadmap. Click any topic in the sidebar to open it right here.

{{ sectionCount }}
Sections
{{ topicCount }}
Topics
Free
Forever
Hands-on practice Practice Python Online 141 Python questions for data analysts — strings, records, dates, statistics and regex — with hidden tests and instant verdicts. Start practising →
Section {{ sec.num }}

{{ sec.label }}

Python  /  {{ current.sectionLabel }}  /  {{ current.name }}

{{ current.name }}

Theory

{{ current.def }}

Why we use it

{{ rich.why }}

When to use it

{{ rich.when }}

Diagram

{{ rich.dg.caption }}

{{ tb.title }}
{{ c.v }}
{{ rich.dg.op }}
➜
{{ rich.dg.output.title }}
{{ c.v }}
{{ nd.label }}
{{ nd.sub }}
{{ nd.label }}
{{ nd.sub }}
{{ rich.dg.left.title }}
{{ it }}
{{ rich.dg.right.title }}
{{ it }}
Flowchart — how it works
{{ nd.text }}
{{ nd.text }}
◇ {{ nd.text }}
Yes → {{ nd.yes }}
No → {{ nd.no }}
Syntax
{{ current.syntax }}
Example
{{ current.example }}
▶ Try It Live — runs real Python 3.12 in your browser (first run loads the engine)
{{ liveOutput }}
{{ liveError }}
Key Points — click to check off as you learn
  • {{ pt.mark }} {{ pt.text }}

Share this topic