Toolmingo
Guides19 min read

Machine Learning Tutorial for Beginners (2025): Learn ML Step by Step

Complete machine learning tutorial for beginners. Learn supervised and unsupervised learning, build real ML models with Python and scikit-learn, from zero to deployed model.

Machine learning lets computers learn from data and make predictions without being explicitly programmed. This tutorial takes you from zero to building real ML models in Python, with no prior ML experience required.

What you'll learn

Topic What you'll be able to do
Core concepts Understand what ML is and how it works
Types of ML Choose the right algorithm for your problem
Python ML stack Use NumPy, pandas, scikit-learn
Data preprocessing Clean and prepare data for training
Supervised learning Train regression and classification models
Unsupervised learning Cluster data and reduce dimensions
Model evaluation Measure and improve model performance
Real projects Build and deploy working ML models

What is machine learning?

Machine learning is a branch of AI where algorithms learn patterns from data to make predictions or decisions.

Traditional programming vs Machine learning:

Traditional: Rules + Data → Output
Machine Learning: Data + Output → Rules (model)

Classic example: Spam filter

  • Traditional: if email contains "buy now" AND "click here" → spam
  • ML: show 10,000 spam/not-spam emails → model learns the pattern itself
Approach You write Computer learns
Traditional programming Rules
Machine learning Rules (the model)

Types of machine learning

Type How it learns Example
Supervised Labeled examples (input + correct answer) Email spam detection, house price prediction
Unsupervised Unlabeled data, finds patterns Customer segmentation, anomaly detection
Reinforcement Trial and error with rewards Game playing AI, robotics
Semi-supervised Mix of labeled and unlabeled Image labeling with few examples
Self-supervised Creates labels from data itself LLMs, word2vec

90% of practical ML is supervised or unsupervised. Start there.

Supervised learning subtypes

Subtype Output Example algorithms
Regression Continuous number Linear Regression, Random Forest Regressor
Classification Category/label Logistic Regression, Decision Tree, SVM, KNN

Unsupervised learning subtypes

Subtype What it does Example algorithms
Clustering Groups similar data K-Means, DBSCAN, Hierarchical
Dimensionality reduction Compresses features PCA, t-SNE, UMAP
Anomaly detection Finds outliers Isolation Forest, One-class SVM

Setup: Python ML environment

You need Python 3.9+ and four libraries.

Install

pip install numpy pandas scikit-learn matplotlib seaborn

Or with conda:

conda install numpy pandas scikit-learn matplotlib seaborn

Verify

import numpy as np
import pandas as pd
import sklearn
import matplotlib.pyplot as plt

print(f"numpy: {np.__version__}")
print(f"pandas: {pd.__version__}")
print(f"scikit-learn: {sklearn.__version__}")

Core libraries

Library What it does Main use
NumPy Fast numerical arrays Math, matrix operations
pandas Data tables (DataFrames) Loading, cleaning, exploring data
scikit-learn ML algorithms Training, evaluating models
matplotlib Plotting Visualizing data and results
seaborn Statistical plots Correlation heatmaps, distributions

The ML workflow

Every ML project follows this pipeline:

1. Define problem → 2. Collect data → 3. Explore data (EDA)
→ 4. Preprocess → 5. Choose algorithm → 6. Train model
→ 7. Evaluate → 8. Improve → 9. Deploy

Let's walk through each step with real code.


Step 1: Load and explore data

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Load a dataset
df = pd.read_csv("housing.csv")

# First look
print(df.shape)        # rows, columns
print(df.head())       # first 5 rows
print(df.dtypes)       # data types
print(df.describe())   # statistics (mean, std, min, max)
print(df.isnull().sum()) # missing values per column

Key EDA questions:

  • How many rows and columns?
  • Any missing values?
  • What are the data types?
  • What does the target variable look like?
  • Are features correlated?
# Correlation heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(df.corr(), annot=True, fmt=".2f", cmap="coolwarm")
plt.title("Feature Correlations")
plt.show()

# Distribution of target variable
df["price"].hist(bins=50)
plt.xlabel("Price")
plt.ylabel("Count")
plt.show()

Step 2: Preprocess data

Raw data is rarely ready for training. You need to:

Handle missing values

# Check missing
print(df.isnull().sum())

# Strategy 1: Drop rows with missing values
df_clean = df.dropna()

# Strategy 2: Fill with mean/median/mode
df["age"].fillna(df["age"].median(), inplace=True)
df["category"].fillna(df["category"].mode()[0], inplace=True)

