Python Training a Model

In the last lesson, Scikit-Learn Basics, you learned the create, fit, predict pattern. So you have the recipe. Now let’s actually cook. This is the lesson where you build a complete, working machine learning model from start to finish: load real data, split it the right way, train the model, and make predictions. By the end you will have trained a model that can tell flower types apart, and you will understand every line of how it happened.

🤔 Why split the data first?

Before we train, there is one step that beginners always want to skip, and it is the most important one: splitting the data into a training set and a test set.

Think about studying for an exam. If the teacher gives you the exact exam questions to practice with, you will score full marks. But that does not prove you learned anything. It only proves you memorized those questions. The real test is questions you have not seen.

A model is the same:

  • The training set is the data the model studies and learns from.
  • The test set is data the model never sees during training, kept aside to check it fairly afterward.

If you test a model on the same data it trained on, of course it scores high, it already saw the answers. Splitting first is the only way to know if your model truly learned the pattern or just memorized.

🪓 Splitting with train_test_split

scikit-learn gives you a tool that splits your data for you, randomly and cleanly: train_test_split. You hand it your features and labels, and it gives back four pieces.

This loads the flower dataset and splits it:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
data = load_iris()
X = data.data # the features (flower measurements)
y = data.target # the labels (flower type)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print("Training examples:", len(X_train))
print("Test examples:", len(X_test))

Output

Training examples: 120
Test examples: 30

Let’s read the important parts:

  • It returns four things: features and labels for training (X_train, y_train), and features and labels for testing (X_test, y_test).
  • test_size=0.2 means keep 20% of the data for testing, so 30 of the 150 flowers. The other 80% (120 flowers) go to training.
  • random_state=42 fixes the random shuffle so you get the same split every time you run it. The exact number does not matter; using any fixed number just makes your results repeatable.

Note

Splitting 80% for training and 20% for testing is a common, sensible default. You want most of the data for learning, but enough held back to test on fairly.

🏋️ Training the model

Now the part you came for. We create a model and fit it on the training data only. We will use a model called DecisionTreeClassifier, which learns simple yes/no questions to sort things into groups. It is easy to picture and works well here.

This trains the model on the training set:

from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)
print("Model trained!")

Output

Model trained!

Two lines did the learning:

  • DecisionTreeClassifier(random_state=42) creates the model, still empty. The random_state again just makes the result repeatable.
  • model.fit(X_train, y_train) is the training step. The model studies the 120 training flowers and learns which measurements point to which flower type.

Notice we fit on X_train and y_train, never the test set. The test flowers stay hidden until we are ready to check the model. That is the whole point of the split.

🔮 Making predictions

A trained model is only useful if it can predict. We call .predict on the test flowers, the ones it has never seen, and compare its guesses to the real answers.

This predicts the types of the test flowers:

predictions = model.predict(X_test)
print("Model predicted:", predictions[:5])
print("Real answers: ", y_test[:5])

Output

Model predicted: [1 0 2 1 1]
Real answers: [1 0 2 1 1]

The numbers 0, 1, and 2 stand for the three flower types (setosa, versicolor, virginica). Looking at the first five, the model’s predictions match the real answers exactly. So on these flowers it has never seen before, it got them right. That is a model that actually learned the pattern, not just memorized.

You can also predict for a brand new flower you make up, by giving its four measurements:

# A new flower: [sepal length, sepal width, petal length, petal width]
new_flower = [[5.1, 3.5, 1.4, 0.2]]
result = model.predict(new_flower)
print("Predicted type:", data.target_names[result[0]])

Output

Predicted type: setosa

Here we gave four measurements and the model said “setosa”. result[0] is the predicted number, and data.target_names turns that number into the readable name. This is the real payoff: a new input goes in, a useful answer comes out.

🖥️ The whole thing together

Here is the complete program, from loading data to predicting, in one place. This is the full shape of a machine learning project.

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 1. Load the data
data = load_iris()
X, y = data.data, data.target
# 2. Split into training and test sets
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. Create and train the model
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)
# 4. Predict on the test set
predictions = model.predict(X_test)
print("First 5 predictions:", predictions[:5])
print("First 5 real answers:", y_test[:5])

Output

First 5 predictions: [1 0 2 1 1]
First 5 real answers: [1 0 2 1 1]

Look at how short it is. Load, split, create, fit, predict. Four ideas, a dozen lines, and you have a working classifier. Every supervised learning project you build will follow this same skeleton, just with different data and a different model.

🌍 The steps in one table

Here is the flow you just built, summarized.

Step The code
Load the data load_iris()
Split it train_test_split(X, y, test_size=0.2)
Create the model DecisionTreeClassifier()
Train it model.fit(X_train, y_train)
Predict model.predict(X_test)

⚠️ Common Mistakes

A few traps when training:

  • Training on all the data with nothing held back. Then you have no honest way to test the model. Always split first.
  • Fitting on the test set. Never call .fit with X_test. The test data must stay unseen during training, or the test means nothing.
# ❌ Never train on the test data
model.fit(X_test, y_test)
# ✅ Train on the training set, keep the test set for checking
model.fit(X_train, y_train)
  • Forgetting that predictions come back as numbers. For the flowers, 0, 1, 2 are codes. Use target_names to turn them into readable labels.

✅ Best Practices

Habits for training models:

  • Always split before you train, and keep the test set untouched until you check the model.
  • Set a random_state so your split and results stay the same each run. It makes debugging far easier.
  • Start with a simple model like a decision tree. Get the whole flow working before trying anything fancy.
  • Keep features in X and labels in y, and use the _train and _test naming. It keeps a busy script readable.

🧩 What You’ve Learned

✅ You split data into a training set (to learn from) and a test set (to check on fairly) before training.

train_test_split(X, y, test_size=0.2) does the split, returning X_train, X_test, y_train, y_test.

✅ You create a model, then model.fit(X_train, y_train) teaches it on the training data only.

model.predict(X_test) makes predictions on unseen data, which you can compare to the real answers.

✅ Every supervised project follows the same skeleton: load, split, create, fit, predict.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Why must you split data into training and test sets before training?

    Why: Testing on data the model already trained on is like studying the exact exam questions. The held-back test set checks whether it really learned.

  2. 2

    What does test_size=0.2 in train_test_split mean?

    Why: test_size=0.2 sets aside 20% of the data as the test set, leaving the other 80% for training the model.

  3. 3

    Which data should you pass to model.fit()?

    Why: You fit on the training set only. The test set must stay unseen during training, or it cannot fairly check the model afterward.

  4. 4

    What is the purpose of setting random_state=42?

    Why: random_state fixes the random shuffling so you get the same split and results every run. Any fixed number works; it just makes things repeatable.

🚀 What’s Next?

You have trained a model and seen it predict correctly on a few flowers. But “looks right on five” is not a real measure. How good is it on all 30 test flowers, as a number? Next we learn to measure a model properly with accuracy and other scores.

Model Evaluation

Share & Connect