Article
Train your first machine learning model in 20 lines of Python
No maths degree required. Load data, split it, fit a model, check the score — the four steps every scikit-learn project uses, explained line by line.
On this page0%
- What you need
- The 20 lines
- Step 1 — Understand X and y
- Step 2 — Split before you look
- Step 3 — Fit the model
- Step 4 — Score honestly
- Step 5 — See what the model learned
- Step 6 — Use it on your own CSV
- Step 7 — Save and reload the model
- Common problems (and fixes)
- What you learned
- FAQ
- How do I train my first machine learning model in Python?
- What do X and y mean in scikit-learn?
- Which model should a beginner start with?
- Why do I need train_test_split?
- What accuracy is good enough?
- Next reading on Sythra Articles
Every machine learning project — recommendation engines, fraud detection, your first homework assignment — follows the same four steps:
- Load data
- Split it into training and testing parts
- Fit a model on the training part
- Score it on the testing part
That is it. The rest is detail. Here is the whole thing in twenty lines, then an explanation of every one.
What you need
python -m pip install scikit-learn pandas
The 20 lines
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
data = load_wine()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, predictions))
Run it. You should see accuracy around 0.97. You just trained a model that identifies which of three vineyards a wine came from, using its chemical measurements.
Step 1 — Understand X and y
X, y = data.data, data.target
X holds the featuresThe input columns the model learns from — alcohol content, colour intensity, magnesium, and ten more measurements. Each row is one wine.
y holds the labelsThe answer you want the model to predict — which vineyard, as 0, 1 or 2.
Capital X and lowercase y is a convention worth keeping: X is a table (many rows, many columns), y is a single column.
Look at the actual shape before doing anything else:
print("Features:", X.shape) # (178, 13)
print("Labels:", y.shape) # (178,)
print("Feature names:", data.feature_names[:5])
print("Classes:", data.target_names)
178 wines, 13 measurements each. Small, clean, perfect for learning.
Step 2 — Split before you look
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
Three arguments matter:
test_size=0.2— keep 20% aside. The model never sees it during training.random_state=42— makes the split reproducible. Without it you get different numbers every run and cannot tell whether a change helped.stratify=y— keeps the class proportions the same in both parts. Skip it on imbalanced data and your test set may be missing an entire class.
Why hold data back at all? Because a model that has seen an answer can simply repeat it. Testing on training data measures memory, not learning. More on the ways this goes wrong in train/test split and data leakage.
Step 3 — Fit the model
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X_train, y_train)
A random forestMany small decision trees voting together on the answer builds 200 decision trees, each on a slightly different slice of the data, then takes a majority vote. It is the best default for tabular data: it handles different scales, ignores useless columns, and rarely needs tuning.
fit is where learning happens. Every scikit-learn model has the same three methods:
| Method | Does |
|---|---|
.fit(X, y) | Learn from the data |
.predict(X) | Guess labels for new rows |
.score(X, y) | Return accuracy in one call |
Learn those three and you can drive any of the hundred-plus models in the library.
Step 4 — Score honestly
predictions = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, predictions))
Accuracy is the fraction of test rows predicted correctly. It is a fine starting metric — but only when your classes are roughly balanced. On data that is 99% one class, a model that always guesses that class scores 99% and is useless. That is why precision and recall exist.
Always ask what a lazy baseline would score:
from sklearn.dummy import DummyClassifier
baseline = DummyClassifier(strategy="most_frequent").fit(X_train, y_train)
print("Baseline:", baseline.score(X_test, y_test))
If your fancy model barely beats the dummy, it has learned nothing.
Step 5 — See what the model learned
Random forests can tell you which measurements mattered:
import pandas as pd
importance = pd.Series(
model.feature_importances_, index=data.feature_names
).sort_values(ascending=False)
print(importance.head(5))
Usually proline, flavanoids and color_intensity dominate. This one line often teaches you more about your problem than the accuracy score does — and it is how you spot a leaked column, where one feature has suspiciously high importance because it secretly contains the answer.
Step 6 — Use it on your own CSV
The same four steps, with a real file:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
df = pd.read_csv("my_data.csv")
df = df.dropna()
y = df["target"]
X = pd.get_dummies(df.drop(columns=["target"]), drop_first=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X_train, y_train)
print("Accuracy:", model.score(X_test, y_test))
Two additions handle real data: dropna() removes rows with holes, and get_dummies turns text categories into numeric columns. If either raises an error, the fixes are in could not convert string to float.
Step 7 — Save and reload the model
import joblib
joblib.dump(model, "wine_model.joblib")
loaded = joblib.load("wine_model.joblib")
print(loaded.predict(X_test[:3]))
Training is slow, prediction is fast. Save once, load anywhere — this is exactly how models get into web apps.
Common problems (and fixes)
| Problem | Fix |
|---|---|
could not convert string to float | Encode text columns with pd.get_dummies |
Input contains NaN | df.dropna() or SimpleImputer |
| 100% accuracy | Suspect leakage — a column contains the answer |
| Accuracy near chance | Check that X and y rows still line up |
| Different result every run | Set random_state everywhere |
What you learned
- The four-step shape of every scikit-learn project
- What
Xandymean and why the split happens first fit,predict,score— the interface of every model- Why a dummy baseline is required context for any score
- How feature importance shows what the model actually used
FAQ
How do I train my first machine learning model in Python?
Load a dataset into X (features) and y (labels), split with train_test_split, call .fit(X_train, y_train) on a model such as RandomForestClassifier, then measure .score(X_test, y_test) on the held-out data.
What do X and y mean in scikit-learn?
X is the table of input features, one row per example. y is the single column of answers you want to predict. The capital letter marks a two-dimensional table and lowercase a one-dimensional column.
Which model should a beginner start with?
RandomForestClassifier for tabular data. It works without scaling, tolerates irrelevant columns, and gives strong results with default settings.
Why do I need train_test_split?
A model can memorise data it has already seen, so scoring on training data measures memory rather than learning. Holding 20% back gives you an honest estimate of performance on new data.
What accuracy is good enough?
It depends entirely on your baseline. Compare against DummyClassifier — if your model barely beats always-guess-the-most-common-class, it has not learned anything useful.