# Strategy 3: scikit-learn imputer (better for pipelines)
from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy="median")
df[["age", "income"]] = imputer.fit_transform(df[["age", "income"]])
Strategy Use when
Drop rows Few missing values (<5%), data is plentiful
Fill mean Numerical features, no heavy outliers
Fill median Numerical features, outliers present
Fill mode Categorical features
Model-based imputation Many missing, important feature

Encode categorical features

ML algorithms work with numbers, not text.

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import pandas as pd

# Label encoding (ordinal categories: small < medium < large)
le = LabelEncoder()
df["size_encoded"] = le.fit_transform(df["size"])

# One-hot encoding (nominal categories: red, blue, green)
df_encoded = pd.get_dummies(df, columns=["color"], drop_first=True)

# Or with scikit-learn
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(sparse_output=False, drop="first")
color_encoded = ohe.fit_transform(df[["color"]])
Encoding Use when Example
Label encoding Ordinal (order matters) Small=0, Medium=1, Large=2
One-hot encoding Nominal (no order) Red=[1,0,0], Blue=[0,1,0]
Target encoding High-cardinality cats City → avg price in that city

Scale features

Many algorithms are sensitive to feature scale (KNN, SVM, neural nets).

from sklearn.preprocessing import StandardScaler, MinMaxScaler

# StandardScaler: mean=0, std=1 (best for most algorithms)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)  # use fit from train only!

# MinMaxScaler: range [0, 1] (good for neural nets)
mm_scaler = MinMaxScaler()
X_scaled = mm_scaler.fit_transform(X_train)

Critical: Fit the scaler on training data only. Apply to test data. Never fit on test data — it leaks information.

Split into train/test sets

from sklearn.model_selection import train_test_split

X = df.drop("price", axis=1)  # features
y = df["price"]                # target

X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.2,      # 20% for testing
    random_state=42,    # reproducibility
    stratify=y          # for classification: keeps class ratios
)

print(f"Train: {X_train.shape}, Test: {X_test.shape}")

Step 3: Supervised learning — Regression

Goal: Predict a continuous number.

Linear Regression

The simplest model. Fits a line (or hyperplane) through data.

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# Train
model = LinearRegression()
model.fit(X_train, y_train)

# Predict
y_pred = model.predict(X_test)

# Evaluate
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"RMSE: {rmse:.2f}")
print(f"R² score: {r2:.4f}")  # 1.0 = perfect, 0.0 = baseline

# Coefficients
for name, coef in zip(X.columns, model.coef_):
    print(f"  {name}: {coef:.4f}")

When to use Linear Regression:

  • Target is continuous (price, temperature, salary)
  • Relationship between features and target is approximately linear
  • You need interpretability (which features matter most)

Random Forest Regressor

Ensemble of decision trees. More powerful than linear regression.

from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor(
    n_estimators=100,   # number of trees
    max_depth=None,     # trees grow until pure
    random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"RMSE: {rmse:.2f}, R²: {r2:.4f}")

# Feature importance
importances = pd.Series(
    model.feature_importances_,
    index=X.columns
).sort_values(ascending=False)
print(importances)

Step 4: Supervised learning — Classification

Goal: Predict a category/label.

Logistic Regression

Despite the name, it's for classification. Outputs probabilities.

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report

model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]  # probability of positive class

print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred))

Decision Tree

Splits data by rules. Easy to interpret.

from sklearn.tree import DecisionTreeClassifier, plot_tree

model = DecisionTreeClassifier(
    max_depth=5,          # prevent overfitting
    min_samples_split=10,
    random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

# Visualize the tree
plt.figure(figsize=(20, 10))
plot_tree(model, feature_names=X.columns, class_names=["No", "Yes"],
          filled=True, max_depth=3)
plt.show()

Random Forest Classifier

Often the best out-of-the-box classifier.

from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(
    n_estimators=100,
    random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred))

Support Vector Machine (SVM)

Good for small-to-medium datasets, especially with many features.

from sklearn.svm import SVC

model = SVC(
    kernel="rbf",    # "linear", "poly", "rbf", "sigmoid"
    C=1.0,           # regularization (higher = less regularization)
    probability=True # needed for predict_proba
)
model.fit(X_train_scaled, y_train)  # requires scaled features!
y_pred = model.predict(X_test_scaled)

K-Nearest Neighbors (KNN)

Classifies based on the K closest training examples.

from sklearn.neighbors import KNeighborsClassifier

model = KNeighborsClassifier(n_neighbors=5)
model.fit(X_train_scaled, y_train)  # requires scaled features!
y_pred = model.predict(X_test_scaled)

Algorithm comparison

Algorithm Speed Interpretability Requires scaling Best for
Logistic Regression Fast High Yes Baseline, linear problems
Decision Tree Fast Very high No Interpretable rules
Random Forest Medium Medium No General purpose, best default
SVM Slow (large data) Low Yes Small/medium, high-dim
KNN Slow (prediction) Medium Yes Small datasets
Gradient Boosting Medium Low No Competitions, best accuracy

Step 5: Model evaluation

Regression metrics

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np

mse  = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae  = mean_absolute_error(y_test, y_pred)
r2   = r2_score(y_test, y_pred)

print(f"MSE:  {mse:.2f}")
print(f"RMSE: {rmse:.2f}")  # same units as target
print(f"MAE:  {mae:.2f}")   # robust to outliers
print(f"R²:   {r2:.4f}")    # 1.0 = perfect
Metric Formula Good when
MSE mean((y - ŷ)²) Penalizes large errors heavily
RMSE √MSE Same units as target, interpretable
MAE mean( y - ŷ
1 - SS_res/SS_tot Percentage of variance explained

Classification metrics

from sklearn.metrics import (
    accuracy_score, precision_score, recall_score,
    f1_score, confusion_matrix, roc_auc_score
)

acc  = accuracy_score(y_test, y_pred)
prec = precision_score(y_test, y_pred)
rec  = recall_score(y_test, y_pred)
f1   = f1_score(y_test, y_pred)
auc  = roc_auc_score(y_test, y_prob)

print(f"Accuracy:  {acc:.4f}")
print(f"Precision: {prec:.4f}")
print(f"Recall:    {rec:.4f}")
print(f"F1 Score:  {f1:.4f}")
print(f"ROC-AUC:   {auc:.4f}")

# Confusion matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
            xticklabels=["No", "Yes"],
            yticklabels=["No", "Yes"])
plt.ylabel("Actual")
plt.xlabel("Predicted")
plt.show()
Metric Formula Use when
Accuracy (TP+TN) / total Balanced classes
Precision TP / (TP+FP) False positives are costly (spam filter)
Recall TP / (TP+FN) False negatives are costly (cancer detection)
F1 Score 2×(P×R)/(P+R) Imbalanced classes, balance P and R
ROC-AUC Area under ROC curve Ranking quality, imbalanced classes

The confusion matrix:

                Predicted No    Predicted Yes
Actual No       TN (correct)    FP (false alarm)
Actual Yes      FN (missed)     TP (correct)

Cross-validation

More reliable than a single train/test split.

from sklearn.model_selection import cross_val_score, StratifiedKFold

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

scores = cross_val_score(
    model, X, y,
    cv=cv,
    scoring="f1"   # or "accuracy", "roc_auc", "neg_mean_squared_error"
)

print(f"CV F1: {scores.mean():.4f} ± {scores.std():.4f}")

Step 6: Improve your model

Hyperparameter tuning

Find the best settings for your algorithm.

from sklearn.model_selection import GridSearchCV, RandomizedSearchCV

# Grid search: try all combinations
param_grid = {
    "n_estimators": [100, 200, 300],
    "max_depth": [None, 5, 10, 20],
    "min_samples_split": [2, 5, 10]
}

grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,
    scoring="f1",
    n_jobs=-1,     # use all CPU cores
    verbose=1
)
grid_search.fit(X_train, y_train)

print(f"Best params: {grid_search.best_params_}")
print(f"Best F1: {grid_search.best_score_:.4f}")
best_model = grid_search.best_estimator_

# Random search: faster for large spaces
from scipy.stats import randint
param_dist = {
    "n_estimators": randint(50, 500),
    "max_depth": [None, 5, 10, 15, 20, 30],
    "min_samples_split": randint(2, 20)
}
random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_dist,
    n_iter=50,   # try 50 random combinations
    cv=5,
    scoring="f1",
    random_state=42,
    n_jobs=-1
)
random_search.fit(X_train, y_train)

Overfitting vs underfitting

Problem Symptoms Fix
Underfitting Low training AND test score More features, complex model, less regularization
Overfitting High training, low test score More data, regularization, simpler model, cross-validation
Good fit High training AND test score You're done
# Diagnose with learning curves
from sklearn.model_selection import learning_curve

train_sizes, train_scores, val_scores = learning_curve(
    model, X, y, cv=5, scoring="f1",
    train_sizes=np.linspace(0.1, 1.0, 10)
)

plt.plot(train_sizes, train_scores.mean(axis=1), label="Train")
plt.plot(train_sizes, val_scores.mean(axis=1), label="Validation")
plt.xlabel("Training set size")
plt.ylabel("F1 Score")
plt.legend()
plt.show()

Feature engineering

Often more impactful than algorithm choice.

# Polynomial features
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X_train)

# Log transform (for skewed distributions)
df["log_price"] = np.log1p(df["price"])

# Interaction features
df["rooms_per_person"] = df["rooms"] / df["household_size"]
df["price_per_sqft"]   = df["price"] / df["sqft"]

# Binning continuous features
df["age_group"] = pd.cut(df["age"], bins=[0, 18, 35, 55, 100],
                          labels=["Youth", "Young Adult", "Middle", "Senior"])

Step 7: Unsupervised learning

K-Means Clustering

Groups data into K clusters.

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# Always scale before clustering
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Find optimal K with elbow method
inertias = []
for k in range(1, 11):
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    km.fit(X_scaled)
    inertias.append(km.inertia_)

plt.plot(range(1, 11), inertias, marker="o")
plt.xlabel("Number of clusters (K)")
plt.ylabel("Inertia (within-cluster sum of squares)")
plt.title("Elbow Method")
plt.show()

# Train with chosen K
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
df["cluster"] = kmeans.fit_predict(X_scaled)

# Analyze clusters
print(df.groupby("cluster").mean())

Principal Component Analysis (PCA)

Reduces dimensions while preserving variance.

from sklearn.decomposition import PCA

# Reduce to 2 components for visualization
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

print(f"Explained variance: {pca.explained_variance_ratio_}")
print(f"Total: {pca.explained_variance_ratio_.sum():.2%}")

# Plot in 2D
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap="viridis", alpha=0.6)
plt.xlabel("First Principal Component")
plt.ylabel("Second Principal Component")
plt.colorbar(label="Target")
plt.show()

# Choose n_components for target variance
pca_full = PCA()
pca_full.fit(X_scaled)
cumvar = pca_full.explained_variance_ratio_.cumsum()
n_components_95 = (cumvar < 0.95).sum() + 1
print(f"Components for 95% variance: {n_components_95}")

Step 8: Build ML pipelines

Pipelines combine preprocessing and modeling into one object. This prevents data leakage and makes deployment easier.

from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier

# Define column types
numeric_features = ["age", "income", "credit_score"]
categorical_features = ["occupation", "region"]

# Preprocessing for numeric columns
numeric_transformer = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler())
])

# Preprocessing for categorical columns
categorical_transformer = Pipeline([
    ("imputer", SimpleImputer(strategy="most_frequent")),
    ("onehot", OneHotEncoder(handle_unknown="ignore", drop="first"))
])

# Combine preprocessors
preprocessor = ColumnTransformer([
    ("num", numeric_transformer, numeric_features),
    ("cat", categorical_transformer, categorical_features)
])

# Full pipeline with model
pipeline = Pipeline([
    ("preprocessor", preprocessor),
    ("classifier", RandomForestClassifier(n_estimators=100, random_state=42))
])

# Train, evaluate — all in one
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

# Save the pipeline (model + preprocessor together)
import joblib
joblib.dump(pipeline, "model_pipeline.pkl")

# Load and predict
loaded_pipeline = joblib.load("model_pipeline.pkl")
predictions = loaded_pipeline.predict(new_data)

Project 1: Predict house prices (regression)

import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.pipeline import Pipeline

# Load dataset (real California housing data)
data = fetch_california_housing(as_frame=True)
df = data.frame
X = df.drop("MedHouseVal", axis=1)
y = df["MedHouseVal"]

print(f"Dataset: {X.shape[0]} homes, {X.shape[1]} features")
print(df.describe())

# Split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Pipeline with Gradient Boosting
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("model", GradientBoostingRegressor(
        n_estimators=200,
        learning_rate=0.1,
        max_depth=5,
        random_state=42
    ))
])

pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2   = r2_score(y_test, y_pred)
print(f"\nResults:")
print(f"  RMSE: ${rmse * 100_000:.0f}")
print(f"  R²:   {r2:.4f} ({r2*100:.1f}% variance explained)")

# Cross-validation
cv_scores = cross_val_score(pipeline, X, y, cv=5, scoring="r2")
print(f"  CV R²: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")

# Feature importance
model = pipeline.named_steps["model"]
importances = pd.Series(
    model.feature_importances_,
    index=X.columns
).sort_values(ascending=False)
print(f"\nTop features:\n{importances.head()}")

Project 2: Classify iris flowers (classification)

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

# Load iris dataset
data = load_iris(as_frame=True)
X = data.data
y = data.target
target_names = data.target_names

print(f"Classes: {target_names}")
print(f"Shape: {X.shape}")

# Split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Train
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Evaluate
y_pred = model.predict(X_test)
print(f"\nAccuracy: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred, target_names=target_names))

# Confusion matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt="d",
            xticklabels=target_names,
            yticklabels=target_names,
            cmap="Blues")
plt.title("Confusion Matrix")
plt.ylabel("Actual")
plt.xlabel("Predicted")
plt.show()

# Cross-validation
cv_acc = cross_val_score(model, X, y, cv=5, scoring="accuracy")
print(f"\nCV Accuracy: {cv_acc.mean():.4f} ± {cv_acc.std():.4f}")

# Feature importance
importances = pd.Series(
    model.feature_importances_,
    index=X.columns
).sort_values(ascending=False)
print(f"\nFeature importance:\n{importances}")

Project 3: Customer segmentation (clustering)

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
import seaborn as sns

# Generate customer data (or load yours)
np.random.seed(42)
n_customers = 500
df = pd.DataFrame({
    "annual_spend":    np.random.exponential(5000, n_customers),
    "purchase_freq":   np.random.randint(1, 52, n_customers),
    "avg_order_value": np.random.exponential(150, n_customers),
    "days_since_last": np.random.randint(1, 365, n_customers),
    "returns_rate":    np.random.beta(1, 9, n_customers)
})

features = df.columns.tolist()
X = df[features].values

# Scale
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Find optimal K
silhouette_scores = []
inertias = []
K_range = range(2, 9)

for k in K_range:
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = km.fit_predict(X_scaled)
    inertias.append(km.inertia_)
    silhouette_scores.append(silhouette_score(X_scaled, labels))

# Plot elbow + silhouette
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(K_range, inertias, marker="o")
ax1.set_title("Elbow Method")
ax1.set_xlabel("K")
ax1.set_ylabel("Inertia")

ax2.plot(K_range, silhouette_scores, marker="o")
ax2.set_title("Silhouette Score")
ax2.set_xlabel("K")
ax2.set_ylabel("Score")
plt.show()

best_k = K_range[np.argmax(silhouette_scores)]
print(f"Best K: {best_k}")

# Final clustering
kmeans = KMeans(n_clusters=best_k, random_state=42, n_init=10)
df["segment"] = kmeans.fit_predict(X_scaled)

# Analyze segments
segment_profiles = df.groupby("segment").mean().round(1)
print("\nSegment profiles:")
print(segment_profiles)

# Visualize with PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

plt.figure(figsize=(8, 6))
for seg in range(best_k):
    mask = df["segment"] == seg
    plt.scatter(X_pca[mask, 0], X_pca[mask, 1], label=f"Segment {seg}", alpha=0.6)
plt.xlabel(f"PC1 ({pca.explained_variance_ratio_[0]:.1%})")
plt.ylabel(f"PC2 ({pca.explained_variance_ratio_[1]:.1%})")
plt.legend()
plt.title("Customer Segments")
plt.show()

Choosing the right algorithm

Is your data labeled?
├── YES → Supervised learning
│   └── What is the output?
│       ├── Number → Regression
│       │   ├── Linear relationship? → Linear Regression
│       │   ├── Need interpretability? → Decision Tree
│       │   └── Best accuracy? → Gradient Boosting
│       └── Category → Classification
│           ├── Need interpretability? → Logistic Regression / Decision Tree
│           ├── Best default? → Random Forest
│           └── Small/medium dataset? → SVM
└── NO → Unsupervised learning
    └── What is the goal?
        ├── Find groups → Clustering (K-Means, DBSCAN)
        ├── Reduce dimensions → PCA, t-SNE, UMAP
        └── Find outliers → Isolation Forest, LOF
Algorithm Interpretable Handles missing Needs scaling Training speed Prediction speed
Linear/Logistic Regression Very fast Very fast
Decision Tree Fast Fast
Random Forest Partial Medium Medium
Gradient Boosting Slow Fast
SVM Slow Fast
KNN None (lazy) Slow
K-Means Fast Fast

ML learning path

Stage What to learn Time Resources
1. Python basics Python, NumPy, pandas 2-4 weeks Official docs, Kaggle learn
2. ML fundamentals Supervised/unsupervised, scikit-learn 4-6 weeks Hands-on ML book
3. Practice on datasets Kaggle competitions, UCI datasets Ongoing Kaggle.com
4. Statistical foundations Statistics, linear algebra, calculus Parallel StatQuest YouTube
5. Deep learning Neural networks, PyTorch/TensorFlow 4-8 weeks fast.ai, PyTorch tutorials
6. Specialization NLP, CV, time series, tabular 4-12 weeks Papers, domain-specific courses
7. MLOps Deployment, monitoring, pipelines 4-8 weeks MLflow, Airflow, Feast

Free resources

Resource Best for
Kaggle Learn (free) Practical ML fast
fast.ai (free) Deep learning, top-down approach
StatQuest (YouTube) Statistics and ML concepts
scikit-learn docs Algorithm reference, examples
Hands-on ML with scikit-learn (book) Comprehensive ML foundation
Google ML Crash Course (free) Google's ML introduction
Papers With Code State-of-the-art research

Common mistakes

Mistake Problem Fix
Data leakage Test data influences training, inflated metrics Fit preprocessors on train only, use Pipelines
Not splitting data Can't measure generalization Always train/test split, use cross-validation
Ignoring class imbalance Model predicts majority class only Use stratify, class_weight="balanced", SMOTE
Scaling test data with test stats Data leakage fit on train, transform only on test
Optimizing for wrong metric High accuracy on imbalanced data means nothing Use F1/AUC for imbalanced, RMSE for regression
Not checking data quality Garbage in, garbage out EDA first: missing values, outliers, distributions
Jumping to complex models Hard to debug, no baseline Start with Linear/Logistic Regression, improve iteratively
No cross-validation Lucky/unlucky split gives false confidence Use k-fold CV for robust estimates

ML vs related terms

Term What it is Relation to ML
AI Broad field of machines acting intelligently ML is a subset of AI
Deep Learning ML using neural networks with many layers Subset of ML
Neural Network Algorithm inspired by the brain A deep learning model
Data Science Extracting insights from data (stats + ML + viz) Uses ML as one tool
Statistics Mathematical data analysis Foundation of ML
MLOps ML operations: deploy, monitor, maintain models Productionizing ML
Feature Engineering Creating/transforming input variables Critical ML step
scikit-learn Python ML library Main tool for classical ML
PyTorch/TensorFlow Deep learning frameworks For neural networks
Kaggle ML competition platform Practice, datasets

FAQ

Do I need math for machine learning?

For practical ML with scikit-learn: basic understanding of statistics helps (mean, variance, distributions) but isn't required to start. You can learn the math as you go. For deep learning research: linear algebra, calculus, and probability are essential.

Python vs R for machine learning?

Python. R is excellent for statistics and academia, but Python dominates industry ML. scikit-learn, PyTorch, TensorFlow, and most production tools are Python-first.

How much data do I need?

General rules: Linear regression ~50-100 rows per feature. Decision trees ~1,000 rows. Random forests ~5,000-10,000 rows. Deep learning: 10,000-1,000,000+. But these vary wildly by problem complexity.

What's the difference between AI, ML, and deep learning?

AI is the broad goal (machines that act intelligently). ML is one approach (learning from data). Deep learning is a subset of ML using neural networks with many layers. All deep learning is ML, all ML is AI.

When should I use deep learning vs classical ML?

Classical ML (scikit-learn): tabular/structured data, small-medium datasets (<100k rows), interpretability needed, limited compute. Deep learning: images, text, audio, video; large datasets; maximum accuracy more important than interpretability.

How do I get ML projects for my portfolio?

Kaggle competitions (start with Titanic, House Prices). UCI Machine Learning Repository. Open government datasets. Find a problem you care about and collect data yourself. Recreate a published ML paper.


Quick reference

# Full supervised learning workflow
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report

# 1. Load data
df = pd.read_csv("data.csv")

# 2. Explore
print(df.head(), df.describe(), df.isnull().sum())

# 3. Prepare features/target
X = df.drop("target", axis=1)
y = df["target"]

# 4. Split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 5. Build pipeline
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("model", RandomForestClassifier(n_estimators=100, random_state=42))
])

# 6. Train and evaluate
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred))

# 7. Cross-validate
scores = cross_val_score(pipeline, X, y, cv=5, scoring="f1_weighted")
print(f"CV F1: {scores.mean():.4f} ± {scores.std():.4f}")

# 8. Save
import joblib
joblib.dump(pipeline, "model.pkl")

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools