<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yash-nigam</title>
    <description>The latest articles on DEV Community by yash-nigam (@yashnigam).</description>
    <link>https://dev.to/yashnigam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1034882%2F859c3509-9e87-46d8-ae9a-ba1c65d73b13.png</url>
      <title>DEV Community: yash-nigam</title>
      <link>https://dev.to/yashnigam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yashnigam"/>
    <language>en</language>
    <item>
      <title>Everything I Learned From My Claude Code Training</title>
      <dc:creator>yash-nigam</dc:creator>
      <pubDate>Mon, 31 Aug 2026 17:28:38 +0000</pubDate>
      <link>https://dev.to/yashnigam/everything-i-learned-from-my-claude-code-training-1k94</link>
      <guid>https://dev.to/yashnigam/everything-i-learned-from-my-claude-code-training-1k94</guid>
      <description>&lt;h1&gt;
  
  
  Everything I Learned From My Claude Code Training
&lt;/h1&gt;

&lt;p&gt;I recently went through a hands-on training on &lt;strong&gt;Claude Code&lt;/strong&gt; and the broader Claude ecosystem. Below are my complete notes, organized by topic, with screenshots from the session included at each relevant step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
The Claude Ecosystem

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;AI-Code-Design-Cowork-Security-Chrome-Office&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The Agentic Loop (Query Engine)

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Architecture&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Models, Effort, and Slash Commands

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Models-Commands&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Session Management

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Export-Fork-Resume-Compact&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Project Configuration

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;ClaudeFolder-Permissions-Init-ClaudeMd&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Auto Mode vs. Plan Mode

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Auto-Plan&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Commands vs. Skills vs. Agents

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Standup-Metaprompting-PR-Invocation&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Code Review via Subagents

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Security-Performance-Coverage-Quality-Usage-Deploy-Setup-Execution-Tests-Stack-Creation-Example-Focus-OWASP-Memory-Output-Background&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Multi-Agent Harness Concepts

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;SecondPass-Comparison&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Hooks

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Flow-PreToolUse-Types-Blocking-Slack-Sharing&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
MCP (Model Context Protocol)

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Concept-Rationale-Types&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
End-to-End Automation

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;End-to-end automation of security review → issue creation → issue fix → PR creation → PR fix, all through agents.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Agent Teams

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Multiple agents (security, performance, test) talk to each other and take actions autonomously — filing issues, creating PRs, merging PRs, and closing issues, all automated.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Key Takeaways

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Loop-Config-Commands-Hooks-Sessions-Teams&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. The Claude Ecosystem
&lt;/h2&gt;

&lt;p&gt;Claude Code is one tool within a larger ecosystem, not a standalone product:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Claude AI&lt;/strong&gt; — the conversational assistant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; — the agentic coding CLI (the focus of this article), which has:

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;agentic loop&lt;/strong&gt; that loops until the task is completed&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;tool system&lt;/strong&gt;: git, bash, read, write files&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;permission pipeline&lt;/strong&gt;, configurable per tool (Allow / Deny / Ask)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;context manager&lt;/strong&gt;: compaction and pruning of context within a session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session persistence&lt;/strong&gt;: work can be paused and resumed later, with context and memory maintained&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Design&lt;/strong&gt; — design tooling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Co-work&lt;/strong&gt; — collaboration tooling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Security&lt;/strong&gt; — security-focused tooling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Chrome plugin&lt;/strong&gt; — browser automation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Office plugin&lt;/strong&gt; — office document integration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the backend, Claude Code talks to the LLM hosted by Anthropic via the &lt;code&gt;/v1/messages&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diagram of the agentic loop: gather context, take action, verify results, repeat until done.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi3wtmefqtym6qcz2k6pd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi3wtmefqtym6qcz2k6pd.png" alt="Claude ecosystem overview" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tools like Cursor, Windsurf, and Perplexity act as &lt;strong&gt;integrators&lt;/strong&gt; — giving access to multiple LLMs. Claude, by contrast, offers an entire vertically integrated ecosystem.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  2. The Agentic Loop (Query Engine)
&lt;/h2&gt;

&lt;p&gt;This is the core engine behind Claude Code. Given a request — e.g. &lt;em&gt;"Create a unit test case for my function"&lt;/em&gt; — the loop works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gather context&lt;/strong&gt; — goes to the file, reads the imported files also, reads the function in the file (which needs to be mocked).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send context to the LLM&lt;/strong&gt; — the LLM decides, based on the context, what unit test cases must be created after it has all the info, and tells Claude Code what actions to take (e.g. "create new test case").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use tools&lt;/strong&gt; — Claude Code creates or modifies the file using its tool system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; — the agent checks whether the job is done or not (e.g. runs the test to confirm it passes).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additional properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;user can modify the context&lt;/strong&gt; in between the loop or after it.&lt;/li&gt;
&lt;li&gt;The loop &lt;strong&gt;runs continuously&lt;/strong&gt; until the task is not done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everything depends on the LLM&lt;/strong&gt; being used — so it's worth knowing which LLM is best suited for the task.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Agentic Coding Tools Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Three-layer architecture diagram showing coding agents (Claude Code, Copilot, Codex, Cursor, etc.) between the chat interface and various LLM hosting backends.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42xif6ull04n8qh8ldsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42xif6ull04n8qh8ldsg.png" alt="Agentic coding tools architecture diagram 1" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude Code's runtime architecture, from terminal command through the CLI parser and QueryEngine agentic loop to tool calls and API routing.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftktqmbdpi8agxcsqsna0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftktqmbdpi8agxcsqsna0.png" alt="Agentic coding tools architecture diagram 2" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code always connects to the Anthropic base URL.&lt;/li&gt;
&lt;li&gt;It can also connect to &lt;strong&gt;Ollama&lt;/strong&gt; and open-source models such as &lt;strong&gt;Qwen&lt;/strong&gt; or &lt;strong&gt;Llama 3.2&lt;/strong&gt; — enabling a fully local setup. This is currently the only fully local option available.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3. Models, Effort, and Slash Commands
&lt;/h2&gt;

&lt;p&gt;Models, effort levels, and sessions are the main levers for controlling how Claude Code works.&lt;/p&gt;
&lt;h3&gt;
  
  
  Models
&lt;/h3&gt;

&lt;p&gt;Four main models, chosen based on the type of task and usage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fable&lt;/strong&gt; — for complex tasks: architecture, design, security, coding&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opus&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sonnet&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Haiku&lt;/strong&gt; — for simpler tasks&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Qwen-local&lt;/code&gt; is the local-model equivalent of Haiku.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;opusplan&lt;/code&gt; = Opus for planning + Sonnet for doing the task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Guidance:&lt;/strong&gt; try a smaller model at higher effort first — otherwise switch to a new/bigger model as required. Use Fable only if Opus cannot handle the task.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal status line showing the active model, session name, context usage, token count, and running cost.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffegodowq5s12f56s5oub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffegodowq5s12f56s5oub.png" alt="Models and effort screen clipping" width="657" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Screen clippings taken: 29-08-2026 02:21 and 29-08-2026 02:14&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Slash commands for managing everything
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt; — switch between different models&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt; — decides the effort to put in: &lt;strong&gt;high → xhigh → max&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt; — shown in the Claude prompt, displays total tokens used; helps decide when to compact the session&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4. Session Management
&lt;/h2&gt;

&lt;p&gt;Before starting with Claude Code, it's worth understanding &lt;code&gt;/sessions&lt;/code&gt; — session management.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can &lt;strong&gt;resume from wherever we stopped&lt;/strong&gt; using a session ID.&lt;/li&gt;
&lt;li&gt;Start a new session: &lt;code&gt;claude -n "session_name"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Resume a previous session: &lt;code&gt;claude --resume&lt;/code&gt;, &lt;code&gt;claude --continue&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt; — check session status&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Practical guidance
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We can create &lt;strong&gt;3 different sessions&lt;/strong&gt; for 3 different issues, potentially working on 3 different models.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export explore-current-project.md&lt;/code&gt; — exports the conversation to a markdown file, e.g.:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ⎿  Conversation exported to: H:\Claude-Code-Projects-17-19-Aug\claude_showcase_17_aug_26\explore-current-project.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt; — forks the current session so you can go to a new forked session without modifying the original session.&lt;/li&gt;
&lt;li&gt;If &lt;strong&gt;80% of context&lt;/strong&gt; is used, we can compact it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt; — switch between sessions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt; — summarizes the session data; some data could be removed in the process.&lt;/li&gt;
&lt;li&gt;If old context is not found in the current session, tokens would need to be spent again to recreate it — and &lt;strong&gt;wrong information could get compacted&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;There is a &lt;strong&gt;usage limit at the account level&lt;/strong&gt;; every session uses a part of that limit.&lt;/li&gt;
&lt;li&gt;We should create multiple sessions — e.g. 3 different sessions for 3 different bugs. Information for the first bug may not be needed for the second bug, and sessions help Claude read old information without wasting tokens to recreate it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Claude Code's /status panel showing version, session details, login/account info, and connected MCP servers.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpsn4bh63mn1aq0u7bkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpsn4bh63mn1aq0u7bkn.png" alt="Session export screen clipping" width="689" height="318"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Project Configuration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  README.md
&lt;/h3&gt;

&lt;p&gt;The most important file for reading all the information about a project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before telling the tool what to do, plan first&lt;/strong&gt; — create the architecture first.&lt;/li&gt;
&lt;li&gt;Decide on a design template.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  CLAUDE.md — Rules
&lt;/h3&gt;

&lt;p&gt;Used to control the behaviour of Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which JavaScript library to use.&lt;/li&gt;
&lt;li&gt;Preventing Claude Code from reading sensitive files so it does not use them.&lt;/li&gt;
&lt;li&gt;How to give Claude permission to access your code — what it can read and what it cannot read.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;.claude&lt;/code&gt; folder and settings
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;First, create a &lt;code&gt;.claude&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;settings.json&lt;/code&gt; — accessible to the whole team, pushed to the repo.&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;settings.local.json&lt;/code&gt; — will &lt;strong&gt;not&lt;/strong&gt; be pushed to the repo, and will override &lt;code&gt;settings.json&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here you can decide which model to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"opusplan"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm run *)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git status)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git diff)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git add *)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git commit *)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Write(src/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Write(tests/**)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm install *)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Write(package.json)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(./.env*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(./secrets/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(./**/credentials*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(rm -rf:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(curl:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(wget:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Claude declining to read a blocked .env.example file per project settings and offering alternative ways to proceed.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5gmdbkyd5x4jg3llkk6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5gmdbkyd5x4jg3llkk6f.png" alt="Settings configuration screen clipping" width="800" height="115"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;/init&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Initializes a &lt;code&gt;CLAUDE.md&lt;/code&gt; file with codebase documentation after going through the project at the root level.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add conditions for Claude to always follow — should not go above &lt;strong&gt;150 to 200 lines max&lt;/strong&gt;; this is very specific to the root of the project.&lt;/li&gt;
&lt;li&gt;We can have a &lt;code&gt;CLAUDE.md&lt;/code&gt; file for &lt;strong&gt;every sub-folder&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If there is no &lt;code&gt;CLAUDE.md&lt;/code&gt; file, don't rely on Claude having project-specific context — use &lt;code&gt;CLAUDE.md&lt;/code&gt; for every project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example: the actual CLAUDE.md used in this training repo
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Coding Standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Always use async/await, never raw Promises
&lt;span class="p"&gt;-&lt;/span&gt; All functions must have JSDoc comments
&lt;span class="p"&gt;-&lt;/span&gt; No console.log in production code — use the logger utility
&lt;span class="p"&gt;-&lt;/span&gt; Every new function must have at least one unit test
&lt;span class="p"&gt;-&lt;/span&gt; Pure validation functions use a single return statement with a composed expression
&lt;span class="p"&gt;-&lt;/span&gt; Never use multiple early-return guard clauses in validator functions

&lt;span class="gu"&gt;## Repository conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; CommonJS (&lt;span class="sb"&gt;`require`&lt;/span&gt;/&lt;span class="sb"&gt;`module.exports`&lt;/span&gt;) throughout, not ESM.
&lt;span class="p"&gt;-&lt;/span&gt; ESLint enforces: &lt;span class="sb"&gt;`eqeqeq`&lt;/span&gt; (always &lt;span class="sb"&gt;`===`&lt;/span&gt;), &lt;span class="sb"&gt;`curly`&lt;/span&gt;, &lt;span class="sb"&gt;`no-var`&lt;/span&gt;/&lt;span class="sb"&gt;`prefer-const`&lt;/span&gt;,
  &lt;span class="sb"&gt;`no-return-await`&lt;/span&gt;, &lt;span class="sb"&gt;`require-await`&lt;/span&gt; (no &lt;span class="sb"&gt;`async`&lt;/span&gt; functions without an &lt;span class="sb"&gt;`await`&lt;/span&gt;),
  unused-arg exception for &lt;span class="sb"&gt;`_`&lt;/span&gt;-prefixed names.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`.claude/settings.json`&lt;/span&gt; denies reads of &lt;span class="sb"&gt;`.env*`&lt;/span&gt;, &lt;span class="sb"&gt;`secrets/**`&lt;/span&gt;, and
  &lt;span class="sb"&gt;`credentials*`&lt;/span&gt; — don't try to work around this to inspect real secrets.

&lt;span class="gu"&gt;## What Claude Must Never Do&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Never modify .env or .env.&lt;span class="se"&gt;\*&lt;/span&gt; files
&lt;span class="p"&gt;-&lt;/span&gt; Never push directly to main branch
&lt;span class="p"&gt;-&lt;/span&gt; Never remove existing tests
&lt;span class="p"&gt;-&lt;/span&gt; Never install packages without confirming with the developer

&lt;span class="gu"&gt;## PR and Git Standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Commit messages follow Conventional Commits: feat:, fix:, docs:, test:
&lt;span class="p"&gt;-&lt;/span&gt; PR descriptions must include: what changed, why it changed, how to test

&lt;span class="gu"&gt;## Tech Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Runtime: Node.js 20
&lt;span class="p"&gt;-&lt;/span&gt; Framework: Express.js
&lt;span class="p"&gt;-&lt;/span&gt; Database: PostgreSQL with Prisma ORM
&lt;span class="p"&gt;-&lt;/span&gt; Testing: Jest
&lt;span class="p"&gt;-&lt;/span&gt; Language: ECMAScript 2022 for all new code only

&lt;span class="gu"&gt;## Architecture&lt;/span&gt;
Request flow: &lt;span class="sb"&gt;`src/index.js`&lt;/span&gt; wires Express with &lt;span class="sb"&gt;`requestLogger`&lt;/span&gt; middleware
globally, mounts all auth endpoints under &lt;span class="sb"&gt;`/api/auth`&lt;/span&gt; from &lt;span class="sb"&gt;`src/api/routes.js`&lt;/span&gt;,
and registers &lt;span class="sb"&gt;`errorHandler`&lt;/span&gt; last as the global error middleware.

Layering:
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/api/routes.js`&lt;/span&gt; — route handlers only; validates input shape, calls into
  &lt;span class="sb"&gt;`authService`&lt;/span&gt;, maps thrown errors to HTTP status codes (e.g. &lt;span class="sb"&gt;`'Invalid
  credentials'`&lt;/span&gt; → 401). It does NOT talk to &lt;span class="sb"&gt;`tokenHelper.js`&lt;/span&gt; directly.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/api/middleware.js`&lt;/span&gt; — cross-cutting concerns: &lt;span class="sb"&gt;`requestLogger`&lt;/span&gt;,
  &lt;span class="sb"&gt;`authenticate`&lt;/span&gt; (verifies Bearer token via &lt;span class="sb"&gt;`tokenHelper.verifyToken`&lt;/span&gt;, attaches
  &lt;span class="sb"&gt;`req.user`&lt;/span&gt;), &lt;span class="sb"&gt;`validateBody`&lt;/span&gt; (checks required fields present), &lt;span class="sb"&gt;`errorHandler`&lt;/span&gt;
  (catch-all, returns generic 500).
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/auth/authService.js`&lt;/span&gt; — business logic: &lt;span class="sb"&gt;`loginUser`&lt;/span&gt;, &lt;span class="sb"&gt;`refreshToken`&lt;/span&gt;,
  &lt;span class="sb"&gt;`revokeToken`&lt;/span&gt;, token generation. Owns the in-memory &lt;span class="sb"&gt;`refreshTokenStore`&lt;/span&gt; (a
  &lt;span class="sb"&gt;`Map`&lt;/span&gt;, standing in for a database — resets on every restart, not shared
  across processes).
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/auth/tokenHelper.js`&lt;/span&gt; — low-level JWT primitives: &lt;span class="sb"&gt;`verifyToken`&lt;/span&gt;
  (signature + expiry check, throws typed errors), &lt;span class="sb"&gt;`decodeToken`&lt;/span&gt; (no
  verification, for reading claims only), &lt;span class="sb"&gt;`extractBearerToken`&lt;/span&gt;, &lt;span class="sb"&gt;`getTokenTTL`&lt;/span&gt;.
  &lt;span class="sb"&gt;`authService.js`&lt;/span&gt; and &lt;span class="sb"&gt;`middleware.js`&lt;/span&gt; both depend on this; it depends on
  nothing else in the app.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/utils/validators.js`&lt;/span&gt; — pure, stateless input validators (email,
  password, UUID, sanitization). No I/O.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`src/utils/logger.js`&lt;/span&gt; — minimal structured JSON logger (stdout/stderr),
  level-gated by &lt;span class="sb"&gt;`LOG_LEVEL`&lt;/span&gt; env var. Not a real observability stack.

There's no real user database: &lt;span class="sb"&gt;`routes.js`&lt;/span&gt; builds a &lt;span class="sb"&gt;`mockUserRecord`&lt;/span&gt; inline
for login, and &lt;span class="sb"&gt;`authService.getUserById`&lt;/span&gt; returns a hardcoded stub — expect
these to be replaced with real persistence rather than extended in place.

JWT config (&lt;span class="sb"&gt;`JWT_SECRET`&lt;/span&gt;, &lt;span class="sb"&gt;`JWT_EXPIRES_IN`&lt;/span&gt;, &lt;span class="sb"&gt;`REFRESH_EXPIRES_IN`&lt;/span&gt;) is read from
env vars in both &lt;span class="sb"&gt;`authService.js`&lt;/span&gt; and &lt;span class="sb"&gt;`tokenHelper.js`&lt;/span&gt; independently, each
with its own fallback default — keep them in sync if changing defaults.

&lt;span class="gu"&gt;### Request flow (login example)&lt;/span&gt;
&lt;span class="sb"&gt;`POST /api/auth/login`&lt;/span&gt; → &lt;span class="sb"&gt;`validateBody(['email','password'])`&lt;/span&gt; → route handler
validates format via &lt;span class="sb"&gt;`validators.js`&lt;/span&gt; → &lt;span class="sb"&gt;`authService.loginUser()`&lt;/span&gt; checks bcrypt
hash, calls &lt;span class="sb"&gt;`generateAccessToken`&lt;/span&gt; (signed JWT) + &lt;span class="sb"&gt;`generateRefreshToken`&lt;/span&gt; (uuid
stored in &lt;span class="sb"&gt;`refreshTokenStore`&lt;/span&gt;) → returns &lt;span class="sb"&gt;`{ accessToken, refreshToken, user }`&lt;/span&gt;.
Protected routes (&lt;span class="sb"&gt;`/logout`&lt;/span&gt;, &lt;span class="sb"&gt;`/me`&lt;/span&gt;) go through &lt;span class="sb"&gt;`authenticate`&lt;/span&gt; middleware,
which calls &lt;span class="sb"&gt;`tokenHelper.verifyToken`&lt;/span&gt; and attaches the decoded payload to
&lt;span class="sb"&gt;`req.user`&lt;/span&gt;.

&lt;span class="gu"&gt;### Error convention&lt;/span&gt;
Route handlers translate known domain errors to HTTP status codes inline
(e.g. &lt;span class="sb"&gt;`'Invalid credentials'`&lt;/span&gt; → 401) and pass everything else to &lt;span class="sb"&gt;`next(err)`&lt;/span&gt;,
where &lt;span class="sb"&gt;`errorHandler`&lt;/span&gt; logs it and returns a generic 500. Preserve this pattern
when adding routes — don't leak internal error messages to clients from the
global handler.

&lt;span class="gu"&gt;### Token model&lt;/span&gt;
Two-token scheme: short-lived signed JWT access token (claims: &lt;span class="sb"&gt;`sub`&lt;/span&gt;, &lt;span class="sb"&gt;`email`&lt;/span&gt;,
&lt;span class="sb"&gt;`role`&lt;/span&gt;) + opaque UUID refresh token stored server-side in &lt;span class="sb"&gt;`refreshTokenStore`&lt;/span&gt;
with &lt;span class="sb"&gt;`{ userId, createdAt }`&lt;/span&gt;. Refresh tokens are revoked by deleting the map
entry (&lt;span class="sb"&gt;`revokeToken`&lt;/span&gt;, logout).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Example: Generating &lt;code&gt;validateCreditCard&lt;/code&gt; and Its Test Case from a Prompt
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: creating a function like this automatically creates a test case also (via the write-tests skill — covered in section 7).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Claude adding a JSDoc-documented validateCreditCard function (Luhn checksum, 13-19 digits) to validators.js.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7mmjqtr6ir0v1fp8qeyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7mmjqtr6ir0v1fp8qeyy.png" alt="CLAUDE.md example screen clipping 1" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude adding Jest test cases for validateCreditCard covering valid Visa and Mastercard test numbers.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9yq8xcx9gf0uhgdrxj9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9yq8xcx9gf0uhgdrxj9j.png" alt="CLAUDE.md example screen clipping 2" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Auto Mode vs. Plan Mode
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto mode&lt;/strong&gt; — Claude decides what to do automatically and does not ask for confirmation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan mode&lt;/strong&gt; — we can ask Claude to create a plan only, without executing.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;btw&lt;/code&gt; to ask a question which runs separately from the main section.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always switch to manual mode before making changes&lt;/strong&gt; you want to review first.&lt;/li&gt;
&lt;li&gt;In plan mode, Claude will ask you to go ahead with the changes first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Claude's plan mode proposal for a new validateBirthDate validator, with scope and constraints confirmed before execution.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5s82x6gw97xqs8wvpgy7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5s82x6gw97xqs8wvpgy7.png" alt="Plan mode screen clipping" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In auto mode, this behaviour changes — Claude proceeds independently.&lt;/p&gt;


&lt;h2&gt;
  
  
  7. Commands vs. Skills vs. Agents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/commands&lt;/code&gt;&lt;/strong&gt; — executed &lt;strong&gt;manually&lt;/strong&gt;, defined via a markdown file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt; — run &lt;strong&gt;automatically&lt;/strong&gt; for us, based on what's asked. A command can be converted into a skill. Skills go into a skills folder.

&lt;ul&gt;
&lt;li&gt;There are a lot of third-party skills available.&lt;/li&gt;
&lt;li&gt;It's better to create our own skills, which use fewer tokens compared to those available externally, which tend to use more.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt; — specialized assistants that do a task in the background and come up with an answer. Run an agent separately in the background, or run it via a skill — a skill can also hand over a task to an agent.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt; never use one-liners to do your job — don't go back to the tool again and again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Example: custom command — &lt;code&gt;/standup&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;standup&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate a daily standup update from git history and open files&lt;/span&gt;
&lt;span class="na"&gt;disable-model-invocation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
You are a senior developer preparing a daily standup update for your team.
This is a Node.js/Express authentication API project. You have been working
in this codebase today. Check git log --since="00:00" --oneline and
git diff HEAD to understand what actually changed.

Draft a standup update based only on what you find in the git history
and open files — do not invent or assume work that is not visible.

Format:
Yesterday: [completed items, specific function or file names]
Today:     [in-progress items based on uncommitted changes or open TODOs]
Blockers:  [failing tests, TODO/FIXME comments, incomplete functions]

Keep each section to 3 bullet points maximum.
Use specific names — file names, function names, issue numbers where visible.
Be factual and brief. No filler. Write it as if reading it aloud in 30 seconds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Output of the /standup command summarizing yesterday's commits, today's work, and current blockers.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmezi1ym8nuq1oz806ako.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmezi1ym8nuq1oz806ako.png" alt="Standup command screen clipping" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If Claude Code is used to create code, it should also be used to create the commit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Metaprompting
&lt;/h3&gt;

&lt;p&gt;Take help of Claude to create a prompt using the &lt;strong&gt;RCTFCF&lt;/strong&gt; framework (Role, Context, Task, Constraint, Format):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Act as a prompt expert and help me create a structured prompt using role, context, task, constraint, and output format which can be used to do a security review for a Node.js API written in the Express framework. I want to check top 10 OWASP issues."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also relevant: &lt;strong&gt;chain of thought prompting&lt;/strong&gt;, and the observation that &lt;strong&gt;LLMs understand prompting better in their own language&lt;/strong&gt; (i.e. structured, explicit formats they're trained to parse).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude implementing validateDateOfBirth in validators.js following the ISO-date, no-future, 120-year-limit convention.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bzyp8hd0rxxmivri0jc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bzyp8hd0rxxmivri0jc.png" alt="Metaprompting screen clipping 1" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The /raise-pr command refusing to push directly to main and creating a feature branch instead.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabndbnnfhjnhq018qhgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabndbnnfhjnhq018qhgn.png" alt="Metaprompting screen clipping 2" width="799" height="397"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: custom command — &lt;code&gt;/raise-pr&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;raise-pr&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Raise a GitHub pull request for the current branch targeting main&lt;/span&gt;
&lt;span class="na"&gt;disable-model-invocation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
You are a senior developer raising a pull request for a fix or feature branch.

Steps:
&lt;span class="p"&gt;1.&lt;/span&gt; Run git branch --show-current to get the current branch name.
&lt;span class="p"&gt;2.&lt;/span&gt; Run git log main..HEAD --oneline to list all commits on this branch.
&lt;span class="p"&gt;3.&lt;/span&gt; Run git diff main...HEAD to inspect all changes introduced by this branch.
&lt;span class="p"&gt;4.&lt;/span&gt; Check if the branch name or commits reference an issue number (e.g. fix/issue-204
   or "closes #204"). Extract it if present.

Using what you observe, generate a PR title and body:

Title format:
  type(scope): short summary under 72 characters  (same as the commit message)

Body format:
  ## What changed
&lt;span class="p"&gt;  -&lt;/span&gt; Bullet points describing each logical change
  ## Why it changed
&lt;span class="p"&gt;  -&lt;/span&gt; The problem or issue this PR resolves (reference issue number if found, e.g. closes #204)
  ## How to test
&lt;span class="p"&gt;  -&lt;/span&gt; Step-by-step instructions to verify the fix or feature works

Then run:
  gh pr create --base main --title "&lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;" --body "&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;"

If the branch has no upstream yet, push it first:
  git push -u origin &lt;span class="nt"&gt;&amp;lt;branch-name&amp;gt;&lt;/span&gt;

Output only the PR title and body. No explanation, no commentary, no preamble.
Be precise and factual. Every word should earn its place.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Running &lt;code&gt;/raise-pr&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Permission prompt confirming the git push of the new feature branch to origin.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ujjq0qlugbz9x6ut8ut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ujjq0qlugbz9x6ut8ut.png" alt="Raise PR screen clipping 1" width="652" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Confirmation that the feature branch was pushed and PR #1 was opened on GitHub.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa4s16dp9snt8nnqfsnsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa4s16dp9snt8nnqfsnsy.png" alt="Raise PR screen clipping 2" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the PR is created:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub pull requests tab showing the newly opened validateDateOfBirth PR.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffioz60p0f52ljnlhlhbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffioz60p0f52ljnlhlhbi.png" alt="PR created screen clipping" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Skills are auto-invoked
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/commands&lt;/code&gt; are executed manually, but &lt;strong&gt;skills&lt;/strong&gt; get applied automatically based on the prompt. Seeing a list of all skills:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The /skills menu listing all 9 available skills and their lock/enabled status.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8jxfsx6612h9ftk82tz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8jxfsx6612h9ftk82tz9.png" alt="List of all skills screen clipping" width="762" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skills could also come from installed plugins.&lt;/p&gt;


&lt;h2&gt;
  
  
  8. Code Review via Subagents
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;code review skill&lt;/strong&gt; can delegate each dimension of the review to a dedicated subagent using the Task tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## 1. Security&lt;/span&gt;
Delegate this dimension to the &lt;span class="sb"&gt;`security-analyst`&lt;/span&gt; subagent using the Task tool.

&lt;span class="gu"&gt;## 2. Performance&lt;/span&gt;
Delegate this dimension to the &lt;span class="sb"&gt;`performance-analyst`&lt;/span&gt; subagent using the Task tool.

&lt;span class="gu"&gt;## 3. Test Coverage&lt;/span&gt;
Delegate this dimension to the &lt;span class="sb"&gt;`test-coverage-analyst`&lt;/span&gt; subagent using the Task tool.

&lt;span class="gu"&gt;## 4. Code Quality&lt;/span&gt;
Delegate this dimension to the &lt;span class="sb"&gt;`code-quality-analyst`&lt;/span&gt; subagent using the Task tool.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to use a skill
&lt;/h3&gt;

&lt;p&gt;Example prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❯ look at the auth module and tell me if there are any problems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The code review skill should auto-invoke:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude auto-invoking the code-review skill and launching four parallel review agents against the auth module.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe9ed10u8gsji0sc5f1s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe9ed10u8gsji0sc5f1s9.png" alt="Code review skill auto-invoked screen clipping" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No explicit integration is needed — it's auto-invoked. No need to use &lt;code&gt;/command&lt;/code&gt; explicitly.&lt;/p&gt;

&lt;p&gt;A sample of the code review report:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Consolidated code review report table listing critical and high-severity findings across the auth module.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6udqpubhuzzc014pz8ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6udqpubhuzzc014pz8ca.png" alt="Code review report sample screen clipping 1" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Detailed write-up of two critical findings: a syntax-breaking stray await and a bypassed bcrypt password check.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F14alq81al21sbqzux6eg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F14alq81al21sbqzux6eg.png" alt="Code review report sample screen clipping 2" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Example: skill — &lt;code&gt;deploy&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If I want to deploy, &lt;code&gt;deploy.sh&lt;/code&gt; should be used — so we use a deploy skill:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Deploy the application to staging. Use when the user says "deploy",&lt;/span&gt;
  &lt;span class="s"&gt;"ship it", "push to staging", or "release". Runs pre-flight checks,&lt;/span&gt;
  &lt;span class="s"&gt;builds, tags, and verifies the deployment. Always confirm with the&lt;/span&gt;
  &lt;span class="s"&gt;user before executing.&lt;/span&gt;
&lt;span class="na"&gt;disable-model-invocation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="gh"&gt;# Deploy Skill&lt;/span&gt;
Deployment logic lives in &lt;span class="sb"&gt;`scripts/deploy.sh`&lt;/span&gt;. That script is the
source of truth — do not re-implement its steps here.

&lt;span class="gu"&gt;## Before Running&lt;/span&gt;
Confirm with the user:
&lt;span class="p"&gt;-&lt;/span&gt; "Ready to deploy to staging. This will tag and push. Proceed?"
&lt;span class="p"&gt;-&lt;/span&gt; Do not proceed without explicit confirmation.

&lt;span class="gu"&gt;## Execution&lt;/span&gt;
Run: &lt;span class="sb"&gt;`bash scripts/deploy.sh`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: skill — &lt;code&gt;write-tests&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Similarly, we can use a write-tests skill to write a test case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write-tests&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Use this skill whenever new testable logic is added or modified — functions,&lt;/span&gt;
  &lt;span class="s"&gt;methods, classes, route handlers, or modules in src/. Triggers on: "add a&lt;/span&gt;
  &lt;span class="s"&gt;function", "create a utility", "implement this", "write a handler", "add a&lt;/span&gt;
  &lt;span class="s"&gt;route", or any task that produces new logic with inputs and outputs or&lt;/span&gt;
  &lt;span class="s"&gt;side effects. Do NOT wait to be asked — write tests as part of completing&lt;/span&gt;
  &lt;span class="s"&gt;the task. Skip this skill only for: config constants, type definitions,&lt;/span&gt;
  &lt;span class="s"&gt;pure re-exports, or framework boilerplate with no logic.&lt;/span&gt;
&lt;span class="s"&gt;---&lt;/span&gt;
&lt;span class="gh"&gt;# Write Tests Skill&lt;/span&gt;
You are a senior QA engineer writing exhaustive Jest test suites for a
Node.js application.

&lt;span class="gu"&gt;## Stack &amp;amp; Conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Framework**&lt;/span&gt;: Jest with Supertest for HTTP integration tests
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Test location**&lt;/span&gt;: &lt;span class="sb"&gt;`tests/`&lt;/span&gt; mirroring &lt;span class="sb"&gt;`src/`&lt;/span&gt; structure, &lt;span class="sb"&gt;`.test.js`&lt;/span&gt; suffix
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Logger**&lt;/span&gt;: Structured JSON — never assert on &lt;span class="sb"&gt;`console`&lt;/span&gt; output
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Auth**&lt;/span&gt;: &lt;span class="sb"&gt;`JWT_SECRET`&lt;/span&gt; defaults to &lt;span class="sb"&gt;`'dev-secret-key'`&lt;/span&gt; in tests — do not
  assert real security guarantees against this value
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Test data**&lt;/span&gt;: Define inline for simple cases; use &lt;span class="sb"&gt;`tests/fixtures/`&lt;/span&gt; for
  objects reused across 3+ tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initiating the write-tests skill:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The write-tests skill identifying and filling a missing leap-year test case for validateDateOfBirth.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvrg4tn079eiq9dfkz3wv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvrg4tn079eiq9dfkz3wv.png" alt="Write tests skill screen clipping" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skills are auto-invoked. LCOV coverage output:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Test suite results showing 76 passing tests with 100% coverage on validators.js.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpfc947ew7k9rmm171owe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpfc947ew7k9rmm171owe.png" alt="LCOV coverage screen clipping" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a custom agent
&lt;/h3&gt;

&lt;p&gt;Skills, agents, and commands differ as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt; — a specialized assistant that does a task in the background and comes up with an answer. Run it separately in the background, or run it via a skill — a skill can also hand a task over to an agent.&lt;/li&gt;
&lt;li&gt;In an agent definition, we can specify exactly &lt;strong&gt;what tools the agent can use&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of agents:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The project's custom subagent definitions listed in the .claude/agents folder.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyy3p6oq5oz8jsgutfn9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyy3p6oq5oz8jsgutfn9b.png" alt="Example of agents screen clipping" width="336" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: custom agent — &lt;code&gt;security-analyst&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security-analyst&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Use this agent for security reviews: authentication bypass, injection vulnerabilities, OWASP Top 10, token handling, and input validation. Invoke with: ask the security-analyst to audit this file.&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Read, Bash(npm audit *), Bash(grep *), Write, Edit&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;opus&lt;/span&gt;
&lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="gh"&gt;# Security Analyst Agent&lt;/span&gt;
You are a senior application security engineer. You read code exclusively through
a security lens. You do not suggest feature improvements or code style changes.
You find vulnerabilities and you explain how to fix them.

&lt;span class="gu"&gt;## Your Focus Areas&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Authentication bypass and broken access control
&lt;span class="p"&gt;-&lt;/span&gt; Injection vulnerabilities: SQL, command, path traversal
&lt;span class="p"&gt;-&lt;/span&gt; Sensitive data exposure in logs, responses, or error messages
&lt;span class="p"&gt;-&lt;/span&gt; Insecure token handling: weak secrets, missing expiry, improper storage
&lt;span class="p"&gt;-&lt;/span&gt; Missing input validation and sanitisation
&lt;span class="p"&gt;-&lt;/span&gt; Dependency vulnerabilities (flag for npm audit review)

&lt;span class="gu"&gt;## OWASP Categorisation&lt;/span&gt;
Tag every finding with its OWASP Top 10 category where applicable.

&lt;span class="gu"&gt;## Memory Protocol&lt;/span&gt;
Before starting, read &lt;span class="sb"&gt;`MEMORY.md`&lt;/span&gt; (an index of one-line links to note files) and
skim any linked notes whose description looks relevant to the file(s) you're
about to audit.

After completing your audit, write to memory only if you found something
non-obvious, recurring, or specific to this codebase that would save real time
on a future audit — not routine findings you'd already report. If so:
&lt;span class="p"&gt;1.&lt;/span&gt; Create a new note file named for the pattern (e.g. &lt;span class="sb"&gt;`jwt-secret-hardcoded-in-config.md`&lt;/span&gt;)
   with &lt;span class="sb"&gt;`name`&lt;/span&gt;, &lt;span class="sb"&gt;`description`&lt;/span&gt;, and &lt;span class="sb"&gt;`metadata: {type: feedback}`&lt;/span&gt; frontmatter, following
   the structure used in existing notes.
&lt;span class="p"&gt;2.&lt;/span&gt; Add a one-line link to it from &lt;span class="sb"&gt;`MEMORY.md`&lt;/span&gt;.

Do not rewrite or duplicate an existing note — update it in place if the same
pattern recurs with new detail.

&lt;span class="gu"&gt;## Output Format&lt;/span&gt;
For each finding:
&lt;span class="p"&gt;-&lt;/span&gt; OWASP Category
&lt;span class="p"&gt;-&lt;/span&gt; Severity: Critical / High / Medium / Low
&lt;span class="p"&gt;-&lt;/span&gt; File and line number
&lt;span class="p"&gt;-&lt;/span&gt; What an attacker could do with this vulnerability
&lt;span class="p"&gt;-&lt;/span&gt; Exact fix with corrected code snippet

End with: total finding count by severity, and one recommended immediate action.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does a skill hand over a task to an agent?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude launching the security-analyst subagent in the background to audit the authentication codebase.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbsizi0fu5x22fd4lze1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbsizi0fu5x22fd4lze1.png" alt="Skill handover to agent screen clipping" width="799" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The agent runs in the background
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● Agent "Security audit of auth codebase" finished · 4m 42s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The security-analyst audit found &lt;strong&gt;18 findings&lt;/strong&gt; across &lt;code&gt;authService.js&lt;/code&gt;, &lt;code&gt;tokenHelper.js&lt;/code&gt;, &lt;code&gt;routes.js&lt;/code&gt;, &lt;code&gt;middleware.js&lt;/code&gt;, and &lt;code&gt;validators.js&lt;/code&gt;. Two are critical and one of them also breaks the server outright.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Critical&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auth bypass&lt;/strong&gt; — &lt;code&gt;bcrypt.compare(...)&lt;/code&gt; at &lt;code&gt;authService.js:32&lt;/code&gt; is called without &lt;code&gt;await&lt;/code&gt;, so the truthy Promise always passes the check. Every password is accepted for any login.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardcoded JWT fallback secret&lt;/strong&gt; — &lt;code&gt;'dev-secret-key'&lt;/code&gt; in both &lt;code&gt;authService.js:11&lt;/code&gt; and &lt;code&gt;tokenHelper.js:8&lt;/code&gt;, used silently if &lt;code&gt;JWT_SECRET&lt;/code&gt; is unset. Anyone can forge admin tokens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login always builds an inline &lt;code&gt;mockUserRecord&lt;/code&gt; with a constant &lt;code&gt;id: 'user-001'&lt;/code&gt; and attacker-supplied email — every session collapses to the same identity, with a spoofable email claim.&lt;/li&gt;
&lt;li&gt;No rate limiting on &lt;code&gt;/login&lt;/code&gt; or &lt;code&gt;/refresh&lt;/code&gt; — unlimited credential stuffing / refresh-token brute-forcing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;REFRESH_EXPIRES_IN&lt;/code&gt; is declared but never enforced — refresh tokens never expire.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Medium (6 findings)&lt;/strong&gt; — notably: &lt;code&gt;authService.js:80&lt;/code&gt; is missing the &lt;code&gt;async&lt;/code&gt; keyword on &lt;code&gt;refreshToken&lt;/code&gt;, which is a &lt;code&gt;SyntaxError&lt;/code&gt; that prevents the server from booting at all (confirmed via &lt;code&gt;node --check&lt;/code&gt;) — meaning none of this is currently under test/CI coverage; an inverted expiry comparison in &lt;code&gt;isTokenExpired&lt;/code&gt; that also deletes valid sessions; &lt;code&gt;/logout&lt;/code&gt; can revoke anyone's refresh token (no ownership check); access tokens aren't invalidated on logout; PII (raw emails) logged on every auth attempt; unbounded in-memory token store (memory-exhaustion DoS).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Low (7 findings)&lt;/strong&gt; — untrimmed email reaching downstream sinks, internal error messages leaked to clients via substring matching, missing JWT algorithm allowlist, missing security headers/CORS/body-size limits, loose &lt;code&gt;validateBody&lt;/code&gt; treating &lt;code&gt;null&lt;/code&gt;/&lt;code&gt;0&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt; as "present," a low-severity uuid advisory (not reachable, since &lt;code&gt;uuidv4()&lt;/code&gt; is called with no args), and a latent timing side-channel for user enumeration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good news: the newly added &lt;code&gt;validateDateOfBirth&lt;/code&gt; (commit &lt;code&gt;de91f6f&lt;/code&gt;) was checked directly and is clean — correctly rejects rollover dates, future dates, ages over 120, and malformed input. It's not currently wired into any route, so it's not a live attack surface either way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Recommended immediate fix (one commit):&lt;/strong&gt; add the missing &lt;code&gt;await&lt;/code&gt; on &lt;code&gt;bcrypt.compare&lt;/code&gt; (line 32) and the missing &lt;code&gt;async&lt;/code&gt; on &lt;code&gt;refreshToken&lt;/code&gt; (line 80) together — the second is required just to get the app to boot, and without it nothing else can even be tested. Rotate &lt;code&gt;JWT_SECRET&lt;/code&gt; and make it mandatory at startup right after.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Multi-Agent Harness Concepts
&lt;/h2&gt;

&lt;p&gt;When Claude Code itself uses multiple subagents to work on a task, we can say it's using a &lt;strong&gt;multi-agent harness&lt;/strong&gt;. The main thread uses the info from all the agents to create a single report.&lt;/p&gt;

&lt;h3&gt;
  
  
  A second pass: performance, test coverage, and code quality
&lt;/h3&gt;

&lt;p&gt;Prompt: &lt;em&gt;"Create agent for performance review, test coverage, and code quality — use the code review skill."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude clarifying review scope, then running performance, test-coverage, and code-quality agents in parallel while fixing the critical bugs.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmjotxcqcpu6cv7l7t99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmjotxcqcpu6cv7l7t99.png" alt="Performance/test-coverage/code-quality review screen clipping" width="799" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full output — Code Review Report (Performance / Test Coverage / Code Quality)&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Context: Re-run of the performance, test-coverage, and code-quality dimensions against &lt;code&gt;src/auth/authService.js&lt;/code&gt; (security was already covered in the prior review). Findings are consistent with the earlier pass; a few additional specifics surfaced this time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Finding&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Code Quality / Test Coverage&lt;/td&gt;
&lt;td&gt;Missing &lt;code&gt;async&lt;/code&gt; on &lt;code&gt;refreshToken&lt;/code&gt; (line 80) + &lt;code&gt;await&lt;/code&gt; at line 92 → &lt;code&gt;SyntaxError&lt;/code&gt;, module can't load, entire app fails to boot&lt;/td&gt;
&lt;td&gt;🔴 Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Code Quality / Test Coverage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bcrypt.compare&lt;/code&gt; not awaited (line 32) → auth bypass, confirmed independently by ESLint's &lt;code&gt;require-await&lt;/code&gt; flagging &lt;code&gt;loginUser&lt;/code&gt; as having no real await&lt;/td&gt;
&lt;td&gt;🔴 Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Test Coverage&lt;/td&gt;
&lt;td&gt;No test file exists for &lt;code&gt;authService.js&lt;/code&gt; at all — every exported function has 0% coverage&lt;/td&gt;
&lt;td&gt;🔴 Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Test Coverage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;isTokenExpired&lt;/code&gt; inverted logic (line 68) — verified via failing Jest assertions against real signed JWTs&lt;/td&gt;
&lt;td&gt;🔴 Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;isTokenExpired&lt;/code&gt; duplicates &lt;code&gt;tokenHelper.js&lt;/code&gt;'s JWT logic instead of delegating (violates CLAUDE.md's documented layering), and is applied to opaque UUID refresh tokens where it always short-circuits via &lt;code&gt;jwt.decode() === null&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;🟠 High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;REFRESH_EXPIRES_IN&lt;/code&gt; and &lt;code&gt;createdAt&lt;/code&gt; are dead code — confirmed via ESLint &lt;code&gt;no-unused-vars&lt;/code&gt; — refresh tokens never actually expire despite CLAUDE.md documenting a 7-day window&lt;/td&gt;
&lt;td&gt;🟠 High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Unbounded &lt;code&gt;refreshTokenStore&lt;/code&gt; Map — no TTL sweep, grows with cumulative logins not concurrent sessions&lt;/td&gt;
&lt;td&gt;🟠 High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Test Coverage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;refreshToken()&lt;/code&gt;, &lt;code&gt;revokeToken()&lt;/code&gt;, &lt;code&gt;generateRefreshToken()&lt;/code&gt;, &lt;code&gt;generateAccessToken()&lt;/code&gt; have no direct unit tests or edge-case coverage&lt;/td&gt;
&lt;td&gt;🟠 High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bcryptjs&lt;/code&gt; (pure-JS, not native bcrypt) runs password comparison on the main thread, not the libuv threadpool — inflates tail latency under concurrent login bursts&lt;/td&gt;
&lt;td&gt;🟡 Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;Swallowed error in &lt;code&gt;isTokenExpired&lt;/code&gt;'s &lt;code&gt;catch (err)&lt;/code&gt; (line 69-71) — caught but never logged, inconsistent with the rest of the file's logging pattern&lt;/td&gt;
&lt;td&gt;🟡 Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;curly&lt;/code&gt; ESLint rule violation on line 64 (&lt;code&gt;if (...) return true;&lt;/code&gt; without braces)&lt;/td&gt;
&lt;td&gt;🟡 Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;require-await&lt;/code&gt; violation on &lt;code&gt;getUserById&lt;/code&gt; (line 153) — declared async with no await inside&lt;/td&gt;
&lt;td&gt;🟡 Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Test Coverage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;loginUser&lt;/code&gt; with no &lt;code&gt;userRecord&lt;/code&gt;, JWT claims shape, &lt;code&gt;getUserById&lt;/code&gt; stub contract — untested but low-risk edge cases&lt;/td&gt;
&lt;td&gt;🟢 Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;revokeToken&lt;/code&gt;'s "not found" branch logs nothing, inconsistent with other failure branches in the file&lt;/td&gt;
&lt;td&gt;🟢 Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;Imprecise JSDoc return shapes (&lt;code&gt;@returns {object}&lt;/code&gt; instead of a typed shape)&lt;/td&gt;
&lt;td&gt;🟢 Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;New since the last pass&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tooling is broken at the project level: &lt;code&gt;npm run lint&lt;/code&gt; currently fails outright — the repo ships &lt;code&gt;.eslintrc.json&lt;/code&gt; (legacy config) but has ESLint 10.9.1 installed, which requires flat &lt;code&gt;eslint.config.*&lt;/code&gt;. No flat config exists at the repo root. The code-quality agent worked around this by building an equivalent flat config in the scratchpad to get real lint signal (never touched the actual repo files), but as things stand today, &lt;code&gt;npm run lint&lt;/code&gt; gives false confidence — it fails before it even reaches your code. This is worth fixing independent of &lt;code&gt;authService.js&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bcryptjs&lt;/code&gt; vs native bcrypt (finding 9): not raised as a distinct finding in the first pass — flagged now because it compounds with the login-bypass fix. Once &lt;code&gt;await&lt;/code&gt; is added back (finding 2), every login request will run a real CPU-bound bcrypt comparison on the main thread; under concurrent login bursts this inflates latency for unrelated concurrent requests. Not urgent, but worth knowing before assuming the fix is "free."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary Score: 2/10 (unchanged)&lt;/strong&gt; — the file can't boot, has zero test coverage, and now additionally the project's lint tooling can't even verify it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended First Action:&lt;/strong&gt; unchanged — fix the missing &lt;code&gt;async&lt;/code&gt; on &lt;code&gt;refreshToken&lt;/code&gt; (line 80) together with the missing &lt;code&gt;await&lt;/code&gt; on &lt;code&gt;bcrypt.compare&lt;/code&gt; (line 32) in one commit — nothing else here (tests, lint, the rest of the app) is reachable until the module can actually load. Separately, worth a quick fix to add &lt;code&gt;eslint.config.js&lt;/code&gt; so &lt;code&gt;npm run lint&lt;/code&gt; works again — that's a repo-wide gap, not specific to this file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a &lt;strong&gt;hub and spoke model&lt;/strong&gt; — using subagents via a skill. However, what we actually want in some cases is &lt;strong&gt;agents communicating with each other independently in the background&lt;/strong&gt; to finish a task; the hub-and-spoke approach above cannot do that. Agents can instead be run using other agentic harnesses — loop, schedule, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Difference between agent and agentic
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Comparison diagram contrasting framework-driven "Agent" orchestration with model-native "Agentic" execution.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7quqv62a70qls0bn9nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7quqv62a70qls0bn9nt.png" alt="Agent vs agentic diagram screen clipping" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal&lt;/strong&gt;, &lt;strong&gt;loop&lt;/strong&gt;, &lt;strong&gt;schedule&lt;/strong&gt;, &lt;strong&gt;workflow&lt;/strong&gt;, &lt;strong&gt;batch&lt;/strong&gt; — agentic primitives available which help create subtasks (e.g. ultraplan, autofix-pr).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/commands&lt;/code&gt; are manual.&lt;/li&gt;
&lt;li&gt;Skills get applied automatically based on the prompt.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agent&lt;/code&gt; runs in the background.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Hooks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;HOOKS, PLUGINS, MCP e2e flow&lt;/strong&gt; — from evaluating code to fixing code, full auto flow.&lt;/p&gt;

&lt;p&gt;Lifecycle methods available in Claude: from the start to the end of a session, internal events fire inside the session, which are used as plug points for our own code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hook event flow
&lt;/h3&gt;

&lt;p&gt;Whenever Claude reaches a lifecycle boundary — e.g. when a tool is about to run — it spawns our custom script as a subprocess and feeds it a JSON blob on stdin. The script can execute anything, then return:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an exit code (&lt;code&gt;0&lt;/code&gt; or &lt;code&gt;2&lt;/code&gt;), or&lt;/li&gt;
&lt;li&gt;a JSON object on stdout containing a structured decision, reason, and context for Claude to read.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hooks can be created using Python or JavaScript. They take input from Claude Code, display it on screen, and allow the tool to run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: &lt;code&gt;PreToolUse&lt;/code&gt; hook on Bash
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PreToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .claude/hooks/bash-guard.js"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .claude/hooks/pretooluse-demo.js"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this hook sits directly in front of every Bash call, it's a good interception point for anything you want enforced before a shell command runs. Some concrete uses, especially relevant to a repo like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails / safety&lt;/strong&gt; (this is what &lt;code&gt;bash-guard.js&lt;/code&gt; already seems to do) — block dangerous patterns beyond what &lt;code&gt;settings.json&lt;/code&gt;'s deny-list covers, e.g. &lt;code&gt;rm -rf&lt;/code&gt; variants, &lt;code&gt;git push --force&lt;/code&gt;, piping to &lt;code&gt;sh&lt;/code&gt;, etc., using regex instead of exact string matching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  All hook handler types
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PreToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .claude/hooks/pretooluse-demo.js"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.example.com/validate"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Evaluate the steps before running the tool"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Run security-analyst to verify the issues"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp_tool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"some-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validate_edit"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;The bash-guard hook's log file recording every Bash command it allowed during the session.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frw6yxiutl9hbbhxy54ux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frw6yxiutl9hbbhxy54ux.png" alt="Hook handler types screen clipping" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Blocking dangerous commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DANGER_PATTERNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sr"&gt;/rm&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+-rf&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                          &lt;span class="c1"&gt;// recursive force-delete from root (e.g. "rm -rf /")&lt;/span&gt;
    &lt;span class="sr"&gt;/sudo&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+rm/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                              &lt;span class="c1"&gt;// any sudo-elevated delete — bypasses normal permission checks&lt;/span&gt;
    &lt;span class="sr"&gt;/:&lt;/span&gt;&lt;span class="se"&gt;\(\)\{\s&lt;/span&gt;&lt;span class="sr"&gt;*:&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="sr"&gt;:&amp;amp;&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\}\s&lt;/span&gt;&lt;span class="sr"&gt;*;&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*:/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// fork bomb — ":(){ :|:&amp;amp; };:" spawns processes until the system locks up&lt;/span&gt;
    &lt;span class="sr"&gt;/dd&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+if=.*of=&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;dev&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;sd/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;// raw disk write via dd — can overwrite an entire drive&lt;/span&gt;
    &lt;span class="sr"&gt;/chmod&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+777&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                       &lt;span class="c1"&gt;// world-writable permissions on root — opens up the whole filesystem&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notification on Slack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Notification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"permission_prompt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .claude/hooks/slack-notify.js"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logs can be used to audit our work — when we did what, and how much time we spent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing configuration
&lt;/h3&gt;

&lt;p&gt;What if I want to use all my settings in the &lt;code&gt;.claude&lt;/code&gt; folder in another project? This can be done via GitHub. But how can we give it to a third party? Through &lt;strong&gt;plugins&lt;/strong&gt; — see &lt;a href="https://code.claude.com/docs/en/plugins" rel="noopener noreferrer"&gt;code.claude.com/docs/en/plugins&lt;/a&gt; for how to create one.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. MCP (Model Context Protocol)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The concept of an MCP server
&lt;/h3&gt;

&lt;p&gt;The GitHub REST API knows how to connect to GitHub on your behalf.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diagram showing Git Bash and the GH CLI both reaching GitHub's SaaS platform through the GitHub REST API.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fccqi23ew433pu5lby7w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fccqi23ew433pu5lby7w3.png" alt="GitHub REST API screen clipping" width="502" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Either Claude directly connects via Bash, or via the &lt;code&gt;gh&lt;/code&gt; CLI — both of which need to be authenticated. Actually, the &lt;code&gt;gh&lt;/code&gt; CLI is itself using Bash commands under the hood. But can Claude Code directly connect to the GitHub REST API to be faster and more efficient? &lt;code&gt;curl&lt;/code&gt; can be used for that:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Expanded diagram showing how Claude Code uses its Bash tool (via curl, git, or gh CLI) to reach the GitHub REST API.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3c6l5i5p3myzgsw918c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3c6l5i5p3myzgsw918c.png" alt="Curl-based GH REST API connection screen clipping" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why MCP exists
&lt;/h3&gt;

&lt;p&gt;Every ecosystem/SaaS (like GitHub) has a separate, specific, proprietary way of connecting to it — so if Claude has to connect to multiple SaaS platforms, it would need to know all of them, which deviates Claude from its core functionality.&lt;/p&gt;

&lt;p&gt;Can GitHub give a way to connect directly to a REST API? So Anthropic created a new protocol:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude Code has an &lt;strong&gt;inbuilt MCP client&lt;/strong&gt; when installed.&lt;/li&gt;
&lt;li&gt;GitHub/any SaaS provider provides an &lt;strong&gt;MCP server&lt;/strong&gt; — basically an endpoint.&lt;/li&gt;
&lt;li&gt;Our job is only to connect to the MCP server; the MCP server handles the rest.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Three types of MCP server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;stdio&lt;/strong&gt; — runs locally on the machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;http&lt;/strong&gt; — hosted at an HTTP location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSE&lt;/strong&gt; — Server-Sent Events, a streaming protocol&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All AI tools support MCP servers. The MCP client is part of the ecosystem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Claude Code runs with an agentic harness — the LLM decides what to do, and the LLM tells Claude Code which tools to use.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. End-to-End Automation
&lt;/h2&gt;

&lt;p&gt;End-to-end automation of security review → issue creation → issue fix → PR creation → PR fix, all through agents.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The /security-review command loading its skill to audit tokenHelper.js.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsecislasgjmafpge71ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsecislasgjmafpge71ah.png" alt="End-to-end automation intro screen clipping" width="584" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Security review finding a critical hardcoded fallback JWT signing secret vulnerability in tokenHelper.js.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwoo4jschokn8ljjgfryl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwoo4jschokn8ljjgfryl.png" alt="Automation flow screen clipping" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/create-issue&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Claude using the gh CLI to file a GitHub issue for the hardcoded JWT secret vulnerability.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flw19l10sb7c8eyw6k7l1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flw19l10sb7c8eyw6k7l1.png" alt="Create issue screen clipping" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub issue #2 detailing the hardcoded fallback JWT secret bug, its impact, and expected fix.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3iy5j7gpzpo5cze2hi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3iy5j7gpzpo5cze2hi4.png" alt="Create issue result screen clipping" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now fix the issue
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Claude implementing the fix: removing the hardcoded JWT secret fallback and requiring the env var explicitly.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2aaxl64ntvxmah7wgtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2aaxl64ntvxmah7wgtg.png" alt="Fix the issue screen clipping" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Commit the changes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The /commit command staging, reviewing, and pushing the JWT secret fix with a detailed commit message.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foxh3fk45tvwrtqkx79vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foxh3fk45tvwrtqkx79vp.png" alt="Commit changes screen clipping" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub activity showing the fix commit automatically linked to close issue #2.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhxq6ggwpjdlmjbxqocre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhxq6ggwpjdlmjbxqocre.png" alt="Commit result screen clipping 1" width="798" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pull request description summarizing what changed and why for the JWT secret fix.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8sdrtyg52zwzg139t09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8sdrtyg52zwzg139t09.png" alt="Commit result screen clipping 2" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Agent Teams
&lt;/h2&gt;

&lt;p&gt;Beyond single subagent delegation, Claude Code supports &lt;strong&gt;Agent Teams&lt;/strong&gt; — multiple agents working the same task from different angles in parallel, then synthesizing a combined result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example prompt
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Create an agent team to review PR #1.&lt;br&gt;
Spawn three reviewers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reviewer 1: focused exclusively on security implications&lt;/li&gt;
&lt;li&gt;Reviewer 2: focused on performance and scalability&lt;/li&gt;
&lt;li&gt;Reviewer 3: validating test coverage and edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have them each review independently, then synthesize findings into a single report.&lt;br&gt;
Create a new branch with custom name including today's date.&lt;br&gt;
Merge and close the PR with comment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;User prompt instructing Claude to spawn three specialized reviewer agents to review and merge PR #1.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3y6axvgkb9davveadh4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3y6axvgkb9davveadh4y.png" alt="Agent teams prompt screen clipping" width="799" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 3 agents are invoked in the background:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude launching three specialized reviewer agents in parallel to review PR #1.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwtyyqypghqmxtt8q83t3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwtyyqypghqmxtt8q83t3.png" alt="Agents invoked in background screen clipping" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Progress log showing the security and test-coverage reviewer agents finishing with real findings.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa61rg7s3odmebbkaz7a8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa61rg7s3odmebbkaz7a8.png" alt="Agent team progress screen clipping 1" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude synthesizing all three reviewer agents' findings before applying fixes and merging.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbt0r6fynkc7sj88vjwu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbt0r6fynkc7sj88vjwu9.png" alt="Agent team progress screen clipping 2" width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude merging the verified fix, filing two follow-up issues, and preparing to post the review synthesis as a PR comment.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjg8b2d7k3m8twcxgyzj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjg8b2d7k3m8twcxgyzj.png" alt="Agent team result screen clipping 1" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Final summary of the agent-team review: verdicts from all three reviewers and the actions taken to merge PR #1.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwep2tfayik2sa7gce8e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwep2tfayik2sa7gce8e6.png" alt="Agent team result screen clipping 2" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;agentic loop&lt;/strong&gt; (gather context → decide → act → verify) is the mental model for everything Claude Code does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLAUDE.md&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.claude/settings.json&lt;/code&gt;&lt;/strong&gt; are how you shape Claude's behavior and permissions for a specific project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commands&lt;/strong&gt; are manual, &lt;strong&gt;Skills&lt;/strong&gt; auto-trigger, and &lt;strong&gt;Agents&lt;/strong&gt; run scoped, background work — often orchestrated together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks&lt;/strong&gt; and &lt;strong&gt;MCP&lt;/strong&gt; are the two extension points: hooks intercept lifecycle events for guardrails/automation, MCP standardizes how Claude talks to external tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session management&lt;/strong&gt; (&lt;code&gt;/resume&lt;/code&gt;, &lt;code&gt;/fork&lt;/code&gt;, &lt;code&gt;/compact&lt;/code&gt;) is essential for working on multiple issues without polluting context or wasting tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Teams&lt;/strong&gt; unlock genuinely parallel, multi-perspective work — like having three reviewers look at a PR simultaneously.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This was a genuinely comprehensive look at how far the agentic coding model has come — from a single loop reading and writing files, to fully orchestrated, permissioned, multi-agent development workflows.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>productivity</category>
      <category>devtools</category>
    </item>
    <item>
      <title>AI &amp; ML Foundations: Cleaning Data, Building Regression &amp; Classification Models in Python.</title>
      <dc:creator>yash-nigam</dc:creator>
      <pubDate>Mon, 31 Aug 2026 16:53:20 +0000</pubDate>
      <link>https://dev.to/yashnigam/ai-ml-foundations-cleaning-data-building-regression-classification-models-in-python-7gc</link>
      <guid>https://dev.to/yashnigam/ai-ml-foundations-cleaning-data-building-regression-classification-models-in-python-7gc</guid>
      <description>&lt;h1&gt;
  
  
  My 5-Day Journey into Machine Learning: From Data Cleaning to My First ML Models
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning goal:&lt;/strong&gt; This is not a collection of code snippets to memorize. It is a beginner-friendly guide to understanding &lt;em&gt;why&lt;/em&gt; each step in a typical machine-learning workflow exists, what problem it solves, and how the pieces fit together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A note about the source material
&lt;/h2&gt;

&lt;p&gt;This guide was built primarily from the four Jupyter notebooks you provided:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;11_Aug_mpg.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;12-Aug-2.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;12th-Aug-Telco-Customer-churn.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;13-Aug.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;123&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your PDF notes were also provided, but the PDF is image-based and its text could not be reliably extracted. So I have &lt;strong&gt;not invented or silently reconstructed&lt;/strong&gt; material from the PDF. The explanations below are grounded mainly in the notebooks, with general ML knowledge added to explain the concepts behind the code.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Overview: What did I actually learn in these five days?
&lt;/h1&gt;

&lt;p&gt;At first glance, machine learning can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load dataset
    ↓
Clean data
    ↓
Create graphs
    ↓
Train model
    ↓
Check accuracy
    ↓
Done!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that misses the most important part.&lt;/p&gt;

&lt;p&gt;The real ML workflow is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business / real-world question
        ↓
Define what we want to predict
        ↓
Understand the data
        ↓
Clean and prepare the data
        ↓
Explore the data visually
        ↓
Choose useful features
        ↓
Convert data into numbers
        ↓
Split into training and testing data
        ↓
Choose an appropriate ML algorithm
        ↓
Train the model
        ↓
Evaluate it on unseen data
        ↓
Compare models
        ↓
Improve preprocessing / model settings
        ↓
Use the model to make predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important insight is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Machine learning is not mainly about choosing an algorithm. It is about turning a real-world question and messy data into a reliable prediction process.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your notebooks actually demonstrate most of this workflow.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. What is Artificial Intelligence?
&lt;/h1&gt;

&lt;p&gt;Artificial Intelligence (AI) is the broad idea of building systems that can perform tasks that normally require some form of human intelligence.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recognizing an image&lt;/li&gt;
&lt;li&gt;understanding language&lt;/li&gt;
&lt;li&gt;recommending a movie&lt;/li&gt;
&lt;li&gt;detecting fraud&lt;/li&gt;
&lt;li&gt;predicting whether a customer will leave&lt;/li&gt;
&lt;li&gt;predicting the price/value of something&lt;/li&gt;
&lt;li&gt;generating text or images&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artificial Intelligence
│
├── Machine Learning
│   │
│   ├── Supervised Learning
│   ├── Unsupervised Learning
│   └── Reinforcement Learning
│
├── Deep Learning
│
└── Generative AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyash-nigam%2FAI-ML-Foundations%2Fblob%2F7516a4b681369d4b105ca19706f7d06da65e30a9%2Fimages%2FAIMLHierarchy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyash-nigam%2FAI-ML-Foundations%2Fblob%2F7516a4b681369d4b105ca19706f7d06da65e30a9%2Fimages%2FAIMLHierarchy.png" alt="image" width="" height=""&gt;&lt;/a&gt;&lt;br&gt;
This is simplified because these areas overlap, but it is a useful beginner mental model.&lt;/p&gt;


&lt;h1&gt;
  
  
  3. What is Machine Learning?
&lt;/h1&gt;

&lt;p&gt;Machine learning is a way of building systems where the computer learns patterns from data instead of us manually writing every rule.&lt;/p&gt;

&lt;p&gt;Imagine we want to predict whether a telecom customer will churn.&lt;/p&gt;

&lt;p&gt;A traditional rule-based approach might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF customer has a month-to-month contract
AND monthly charges are high
AND tenure is low
THEN churn = yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that we have to invent those rules ourselves.&lt;/p&gt;

&lt;p&gt;With machine learning, we give the algorithm historical examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer information → Actual churn result

Customer A → No
Customer B → Yes
Customer C → No
Customer D → Yes
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The algorithm tries to learn the relationship between the input information and the known outcome.&lt;/p&gt;

&lt;p&gt;Then we can give it a new customer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New customer information
        ↓
      Model
        ↓
Predicted churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the core idea of supervised machine learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. The most important ML vocabulary
&lt;/h1&gt;

&lt;p&gt;Before learning algorithms, understand these words.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.1 Dataset
&lt;/h2&gt;

&lt;p&gt;A dataset is a collection of examples.&lt;/p&gt;

&lt;p&gt;In your notebooks, a dataset is loaded into a Pandas DataFrame.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Telco_Customer_Churn.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of the DataFrame as a spreadsheet.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.2 Row / observation / sample
&lt;/h2&gt;

&lt;p&gt;Each row represents one example.&lt;/p&gt;

&lt;p&gt;For the Telco dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one customer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the Auto MPG dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one car
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the insurance dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one customer/policy record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These words are often used interchangeably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;row&lt;/li&gt;
&lt;li&gt;observation&lt;/li&gt;
&lt;li&gt;sample&lt;/li&gt;
&lt;li&gt;instance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4.3 Feature
&lt;/h2&gt;

&lt;p&gt;A feature is an input variable that the model can use to make a prediction.&lt;/p&gt;

&lt;p&gt;For customer churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tenure
MonthlyCharges
Contract
InternetService
PaymentMethod
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are features.&lt;/p&gt;

&lt;p&gt;A useful question to ask is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What information is available to the model before it makes its prediction?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That information is generally your feature set.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.4 Target
&lt;/h2&gt;

&lt;p&gt;The target is what we are trying to predict.&lt;/p&gt;

&lt;p&gt;Examples from your notebooks:&lt;/p&gt;

&lt;h3&gt;
  
  
  Telco
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target = Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model predicts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 → No churn
1 → Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insurance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target = Customer Lifetime Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model predicts a numerical value.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.5 X and y
&lt;/h2&gt;

&lt;p&gt;You repeatedly used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important patterns in supervised ML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X = inputs/features
Y = target/output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X
├── tenure
├── MonthlyCharges
├── Contract
├── InternetService
└── ...

Y
└── Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;X = what the model knows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Y = what we want the model to learn to predict&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  5. The three major types of Machine Learning
&lt;/h1&gt;

&lt;h2&gt;
  
  
  5.1 Supervised Learning
&lt;/h2&gt;

&lt;p&gt;In supervised learning, we have examples where the correct answer is already known.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input X → Known answer Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model learns the relationship between X and Y.&lt;/p&gt;

&lt;p&gt;Your notebooks mainly use supervised learning.&lt;/p&gt;

&lt;p&gt;There are two major supervised learning tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classification
&lt;/h3&gt;

&lt;p&gt;The target is a category.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Spam / Not Spam
Churn / No Churn
Fraud / Not Fraud
Disease / No Disease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Telco project is a classification problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regression
&lt;/h3&gt;

&lt;p&gt;The target is a numerical value.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;House price
Temperature
Sales
Customer Lifetime Value
Fuel efficiency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Customer Lifetime Value project is a regression problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Classification vs Regression
&lt;/h1&gt;

&lt;p&gt;This distinction is extremely important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classification
&lt;/h2&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which category does this example belong to?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Churn or No Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common classification algorithms you tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logistic Regression&lt;/li&gt;
&lt;li&gt;Support Vector Classifier (SVC)&lt;/li&gt;
&lt;li&gt;Decision Tree Classifier&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Regression
&lt;/h2&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What numerical value should we predict?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Customer Lifetime Value = 6,543.21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common regression algorithms you tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear Regression&lt;/li&gt;
&lt;li&gt;KNN Regressor&lt;/li&gt;
&lt;li&gt;SVR&lt;/li&gt;
&lt;li&gt;Decision Tree Regressor&lt;/li&gt;
&lt;li&gt;Bagging Regressor&lt;/li&gt;
&lt;li&gt;AdaBoost Regressor&lt;/li&gt;
&lt;li&gt;Random Forest Regressor&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  7. Unsupervised Learning
&lt;/h1&gt;

&lt;p&gt;In unsupervised learning, we do not have a known target.&lt;/p&gt;

&lt;p&gt;Instead, the algorithm tries to discover structure in the data.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer data
     ↓
Find groups
     ↓
Group 1: high-value customers
Group 2: price-sensitive customers
Group 3: new customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;K-Means clustering&lt;/li&gt;
&lt;li&gt;Hierarchical clustering&lt;/li&gt;
&lt;li&gt;PCA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You did not build an unsupervised-learning project in these notebooks, but it is important to know where it fits.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Reinforcement Learning
&lt;/h1&gt;

&lt;p&gt;Reinforcement learning is different.&lt;/p&gt;

&lt;p&gt;An agent interacts with an environment and receives rewards or penalties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓ action
Environment
  ↓
Reward / penalty
  ↓
Agent learns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;game-playing agents&lt;/li&gt;
&lt;li&gt;robotics&lt;/li&gt;
&lt;li&gt;certain recommendation/control systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was not part of your five-day practical work.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Different ways to approach an ML problem
&lt;/h1&gt;

&lt;p&gt;A useful way to think about ML is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which algorithm should I use?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — What is the question?
&lt;/h3&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can I predict whether a telecom customer will churn?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 2 — What type of target do I have?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn → category → Classification
Customer Lifetime Value → number → Regression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — What data is available?
&lt;/h3&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What columns exist?&lt;/li&gt;
&lt;li&gt;Which are numerical?&lt;/li&gt;
&lt;li&gt;Which are categorical?&lt;/li&gt;
&lt;li&gt;Are values missing?&lt;/li&gt;
&lt;li&gt;Are there strange values?&lt;/li&gt;
&lt;li&gt;Are some columns identifiers?&lt;/li&gt;
&lt;li&gt;Is the target balanced?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4 — Explore before modeling
&lt;/h3&gt;

&lt;p&gt;Use statistics and graphs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — Prepare the data
&lt;/h3&gt;

&lt;p&gt;Convert it into a form the algorithm can understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 — Establish a baseline
&lt;/h3&gt;

&lt;p&gt;Train a simple model first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7 — Compare alternatives
&lt;/h3&gt;

&lt;p&gt;Try other appropriate models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8 — Evaluate on unseen data
&lt;/h3&gt;

&lt;p&gt;A model is useful only if it works beyond the data it memorized.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Google Colab: Why did we use it?
&lt;/h1&gt;

&lt;p&gt;Google Colab gives you a cloud-based Jupyter Notebook environment.&lt;/p&gt;

&lt;p&gt;Instead of installing everything locally, you can run Python code in the browser.&lt;/p&gt;

&lt;p&gt;A notebook combines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explanation
+
Python code
+
Output
+
Graphs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it very useful for learning ML.&lt;/p&gt;

&lt;p&gt;Your notebooks use paths such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is typical of a Colab environment.&lt;/p&gt;

&lt;p&gt;A normal learning workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upload dataset
      ↓
Open notebook
      ↓
Run cells
      ↓
Inspect output
      ↓
Change code
      ↓
Run again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  11. The Python libraries you used
&lt;/h1&gt;

&lt;h2&gt;
  
  
  11.1 NumPy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NumPy provides numerical operations and arrays.&lt;/p&gt;

&lt;p&gt;You used it for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;
&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expm1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;np.nan&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a missing numerical value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;np.log1p(x)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Calculates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log(1 + x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is useful when a target is heavily skewed.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;np.expm1(x)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Reverses &lt;code&gt;log1p&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exp(x) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You used this later to convert log predictions back to the original CLV scale.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Pandas
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pandas is one of the most important Python libraries for data work.&lt;/p&gt;

&lt;p&gt;Think of a Pandas DataFrame as a spreadsheet that Python can manipulate.&lt;/p&gt;

&lt;p&gt;You used it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load CSV files&lt;/li&gt;
&lt;li&gt;inspect data&lt;/li&gt;
&lt;li&gt;remove columns&lt;/li&gt;
&lt;li&gt;convert data types&lt;/li&gt;
&lt;li&gt;detect missing values&lt;/li&gt;
&lt;li&gt;fill missing values&lt;/li&gt;
&lt;li&gt;select X and Y&lt;/li&gt;
&lt;li&gt;create encoded columns&lt;/li&gt;
&lt;li&gt;save predictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Telco_Customer_Churn.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  13. Matplotlib
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matplotlib is a general-purpose plotting library.&lt;/p&gt;

&lt;p&gt;It provides the foundation for many Python visualizations.&lt;/p&gt;

&lt;p&gt;You used it for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  14. Seaborn
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seaborn makes statistical visualizations easier to create.&lt;/p&gt;

&lt;p&gt;You used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;countplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;boxplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;histplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pairplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scatterplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;heatmap&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A graph is not decoration. It is a tool for asking questions about the data.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  15. Scikit-learn
&lt;/h1&gt;

&lt;p&gt;Scikit-learn is the main ML library used in your notebooks.&lt;/p&gt;

&lt;p&gt;You used it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;splitting data&lt;/li&gt;
&lt;li&gt;preprocessing&lt;/li&gt;
&lt;li&gt;encoding&lt;/li&gt;
&lt;li&gt;scaling&lt;/li&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;regression&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern appears again and again in ML.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. The most important workflow: EDA
&lt;/h1&gt;

&lt;p&gt;EDA means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Exploratory Data Analysis&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;EDA is the process of investigating the dataset before building the final model.&lt;/p&gt;

&lt;p&gt;Your notebooks use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;plus graphs.&lt;/p&gt;

&lt;p&gt;These are not random commands.&lt;/p&gt;

&lt;p&gt;They answer different questions.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. &lt;code&gt;df.head()&lt;/code&gt; — What does the data look like?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It displays the first few rows.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because before doing anything else, you want to see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;column names&lt;/li&gt;
&lt;li&gt;example values&lt;/li&gt;
&lt;li&gt;obvious data problems&lt;/li&gt;
&lt;li&gt;whether the data loaded correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as opening the box before using what is inside.&lt;/p&gt;




&lt;h1&gt;
  
  
  18. &lt;code&gt;df.shape&lt;/code&gt; — How much data do I have?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Auto MPG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(398, 9)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;398 rows
9 columns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does this matter?&lt;/p&gt;

&lt;p&gt;Because dataset size affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;model choice&lt;/li&gt;
&lt;li&gt;computation time&lt;/li&gt;
&lt;li&gt;confidence in results&lt;/li&gt;
&lt;li&gt;risk of overfitting&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  19. &lt;code&gt;df.info()&lt;/code&gt; — What types of data do I have?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;column names&lt;/li&gt;
&lt;li&gt;number of non-null values&lt;/li&gt;
&lt;li&gt;data types&lt;/li&gt;
&lt;li&gt;memory usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is extremely important.&lt;/p&gt;

&lt;p&gt;For example, in Auto MPG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;horsepower → object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance horsepower sounds numerical.&lt;/p&gt;

&lt;p&gt;But Pandas sees it as text.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the dataset contains values such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A column containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;130
165
150
?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cannot be treated as a clean numerical column.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;df.info()&lt;/code&gt; helps you detect data-type problems before modeling.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  20. &lt;code&gt;df.describe()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and sometimes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives summary statistics.&lt;/p&gt;

&lt;p&gt;For numerical data you get things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;count&lt;/li&gt;
&lt;li&gt;mean&lt;/li&gt;
&lt;li&gt;standard deviation&lt;/li&gt;
&lt;li&gt;minimum&lt;/li&gt;
&lt;li&gt;25th percentile&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;75th percentile&lt;/li&gt;
&lt;li&gt;maximum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps you understand the scale and distribution of variables.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minimum
   ↓
25%
   ↓
median
   ↓
75%
   ↓
maximum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A large difference between the 75th percentile and maximum can be a clue that there may be extreme values.&lt;/p&gt;




&lt;h1&gt;
  
  
  21. &lt;code&gt;df.sample()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or similar.&lt;/p&gt;

&lt;p&gt;This shows random rows.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the first rows may not represent the whole dataset.&lt;/p&gt;

&lt;p&gt;Random samples can expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unusual values&lt;/li&gt;
&lt;li&gt;formatting issues&lt;/li&gt;
&lt;li&gt;unexpected categories&lt;/li&gt;
&lt;li&gt;data-entry problems&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  22. Missing data
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many missing values are there in each column?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Missing data is important because many ML algorithms cannot directly work with missing values.&lt;/p&gt;

&lt;p&gt;But there is a subtle lesson from your Auto MPG notebook.&lt;/p&gt;

&lt;p&gt;You first checked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while &lt;code&gt;horsepower&lt;/code&gt; still contained &lt;code&gt;"?"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pandas did not count &lt;code&gt;"?"&lt;/code&gt; as a missing value because &lt;code&gt;"?"&lt;/code&gt; is a string, not a true &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"?" ≠ NaN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So data cleaning sometimes requires identifying &lt;strong&gt;fake missing values&lt;/strong&gt; first.&lt;/p&gt;




&lt;h1&gt;
  
  
  23. Auto MPG: cleaning horsepower
&lt;/h1&gt;

&lt;p&gt;Your notebook did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This converts the placeholder into a real missing value.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Pandas can treat horsepower as numerical data.&lt;/p&gt;

&lt;p&gt;This is a very important data-cleaning pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messy text
   ↓
identify invalid placeholder
   ↓
convert to NaN
   ↓
convert column to numeric
   ↓
handle missing values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  24. Why use the median?
&lt;/h1&gt;

&lt;p&gt;You calculated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;median_horsepower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then filled missing values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;median_horsepower&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why median?&lt;/p&gt;

&lt;p&gt;Because the median is less affected by extreme values than the mean.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10, 11, 12, 13, 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mean is pulled heavily upward by 1000.&lt;/p&gt;

&lt;p&gt;The median is much more representative of the middle of the data.&lt;/p&gt;

&lt;p&gt;A useful rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fairly symmetric data → mean may work well&lt;/li&gt;
&lt;li&gt;skewed data / outliers → median is often safer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is no universal rule that "median is always correct."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The best treatment depends on the data and the problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  25. Dropping an identifier
&lt;/h1&gt;

&lt;p&gt;You considered dropping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;car name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and actually dropped &lt;code&gt;customerID&lt;/code&gt; in the Telco work.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;An identifier is usually not a meaningful predictive feature.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID = 759832
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not inherently mean the customer is more or less likely to churn.&lt;/p&gt;

&lt;p&gt;The ID exists to identify the row, not to describe the customer.&lt;/p&gt;

&lt;p&gt;Important distinction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A column can be useful for identifying a record without being useful for predicting the target.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  26. But don't blindly drop columns
&lt;/h1&gt;

&lt;p&gt;This is an important improvement to your original reasoning.&lt;/p&gt;

&lt;p&gt;A column should not be dropped merely because it is an object/string.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract
InternetService
PaymentMethod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;are categorical strings, but they can contain very useful predictive information.&lt;/p&gt;

&lt;p&gt;So the correct question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does this column contain useful information that is available at prediction time?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this column numeric?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  27. Understanding your graphs
&lt;/h1&gt;

&lt;p&gt;You created many graphs. The important thing is to understand what question each graph answers.&lt;/p&gt;




&lt;h1&gt;
  
  
  28. Countplot
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A countplot answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many observations are in each category?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No churn → number of customers
Churn    → number of customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This immediately helps you understand class balance.&lt;/p&gt;

&lt;p&gt;If the graph looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No Churn ███████████████████
Churn    ███████
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the classes are imbalanced.&lt;/p&gt;

&lt;p&gt;That matters because a model could achieve high accuracy simply by favoring the majority class.&lt;/p&gt;




&lt;h1&gt;
  
  
  29. Countplot with &lt;code&gt;hue&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contract&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How does the target category vary across another category?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract type
     ↓
Churn / No churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If month-to-month customers show much more churn than two-year customers, that is an important pattern worth investigating.&lt;/p&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A graph showing association does not automatically prove causation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  30. Histogram
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;histplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MonthlyCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;kde&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A histogram shows the distribution of a numerical variable.&lt;/p&gt;

&lt;p&gt;It helps answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are most values?&lt;/li&gt;
&lt;li&gt;Is the data symmetric?&lt;/li&gt;
&lt;li&gt;Is it skewed?&lt;/li&gt;
&lt;li&gt;Are there multiple groups?&lt;/li&gt;
&lt;li&gt;Are there extreme values?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frequency
   ^
   |       ███
   |     ███████
   |   █████████
   | ███████████
   +-----------------&amp;gt; value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  31. Why distributions matter
&lt;/h1&gt;

&lt;p&gt;Suppose a feature looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most values: 0–100
A few values: 10,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That may indicate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;genuine outliers&lt;/li&gt;
&lt;li&gt;a different population&lt;/li&gt;
&lt;li&gt;data-entry errors&lt;/li&gt;
&lt;li&gt;a highly skewed distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model may react differently depending on the algorithm.&lt;/p&gt;

&lt;p&gt;This is one reason EDA happens before modeling.&lt;/p&gt;




&lt;h1&gt;
  
  
  32. Boxplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A boxplot summarizes a distribution.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       outlier
          •
          |
      ┌───────┐
      │       │
------│  box  │------
      │       │
      └───────┘
          |
       outlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The box represents the middle portion of the data.&lt;/p&gt;

&lt;p&gt;The line inside the box is the median.&lt;/p&gt;

&lt;p&gt;Points outside the whiskers may be treated as potential outliers.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An outlier is not automatically an error.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A high-income customer may be perfectly legitimate.&lt;/p&gt;




&lt;h1&gt;
  
  
  33. Boxplot: target vs category
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Coverage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a powerful graph.&lt;/p&gt;

&lt;p&gt;It asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How does the distribution of Customer Lifetime Value differ between categories?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Coverage A → CLV distribution
Coverage B → CLV distribution
Coverage C → CLV distribution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;spread&lt;/li&gt;
&lt;li&gt;outliers&lt;/li&gt;
&lt;li&gt;overlap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can help you identify potentially useful relationships.&lt;/p&gt;




&lt;h1&gt;
  
  
  34. Scatterplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A scatterplot examines the relationship between two numerical variables.&lt;/p&gt;

&lt;p&gt;Each dot represents an observation.&lt;/p&gt;

&lt;p&gt;It helps answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"As X changes, does Y appear to change?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Possible patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Positive relationship:
  •
    •
      •
        •

Negative relationship:
        •
      •
    •
  •

No obvious relationship:
 •    •
    •
  •      •
     •
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern does not have to be a straight line.&lt;/p&gt;




&lt;h1&gt;
  
  
  35. Pairplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pairplot&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A pairplot shows many numerical relationships at once.&lt;/p&gt;

&lt;p&gt;It is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spotting correlations&lt;/li&gt;
&lt;li&gt;identifying clusters&lt;/li&gt;
&lt;li&gt;seeing distributions&lt;/li&gt;
&lt;li&gt;finding obvious relationships&lt;/li&gt;
&lt;li&gt;detecting possible outliers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The downside is that it becomes difficult to read when there are many columns.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pairplot is excellent for small-to-medium exploratory datasets, but not something you blindly run on every large dataset.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  36. Correlation heatmap
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heatmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MonthlyCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;annot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Correlation measures how two numerical variables move together in a linear relationship.&lt;/p&gt;

&lt;p&gt;A correlation close to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+1 → strong positive linear relationship
 0 → little/no linear relationship
-1 → strong negative linear relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tenure ↑
TotalCharges ↑
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could result in positive correlation.&lt;/p&gt;

&lt;p&gt;But correlation has an important limitation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Correlation does not prove causation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, zero correlation does not necessarily mean "no relationship" because the relationship might be non-linear.&lt;/p&gt;




&lt;h1&gt;
  
  
  37. A key lesson from visualization
&lt;/h1&gt;

&lt;p&gt;The graphs answer different questions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Graph&lt;/th&gt;
&lt;th&gt;Main question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Countplot&lt;/td&gt;
&lt;td&gt;How many observations are in each category?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot + hue&lt;/td&gt;
&lt;td&gt;How does one category vary with another?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Histogram&lt;/td&gt;
&lt;td&gt;What does a numerical distribution look like?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boxplot&lt;/td&gt;
&lt;td&gt;What are the median, spread and potential outliers?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boxplot + category&lt;/td&gt;
&lt;td&gt;How does a numerical distribution differ by category?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scatterplot&lt;/td&gt;
&lt;td&gt;How do two numerical variables relate?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pairplot&lt;/td&gt;
&lt;td&gt;What relationships exist among several numerical variables?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heatmap&lt;/td&gt;
&lt;td&gt;How strongly are numerical variables linearly correlated?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The goal is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create lots of graphs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use the right graph to answer the right question."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  38. Encoding: why does ML need it?
&lt;/h1&gt;

&lt;p&gt;Many ML algorithms work with numbers.&lt;/p&gt;

&lt;p&gt;But real-world data contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Male
Female

Yes
No

Month-to-month
One year
Two year

Fiber optic
DSL
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model needs these values represented numerically.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;encoding&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  39. Label Encoding
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LabelEncoder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and encoded categorical columns.&lt;/p&gt;

&lt;p&gt;For a binary column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be reasonable for a binary variable.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn:
No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes intuitive sense.&lt;/p&gt;




&lt;h1&gt;
  
  
  40. Why LabelEncoder can be dangerous for multi-category variables
&lt;/h1&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract:
Month-to-month
One year
Two year
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Label encoding might produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Month-to-month → 0
One year       → 1
Two year       → 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A numerical model may interpret that as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Two year &amp;gt; One year &amp;gt; Month-to-month
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ordering may not be appropriate for the algorithm.&lt;/p&gt;

&lt;p&gt;The numbers are just codes.&lt;/p&gt;

&lt;p&gt;They do not automatically mean that category 2 is "twice" category 1.&lt;/p&gt;

&lt;p&gt;For nominal categories, one-hot encoding is usually safer.&lt;/p&gt;




&lt;h1&gt;
  
  
  41. One-hot encoding
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dummies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drop_first&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transforms categories into separate binary columns.&lt;/p&gt;

&lt;p&gt;For:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InternetService:
DSL
Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we might create columns such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InternetService_Fiber optic
InternetService_No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the remaining category represented by both values being 0.&lt;/p&gt;

&lt;p&gt;This avoids inventing a fake numerical ordering.&lt;/p&gt;




&lt;h1&gt;
  
  
  42. Why &lt;code&gt;drop_first=True&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;If a categorical variable has several categories, using all one-hot columns can introduce redundancy in some models.&lt;/p&gt;

&lt;p&gt;Dropping one category creates a reference category.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DSL
Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fiber optic = 0
No = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the reference category:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DSL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For beginner understanding, the key idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One-hot encoding converts categories into machine-readable indicator variables without pretending the categories have numerical order.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  43. Train/test split
&lt;/h1&gt;

&lt;p&gt;You repeatedly used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important ML concepts.&lt;/p&gt;

&lt;p&gt;Suppose we have 1,000 examples.&lt;/p&gt;

&lt;p&gt;We might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;700 → training
300 → testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The training set is used to learn the model.&lt;/p&gt;

&lt;p&gt;The test set is held back to evaluate how the trained model performs on unseen data.&lt;/p&gt;

&lt;p&gt;Think of it like an exam:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data = practice questions
Test data     = unseen exam questions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  44. Why not train and test on the same data?
&lt;/h1&gt;

&lt;p&gt;Because the model could simply memorize the training examples.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 99%
Test score     = 65%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a warning sign.&lt;/p&gt;

&lt;p&gt;The model learned the training data extremely well but does not generalize well.&lt;/p&gt;

&lt;p&gt;This is called:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Overfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  45. Underfitting
&lt;/h1&gt;

&lt;p&gt;The opposite can happen.&lt;/p&gt;

&lt;p&gt;If the model is too simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 60%
Test score     = 58%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may not have learned enough from the data.&lt;/p&gt;

&lt;p&gt;This is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Underfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A useful mental picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Underfitting
Model too simple
       ↓
misses important patterns

Good fit
Learns useful patterns
       ↓
works on unseen data

Overfitting
Model learns noise/details
       ↓
great training performance
poor unseen performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  46. Why &lt;code&gt;random_state&lt;/code&gt; matters
&lt;/h1&gt;

&lt;p&gt;In one Telco notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the improved notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A random state makes the split reproducible.&lt;/p&gt;

&lt;p&gt;Without it, the random split can change between runs.&lt;/p&gt;

&lt;p&gt;That means your score may change.&lt;/p&gt;

&lt;p&gt;With:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can reproduce the same split.&lt;/p&gt;

&lt;p&gt;The number &lt;code&gt;42&lt;/code&gt; is not magical.&lt;/p&gt;

&lt;p&gt;Any fixed integer can serve this purpose.&lt;/p&gt;




&lt;h1&gt;
  
  
  47. Why &lt;code&gt;stratify=Y&lt;/code&gt; is useful for classification
&lt;/h1&gt;

&lt;p&gt;In your improved Telco notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;stratify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps preserve the class distribution between training and testing data.&lt;/p&gt;

&lt;p&gt;For example, if the full dataset contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;73% No Churn
27% Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;stratification aims to keep roughly the same proportion in both splits.&lt;/p&gt;

&lt;p&gt;This is particularly useful when classes are imbalanced.&lt;/p&gt;




&lt;h1&gt;
  
  
  48. Logistic Regression
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.linear_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LogisticRegression&lt;/span&gt;

&lt;span class="n"&gt;model_lr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model_lr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite its name, Logistic Regression is commonly used for &lt;strong&gt;classification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its goal is to estimate the probability of belonging to a class.&lt;/p&gt;

&lt;p&gt;For binary classification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features
   ↓
Logistic Regression
   ↓
probability
   ↓
class
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Probability of churn = 0.82
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may classify that customer as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;depending on its decision threshold.&lt;/p&gt;




&lt;h1&gt;
  
  
  49. Why Logistic Regression is a good beginner model
&lt;/h1&gt;

&lt;p&gt;It is useful because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;relatively simple&lt;/li&gt;
&lt;li&gt;fast&lt;/li&gt;
&lt;li&gt;often strong as a baseline&lt;/li&gt;
&lt;li&gt;easier to interpret than many complex models&lt;/li&gt;
&lt;li&gt;naturally suited to binary classification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good ML habit is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Start with a simple baseline before reaching for complex models.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  50. Support Vector Machine / SVC
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.svm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SVC&lt;/span&gt;

&lt;span class="n"&gt;model_lr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SVC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable name &lt;code&gt;model_lr&lt;/code&gt; is misleading here.&lt;/p&gt;

&lt;p&gt;It is actually an SVC model.&lt;/p&gt;

&lt;p&gt;SVC means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Support Vector Classifier&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The basic idea is to find a decision boundary that separates classes.&lt;/p&gt;

&lt;p&gt;In simple 2D data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class A: ● ● ●

--------- decision boundary ---------

Class B: ▲ ▲ ▲
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SVM tries to find a boundary with a useful margin between classes.&lt;/p&gt;




&lt;h1&gt;
  
  
  51. Why scaling matters for SVM
&lt;/h1&gt;

&lt;p&gt;SVM is sensitive to feature scale.&lt;/p&gt;

&lt;p&gt;Suppose one feature ranges from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0–1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and another ranges from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0–100,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The larger-scale feature can dominate distance-related calculations.&lt;/p&gt;

&lt;p&gt;That is why scaling is often important for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVM&lt;/li&gt;
&lt;li&gt;KNN&lt;/li&gt;
&lt;li&gt;Logistic Regression in many situations&lt;/li&gt;
&lt;li&gt;neural networks&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  52. Decision Tree
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeClassifier&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A decision tree makes predictions using a sequence of questions.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is tenure &amp;lt; 12?
       /       \
     Yes       No
     /           \
Is charge &amp;gt; X?   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually the tree reaches a leaf containing a prediction.&lt;/p&gt;

&lt;p&gt;This is attractive because it is easy to visualize conceptually.&lt;/p&gt;




&lt;h1&gt;
  
  
  53. Why trees can overfit
&lt;/h1&gt;

&lt;p&gt;A tree can keep splitting the data until it creates extremely specific rules.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If feature A &amp;gt; 10
and feature B &amp;lt; 4
and feature C = 7
and feature D &amp;gt; 92
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually the tree may memorize training examples.&lt;/p&gt;

&lt;p&gt;That is why you later tried:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="n"&gt;min_samples_split&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are ways of controlling tree complexity.&lt;/p&gt;




&lt;h1&gt;
  
  
  54. Random Forest
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;RandomForestRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A random forest combines many decision trees.&lt;/p&gt;

&lt;p&gt;Instead of relying on one tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tree 1 ─┐
Tree 2 ─┤
Tree 3 ─┤
Tree 4 ─┤ → combined prediction
...     ┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is that many different trees can produce a more robust prediction than a single tree.&lt;/p&gt;

&lt;p&gt;This is an example of an &lt;strong&gt;ensemble method&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  55. Bagging
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;BaggingRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_samples&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bagging means combining models trained on different samples of the data.&lt;/p&gt;

&lt;p&gt;The overall idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dataset
  ↓
Different samples
  ↓
Multiple models
  ↓
Combine predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is often to reduce variance and make predictions more stable.&lt;/p&gt;

&lt;p&gt;Random Forest can be viewed as a specialized tree-based ensemble that adds additional randomness in how trees are built.&lt;/p&gt;




&lt;h1&gt;
  
  
  56. AdaBoost
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;AdaBoostRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AdaBoost means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Adaptive Boosting&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of training many independent models and simply averaging them, boosting builds models sequentially.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model 1
  ↓
find mistakes
  ↓
Model 2 focuses more on difficult cases
  ↓
Model 3 focuses further
  ↓
combine models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Later models try to improve on the weaknesses of earlier models.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  57. K-Nearest Neighbors (KNN)
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;KNeighborsRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;KNN predicts using nearby examples.&lt;/p&gt;

&lt;p&gt;Imagine a new customer.&lt;/p&gt;

&lt;p&gt;The algorithm asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which existing customers are most similar to this customer?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then it uses those neighbors to estimate the output.&lt;/p&gt;

&lt;p&gt;For regression, the prediction is commonly based on the neighbors' target values.&lt;/p&gt;




&lt;h1&gt;
  
  
  58. Why KNN needs scaling
&lt;/h1&gt;

&lt;p&gt;KNN relies on distance.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Income:   0–100,000
Age:      18–80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If raw values are used, income can dominate the distance calculation.&lt;/p&gt;

&lt;p&gt;Scaling puts features onto comparable scales.&lt;/p&gt;

&lt;p&gt;That is why you experimented with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  59. StandardScaler
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;X_train_scaled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;X_test_scaled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an important pattern.&lt;/p&gt;

&lt;p&gt;Notice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;The scaler learns the training data's statistics.&lt;/p&gt;

&lt;p&gt;Then the exact same transformation is applied to the test data.&lt;/p&gt;

&lt;p&gt;You should not independently fit the scaler on the test set.&lt;/p&gt;

&lt;p&gt;Otherwise information from the test set leaks into preprocessing.&lt;/p&gt;

&lt;p&gt;This idea is called avoiding:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data leakage&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  60. Data leakage
&lt;/h1&gt;

&lt;p&gt;Data leakage happens when information that should not be available to the model during training accidentally influences the model.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train preprocessing
     ↓
uses information from test data
     ↓
test is no longer truly unseen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can make evaluation look better than real-world performance.&lt;/p&gt;

&lt;p&gt;The correct principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fit preprocessing steps using training data, then apply them to validation/test/new data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A production ML pipeline should ideally bundle preprocessing and modeling together.&lt;/p&gt;




&lt;h1&gt;
  
  
  61. Linear Regression
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;LinearRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for Customer Lifetime Value.&lt;/p&gt;

&lt;p&gt;Linear regression tries to model a relationship like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = b0 + b1X1 + b2X2 + ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For one feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = intercept + slope × X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to find coefficients that produce predictions close to the observed values.&lt;/p&gt;




&lt;h1&gt;
  
  
  62. Regression score: what does &lt;code&gt;.score()&lt;/code&gt; mean?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the scikit-learn regression models you used, &lt;code&gt;.score()&lt;/code&gt; generally returns &lt;strong&gt;R²&lt;/strong&gt;, the coefficient of determination.&lt;/p&gt;

&lt;p&gt;Very roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R² = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the model explains the observed variation perfectly on that dataset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R² = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the model is no better than a simple baseline based on predicting the mean target.&lt;/p&gt;

&lt;p&gt;R² can also be negative on unseen data.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;R² is not the same thing as accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For regression, do not say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"My regression model has 90% accuracy"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;just because R² is 0.90.&lt;/p&gt;

&lt;p&gt;Instead say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The model achieved an R² of 0.90."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  63. Classification accuracy
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test_pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accuracy is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;correct predictions
-------------------
total predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;90 correct
100 total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;90% accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accuracy is easy to understand.&lt;/p&gt;

&lt;p&gt;But it can be misleading when classes are highly imbalanced.&lt;/p&gt;




&lt;h1&gt;
  
  
  64. Confusion matrix
&lt;/h1&gt;

&lt;p&gt;Your later notes/workflow refer to concepts such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TP
TN
FP
FN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A confusion matrix organizes classification predictions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Actual
                 No       Yes
Predicted No     TN       FN
Predicted Yes    FP       TP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning:&lt;/p&gt;

&lt;h3&gt;
  
  
  True Positive
&lt;/h3&gt;

&lt;p&gt;Model predicted positive and it was positive.&lt;/p&gt;

&lt;h3&gt;
  
  
  True Negative
&lt;/h3&gt;

&lt;p&gt;Model predicted negative and it was negative.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Positive
&lt;/h3&gt;

&lt;p&gt;Model predicted positive but it was negative.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Negative
&lt;/h3&gt;

&lt;p&gt;Model predicted negative but it was positive.&lt;/p&gt;

&lt;p&gt;This is much more informative than accuracy alone when the cost of errors differs.&lt;/p&gt;




&lt;h1&gt;
  
  
  65. Precision and Recall
&lt;/h1&gt;

&lt;p&gt;For classification:&lt;/p&gt;

&lt;h3&gt;
  
  
  Precision
&lt;/h3&gt;

&lt;p&gt;Of everything the model predicted as positive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many were actually positive?&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Precision = TP / (TP + FP)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recall
&lt;/h3&gt;

&lt;p&gt;Of everything that was actually positive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many did the model find?&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recall = TP / (TP + FN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right metric depends on the problem.&lt;/p&gt;

&lt;p&gt;For churn prediction, for example, missing a customer who is about to churn may be more important than contacting an extra customer who would have stayed.&lt;/p&gt;




&lt;h1&gt;
  
  
  66. Your Telco Customer Churn project
&lt;/h1&gt;

&lt;p&gt;This is probably the clearest classification example in your notebooks.&lt;/p&gt;

&lt;p&gt;The business question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we predict whether a telecom customer will churn?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The target is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer data
     ↓
Clean data
     ↓
Explore data
     ↓
Encode categories
     ↓
Split train/test
     ↓
Train classifier
     ↓
Predict churn
     ↓
Evaluate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  67. Telco: removing customerID
&lt;/h1&gt;

&lt;p&gt;You did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customerID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is reasonable because the ID is an identifier rather than a customer characteristic.&lt;/p&gt;

&lt;p&gt;You also commented that it could be kept separately if you later wanted to map predictions back to customers.&lt;/p&gt;

&lt;p&gt;That is a good practical idea.&lt;/p&gt;

&lt;p&gt;In production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID
   ↓
keep separately for business reporting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID
   X
do not necessarily use as a model feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  68. Telco: fixing TotalCharges
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coerce&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;errors="coerce"&lt;/code&gt; means invalid values are converted to &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in one notebook and median imputation in another.&lt;/p&gt;

&lt;p&gt;These are two different decisions.&lt;/p&gt;

&lt;p&gt;The important lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Missing-value handling should be based on the meaning of the data, not simply on whichever replacement is easiest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, if missing &lt;code&gt;TotalCharges&lt;/code&gt; occurs because a customer has zero tenure and has just joined, then filling with zero may have a meaningful business interpretation.&lt;/p&gt;

&lt;p&gt;If missingness represents an unknown measurement, median imputation may be more appropriate.&lt;/p&gt;




&lt;h1&gt;
  
  
  69. Telco: the first modeling version
&lt;/h1&gt;

&lt;p&gt;The earlier Telco notebook used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;LabelEncoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for many categorical columns.&lt;/p&gt;

&lt;p&gt;This is okay as a learning exercise for understanding encoding, but it is not ideal for every categorical variable.&lt;/p&gt;

&lt;p&gt;A better version in your later notebook used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dummies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi_cols&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;drop_first&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a meaningful improvement.&lt;/p&gt;




&lt;h1&gt;
  
  
  70. Telco: your improved preprocessing pipeline
&lt;/h1&gt;

&lt;p&gt;The later notebook did something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw data
   ↓
Drop customerID
   ↓
Convert TotalCharges
   ↓
Encode binary columns
   ↓
One-hot encode multi-category columns
   ↓
Separate X and Y
   ↓
Scale X
   ↓
Train Logistic Regression
   ↓
Create Gradio interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much closer to a real ML application.&lt;/p&gt;




&lt;h1&gt;
  
  
  71. Gradio: turning a model into an application
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gradio&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;gr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and built a UI.&lt;/p&gt;

&lt;p&gt;This is an important step because it changes the project from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Notebook experiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User input
    ↓
Preprocessing
    ↓
Model
    ↓
Prediction
    ↓
Human-readable result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gender: Female
Tenure: 12 months
Contract: Month-to-month
Monthly charges: $70
...
          ↓
    Predict Churn
          ↓
High Churn Risk
Probability: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates an important ML engineering concept:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A model is useful only when it can be integrated into a workflow where people or systems can use its predictions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  72. Very important: preprocessing must match training
&lt;/h1&gt;

&lt;p&gt;Your Gradio code contains a good lesson.&lt;/p&gt;

&lt;p&gt;During training you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;encode the categorical values&lt;/li&gt;
&lt;li&gt;create dummy columns&lt;/li&gt;
&lt;li&gt;scale the features&lt;/li&gt;
&lt;li&gt;train the model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During prediction you must do the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;raw user input
    ↓
same encoding
    ↓
same columns
    ↓
same scaling
    ↓
model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the training data has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature_1
feature_2
feature_3
feature_4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but the application sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature_1
feature_3
feature_4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model cannot interpret the input correctly.&lt;/p&gt;

&lt;p&gt;Your use of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;input_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reindex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;feature_columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fill_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is intended to make the input columns match the training feature structure.&lt;/p&gt;

&lt;p&gt;That is an important practical idea.&lt;/p&gt;




&lt;h1&gt;
  
  
  73. A stronger production pattern: Pipeline
&lt;/h1&gt;

&lt;p&gt;A cleaner production approach is often:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;preprocessor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then preprocessing and prediction are tied together.&lt;/p&gt;

&lt;p&gt;This reduces the risk of accidentally applying different transformations during training and inference.&lt;/p&gt;

&lt;p&gt;Your notebook demonstrates the concept manually, which is useful for learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  74. Your Auto Insurance / Customer Lifetime Value project
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;13-Aug.ipynb&lt;/code&gt; notebook moves into regression.&lt;/p&gt;

&lt;p&gt;The target is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes the question from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Will this customer churn?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What numerical Customer Lifetime Value should we predict?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classification → Churn
Regression     → Customer Lifetime Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  75. Insurance dataset: initial exploration
&lt;/h1&gt;

&lt;p&gt;You loaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AutoInsurance.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inspected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
Effective To Date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the modeling DataFrame.&lt;/p&gt;

&lt;p&gt;Again, the purpose is to separate identifiers / dates that were not being used in the current modeling approach.&lt;/p&gt;

&lt;p&gt;However, an important ML lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dates are not automatically useless.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A date may contain useful information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;month&lt;/li&gt;
&lt;li&gt;day of week&lt;/li&gt;
&lt;li&gt;season&lt;/li&gt;
&lt;li&gt;year&lt;/li&gt;
&lt;li&gt;time since an event&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A stronger project could engineer useful date features instead of simply dropping every date column.&lt;/p&gt;




&lt;h1&gt;
  
  
  76. Insurance EDA
&lt;/h1&gt;

&lt;p&gt;You explored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;State&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Coverage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a good progression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Categorical distribution
        ↓
Numerical distribution
        ↓
Numerical vs categorical
        ↓
Numerical vs numerical
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are gradually asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What might explain the target?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  77. Automatically finding numerical and categorical columns
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;numerical_cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_dtypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;int64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;float64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;

&lt;span class="n"&gt;categorical_cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_dtypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful because instead of manually listing every column, Python can identify columns based on data type.&lt;/p&gt;

&lt;p&gt;Then you looped through them to create graphs.&lt;/p&gt;

&lt;p&gt;This is the beginning of writing reusable data-analysis code.&lt;/p&gt;




&lt;h1&gt;
  
  
  78. Automated boxplots
&lt;/h1&gt;

&lt;p&gt;You created boxplots for all numerical columns.&lt;/p&gt;

&lt;p&gt;This is useful because you can quickly inspect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;distributions&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;spread&lt;/li&gt;
&lt;li&gt;potential outliers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, remember that a large collection of graphs can become overwhelming.&lt;/p&gt;

&lt;p&gt;The goal should eventually move from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Let's plot everything."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Let's plot the variables that help answer our question."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a sign of growing from beginner EDA toward professional analysis.&lt;/p&gt;




&lt;h1&gt;
  
  
  79. Binning numerical variables for boxplots
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This divides a numerical variable into five intervals.&lt;/p&gt;

&lt;p&gt;Then you compare CLV across those ranges.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Income range 1 → CLV distribution
Income range 2 → CLV distribution
Income range 3 → CLV distribution
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for visualization because a boxplot expects categories on one axis.&lt;/p&gt;

&lt;p&gt;But the number and boundaries of bins can affect the story you see.&lt;/p&gt;

&lt;p&gt;So binning is mainly a visualization technique here, not necessarily something you should automatically use as a model feature.&lt;/p&gt;




&lt;h1&gt;
  
  
  80. Comparing many regression algorithms
&lt;/h1&gt;

&lt;p&gt;One of the biggest learning steps in your final notebook was trying multiple regressors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linear Regression
KNN Regressor
SVR
Decision Tree Regressor
Bagging Regressor
AdaBoost Regressor
Random Forest Regressor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is valuable because it teaches a core ML lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Different algorithms make different assumptions and capture different types of patterns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is no universally best algorithm.&lt;/p&gt;




&lt;h1&gt;
  
  
  81. Linear Regression vs tree-based models
&lt;/h1&gt;

&lt;p&gt;Linear Regression assumes a relationship that can be represented through a linear combination of features.&lt;/p&gt;

&lt;p&gt;Tree-based methods can represent more complex non-linear relationships.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linear model:

Y
│       /
│     /
│   /
│ /
└──────── X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tree-based model can approximate more irregular patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y
│    ┌────
│    │
│ ───┘
│
└──────── X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why trying multiple model families can be useful.&lt;/p&gt;




&lt;h1&gt;
  
  
  82. Why model comparison matters
&lt;/h1&gt;

&lt;p&gt;Suppose you obtain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model             Train R²    Test R²
Linear Regression   0.70       0.68
KNN                 0.90       0.62
Decision Tree       0.99       0.55
Random Forest       0.91       0.78
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should not automatically choose the model with the highest training score.&lt;/p&gt;

&lt;p&gt;The more important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which model generalizes well to unseen data?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here Random Forest would be more interesting than the tree with 0.99 training R².&lt;/p&gt;




&lt;h1&gt;
  
  
  83. Log transformation of Customer Lifetime Value
&lt;/h1&gt;

&lt;p&gt;You later used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because some target variables are heavily skewed.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most CLV values: relatively small
A few CLV values: extremely large
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may have difficulty fitting such a distribution.&lt;/p&gt;

&lt;p&gt;A log transformation compresses large values.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original:
1
10
100
1000
10000

Log scale:
small differences between large values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can make the target distribution easier for some models to learn.&lt;/p&gt;




&lt;h1&gt;
  
  
  84. Reversing the log transformation
&lt;/h1&gt;

&lt;p&gt;After predicting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expm1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;If:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y_log = log(1 + Y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = exp(Y_log) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;np.expm1()&lt;/code&gt; performs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exp(x) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log target
   ↓
model
   ↓
log prediction
   ↓
expm1
   ↓
original target scale
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  85. An important issue in the notebook: split consistency
&lt;/h1&gt;

&lt;p&gt;In your log-transform section, you did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;X_train_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_test_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Y_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is okay as a new split, but it means your earlier train/test split and later train/test split are not necessarily the same.&lt;/p&gt;

&lt;p&gt;For a clean experiment, define the split once and reuse it consistently.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;y_train_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y_test_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes comparisons easier to reason about.&lt;/p&gt;




&lt;h1&gt;
  
  
  86. Another important issue: predicting on the full dataset
&lt;/h1&gt;

&lt;p&gt;You later did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and saved predictions for the full dataset.&lt;/p&gt;

&lt;p&gt;That can be useful for producing a business-facing prediction file.&lt;/p&gt;

&lt;p&gt;But these are &lt;strong&gt;not unbiased test predictions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;X&lt;/code&gt; includes training observations the model already saw.&lt;/p&gt;

&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predictions on X_test
→ useful for evaluating unseen data

Predictions on X
→ useful for generating predictions for all records,
   but not for measuring generalization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction is very important.&lt;/p&gt;




&lt;h1&gt;
  
  
  87. Hyperparameters
&lt;/h1&gt;

&lt;p&gt;Later you changed models from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_split&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These settings are called &lt;strong&gt;hyperparameters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are chosen by us before training.&lt;/p&gt;

&lt;p&gt;The model learns its internal parameters from the training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;Learned by the algorithm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hyperparameters
&lt;/h3&gt;

&lt;p&gt;Set by us.&lt;/p&gt;

&lt;p&gt;This distinction is fundamental.&lt;/p&gt;




&lt;h1&gt;
  
  
  88. Understanding your tree hyperparameters
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;max_depth&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Controls how deep the tree can grow.&lt;/p&gt;

&lt;p&gt;Smaller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;simpler tree
less overfitting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Larger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;more complex tree
greater overfitting risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;min_samples_split&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Minimum number of samples required before a node can be split.&lt;/p&gt;

&lt;p&gt;Higher values make the tree more conservative.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;min_samples_leaf&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Minimum number of samples allowed in a leaf.&lt;/p&gt;

&lt;p&gt;Higher values prevent extremely tiny leaves.&lt;/p&gt;




&lt;h1&gt;
  
  
  89. Random Forest hyperparameters
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;RandomForestRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;n_estimators=200&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Build 200 trees.&lt;/p&gt;

&lt;p&gt;More trees can make the ensemble more stable, though computation increases.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;max_depth=8&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Limits tree complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;min_samples_leaf=5&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Prevents leaves from becoming too specific.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;random_state=42&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Makes the experiment reproducible.&lt;/p&gt;




&lt;h1&gt;
  
  
  90. Bagging hyperparameters
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;BaggingRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_samples&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means, conceptually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build many estimators&lt;/li&gt;
&lt;li&gt;each estimator sees a sample of the training rows&lt;/li&gt;
&lt;li&gt;each estimator can use a subset of features&lt;/li&gt;
&lt;li&gt;combine their predictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, the goal is to create a robust ensemble rather than rely on one model.&lt;/p&gt;




&lt;h1&gt;
  
  
  91. Scaling experiment in your notebook
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and compared KNN/SVR.&lt;/p&gt;

&lt;p&gt;This is a very useful experiment because it demonstrates:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Preprocessing requirements depend on the algorithm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tree-based algorithms generally do not need feature scaling in the same way that distance- or margin-based methods do.&lt;/p&gt;

&lt;p&gt;KNN and SVM are much more sensitive to feature scale.&lt;/p&gt;




&lt;h1&gt;
  
  
  92. A subtle issue in your scaling experiment
&lt;/h1&gt;

&lt;p&gt;You created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train_scaled&lt;/span&gt;
&lt;span class="n"&gt;X_test_scaled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but your KNN code first trained on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train_log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;before later looping over scaled KNN.&lt;/p&gt;

&lt;p&gt;That is useful as experimentation, but for a clean article you should present the comparison more systematically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;KNN without scaling
        vs
KNN with scaling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and explicitly explain why the result changed.&lt;/p&gt;

&lt;p&gt;For SVR, you correctly used the scaled data in the shown section.&lt;/p&gt;




&lt;h1&gt;
  
  
  93. The complete mental model
&lt;/h1&gt;

&lt;p&gt;After these five days, the entire workflow can be remembered as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             REAL-WORLD QUESTION
                     ↓
             Define the target
                     ↓
              Collect data
                     ↓
              Understand data
                     ↓
          ┌──────────┴──────────┐
          ↓                     ↓
      Numerical             Categorical
          ↓                     ↓
      distributions        category counts
          └──────────┬──────────┘
                     ↓
                    EDA
                     ↓
              Clean the data
                     ↓
          Handle missing values
                     ↓
             Encode categories
                     ↓
          Select useful features
                     ↓
              Split train/test
                     ↓
          Scale when appropriate
                     ↓
              Train baseline
                     ↓
          Evaluate on test data
                     ↓
             Try other models
                     ↓
         Tune hyperparameters
                     ↓
       Select based on validation
                     ↓
             Final evaluation
                     ↓
              Make predictions
                     ↓
       Integrate into an application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  94. What each notebook taught you
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Day 1 — Auto MPG
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load a dataset&lt;/li&gt;
&lt;li&gt;inspect rows and columns&lt;/li&gt;
&lt;li&gt;understand shape and data types&lt;/li&gt;
&lt;li&gt;inspect summary statistics&lt;/li&gt;
&lt;li&gt;identify categorical/text columns&lt;/li&gt;
&lt;li&gt;detect messy numerical values&lt;/li&gt;
&lt;li&gt;visualize distributions&lt;/li&gt;
&lt;li&gt;use countplots&lt;/li&gt;
&lt;li&gt;use histograms&lt;/li&gt;
&lt;li&gt;use pairplots&lt;/li&gt;
&lt;li&gt;understand missing values&lt;/li&gt;
&lt;li&gt;convert &lt;code&gt;"?"&lt;/code&gt; to &lt;code&gt;NaN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;convert text to numerical data&lt;/li&gt;
&lt;li&gt;use median imputation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Before modeling, understand and clean your data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 2 — Telco Customer Churn
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identify a classification target&lt;/li&gt;
&lt;li&gt;remove an identifier&lt;/li&gt;
&lt;li&gt;handle &lt;code&gt;TotalCharges&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;visualize class balance&lt;/li&gt;
&lt;li&gt;compare categories against churn&lt;/li&gt;
&lt;li&gt;use boxplots and histograms&lt;/li&gt;
&lt;li&gt;use pairplots&lt;/li&gt;
&lt;li&gt;inspect correlations&lt;/li&gt;
&lt;li&gt;encode categorical data&lt;/li&gt;
&lt;li&gt;split into training/testing data&lt;/li&gt;
&lt;li&gt;train Logistic Regression&lt;/li&gt;
&lt;li&gt;train SVC&lt;/li&gt;
&lt;li&gt;train Decision Tree&lt;/li&gt;
&lt;li&gt;compare train/test performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A classification model predicts categories, but the quality of the prediction depends heavily on preprocessing and evaluation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 3 — Improving the Telco project
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one-hot encode multi-category variables&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;random_state&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;stratify&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scale features&lt;/li&gt;
&lt;li&gt;train Logistic Regression&lt;/li&gt;
&lt;li&gt;build a prediction interface with Gradio&lt;/li&gt;
&lt;li&gt;reproduce preprocessing at inference time&lt;/li&gt;
&lt;li&gt;output a human-readable prediction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An ML model is only one part of an ML application.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 4/5 — Customer Lifetime Value
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formulate a regression problem&lt;/li&gt;
&lt;li&gt;inspect numerical/categorical relationships&lt;/li&gt;
&lt;li&gt;automate EDA&lt;/li&gt;
&lt;li&gt;encode categories&lt;/li&gt;
&lt;li&gt;split train/test&lt;/li&gt;
&lt;li&gt;compare multiple regressors&lt;/li&gt;
&lt;li&gt;understand R²&lt;/li&gt;
&lt;li&gt;try target transformation&lt;/li&gt;
&lt;li&gt;use log transformation&lt;/li&gt;
&lt;li&gt;reverse the transformation&lt;/li&gt;
&lt;li&gt;experiment with scaling&lt;/li&gt;
&lt;li&gt;tune hyperparameters&lt;/li&gt;
&lt;li&gt;use ensemble models&lt;/li&gt;
&lt;li&gt;generate prediction files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Different models capture different patterns, and model selection should be based on performance on unseen data—not training performance alone.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  95. What I would change before publishing the project as "production-quality"
&lt;/h1&gt;

&lt;p&gt;Your notebooks are excellent learning material because they show experimentation. For a public article, however, it is worth separating:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Learning experiments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recommended ML workflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the most important improvements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 1 — Use clear train/test terminology
&lt;/h2&gt;

&lt;p&gt;Prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than mixing &lt;code&gt;Y&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Python convention generally uses lowercase &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 2 — Make experiments reproducible
&lt;/h2&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;consistently when appropriate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 3 — Use stratification for classification
&lt;/h2&gt;

&lt;p&gt;For churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;stratify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Improvement 4 — Avoid LabelEncoder for nominal multi-class input features
&lt;/h2&gt;

&lt;p&gt;Use one-hot encoding for categories such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PaymentMethod
Contract
InternetService
VehicleClass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Label encoding is much more naturally suited to targets or truly ordinal categories.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 5 — Fit preprocessing only on training data
&lt;/h2&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data
    ↓
fit scaler
    ↓
transform training

Test data
    ↓
transform using existing scaler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not independently fit preprocessing on the test data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 6 — Use proper evaluation metrics
&lt;/h2&gt;

&lt;p&gt;For classification, consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accuracy
Precision
Recall
F1
Confusion Matrix
ROC-AUC
PR-AUC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For regression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R²
MAE
MSE
RMSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which metrics matter depends on the business problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 7 — Don't compare only training scores
&lt;/h2&gt;

&lt;p&gt;Always look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training performance
+
Validation/test performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A very high training score with much lower test performance can indicate overfitting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 8 — Keep a validation strategy for model selection
&lt;/h2&gt;

&lt;p&gt;A single test set should ideally be kept for final evaluation.&lt;/p&gt;

&lt;p&gt;During experimentation, use cross-validation or a validation set to choose models/hyperparameters.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data
   ↓
Cross-validation / validation
   ↓
Choose model
   ↓
Final test set
   ↓
Final unbiased-ish estimate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  96. A very important distinction: EDA vs ML
&lt;/h1&gt;

&lt;p&gt;EDA asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What does my data look like?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Machine learning asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can I learn a useful relationship that lets me make predictions on new data?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These overlap, but they are not the same.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not build a model.&lt;/p&gt;

&lt;p&gt;It helps you understand the data before deciding how to model it.&lt;/p&gt;




&lt;h1&gt;
  
  
  97. Another important distinction: correlation vs prediction
&lt;/h1&gt;

&lt;p&gt;A strong correlation can be useful.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;high correlation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not automatically mean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;excellent predictive model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prediction depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple features&lt;/li&gt;
&lt;li&gt;data quality&lt;/li&gt;
&lt;li&gt;model type&lt;/li&gt;
&lt;li&gt;noise&lt;/li&gt;
&lt;li&gt;generalization&lt;/li&gt;
&lt;li&gt;preprocessing&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So don't judge an ML problem from one graph.&lt;/p&gt;




&lt;h1&gt;
  
  
  98. Another important distinction: model vs algorithm
&lt;/h1&gt;

&lt;p&gt;It is common to hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I trained a model."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The algorithm is the learning procedure.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Random Forest = algorithm/model family
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After training:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model_rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you have a fitted model containing learned information.&lt;/p&gt;

&lt;p&gt;A useful mental model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Algorithm
   +
Training data
   ↓
Fitted model
   ↓
Predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  99. What "learning" actually means
&lt;/h1&gt;

&lt;p&gt;This is probably the most important concept to understand.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model is not magically understanding the world.&lt;/p&gt;

&lt;p&gt;It is optimizing internal parameters so that its predictions match the training examples according to the algorithm's objective.&lt;/p&gt;

&lt;p&gt;For example, linear regression learns coefficients.&lt;/p&gt;

&lt;p&gt;A tree learns split rules.&lt;/p&gt;

&lt;p&gt;A neural network learns weights.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Training means finding model parameters that make the model perform well according to a defined objective.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  100. What happens during prediction?
&lt;/h1&gt;

&lt;p&gt;Once training is complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model does not learn again from the test examples.&lt;/p&gt;

&lt;p&gt;It applies what it learned during training.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training:

X_train + y_train
        ↓
      model.fit()
        ↓
   learned model

Prediction:

X_test
   ↓
learned model
   ↓
prediction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  101. The biggest beginner misconception to avoid
&lt;/h1&gt;

&lt;p&gt;Do not think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I used Random Forest, so I did machine learning."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real ML skill is being able to explain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What problem are you solving?&lt;/li&gt;
&lt;li&gt;What is the target?&lt;/li&gt;
&lt;li&gt;What features are available?&lt;/li&gt;
&lt;li&gt;What does the data look like?&lt;/li&gt;
&lt;li&gt;What problems did you find?&lt;/li&gt;
&lt;li&gt;How did you clean them?&lt;/li&gt;
&lt;li&gt;How did you encode the data?&lt;/li&gt;
&lt;li&gt;Why did you choose the algorithm?&lt;/li&gt;
&lt;li&gt;How did you evaluate it?&lt;/li&gt;
&lt;li&gt;Does it generalize?&lt;/li&gt;
&lt;li&gt;What would you improve?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you can explain these, you are learning ML—not just memorizing scikit-learn commands.&lt;/p&gt;




&lt;h1&gt;
  
  
  102. A simple explanation of your five-day journey
&lt;/h1&gt;

&lt;p&gt;If someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What did you actually learn in five days?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A strong answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I learned that machine learning is not just about selecting an algorithm. I started by understanding datasets using Pandas, cleaning missing and incorrectly formatted values, and using visualization to understand distributions and relationships. Then I learned the difference between classification and regression, converted categorical data into numerical representations, split data into training and testing sets, trained several models using scikit-learn, and compared their performance on unseen data. Finally, I experimented with scaling, transformations, ensemble models, hyperparameters, and even built a simple Gradio interface around a churn model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much stronger story than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I learned Logistic Regression, SVM and Random Forest."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  103. Suggested article structure for dev.to
&lt;/h1&gt;

&lt;p&gt;For your final public article, I recommend this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title

1. Why I started learning ML
2. What I thought ML was vs what I learned
3. AI vs ML
4. Types of ML
5. My five-day learning roadmap
6. Day 1 — Understanding and cleaning data
7. EDA and why graphs matter
8. Day 2 — Classification with customer churn
9. Encoding categorical data
10. Train/test split
11. Logistic Regression, SVM and Decision Trees
12. How I evaluated classification models
13. Day 3 — Turning the model into an application
14. Day 4/5 — Regression and Customer Lifetime Value
15. Linear Regression vs KNN vs SVR vs Trees vs Ensembles
16. Log transformation
17. Scaling
18. Hyperparameters
19. What I got wrong / what I would improve
20. What I learned
21. What I plan to learn next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make the article feel like a &lt;strong&gt;journey&lt;/strong&gt;, rather than a textbook.&lt;/p&gt;




&lt;h1&gt;
  
  
  104. Recommended article narrative
&lt;/h1&gt;

&lt;p&gt;The most interesting story is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I started with almost no ML knowledge."

        ↓

"I learned that data preparation matters."

        ↓

"I discovered that graphs help me ask questions
before training models."

        ↓

"I learned classification."

        ↓

"I learned regression."

        ↓

"I tried different algorithms and realized
there is no single best model."

        ↓

"I learned that a high training score
doesn't necessarily mean a good model."

        ↓

"I turned one model into a small application."

        ↓

"I now understand the basic ML workflow
and know what I need to learn next."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a much more authentic beginner-to-ML story.&lt;/p&gt;




&lt;h1&gt;
  
  
  105. What to learn next
&lt;/h1&gt;

&lt;p&gt;Based on what your notebooks already cover, I would &lt;strong&gt;not&lt;/strong&gt; recommend immediately jumping into deep learning.&lt;/p&gt;

&lt;p&gt;First strengthen these foundations:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Statistics
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mean&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;variance&lt;/li&gt;
&lt;li&gt;standard deviation&lt;/li&gt;
&lt;li&gt;distributions&lt;/li&gt;
&lt;li&gt;probability&lt;/li&gt;
&lt;li&gt;correlation&lt;/li&gt;
&lt;li&gt;conditional probability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. ML evaluation
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;confusion matrix&lt;/li&gt;
&lt;li&gt;precision&lt;/li&gt;
&lt;li&gt;recall&lt;/li&gt;
&lt;li&gt;F1&lt;/li&gt;
&lt;li&gt;ROC-AUC&lt;/li&gt;
&lt;li&gt;MAE&lt;/li&gt;
&lt;li&gt;RMSE&lt;/li&gt;
&lt;li&gt;R²&lt;/li&gt;
&lt;li&gt;cross-validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Feature engineering
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handling dates&lt;/li&gt;
&lt;li&gt;categorical features&lt;/li&gt;
&lt;li&gt;transformations&lt;/li&gt;
&lt;li&gt;interactions&lt;/li&gt;
&lt;li&gt;outliers&lt;/li&gt;
&lt;li&gt;missing values&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Model selection
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cross-validation&lt;/li&gt;
&lt;li&gt;hyperparameter tuning&lt;/li&gt;
&lt;li&gt;GridSearchCV&lt;/li&gt;
&lt;li&gt;RandomizedSearchCV&lt;/li&gt;
&lt;li&gt;pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. ML fundamentals
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bias vs variance&lt;/li&gt;
&lt;li&gt;underfitting&lt;/li&gt;
&lt;li&gt;overfitting&lt;/li&gt;
&lt;li&gt;regularization&lt;/li&gt;
&lt;li&gt;data leakage&lt;/li&gt;
&lt;li&gt;feature importance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then move toward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classical ML
     ↓
Feature engineering
     ↓
Model selection
     ↓
Cross-validation
     ↓
ML pipelines
     ↓
Deployment
     ↓
Deep Learning
     ↓
Generative AI / LLMs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  106. The one-page cheat sheet
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Problem type
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predict a category → Classification
Predict a number   → Regression
Find hidden groups → Clustering
Learn through reward → Reinforcement Learning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rows       → observations
Columns    → variables/features
X          → input features
y          → target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First inspection
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Visualization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Countplot   → categories
Histogram   → numerical distribution
Boxplot     → spread/outliers
Scatterplot → two numerical variables
Pairplot    → many numerical relationships
Heatmap     → correlation matrix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Missing values
Data types
Categorical encoding
Feature selection
Scaling when needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Training
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prediction
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Evaluation
&lt;/h2&gt;

&lt;p&gt;Classification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accuracy
Precision
Recall
F1
Confusion Matrix
ROC-AUC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R²
MAE
MSE
RMSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Core warning signs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score &amp;gt;&amp;gt; Test score
        ↓
Possible overfitting

Test information used during preprocessing
        ↓
Possible data leakage

Identifier used as feature
        ↓
Possible meaningless pattern

Categorical values converted to arbitrary numbers
        ↓
Possible false ordering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  107. Final takeaway
&lt;/h1&gt;

&lt;p&gt;The biggest lesson from these five days is not a particular Python library or algorithm.&lt;/p&gt;

&lt;p&gt;It is the workflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Understand the problem → understand the data → clean the data → explore the data → prepare features → train → evaluate → improve → deploy.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The algorithms are tools inside that workflow.&lt;/p&gt;

&lt;p&gt;You have already touched many of the important building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pandas&lt;/li&gt;
&lt;li&gt;NumPy&lt;/li&gt;
&lt;li&gt;Matplotlib&lt;/li&gt;
&lt;li&gt;Seaborn&lt;/li&gt;
&lt;li&gt;Scikit-learn&lt;/li&gt;
&lt;li&gt;data cleaning&lt;/li&gt;
&lt;li&gt;EDA&lt;/li&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;regression&lt;/li&gt;
&lt;li&gt;encoding&lt;/li&gt;
&lt;li&gt;train/test split&lt;/li&gt;
&lt;li&gt;scaling&lt;/li&gt;
&lt;li&gt;model evaluation&lt;/li&gt;
&lt;li&gt;hyperparameters&lt;/li&gt;
&lt;li&gt;ensemble models&lt;/li&gt;
&lt;li&gt;target transformation&lt;/li&gt;
&lt;li&gt;Gradio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next step is not to memorize more algorithms.&lt;/p&gt;

&lt;p&gt;The next step is to become comfortable answering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why am I doing this step?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can answer that question for every important line in your notebook, you are moving from "following an ML tutorial" to actually understanding machine learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  Appendix A — Notebook-by-notebook step map
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;11_Aug_mpg.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Notebook step&lt;/th&gt;
&lt;th&gt;Why it was done&lt;/th&gt;
&lt;th&gt;ML concept&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Import NumPy/Pandas/Matplotlib/Seaborn&lt;/td&gt;
&lt;td&gt;Load tools&lt;/td&gt;
&lt;td&gt;Python ML stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read_csv()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load data&lt;/td&gt;
&lt;td&gt;Data ingestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nunique()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand uniqueness&lt;/td&gt;
&lt;td&gt;Data exploration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect examples&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand dataset size&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;describe()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Summary statistics&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;info()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Types/non-null values&lt;/td&gt;
&lt;td&gt;Data quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;countplot()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect categorical distribution&lt;/td&gt;
&lt;td&gt;Visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hist()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect numerical distributions&lt;/td&gt;
&lt;td&gt;Visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isnull()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Detect actual missing values&lt;/td&gt;
&lt;td&gt;Data cleaning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pairplot()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Explore relationships&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sample()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect random examples&lt;/td&gt;
&lt;td&gt;Data quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identify &lt;code&gt;car name&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Recognize identifier-like field&lt;/td&gt;
&lt;td&gt;Feature selection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replace &lt;code&gt;?&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Convert fake missing values&lt;/td&gt;
&lt;td&gt;Data cleaning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;to_numeric()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Make horsepower numerical&lt;/td&gt;
&lt;td&gt;Data preparation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median imputation&lt;/td&gt;
&lt;td&gt;Fill missing horsepower&lt;/td&gt;
&lt;td&gt;Missing-value handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Train/test split&lt;/td&gt;
&lt;td&gt;Separate learning/evaluation data&lt;/td&gt;
&lt;td&gt;Generalization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logistic Regression&lt;/td&gt;
&lt;td&gt;Start classification experiment&lt;/td&gt;
&lt;td&gt;Supervised learning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Important caveat
&lt;/h3&gt;

&lt;p&gt;The notebook switches from Auto MPG to a &lt;code&gt;loan_prediction.csv&lt;/code&gt; dataset near the end. That appears to be a copied/reused modeling experiment rather than a continuation of the Auto MPG workflow. For a polished article, present these as separate experiments rather than one continuous Auto MPG pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;12th-Aug-Telco-Customer-churn.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load Telco CSV&lt;/td&gt;
&lt;td&gt;Get customer data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;describe()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Statistical overview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop &lt;code&gt;customerID&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Remove identifier from features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;info()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check data types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sample()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect random rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot of Churn&lt;/td&gt;
&lt;td&gt;Check class distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot of gender&lt;/td&gt;
&lt;td&gt;Explore category distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Histograms&lt;/td&gt;
&lt;td&gt;Explore numerical distributions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pairplot&lt;/td&gt;
&lt;td&gt;Explore relationships&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert TotalCharges&lt;/td&gt;
&lt;td&gt;Fix numeric type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fill missing TotalCharges&lt;/td&gt;
&lt;td&gt;Handle missing data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LabelEncoder&lt;/td&gt;
&lt;td&gt;Convert categories to numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Train/test split&lt;/td&gt;
&lt;td&gt;Evaluate on unseen data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logistic Regression&lt;/td&gt;
&lt;td&gt;Classification model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVC&lt;/td&gt;
&lt;td&gt;Alternative classifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision Tree&lt;/td&gt;
&lt;td&gt;Alternative classifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradio&lt;/td&gt;
&lt;td&gt;Turn model into interactive app&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Important caveat
&lt;/h3&gt;

&lt;p&gt;The notebook uses LabelEncoder on many categorical input columns. This is useful for learning encoding, but one-hot encoding is generally safer for nominal multi-category features.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;12-Aug-2.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This notebook is a more developed version of the Telco project.&lt;/p&gt;

&lt;p&gt;Important improvements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dropping &lt;code&gt;customerID&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;converting &lt;code&gt;TotalCharges&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;one-hot encoding multi-category variables&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;random_state=42&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;stratify=Y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scaling features&lt;/li&gt;
&lt;li&gt;training Logistic Regression&lt;/li&gt;
&lt;li&gt;building a Gradio prediction interface&lt;/li&gt;
&lt;li&gt;preserving training feature columns&lt;/li&gt;
&lt;li&gt;applying the same preprocessing to new input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the notebook that most clearly demonstrates the transition from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ML experiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;small ML application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;code&gt;13-Aug.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Main steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load AutoInsurance
       ↓
Inspect dataset
       ↓
Drop Customer / date columns
       ↓
EDA
       ↓
Identify numerical/categorical columns
       ↓
Generate many visualizations
       ↓
Encode categorical variables
       ↓
Set CLV as target
       ↓
Train/test split
       ↓
Try multiple regressors
       ↓
Try log target
       ↓
Try scaling
       ↓
Tune tree/ensemble hyperparameters
       ↓
Generate predictions
       ↓
Save prediction CSVs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This notebook demonstrates the transition from classification to regression and from a single baseline model to model comparison and tuning.&lt;/p&gt;




&lt;h1&gt;
  
  
  Appendix B — A cleaner ML template to remember
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. Load
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Understand
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Clean
# handle missing values
# fix data types
# remove inappropriate identifiers
&lt;/span&gt;
&lt;span class="c1"&gt;# 4. Explore
# histograms
# boxplots
# countplots
# scatterplots
# correlation
&lt;/span&gt;
&lt;span class="c1"&gt;# 5. Prepare
&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 6. Split
&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 7. Preprocess
# encoding / scaling
&lt;/span&gt;
&lt;span class="c1"&gt;# 8. Train
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 9. Predict
&lt;/span&gt;&lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 10. Evaluate
# choose metrics appropriate to the problem
&lt;/span&gt;
&lt;span class="c1"&gt;# 11. Compare / improve
# try another model
# tune hyperparameters
# use cross-validation
&lt;/span&gt;
&lt;span class="c1"&gt;# 12. Final model
# train using the selected approach
&lt;/span&gt;
&lt;span class="c1"&gt;# 13. Predict new data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Closing thought for the article
&lt;/h1&gt;

&lt;p&gt;Five days ago, an ML notebook could easily look like a collection of unfamiliar commands.&lt;/p&gt;

&lt;p&gt;Now there is a structure behind those commands.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head()&lt;/code&gt; is not just a command — it is a way to understand the data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isnull()&lt;/code&gt; is not just a command — it is part of data quality.&lt;/p&gt;

&lt;p&gt;A histogram is not just a graph — it tells you about a distribution.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;train_test_split()&lt;/code&gt; is not just boilerplate — it protects your evaluation from simply measuring memorization.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fit()&lt;/code&gt; is not magic — it is the learning stage.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;predict()&lt;/code&gt; is the model applying what it learned.&lt;/p&gt;

&lt;p&gt;And model comparison is not about finding the fanciest algorithm — it is about finding an approach that generalizes well to data the model has never seen.&lt;/p&gt;

&lt;p&gt;That, more than anything else, is what I took away from my first five days of machine learning.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AI &amp; ML Foundations: Cleaning Data, Building Regression &amp; Classification Models in Python</title>
      <dc:creator>yash-nigam</dc:creator>
      <pubDate>Mon, 31 Aug 2026 16:49:07 +0000</pubDate>
      <link>https://dev.to/yashnigam/ai-ml-foundations-cleaning-data-building-regression-classification-models-in-python-n53</link>
      <guid>https://dev.to/yashnigam/ai-ml-foundations-cleaning-data-building-regression-classification-models-in-python-n53</guid>
      <description>&lt;h1&gt;
  
  
  My 5-Day Journey into Machine Learning: From Data Cleaning to My First ML Models
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning goal:&lt;/strong&gt; This is not a collection of code snippets to memorize. It is a beginner-friendly guide to understanding &lt;em&gt;why&lt;/em&gt; each step in a typical machine-learning workflow exists, what problem it solves, and how the pieces fit together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A note about the source material
&lt;/h2&gt;

&lt;p&gt;This guide was built primarily from the four Jupyter notebooks you provided:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;11_Aug_mpg.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;12-Aug-2.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;12th-Aug-Telco-Customer-churn.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;13-Aug.ipynb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;123&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your PDF notes were also provided, but the PDF is image-based and its text could not be reliably extracted. So I have &lt;strong&gt;not invented or silently reconstructed&lt;/strong&gt; material from the PDF. The explanations below are grounded mainly in the notebooks, with general ML knowledge added to explain the concepts behind the code.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Overview: What did I actually learn in these five days?
&lt;/h1&gt;

&lt;p&gt;At first glance, machine learning can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load dataset
    ↓
Clean data
    ↓
Create graphs
    ↓
Train model
    ↓
Check accuracy
    ↓
Done!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that misses the most important part.&lt;/p&gt;

&lt;p&gt;The real ML workflow is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business / real-world question
        ↓
Define what we want to predict
        ↓
Understand the data
        ↓
Clean and prepare the data
        ↓
Explore the data visually
        ↓
Choose useful features
        ↓
Convert data into numbers
        ↓
Split into training and testing data
        ↓
Choose an appropriate ML algorithm
        ↓
Train the model
        ↓
Evaluate it on unseen data
        ↓
Compare models
        ↓
Improve preprocessing / model settings
        ↓
Use the model to make predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important insight is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Machine learning is not mainly about choosing an algorithm. It is about turning a real-world question and messy data into a reliable prediction process.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your notebooks actually demonstrate most of this workflow.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. What is Artificial Intelligence?
&lt;/h1&gt;

&lt;p&gt;Artificial Intelligence (AI) is the broad idea of building systems that can perform tasks that normally require some form of human intelligence.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recognizing an image&lt;/li&gt;
&lt;li&gt;understanding language&lt;/li&gt;
&lt;li&gt;recommending a movie&lt;/li&gt;
&lt;li&gt;detecting fraud&lt;/li&gt;
&lt;li&gt;predicting whether a customer will leave&lt;/li&gt;
&lt;li&gt;predicting the price/value of something&lt;/li&gt;
&lt;li&gt;generating text or images&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artificial Intelligence
│
├── Machine Learning
│   │
│   ├── Supervised Learning
│   ├── Unsupervised Learning
│   └── Reinforcement Learning
│
├── Deep Learning
│
└── Generative AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyash-nigam%2FAI-ML-Foundations%2Fblob%2F7516a4b681369d4b105ca19706f7d06da65e30a9%2Fimages%2FAIMLHierarchy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyash-nigam%2FAI-ML-Foundations%2Fblob%2F7516a4b681369d4b105ca19706f7d06da65e30a9%2Fimages%2FAIMLHierarchy.png" alt="image" width="" height=""&gt;&lt;/a&gt;&lt;br&gt;
This is simplified because these areas overlap, but it is a useful beginner mental model.&lt;/p&gt;


&lt;h1&gt;
  
  
  3. What is Machine Learning?
&lt;/h1&gt;

&lt;p&gt;Machine learning is a way of building systems where the computer learns patterns from data instead of us manually writing every rule.&lt;/p&gt;

&lt;p&gt;Imagine we want to predict whether a telecom customer will churn.&lt;/p&gt;

&lt;p&gt;A traditional rule-based approach might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF customer has a month-to-month contract
AND monthly charges are high
AND tenure is low
THEN churn = yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that we have to invent those rules ourselves.&lt;/p&gt;

&lt;p&gt;With machine learning, we give the algorithm historical examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer information → Actual churn result

Customer A → No
Customer B → Yes
Customer C → No
Customer D → Yes
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The algorithm tries to learn the relationship between the input information and the known outcome.&lt;/p&gt;

&lt;p&gt;Then we can give it a new customer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New customer information
        ↓
      Model
        ↓
Predicted churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the core idea of supervised machine learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. The most important ML vocabulary
&lt;/h1&gt;

&lt;p&gt;Before learning algorithms, understand these words.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.1 Dataset
&lt;/h2&gt;

&lt;p&gt;A dataset is a collection of examples.&lt;/p&gt;

&lt;p&gt;In your notebooks, a dataset is loaded into a Pandas DataFrame.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Telco_Customer_Churn.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of the DataFrame as a spreadsheet.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.2 Row / observation / sample
&lt;/h2&gt;

&lt;p&gt;Each row represents one example.&lt;/p&gt;

&lt;p&gt;For the Telco dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one customer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the Auto MPG dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one car
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the insurance dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one row = one customer/policy record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These words are often used interchangeably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;row&lt;/li&gt;
&lt;li&gt;observation&lt;/li&gt;
&lt;li&gt;sample&lt;/li&gt;
&lt;li&gt;instance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4.3 Feature
&lt;/h2&gt;

&lt;p&gt;A feature is an input variable that the model can use to make a prediction.&lt;/p&gt;

&lt;p&gt;For customer churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tenure
MonthlyCharges
Contract
InternetService
PaymentMethod
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are features.&lt;/p&gt;

&lt;p&gt;A useful question to ask is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What information is available to the model before it makes its prediction?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That information is generally your feature set.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.4 Target
&lt;/h2&gt;

&lt;p&gt;The target is what we are trying to predict.&lt;/p&gt;

&lt;p&gt;Examples from your notebooks:&lt;/p&gt;

&lt;h3&gt;
  
  
  Telco
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target = Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model predicts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 → No churn
1 → Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insurance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target = Customer Lifetime Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model predicts a numerical value.&lt;/p&gt;




&lt;h2&gt;
  
  
  4.5 X and y
&lt;/h2&gt;

&lt;p&gt;You repeatedly used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important patterns in supervised ML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X = inputs/features
Y = target/output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X
├── tenure
├── MonthlyCharges
├── Contract
├── InternetService
└── ...

Y
└── Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;X = what the model knows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Y = what we want the model to learn to predict&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  5. The three major types of Machine Learning
&lt;/h1&gt;

&lt;h2&gt;
  
  
  5.1 Supervised Learning
&lt;/h2&gt;

&lt;p&gt;In supervised learning, we have examples where the correct answer is already known.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input X → Known answer Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model learns the relationship between X and Y.&lt;/p&gt;

&lt;p&gt;Your notebooks mainly use supervised learning.&lt;/p&gt;

&lt;p&gt;There are two major supervised learning tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classification
&lt;/h3&gt;

&lt;p&gt;The target is a category.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Spam / Not Spam
Churn / No Churn
Fraud / Not Fraud
Disease / No Disease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Telco project is a classification problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regression
&lt;/h3&gt;

&lt;p&gt;The target is a numerical value.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;House price
Temperature
Sales
Customer Lifetime Value
Fuel efficiency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Customer Lifetime Value project is a regression problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Classification vs Regression
&lt;/h1&gt;

&lt;p&gt;This distinction is extremely important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classification
&lt;/h2&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which category does this example belong to?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Churn or No Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common classification algorithms you tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logistic Regression&lt;/li&gt;
&lt;li&gt;Support Vector Classifier (SVC)&lt;/li&gt;
&lt;li&gt;Decision Tree Classifier&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Regression
&lt;/h2&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What numerical value should we predict?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Customer Lifetime Value = 6,543.21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common regression algorithms you tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear Regression&lt;/li&gt;
&lt;li&gt;KNN Regressor&lt;/li&gt;
&lt;li&gt;SVR&lt;/li&gt;
&lt;li&gt;Decision Tree Regressor&lt;/li&gt;
&lt;li&gt;Bagging Regressor&lt;/li&gt;
&lt;li&gt;AdaBoost Regressor&lt;/li&gt;
&lt;li&gt;Random Forest Regressor&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  7. Unsupervised Learning
&lt;/h1&gt;

&lt;p&gt;In unsupervised learning, we do not have a known target.&lt;/p&gt;

&lt;p&gt;Instead, the algorithm tries to discover structure in the data.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer data
     ↓
Find groups
     ↓
Group 1: high-value customers
Group 2: price-sensitive customers
Group 3: new customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;K-Means clustering&lt;/li&gt;
&lt;li&gt;Hierarchical clustering&lt;/li&gt;
&lt;li&gt;PCA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You did not build an unsupervised-learning project in these notebooks, but it is important to know where it fits.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Reinforcement Learning
&lt;/h1&gt;

&lt;p&gt;Reinforcement learning is different.&lt;/p&gt;

&lt;p&gt;An agent interacts with an environment and receives rewards or penalties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓ action
Environment
  ↓
Reward / penalty
  ↓
Agent learns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;game-playing agents&lt;/li&gt;
&lt;li&gt;robotics&lt;/li&gt;
&lt;li&gt;certain recommendation/control systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was not part of your five-day practical work.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Different ways to approach an ML problem
&lt;/h1&gt;

&lt;p&gt;A useful way to think about ML is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which algorithm should I use?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — What is the question?
&lt;/h3&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can I predict whether a telecom customer will churn?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 2 — What type of target do I have?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn → category → Classification
Customer Lifetime Value → number → Regression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — What data is available?
&lt;/h3&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What columns exist?&lt;/li&gt;
&lt;li&gt;Which are numerical?&lt;/li&gt;
&lt;li&gt;Which are categorical?&lt;/li&gt;
&lt;li&gt;Are values missing?&lt;/li&gt;
&lt;li&gt;Are there strange values?&lt;/li&gt;
&lt;li&gt;Are some columns identifiers?&lt;/li&gt;
&lt;li&gt;Is the target balanced?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4 — Explore before modeling
&lt;/h3&gt;

&lt;p&gt;Use statistics and graphs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — Prepare the data
&lt;/h3&gt;

&lt;p&gt;Convert it into a form the algorithm can understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 — Establish a baseline
&lt;/h3&gt;

&lt;p&gt;Train a simple model first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7 — Compare alternatives
&lt;/h3&gt;

&lt;p&gt;Try other appropriate models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8 — Evaluate on unseen data
&lt;/h3&gt;

&lt;p&gt;A model is useful only if it works beyond the data it memorized.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Google Colab: Why did we use it?
&lt;/h1&gt;

&lt;p&gt;Google Colab gives you a cloud-based Jupyter Notebook environment.&lt;/p&gt;

&lt;p&gt;Instead of installing everything locally, you can run Python code in the browser.&lt;/p&gt;

&lt;p&gt;A notebook combines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explanation
+
Python code
+
Output
+
Graphs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it very useful for learning ML.&lt;/p&gt;

&lt;p&gt;Your notebooks use paths such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mpg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is typical of a Colab environment.&lt;/p&gt;

&lt;p&gt;A normal learning workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upload dataset
      ↓
Open notebook
      ↓
Run cells
      ↓
Inspect output
      ↓
Change code
      ↓
Run again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  11. The Python libraries you used
&lt;/h1&gt;

&lt;h2&gt;
  
  
  11.1 NumPy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NumPy provides numerical operations and arrays.&lt;/p&gt;

&lt;p&gt;You used it for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;
&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expm1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;np.nan&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a missing numerical value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;np.log1p(x)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Calculates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log(1 + x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is useful when a target is heavily skewed.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;np.expm1(x)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Reverses &lt;code&gt;log1p&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exp(x) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You used this later to convert log predictions back to the original CLV scale.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Pandas
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pandas is one of the most important Python libraries for data work.&lt;/p&gt;

&lt;p&gt;Think of a Pandas DataFrame as a spreadsheet that Python can manipulate.&lt;/p&gt;

&lt;p&gt;You used it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load CSV files&lt;/li&gt;
&lt;li&gt;inspect data&lt;/li&gt;
&lt;li&gt;remove columns&lt;/li&gt;
&lt;li&gt;convert data types&lt;/li&gt;
&lt;li&gt;detect missing values&lt;/li&gt;
&lt;li&gt;fill missing values&lt;/li&gt;
&lt;li&gt;select X and Y&lt;/li&gt;
&lt;li&gt;create encoded columns&lt;/li&gt;
&lt;li&gt;save predictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Telco_Customer_Churn.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  13. Matplotlib
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matplotlib is a general-purpose plotting library.&lt;/p&gt;

&lt;p&gt;It provides the foundation for many Python visualizations.&lt;/p&gt;

&lt;p&gt;You used it for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  14. Seaborn
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seaborn makes statistical visualizations easier to create.&lt;/p&gt;

&lt;p&gt;You used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;countplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;boxplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;histplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pairplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scatterplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;heatmap&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A graph is not decoration. It is a tool for asking questions about the data.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  15. Scikit-learn
&lt;/h1&gt;

&lt;p&gt;Scikit-learn is the main ML library used in your notebooks.&lt;/p&gt;

&lt;p&gt;You used it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;splitting data&lt;/li&gt;
&lt;li&gt;preprocessing&lt;/li&gt;
&lt;li&gt;encoding&lt;/li&gt;
&lt;li&gt;scaling&lt;/li&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;regression&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern appears again and again in ML.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. The most important workflow: EDA
&lt;/h1&gt;

&lt;p&gt;EDA means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Exploratory Data Analysis&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;EDA is the process of investigating the dataset before building the final model.&lt;/p&gt;

&lt;p&gt;Your notebooks use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;plus graphs.&lt;/p&gt;

&lt;p&gt;These are not random commands.&lt;/p&gt;

&lt;p&gt;They answer different questions.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. &lt;code&gt;df.head()&lt;/code&gt; — What does the data look like?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It displays the first few rows.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because before doing anything else, you want to see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;column names&lt;/li&gt;
&lt;li&gt;example values&lt;/li&gt;
&lt;li&gt;obvious data problems&lt;/li&gt;
&lt;li&gt;whether the data loaded correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as opening the box before using what is inside.&lt;/p&gt;




&lt;h1&gt;
  
  
  18. &lt;code&gt;df.shape&lt;/code&gt; — How much data do I have?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Auto MPG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(398, 9)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;398 rows
9 columns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does this matter?&lt;/p&gt;

&lt;p&gt;Because dataset size affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;model choice&lt;/li&gt;
&lt;li&gt;computation time&lt;/li&gt;
&lt;li&gt;confidence in results&lt;/li&gt;
&lt;li&gt;risk of overfitting&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  19. &lt;code&gt;df.info()&lt;/code&gt; — What types of data do I have?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;column names&lt;/li&gt;
&lt;li&gt;number of non-null values&lt;/li&gt;
&lt;li&gt;data types&lt;/li&gt;
&lt;li&gt;memory usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is extremely important.&lt;/p&gt;

&lt;p&gt;For example, in Auto MPG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;horsepower → object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance horsepower sounds numerical.&lt;/p&gt;

&lt;p&gt;But Pandas sees it as text.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the dataset contains values such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A column containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;130
165
150
?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cannot be treated as a clean numerical column.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;df.info()&lt;/code&gt; helps you detect data-type problems before modeling.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  20. &lt;code&gt;df.describe()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and sometimes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives summary statistics.&lt;/p&gt;

&lt;p&gt;For numerical data you get things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;count&lt;/li&gt;
&lt;li&gt;mean&lt;/li&gt;
&lt;li&gt;standard deviation&lt;/li&gt;
&lt;li&gt;minimum&lt;/li&gt;
&lt;li&gt;25th percentile&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;75th percentile&lt;/li&gt;
&lt;li&gt;maximum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps you understand the scale and distribution of variables.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minimum
   ↓
25%
   ↓
median
   ↓
75%
   ↓
maximum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A large difference between the 75th percentile and maximum can be a clue that there may be extreme values.&lt;/p&gt;




&lt;h1&gt;
  
  
  21. &lt;code&gt;df.sample()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or similar.&lt;/p&gt;

&lt;p&gt;This shows random rows.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the first rows may not represent the whole dataset.&lt;/p&gt;

&lt;p&gt;Random samples can expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unusual values&lt;/li&gt;
&lt;li&gt;formatting issues&lt;/li&gt;
&lt;li&gt;unexpected categories&lt;/li&gt;
&lt;li&gt;data-entry problems&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  22. Missing data
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many missing values are there in each column?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Missing data is important because many ML algorithms cannot directly work with missing values.&lt;/p&gt;

&lt;p&gt;But there is a subtle lesson from your Auto MPG notebook.&lt;/p&gt;

&lt;p&gt;You first checked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while &lt;code&gt;horsepower&lt;/code&gt; still contained &lt;code&gt;"?"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pandas did not count &lt;code&gt;"?"&lt;/code&gt; as a missing value because &lt;code&gt;"?"&lt;/code&gt; is a string, not a true &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"?" ≠ NaN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So data cleaning sometimes requires identifying &lt;strong&gt;fake missing values&lt;/strong&gt; first.&lt;/p&gt;




&lt;h1&gt;
  
  
  23. Auto MPG: cleaning horsepower
&lt;/h1&gt;

&lt;p&gt;Your notebook did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This converts the placeholder into a real missing value.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Pandas can treat horsepower as numerical data.&lt;/p&gt;

&lt;p&gt;This is a very important data-cleaning pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messy text
   ↓
identify invalid placeholder
   ↓
convert to NaN
   ↓
convert column to numeric
   ↓
handle missing values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  24. Why use the median?
&lt;/h1&gt;

&lt;p&gt;You calculated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;median_horsepower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then filled missing values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;median_horsepower&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why median?&lt;/p&gt;

&lt;p&gt;Because the median is less affected by extreme values than the mean.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10, 11, 12, 13, 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mean is pulled heavily upward by 1000.&lt;/p&gt;

&lt;p&gt;The median is much more representative of the middle of the data.&lt;/p&gt;

&lt;p&gt;A useful rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fairly symmetric data → mean may work well&lt;/li&gt;
&lt;li&gt;skewed data / outliers → median is often safer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is no universal rule that "median is always correct."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The best treatment depends on the data and the problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  25. Dropping an identifier
&lt;/h1&gt;

&lt;p&gt;You considered dropping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;car name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and actually dropped &lt;code&gt;customerID&lt;/code&gt; in the Telco work.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;An identifier is usually not a meaningful predictive feature.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID = 759832
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not inherently mean the customer is more or less likely to churn.&lt;/p&gt;

&lt;p&gt;The ID exists to identify the row, not to describe the customer.&lt;/p&gt;

&lt;p&gt;Important distinction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A column can be useful for identifying a record without being useful for predicting the target.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  26. But don't blindly drop columns
&lt;/h1&gt;

&lt;p&gt;This is an important improvement to your original reasoning.&lt;/p&gt;

&lt;p&gt;A column should not be dropped merely because it is an object/string.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract
InternetService
PaymentMethod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;are categorical strings, but they can contain very useful predictive information.&lt;/p&gt;

&lt;p&gt;So the correct question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does this column contain useful information that is available at prediction time?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this column numeric?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  27. Understanding your graphs
&lt;/h1&gt;

&lt;p&gt;You created many graphs. The important thing is to understand what question each graph answers.&lt;/p&gt;




&lt;h1&gt;
  
  
  28. Countplot
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A countplot answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many observations are in each category?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No churn → number of customers
Churn    → number of customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This immediately helps you understand class balance.&lt;/p&gt;

&lt;p&gt;If the graph looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No Churn ███████████████████
Churn    ███████
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the classes are imbalanced.&lt;/p&gt;

&lt;p&gt;That matters because a model could achieve high accuracy simply by favoring the majority class.&lt;/p&gt;




&lt;h1&gt;
  
  
  29. Countplot with &lt;code&gt;hue&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contract&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How does the target category vary across another category?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract type
     ↓
Churn / No churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If month-to-month customers show much more churn than two-year customers, that is an important pattern worth investigating.&lt;/p&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A graph showing association does not automatically prove causation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  30. Histogram
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;histplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MonthlyCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;kde&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A histogram shows the distribution of a numerical variable.&lt;/p&gt;

&lt;p&gt;It helps answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are most values?&lt;/li&gt;
&lt;li&gt;Is the data symmetric?&lt;/li&gt;
&lt;li&gt;Is it skewed?&lt;/li&gt;
&lt;li&gt;Are there multiple groups?&lt;/li&gt;
&lt;li&gt;Are there extreme values?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frequency
   ^
   |       ███
   |     ███████
   |   █████████
   | ███████████
   +-----------------&amp;gt; value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  31. Why distributions matter
&lt;/h1&gt;

&lt;p&gt;Suppose a feature looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most values: 0–100
A few values: 10,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That may indicate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;genuine outliers&lt;/li&gt;
&lt;li&gt;a different population&lt;/li&gt;
&lt;li&gt;data-entry errors&lt;/li&gt;
&lt;li&gt;a highly skewed distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model may react differently depending on the algorithm.&lt;/p&gt;

&lt;p&gt;This is one reason EDA happens before modeling.&lt;/p&gt;




&lt;h1&gt;
  
  
  32. Boxplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A boxplot summarizes a distribution.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       outlier
          •
          |
      ┌───────┐
      │       │
------│  box  │------
      │       │
      └───────┘
          |
       outlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The box represents the middle portion of the data.&lt;/p&gt;

&lt;p&gt;The line inside the box is the median.&lt;/p&gt;

&lt;p&gt;Points outside the whiskers may be treated as potential outliers.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An outlier is not automatically an error.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A high-income customer may be perfectly legitimate.&lt;/p&gt;




&lt;h1&gt;
  
  
  33. Boxplot: target vs category
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Coverage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a powerful graph.&lt;/p&gt;

&lt;p&gt;It asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How does the distribution of Customer Lifetime Value differ between categories?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Coverage A → CLV distribution
Coverage B → CLV distribution
Coverage C → CLV distribution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;spread&lt;/li&gt;
&lt;li&gt;outliers&lt;/li&gt;
&lt;li&gt;overlap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can help you identify potentially useful relationships.&lt;/p&gt;




&lt;h1&gt;
  
  
  34. Scatterplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A scatterplot examines the relationship between two numerical variables.&lt;/p&gt;

&lt;p&gt;Each dot represents an observation.&lt;/p&gt;

&lt;p&gt;It helps answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"As X changes, does Y appear to change?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Possible patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Positive relationship:
  •
    •
      •
        •

Negative relationship:
        •
      •
    •
  •

No obvious relationship:
 •    •
    •
  •      •
     •
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern does not have to be a straight line.&lt;/p&gt;




&lt;h1&gt;
  
  
  35. Pairplot
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pairplot&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A pairplot shows many numerical relationships at once.&lt;/p&gt;

&lt;p&gt;It is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spotting correlations&lt;/li&gt;
&lt;li&gt;identifying clusters&lt;/li&gt;
&lt;li&gt;seeing distributions&lt;/li&gt;
&lt;li&gt;finding obvious relationships&lt;/li&gt;
&lt;li&gt;detecting possible outliers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The downside is that it becomes difficult to read when there are many columns.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pairplot is excellent for small-to-medium exploratory datasets, but not something you blindly run on every large dataset.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  36. Correlation heatmap
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heatmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MonthlyCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;annot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Correlation measures how two numerical variables move together in a linear relationship.&lt;/p&gt;

&lt;p&gt;A correlation close to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+1 → strong positive linear relationship
 0 → little/no linear relationship
-1 → strong negative linear relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tenure ↑
TotalCharges ↑
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could result in positive correlation.&lt;/p&gt;

&lt;p&gt;But correlation has an important limitation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Correlation does not prove causation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, zero correlation does not necessarily mean "no relationship" because the relationship might be non-linear.&lt;/p&gt;




&lt;h1&gt;
  
  
  37. A key lesson from visualization
&lt;/h1&gt;

&lt;p&gt;The graphs answer different questions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Graph&lt;/th&gt;
&lt;th&gt;Main question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Countplot&lt;/td&gt;
&lt;td&gt;How many observations are in each category?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot + hue&lt;/td&gt;
&lt;td&gt;How does one category vary with another?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Histogram&lt;/td&gt;
&lt;td&gt;What does a numerical distribution look like?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boxplot&lt;/td&gt;
&lt;td&gt;What are the median, spread and potential outliers?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boxplot + category&lt;/td&gt;
&lt;td&gt;How does a numerical distribution differ by category?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scatterplot&lt;/td&gt;
&lt;td&gt;How do two numerical variables relate?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pairplot&lt;/td&gt;
&lt;td&gt;What relationships exist among several numerical variables?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heatmap&lt;/td&gt;
&lt;td&gt;How strongly are numerical variables linearly correlated?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The goal is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create lots of graphs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use the right graph to answer the right question."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  38. Encoding: why does ML need it?
&lt;/h1&gt;

&lt;p&gt;Many ML algorithms work with numbers.&lt;/p&gt;

&lt;p&gt;But real-world data contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Male
Female

Yes
No

Month-to-month
One year
Two year

Fiber optic
DSL
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model needs these values represented numerically.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;encoding&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  39. Label Encoding
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LabelEncoder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and encoded categorical columns.&lt;/p&gt;

&lt;p&gt;For a binary column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be reasonable for a binary variable.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn:
No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes intuitive sense.&lt;/p&gt;




&lt;h1&gt;
  
  
  40. Why LabelEncoder can be dangerous for multi-category variables
&lt;/h1&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract:
Month-to-month
One year
Two year
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Label encoding might produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Month-to-month → 0
One year       → 1
Two year       → 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A numerical model may interpret that as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Two year &amp;gt; One year &amp;gt; Month-to-month
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ordering may not be appropriate for the algorithm.&lt;/p&gt;

&lt;p&gt;The numbers are just codes.&lt;/p&gt;

&lt;p&gt;They do not automatically mean that category 2 is "twice" category 1.&lt;/p&gt;

&lt;p&gt;For nominal categories, one-hot encoding is usually safer.&lt;/p&gt;




&lt;h1&gt;
  
  
  41. One-hot encoding
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dummies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drop_first&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transforms categories into separate binary columns.&lt;/p&gt;

&lt;p&gt;For:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InternetService:
DSL
Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we might create columns such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InternetService_Fiber optic
InternetService_No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the remaining category represented by both values being 0.&lt;/p&gt;

&lt;p&gt;This avoids inventing a fake numerical ordering.&lt;/p&gt;




&lt;h1&gt;
  
  
  42. Why &lt;code&gt;drop_first=True&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;If a categorical variable has several categories, using all one-hot columns can introduce redundancy in some models.&lt;/p&gt;

&lt;p&gt;Dropping one category creates a reference category.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DSL
Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fiber optic
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fiber optic = 0
No = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the reference category:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DSL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For beginner understanding, the key idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One-hot encoding converts categories into machine-readable indicator variables without pretending the categories have numerical order.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  43. Train/test split
&lt;/h1&gt;

&lt;p&gt;You repeatedly used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important ML concepts.&lt;/p&gt;

&lt;p&gt;Suppose we have 1,000 examples.&lt;/p&gt;

&lt;p&gt;We might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;700 → training
300 → testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The training set is used to learn the model.&lt;/p&gt;

&lt;p&gt;The test set is held back to evaluate how the trained model performs on unseen data.&lt;/p&gt;

&lt;p&gt;Think of it like an exam:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data = practice questions
Test data     = unseen exam questions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  44. Why not train and test on the same data?
&lt;/h1&gt;

&lt;p&gt;Because the model could simply memorize the training examples.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 99%
Test score     = 65%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a warning sign.&lt;/p&gt;

&lt;p&gt;The model learned the training data extremely well but does not generalize well.&lt;/p&gt;

&lt;p&gt;This is called:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Overfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  45. Underfitting
&lt;/h1&gt;

&lt;p&gt;The opposite can happen.&lt;/p&gt;

&lt;p&gt;If the model is too simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 60%
Test score     = 58%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may not have learned enough from the data.&lt;/p&gt;

&lt;p&gt;This is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Underfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A useful mental picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Underfitting
Model too simple
       ↓
misses important patterns

Good fit
Learns useful patterns
       ↓
works on unseen data

Overfitting
Model learns noise/details
       ↓
great training performance
poor unseen performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  46. Why &lt;code&gt;random_state&lt;/code&gt; matters
&lt;/h1&gt;

&lt;p&gt;In one Telco notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the improved notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A random state makes the split reproducible.&lt;/p&gt;

&lt;p&gt;Without it, the random split can change between runs.&lt;/p&gt;

&lt;p&gt;That means your score may change.&lt;/p&gt;

&lt;p&gt;With:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can reproduce the same split.&lt;/p&gt;

&lt;p&gt;The number &lt;code&gt;42&lt;/code&gt; is not magical.&lt;/p&gt;

&lt;p&gt;Any fixed integer can serve this purpose.&lt;/p&gt;




&lt;h1&gt;
  
  
  47. Why &lt;code&gt;stratify=Y&lt;/code&gt; is useful for classification
&lt;/h1&gt;

&lt;p&gt;In your improved Telco notebook you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;stratify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps preserve the class distribution between training and testing data.&lt;/p&gt;

&lt;p&gt;For example, if the full dataset contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;73% No Churn
27% Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;stratification aims to keep roughly the same proportion in both splits.&lt;/p&gt;

&lt;p&gt;This is particularly useful when classes are imbalanced.&lt;/p&gt;




&lt;h1&gt;
  
  
  48. Logistic Regression
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.linear_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LogisticRegression&lt;/span&gt;

&lt;span class="n"&gt;model_lr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model_lr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite its name, Logistic Regression is commonly used for &lt;strong&gt;classification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its goal is to estimate the probability of belonging to a class.&lt;/p&gt;

&lt;p&gt;For binary classification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features
   ↓
Logistic Regression
   ↓
probability
   ↓
class
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Probability of churn = 0.82
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may classify that customer as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;depending on its decision threshold.&lt;/p&gt;




&lt;h1&gt;
  
  
  49. Why Logistic Regression is a good beginner model
&lt;/h1&gt;

&lt;p&gt;It is useful because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;relatively simple&lt;/li&gt;
&lt;li&gt;fast&lt;/li&gt;
&lt;li&gt;often strong as a baseline&lt;/li&gt;
&lt;li&gt;easier to interpret than many complex models&lt;/li&gt;
&lt;li&gt;naturally suited to binary classification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good ML habit is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Start with a simple baseline before reaching for complex models.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  50. Support Vector Machine / SVC
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.svm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SVC&lt;/span&gt;

&lt;span class="n"&gt;model_lr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SVC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable name &lt;code&gt;model_lr&lt;/code&gt; is misleading here.&lt;/p&gt;

&lt;p&gt;It is actually an SVC model.&lt;/p&gt;

&lt;p&gt;SVC means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Support Vector Classifier&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The basic idea is to find a decision boundary that separates classes.&lt;/p&gt;

&lt;p&gt;In simple 2D data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class A: ● ● ●

--------- decision boundary ---------

Class B: ▲ ▲ ▲
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SVM tries to find a boundary with a useful margin between classes.&lt;/p&gt;




&lt;h1&gt;
  
  
  51. Why scaling matters for SVM
&lt;/h1&gt;

&lt;p&gt;SVM is sensitive to feature scale.&lt;/p&gt;

&lt;p&gt;Suppose one feature ranges from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0–1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and another ranges from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0–100,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The larger-scale feature can dominate distance-related calculations.&lt;/p&gt;

&lt;p&gt;That is why scaling is often important for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVM&lt;/li&gt;
&lt;li&gt;KNN&lt;/li&gt;
&lt;li&gt;Logistic Regression in many situations&lt;/li&gt;
&lt;li&gt;neural networks&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  52. Decision Tree
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeClassifier&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A decision tree makes predictions using a sequence of questions.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is tenure &amp;lt; 12?
       /       \
     Yes       No
     /           \
Is charge &amp;gt; X?   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually the tree reaches a leaf containing a prediction.&lt;/p&gt;

&lt;p&gt;This is attractive because it is easy to visualize conceptually.&lt;/p&gt;




&lt;h1&gt;
  
  
  53. Why trees can overfit
&lt;/h1&gt;

&lt;p&gt;A tree can keep splitting the data until it creates extremely specific rules.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If feature A &amp;gt; 10
and feature B &amp;lt; 4
and feature C = 7
and feature D &amp;gt; 92
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually the tree may memorize training examples.&lt;/p&gt;

&lt;p&gt;That is why you later tried:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="n"&gt;min_samples_split&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are ways of controlling tree complexity.&lt;/p&gt;




&lt;h1&gt;
  
  
  54. Random Forest
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;RandomForestRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A random forest combines many decision trees.&lt;/p&gt;

&lt;p&gt;Instead of relying on one tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tree 1 ─┐
Tree 2 ─┤
Tree 3 ─┤
Tree 4 ─┤ → combined prediction
...     ┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is that many different trees can produce a more robust prediction than a single tree.&lt;/p&gt;

&lt;p&gt;This is an example of an &lt;strong&gt;ensemble method&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  55. Bagging
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;BaggingRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_samples&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bagging means combining models trained on different samples of the data.&lt;/p&gt;

&lt;p&gt;The overall idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dataset
  ↓
Different samples
  ↓
Multiple models
  ↓
Combine predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is often to reduce variance and make predictions more stable.&lt;/p&gt;

&lt;p&gt;Random Forest can be viewed as a specialized tree-based ensemble that adds additional randomness in how trees are built.&lt;/p&gt;




&lt;h1&gt;
  
  
  56. AdaBoost
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;AdaBoostRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AdaBoost means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Adaptive Boosting&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of training many independent models and simply averaging them, boosting builds models sequentially.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model 1
  ↓
find mistakes
  ↓
Model 2 focuses more on difficult cases
  ↓
Model 3 focuses further
  ↓
combine models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Later models try to improve on the weaknesses of earlier models.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  57. K-Nearest Neighbors (KNN)
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;KNeighborsRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;KNN predicts using nearby examples.&lt;/p&gt;

&lt;p&gt;Imagine a new customer.&lt;/p&gt;

&lt;p&gt;The algorithm asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which existing customers are most similar to this customer?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then it uses those neighbors to estimate the output.&lt;/p&gt;

&lt;p&gt;For regression, the prediction is commonly based on the neighbors' target values.&lt;/p&gt;




&lt;h1&gt;
  
  
  58. Why KNN needs scaling
&lt;/h1&gt;

&lt;p&gt;KNN relies on distance.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Income:   0–100,000
Age:      18–80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If raw values are used, income can dominate the distance calculation.&lt;/p&gt;

&lt;p&gt;Scaling puts features onto comparable scales.&lt;/p&gt;

&lt;p&gt;That is why you experimented with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  59. StandardScaler
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;X_train_scaled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;X_test_scaled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an important pattern.&lt;/p&gt;

&lt;p&gt;Notice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;The scaler learns the training data's statistics.&lt;/p&gt;

&lt;p&gt;Then the exact same transformation is applied to the test data.&lt;/p&gt;

&lt;p&gt;You should not independently fit the scaler on the test set.&lt;/p&gt;

&lt;p&gt;Otherwise information from the test set leaks into preprocessing.&lt;/p&gt;

&lt;p&gt;This idea is called avoiding:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data leakage&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  60. Data leakage
&lt;/h1&gt;

&lt;p&gt;Data leakage happens when information that should not be available to the model during training accidentally influences the model.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train preprocessing
     ↓
uses information from test data
     ↓
test is no longer truly unseen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can make evaluation look better than real-world performance.&lt;/p&gt;

&lt;p&gt;The correct principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fit preprocessing steps using training data, then apply them to validation/test/new data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A production ML pipeline should ideally bundle preprocessing and modeling together.&lt;/p&gt;




&lt;h1&gt;
  
  
  61. Linear Regression
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;LinearRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for Customer Lifetime Value.&lt;/p&gt;

&lt;p&gt;Linear regression tries to model a relationship like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = b0 + b1X1 + b2X2 + ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For one feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = intercept + slope × X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to find coefficients that produce predictions close to the observed values.&lt;/p&gt;




&lt;h1&gt;
  
  
  62. Regression score: what does &lt;code&gt;.score()&lt;/code&gt; mean?
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the scikit-learn regression models you used, &lt;code&gt;.score()&lt;/code&gt; generally returns &lt;strong&gt;R²&lt;/strong&gt;, the coefficient of determination.&lt;/p&gt;

&lt;p&gt;Very roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R² = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the model explains the observed variation perfectly on that dataset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R² = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the model is no better than a simple baseline based on predicting the mean target.&lt;/p&gt;

&lt;p&gt;R² can also be negative on unseen data.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;R² is not the same thing as accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For regression, do not say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"My regression model has 90% accuracy"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;just because R² is 0.90.&lt;/p&gt;

&lt;p&gt;Instead say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The model achieved an R² of 0.90."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  63. Classification accuracy
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test_pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accuracy is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;correct predictions
-------------------
total predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;90 correct
100 total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;90% accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accuracy is easy to understand.&lt;/p&gt;

&lt;p&gt;But it can be misleading when classes are highly imbalanced.&lt;/p&gt;




&lt;h1&gt;
  
  
  64. Confusion matrix
&lt;/h1&gt;

&lt;p&gt;Your later notes/workflow refer to concepts such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TP
TN
FP
FN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A confusion matrix organizes classification predictions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Actual
                 No       Yes
Predicted No     TN       FN
Predicted Yes    FP       TP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning:&lt;/p&gt;

&lt;h3&gt;
  
  
  True Positive
&lt;/h3&gt;

&lt;p&gt;Model predicted positive and it was positive.&lt;/p&gt;

&lt;h3&gt;
  
  
  True Negative
&lt;/h3&gt;

&lt;p&gt;Model predicted negative and it was negative.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Positive
&lt;/h3&gt;

&lt;p&gt;Model predicted positive but it was negative.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Negative
&lt;/h3&gt;

&lt;p&gt;Model predicted negative but it was positive.&lt;/p&gt;

&lt;p&gt;This is much more informative than accuracy alone when the cost of errors differs.&lt;/p&gt;




&lt;h1&gt;
  
  
  65. Precision and Recall
&lt;/h1&gt;

&lt;p&gt;For classification:&lt;/p&gt;

&lt;h3&gt;
  
  
  Precision
&lt;/h3&gt;

&lt;p&gt;Of everything the model predicted as positive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many were actually positive?&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Precision = TP / (TP + FP)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recall
&lt;/h3&gt;

&lt;p&gt;Of everything that was actually positive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many did the model find?&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recall = TP / (TP + FN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right metric depends on the problem.&lt;/p&gt;

&lt;p&gt;For churn prediction, for example, missing a customer who is about to churn may be more important than contacting an extra customer who would have stayed.&lt;/p&gt;




&lt;h1&gt;
  
  
  66. Your Telco Customer Churn project
&lt;/h1&gt;

&lt;p&gt;This is probably the clearest classification example in your notebooks.&lt;/p&gt;

&lt;p&gt;The business question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we predict whether a telecom customer will churn?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The target is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Churn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer data
     ↓
Clean data
     ↓
Explore data
     ↓
Encode categories
     ↓
Split train/test
     ↓
Train classifier
     ↓
Predict churn
     ↓
Evaluate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  67. Telco: removing customerID
&lt;/h1&gt;

&lt;p&gt;You did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customerID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is reasonable because the ID is an identifier rather than a customer characteristic.&lt;/p&gt;

&lt;p&gt;You also commented that it could be kept separately if you later wanted to map predictions back to customers.&lt;/p&gt;

&lt;p&gt;That is a good practical idea.&lt;/p&gt;

&lt;p&gt;In production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID
   ↓
keep separately for business reporting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerID
   X
do not necessarily use as a model feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  68. Telco: fixing TotalCharges
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TotalCharges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coerce&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;errors="coerce"&lt;/code&gt; means invalid values are converted to &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in one notebook and median imputation in another.&lt;/p&gt;

&lt;p&gt;These are two different decisions.&lt;/p&gt;

&lt;p&gt;The important lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Missing-value handling should be based on the meaning of the data, not simply on whichever replacement is easiest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, if missing &lt;code&gt;TotalCharges&lt;/code&gt; occurs because a customer has zero tenure and has just joined, then filling with zero may have a meaningful business interpretation.&lt;/p&gt;

&lt;p&gt;If missingness represents an unknown measurement, median imputation may be more appropriate.&lt;/p&gt;




&lt;h1&gt;
  
  
  69. Telco: the first modeling version
&lt;/h1&gt;

&lt;p&gt;The earlier Telco notebook used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;LabelEncoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for many categorical columns.&lt;/p&gt;

&lt;p&gt;This is okay as a learning exercise for understanding encoding, but it is not ideal for every categorical variable.&lt;/p&gt;

&lt;p&gt;A better version in your later notebook used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dummies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi_cols&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;drop_first&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a meaningful improvement.&lt;/p&gt;




&lt;h1&gt;
  
  
  70. Telco: your improved preprocessing pipeline
&lt;/h1&gt;

&lt;p&gt;The later notebook did something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw data
   ↓
Drop customerID
   ↓
Convert TotalCharges
   ↓
Encode binary columns
   ↓
One-hot encode multi-category columns
   ↓
Separate X and Y
   ↓
Scale X
   ↓
Train Logistic Regression
   ↓
Create Gradio interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much closer to a real ML application.&lt;/p&gt;




&lt;h1&gt;
  
  
  71. Gradio: turning a model into an application
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gradio&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;gr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and built a UI.&lt;/p&gt;

&lt;p&gt;This is an important step because it changes the project from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Notebook experiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User input
    ↓
Preprocessing
    ↓
Model
    ↓
Prediction
    ↓
Human-readable result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gender: Female
Tenure: 12 months
Contract: Month-to-month
Monthly charges: $70
...
          ↓
    Predict Churn
          ↓
High Churn Risk
Probability: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates an important ML engineering concept:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A model is useful only when it can be integrated into a workflow where people or systems can use its predictions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  72. Very important: preprocessing must match training
&lt;/h1&gt;

&lt;p&gt;Your Gradio code contains a good lesson.&lt;/p&gt;

&lt;p&gt;During training you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;encode the categorical values&lt;/li&gt;
&lt;li&gt;create dummy columns&lt;/li&gt;
&lt;li&gt;scale the features&lt;/li&gt;
&lt;li&gt;train the model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During prediction you must do the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;raw user input
    ↓
same encoding
    ↓
same columns
    ↓
same scaling
    ↓
model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the training data has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature_1
feature_2
feature_3
feature_4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but the application sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature_1
feature_3
feature_4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model cannot interpret the input correctly.&lt;/p&gt;

&lt;p&gt;Your use of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;input_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reindex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;feature_columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fill_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is intended to make the input columns match the training feature structure.&lt;/p&gt;

&lt;p&gt;That is an important practical idea.&lt;/p&gt;




&lt;h1&gt;
  
  
  73. A stronger production pattern: Pipeline
&lt;/h1&gt;

&lt;p&gt;A cleaner production approach is often:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;preprocessor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then preprocessing and prediction are tied together.&lt;/p&gt;

&lt;p&gt;This reduces the risk of accidentally applying different transformations during training and inference.&lt;/p&gt;

&lt;p&gt;Your notebook demonstrates the concept manually, which is useful for learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  74. Your Auto Insurance / Customer Lifetime Value project
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;13-Aug.ipynb&lt;/code&gt; notebook moves into regression.&lt;/p&gt;

&lt;p&gt;The target is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes the question from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Will this customer churn?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What numerical Customer Lifetime Value should we predict?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classification → Churn
Regression     → Customer Lifetime Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  75. Insurance dataset: initial exploration
&lt;/h1&gt;

&lt;p&gt;You loaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AutoInsurance.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inspected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
Effective To Date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the modeling DataFrame.&lt;/p&gt;

&lt;p&gt;Again, the purpose is to separate identifiers / dates that were not being used in the current modeling approach.&lt;/p&gt;

&lt;p&gt;However, an important ML lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dates are not automatically useless.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A date may contain useful information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;month&lt;/li&gt;
&lt;li&gt;day of week&lt;/li&gt;
&lt;li&gt;season&lt;/li&gt;
&lt;li&gt;year&lt;/li&gt;
&lt;li&gt;time since an event&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A stronger project could engineer useful date features instead of simply dropping every date column.&lt;/p&gt;




&lt;h1&gt;
  
  
  76. Insurance EDA
&lt;/h1&gt;

&lt;p&gt;You explored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;State&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Coverage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer Lifetime Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Income&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a good progression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Categorical distribution
        ↓
Numerical distribution
        ↓
Numerical vs categorical
        ↓
Numerical vs numerical
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are gradually asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What might explain the target?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  77. Automatically finding numerical and categorical columns
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;numerical_cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_dtypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;int64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;float64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;

&lt;span class="n"&gt;categorical_cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_dtypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful because instead of manually listing every column, Python can identify columns based on data type.&lt;/p&gt;

&lt;p&gt;Then you looped through them to create graphs.&lt;/p&gt;

&lt;p&gt;This is the beginning of writing reusable data-analysis code.&lt;/p&gt;




&lt;h1&gt;
  
  
  78. Automated boxplots
&lt;/h1&gt;

&lt;p&gt;You created boxplots for all numerical columns.&lt;/p&gt;

&lt;p&gt;This is useful because you can quickly inspect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;distributions&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;spread&lt;/li&gt;
&lt;li&gt;potential outliers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, remember that a large collection of graphs can become overwhelming.&lt;/p&gt;

&lt;p&gt;The goal should eventually move from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Let's plot everything."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Let's plot the variables that help answer our question."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a sign of growing from beginner EDA toward professional analysis.&lt;/p&gt;




&lt;h1&gt;
  
  
  79. Binning numerical variables for boxplots
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This divides a numerical variable into five intervals.&lt;/p&gt;

&lt;p&gt;Then you compare CLV across those ranges.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Income range 1 → CLV distribution
Income range 2 → CLV distribution
Income range 3 → CLV distribution
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for visualization because a boxplot expects categories on one axis.&lt;/p&gt;

&lt;p&gt;But the number and boundaries of bins can affect the story you see.&lt;/p&gt;

&lt;p&gt;So binning is mainly a visualization technique here, not necessarily something you should automatically use as a model feature.&lt;/p&gt;




&lt;h1&gt;
  
  
  80. Comparing many regression algorithms
&lt;/h1&gt;

&lt;p&gt;One of the biggest learning steps in your final notebook was trying multiple regressors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linear Regression
KNN Regressor
SVR
Decision Tree Regressor
Bagging Regressor
AdaBoost Regressor
Random Forest Regressor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is valuable because it teaches a core ML lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Different algorithms make different assumptions and capture different types of patterns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is no universally best algorithm.&lt;/p&gt;




&lt;h1&gt;
  
  
  81. Linear Regression vs tree-based models
&lt;/h1&gt;

&lt;p&gt;Linear Regression assumes a relationship that can be represented through a linear combination of features.&lt;/p&gt;

&lt;p&gt;Tree-based methods can represent more complex non-linear relationships.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linear model:

Y
│       /
│     /
│   /
│ /
└──────── X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tree-based model can approximate more irregular patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y
│    ┌────
│    │
│ ───┘
│
└──────── X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why trying multiple model families can be useful.&lt;/p&gt;




&lt;h1&gt;
  
  
  82. Why model comparison matters
&lt;/h1&gt;

&lt;p&gt;Suppose you obtain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model             Train R²    Test R²
Linear Regression   0.70       0.68
KNN                 0.90       0.62
Decision Tree       0.99       0.55
Random Forest       0.91       0.78
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should not automatically choose the model with the highest training score.&lt;/p&gt;

&lt;p&gt;The more important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which model generalizes well to unseen data?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here Random Forest would be more interesting than the tree with 0.99 training R².&lt;/p&gt;




&lt;h1&gt;
  
  
  83. Log transformation of Customer Lifetime Value
&lt;/h1&gt;

&lt;p&gt;You later used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because some target variables are heavily skewed.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most CLV values: relatively small
A few CLV values: extremely large
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may have difficulty fitting such a distribution.&lt;/p&gt;

&lt;p&gt;A log transformation compresses large values.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original:
1
10
100
1000
10000

Log scale:
small differences between large values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can make the target distribution easier for some models to learn.&lt;/p&gt;




&lt;h1&gt;
  
  
  84. Reversing the log transformation
&lt;/h1&gt;

&lt;p&gt;After predicting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expm1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;If:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y_log = log(1 + Y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Y = exp(Y_log) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;np.expm1()&lt;/code&gt; performs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exp(x) - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log target
   ↓
model
   ↓
log prediction
   ↓
expm1
   ↓
original target scale
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  85. An important issue in the notebook: split consistency
&lt;/h1&gt;

&lt;p&gt;In your log-transform section, you did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Y_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;X_train_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_train_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y_test_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Y_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is okay as a new split, but it means your earlier train/test split and later train/test split are not necessarily the same.&lt;/p&gt;

&lt;p&gt;For a clean experiment, define the split once and reuse it consistently.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;y_train_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y_test_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log1p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes comparisons easier to reason about.&lt;/p&gt;




&lt;h1&gt;
  
  
  86. Another important issue: predicting on the full dataset
&lt;/h1&gt;

&lt;p&gt;You later did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predictions_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and saved predictions for the full dataset.&lt;/p&gt;

&lt;p&gt;That can be useful for producing a business-facing prediction file.&lt;/p&gt;

&lt;p&gt;But these are &lt;strong&gt;not unbiased test predictions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;X&lt;/code&gt; includes training observations the model already saw.&lt;/p&gt;

&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predictions on X_test
→ useful for evaluating unseen data

Predictions on X
→ useful for generating predictions for all records,
   but not for measuring generalization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction is very important.&lt;/p&gt;




&lt;h1&gt;
  
  
  87. Hyperparameters
&lt;/h1&gt;

&lt;p&gt;Later you changed models from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;DecisionTreeRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_split&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These settings are called &lt;strong&gt;hyperparameters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are chosen by us before training.&lt;/p&gt;

&lt;p&gt;The model learns its internal parameters from the training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;Learned by the algorithm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hyperparameters
&lt;/h3&gt;

&lt;p&gt;Set by us.&lt;/p&gt;

&lt;p&gt;This distinction is fundamental.&lt;/p&gt;




&lt;h1&gt;
  
  
  88. Understanding your tree hyperparameters
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;max_depth&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Controls how deep the tree can grow.&lt;/p&gt;

&lt;p&gt;Smaller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;simpler tree
less overfitting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Larger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;more complex tree
greater overfitting risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;min_samples_split&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Minimum number of samples required before a node can be split.&lt;/p&gt;

&lt;p&gt;Higher values make the tree more conservative.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;min_samples_leaf&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Minimum number of samples allowed in a leaf.&lt;/p&gt;

&lt;p&gt;Higher values prevent extremely tiny leaves.&lt;/p&gt;




&lt;h1&gt;
  
  
  89. Random Forest hyperparameters
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;RandomForestRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;min_samples_leaf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;n_estimators=200&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Build 200 trees.&lt;/p&gt;

&lt;p&gt;More trees can make the ensemble more stable, though computation increases.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;max_depth=8&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Limits tree complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;min_samples_leaf=5&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Prevents leaves from becoming too specific.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;random_state=42&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Makes the experiment reproducible.&lt;/p&gt;




&lt;h1&gt;
  
  
  90. Bagging hyperparameters
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;BaggingRegressor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;n_estimators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_samples&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means, conceptually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build many estimators&lt;/li&gt;
&lt;li&gt;each estimator sees a sample of the training rows&lt;/li&gt;
&lt;li&gt;each estimator can use a subset of features&lt;/li&gt;
&lt;li&gt;combine their predictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, the goal is to create a robust ensemble rather than rely on one model.&lt;/p&gt;




&lt;h1&gt;
  
  
  91. Scaling experiment in your notebook
&lt;/h1&gt;

&lt;p&gt;You used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and compared KNN/SVR.&lt;/p&gt;

&lt;p&gt;This is a very useful experiment because it demonstrates:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Preprocessing requirements depend on the algorithm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tree-based algorithms generally do not need feature scaling in the same way that distance- or margin-based methods do.&lt;/p&gt;

&lt;p&gt;KNN and SVM are much more sensitive to feature scale.&lt;/p&gt;




&lt;h1&gt;
  
  
  92. A subtle issue in your scaling experiment
&lt;/h1&gt;

&lt;p&gt;You created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train_scaled&lt;/span&gt;
&lt;span class="n"&gt;X_test_scaled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but your KNN code first trained on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train_log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;before later looping over scaled KNN.&lt;/p&gt;

&lt;p&gt;That is useful as experimentation, but for a clean article you should present the comparison more systematically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;KNN without scaling
        vs
KNN with scaling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and explicitly explain why the result changed.&lt;/p&gt;

&lt;p&gt;For SVR, you correctly used the scaled data in the shown section.&lt;/p&gt;




&lt;h1&gt;
  
  
  93. The complete mental model
&lt;/h1&gt;

&lt;p&gt;After these five days, the entire workflow can be remembered as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             REAL-WORLD QUESTION
                     ↓
             Define the target
                     ↓
              Collect data
                     ↓
              Understand data
                     ↓
          ┌──────────┴──────────┐
          ↓                     ↓
      Numerical             Categorical
          ↓                     ↓
      distributions        category counts
          └──────────┬──────────┘
                     ↓
                    EDA
                     ↓
              Clean the data
                     ↓
          Handle missing values
                     ↓
             Encode categories
                     ↓
          Select useful features
                     ↓
              Split train/test
                     ↓
          Scale when appropriate
                     ↓
              Train baseline
                     ↓
          Evaluate on test data
                     ↓
             Try other models
                     ↓
         Tune hyperparameters
                     ↓
       Select based on validation
                     ↓
             Final evaluation
                     ↓
              Make predictions
                     ↓
       Integrate into an application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  94. What each notebook taught you
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Day 1 — Auto MPG
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load a dataset&lt;/li&gt;
&lt;li&gt;inspect rows and columns&lt;/li&gt;
&lt;li&gt;understand shape and data types&lt;/li&gt;
&lt;li&gt;inspect summary statistics&lt;/li&gt;
&lt;li&gt;identify categorical/text columns&lt;/li&gt;
&lt;li&gt;detect messy numerical values&lt;/li&gt;
&lt;li&gt;visualize distributions&lt;/li&gt;
&lt;li&gt;use countplots&lt;/li&gt;
&lt;li&gt;use histograms&lt;/li&gt;
&lt;li&gt;use pairplots&lt;/li&gt;
&lt;li&gt;understand missing values&lt;/li&gt;
&lt;li&gt;convert &lt;code&gt;"?"&lt;/code&gt; to &lt;code&gt;NaN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;convert text to numerical data&lt;/li&gt;
&lt;li&gt;use median imputation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Before modeling, understand and clean your data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 2 — Telco Customer Churn
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identify a classification target&lt;/li&gt;
&lt;li&gt;remove an identifier&lt;/li&gt;
&lt;li&gt;handle &lt;code&gt;TotalCharges&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;visualize class balance&lt;/li&gt;
&lt;li&gt;compare categories against churn&lt;/li&gt;
&lt;li&gt;use boxplots and histograms&lt;/li&gt;
&lt;li&gt;use pairplots&lt;/li&gt;
&lt;li&gt;inspect correlations&lt;/li&gt;
&lt;li&gt;encode categorical data&lt;/li&gt;
&lt;li&gt;split into training/testing data&lt;/li&gt;
&lt;li&gt;train Logistic Regression&lt;/li&gt;
&lt;li&gt;train SVC&lt;/li&gt;
&lt;li&gt;train Decision Tree&lt;/li&gt;
&lt;li&gt;compare train/test performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A classification model predicts categories, but the quality of the prediction depends heavily on preprocessing and evaluation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 3 — Improving the Telco project
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one-hot encode multi-category variables&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;random_state&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;stratify&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scale features&lt;/li&gt;
&lt;li&gt;train Logistic Regression&lt;/li&gt;
&lt;li&gt;build a prediction interface with Gradio&lt;/li&gt;
&lt;li&gt;reproduce preprocessing at inference time&lt;/li&gt;
&lt;li&gt;output a human-readable prediction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An ML model is only one part of an ML application.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Day 4/5 — Customer Lifetime Value
&lt;/h2&gt;

&lt;p&gt;Main lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formulate a regression problem&lt;/li&gt;
&lt;li&gt;inspect numerical/categorical relationships&lt;/li&gt;
&lt;li&gt;automate EDA&lt;/li&gt;
&lt;li&gt;encode categories&lt;/li&gt;
&lt;li&gt;split train/test&lt;/li&gt;
&lt;li&gt;compare multiple regressors&lt;/li&gt;
&lt;li&gt;understand R²&lt;/li&gt;
&lt;li&gt;try target transformation&lt;/li&gt;
&lt;li&gt;use log transformation&lt;/li&gt;
&lt;li&gt;reverse the transformation&lt;/li&gt;
&lt;li&gt;experiment with scaling&lt;/li&gt;
&lt;li&gt;tune hyperparameters&lt;/li&gt;
&lt;li&gt;use ensemble models&lt;/li&gt;
&lt;li&gt;generate prediction files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Different models capture different patterns, and model selection should be based on performance on unseen data—not training performance alone.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  95. What I would change before publishing the project as "production-quality"
&lt;/h1&gt;

&lt;p&gt;Your notebooks are excellent learning material because they show experimentation. For a public article, however, it is worth separating:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Learning experiments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recommended ML workflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the most important improvements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 1 — Use clear train/test terminology
&lt;/h2&gt;

&lt;p&gt;Prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than mixing &lt;code&gt;Y&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Python convention generally uses lowercase &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 2 — Make experiments reproducible
&lt;/h2&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;consistently when appropriate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 3 — Use stratification for classification
&lt;/h2&gt;

&lt;p&gt;For churn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;stratify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Improvement 4 — Avoid LabelEncoder for nominal multi-class input features
&lt;/h2&gt;

&lt;p&gt;Use one-hot encoding for categories such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PaymentMethod
Contract
InternetService
VehicleClass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Label encoding is much more naturally suited to targets or truly ordinal categories.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 5 — Fit preprocessing only on training data
&lt;/h2&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data
    ↓
fit scaler
    ↓
transform training

Test data
    ↓
transform using existing scaler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not independently fit preprocessing on the test data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 6 — Use proper evaluation metrics
&lt;/h2&gt;

&lt;p&gt;For classification, consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accuracy
Precision
Recall
F1
Confusion Matrix
ROC-AUC
PR-AUC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For regression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R²
MAE
MSE
RMSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which metrics matter depends on the business problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 7 — Don't compare only training scores
&lt;/h2&gt;

&lt;p&gt;Always look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training performance
+
Validation/test performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A very high training score with much lower test performance can indicate overfitting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Improvement 8 — Keep a validation strategy for model selection
&lt;/h2&gt;

&lt;p&gt;A single test set should ideally be kept for final evaluation.&lt;/p&gt;

&lt;p&gt;During experimentation, use cross-validation or a validation set to choose models/hyperparameters.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data
   ↓
Cross-validation / validation
   ↓
Choose model
   ↓
Final test set
   ↓
Final unbiased-ish estimate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  96. A very important distinction: EDA vs ML
&lt;/h1&gt;

&lt;p&gt;EDA asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What does my data look like?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Machine learning asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can I learn a useful relationship that lets me make predictions on new data?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These overlap, but they are not the same.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatterplot&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not build a model.&lt;/p&gt;

&lt;p&gt;It helps you understand the data before deciding how to model it.&lt;/p&gt;




&lt;h1&gt;
  
  
  97. Another important distinction: correlation vs prediction
&lt;/h1&gt;

&lt;p&gt;A strong correlation can be useful.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;high correlation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not automatically mean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;excellent predictive model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prediction depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple features&lt;/li&gt;
&lt;li&gt;data quality&lt;/li&gt;
&lt;li&gt;model type&lt;/li&gt;
&lt;li&gt;noise&lt;/li&gt;
&lt;li&gt;generalization&lt;/li&gt;
&lt;li&gt;preprocessing&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So don't judge an ML problem from one graph.&lt;/p&gt;




&lt;h1&gt;
  
  
  98. Another important distinction: model vs algorithm
&lt;/h1&gt;

&lt;p&gt;It is common to hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I trained a model."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The algorithm is the learning procedure.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Random Forest = algorithm/model family
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After training:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model_rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you have a fitted model containing learned information.&lt;/p&gt;

&lt;p&gt;A useful mental model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Algorithm
   +
Training data
   ↓
Fitted model
   ↓
Predictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  99. What "learning" actually means
&lt;/h1&gt;

&lt;p&gt;This is probably the most important concept to understand.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model is not magically understanding the world.&lt;/p&gt;

&lt;p&gt;It is optimizing internal parameters so that its predictions match the training examples according to the algorithm's objective.&lt;/p&gt;

&lt;p&gt;For example, linear regression learns coefficients.&lt;/p&gt;

&lt;p&gt;A tree learns split rules.&lt;/p&gt;

&lt;p&gt;A neural network learns weights.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Training means finding model parameters that make the model perform well according to a defined objective.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  100. What happens during prediction?
&lt;/h1&gt;

&lt;p&gt;Once training is complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model does not learn again from the test examples.&lt;/p&gt;

&lt;p&gt;It applies what it learned during training.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training:

X_train + y_train
        ↓
      model.fit()
        ↓
   learned model

Prediction:

X_test
   ↓
learned model
   ↓
prediction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  101. The biggest beginner misconception to avoid
&lt;/h1&gt;

&lt;p&gt;Do not think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I used Random Forest, so I did machine learning."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real ML skill is being able to explain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What problem are you solving?&lt;/li&gt;
&lt;li&gt;What is the target?&lt;/li&gt;
&lt;li&gt;What features are available?&lt;/li&gt;
&lt;li&gt;What does the data look like?&lt;/li&gt;
&lt;li&gt;What problems did you find?&lt;/li&gt;
&lt;li&gt;How did you clean them?&lt;/li&gt;
&lt;li&gt;How did you encode the data?&lt;/li&gt;
&lt;li&gt;Why did you choose the algorithm?&lt;/li&gt;
&lt;li&gt;How did you evaluate it?&lt;/li&gt;
&lt;li&gt;Does it generalize?&lt;/li&gt;
&lt;li&gt;What would you improve?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you can explain these, you are learning ML—not just memorizing scikit-learn commands.&lt;/p&gt;




&lt;h1&gt;
  
  
  102. A simple explanation of your five-day journey
&lt;/h1&gt;

&lt;p&gt;If someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What did you actually learn in five days?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A strong answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I learned that machine learning is not just about selecting an algorithm. I started by understanding datasets using Pandas, cleaning missing and incorrectly formatted values, and using visualization to understand distributions and relationships. Then I learned the difference between classification and regression, converted categorical data into numerical representations, split data into training and testing sets, trained several models using scikit-learn, and compared their performance on unseen data. Finally, I experimented with scaling, transformations, ensemble models, hyperparameters, and even built a simple Gradio interface around a churn model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much stronger story than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I learned Logistic Regression, SVM and Random Forest."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  103. Suggested article structure for dev.to
&lt;/h1&gt;

&lt;p&gt;For your final public article, I recommend this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title

1. Why I started learning ML
2. What I thought ML was vs what I learned
3. AI vs ML
4. Types of ML
5. My five-day learning roadmap
6. Day 1 — Understanding and cleaning data
7. EDA and why graphs matter
8. Day 2 — Classification with customer churn
9. Encoding categorical data
10. Train/test split
11. Logistic Regression, SVM and Decision Trees
12. How I evaluated classification models
13. Day 3 — Turning the model into an application
14. Day 4/5 — Regression and Customer Lifetime Value
15. Linear Regression vs KNN vs SVR vs Trees vs Ensembles
16. Log transformation
17. Scaling
18. Hyperparameters
19. What I got wrong / what I would improve
20. What I learned
21. What I plan to learn next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make the article feel like a &lt;strong&gt;journey&lt;/strong&gt;, rather than a textbook.&lt;/p&gt;




&lt;h1&gt;
  
  
  104. Recommended article narrative
&lt;/h1&gt;

&lt;p&gt;The most interesting story is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I started with almost no ML knowledge."

        ↓

"I learned that data preparation matters."

        ↓

"I discovered that graphs help me ask questions
before training models."

        ↓

"I learned classification."

        ↓

"I learned regression."

        ↓

"I tried different algorithms and realized
there is no single best model."

        ↓

"I learned that a high training score
doesn't necessarily mean a good model."

        ↓

"I turned one model into a small application."

        ↓

"I now understand the basic ML workflow
and know what I need to learn next."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a much more authentic beginner-to-ML story.&lt;/p&gt;




&lt;h1&gt;
  
  
  105. What to learn next
&lt;/h1&gt;

&lt;p&gt;Based on what your notebooks already cover, I would &lt;strong&gt;not&lt;/strong&gt; recommend immediately jumping into deep learning.&lt;/p&gt;

&lt;p&gt;First strengthen these foundations:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Statistics
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mean&lt;/li&gt;
&lt;li&gt;median&lt;/li&gt;
&lt;li&gt;variance&lt;/li&gt;
&lt;li&gt;standard deviation&lt;/li&gt;
&lt;li&gt;distributions&lt;/li&gt;
&lt;li&gt;probability&lt;/li&gt;
&lt;li&gt;correlation&lt;/li&gt;
&lt;li&gt;conditional probability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. ML evaluation
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;confusion matrix&lt;/li&gt;
&lt;li&gt;precision&lt;/li&gt;
&lt;li&gt;recall&lt;/li&gt;
&lt;li&gt;F1&lt;/li&gt;
&lt;li&gt;ROC-AUC&lt;/li&gt;
&lt;li&gt;MAE&lt;/li&gt;
&lt;li&gt;RMSE&lt;/li&gt;
&lt;li&gt;R²&lt;/li&gt;
&lt;li&gt;cross-validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Feature engineering
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handling dates&lt;/li&gt;
&lt;li&gt;categorical features&lt;/li&gt;
&lt;li&gt;transformations&lt;/li&gt;
&lt;li&gt;interactions&lt;/li&gt;
&lt;li&gt;outliers&lt;/li&gt;
&lt;li&gt;missing values&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Model selection
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cross-validation&lt;/li&gt;
&lt;li&gt;hyperparameter tuning&lt;/li&gt;
&lt;li&gt;GridSearchCV&lt;/li&gt;
&lt;li&gt;RandomizedSearchCV&lt;/li&gt;
&lt;li&gt;pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. ML fundamentals
&lt;/h2&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bias vs variance&lt;/li&gt;
&lt;li&gt;underfitting&lt;/li&gt;
&lt;li&gt;overfitting&lt;/li&gt;
&lt;li&gt;regularization&lt;/li&gt;
&lt;li&gt;data leakage&lt;/li&gt;
&lt;li&gt;feature importance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then move toward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classical ML
     ↓
Feature engineering
     ↓
Model selection
     ↓
Cross-validation
     ↓
ML pipelines
     ↓
Deployment
     ↓
Deep Learning
     ↓
Generative AI / LLMs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  106. The one-page cheat sheet
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Problem type
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predict a category → Classification
Predict a number   → Regression
Find hidden groups → Clustering
Learn through reward → Reinforcement Learning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rows       → observations
Columns    → variables/features
X          → input features
y          → target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First inspection
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Visualization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Countplot   → categories
Histogram   → numerical distribution
Boxplot     → spread/outliers
Scatterplot → two numerical variables
Pairplot    → many numerical relationships
Heatmap     → correlation matrix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Missing values
Data types
Categorical encoding
Feature selection
Scaling when needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Training
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prediction
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Evaluation
&lt;/h2&gt;

&lt;p&gt;Classification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accuracy
Precision
Recall
F1
Confusion Matrix
ROC-AUC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R²
MAE
MSE
RMSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Core warning signs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score &amp;gt;&amp;gt; Test score
        ↓
Possible overfitting

Test information used during preprocessing
        ↓
Possible data leakage

Identifier used as feature
        ↓
Possible meaningless pattern

Categorical values converted to arbitrary numbers
        ↓
Possible false ordering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  107. Final takeaway
&lt;/h1&gt;

&lt;p&gt;The biggest lesson from these five days is not a particular Python library or algorithm.&lt;/p&gt;

&lt;p&gt;It is the workflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Understand the problem → understand the data → clean the data → explore the data → prepare features → train → evaluate → improve → deploy.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The algorithms are tools inside that workflow.&lt;/p&gt;

&lt;p&gt;You have already touched many of the important building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pandas&lt;/li&gt;
&lt;li&gt;NumPy&lt;/li&gt;
&lt;li&gt;Matplotlib&lt;/li&gt;
&lt;li&gt;Seaborn&lt;/li&gt;
&lt;li&gt;Scikit-learn&lt;/li&gt;
&lt;li&gt;data cleaning&lt;/li&gt;
&lt;li&gt;EDA&lt;/li&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;regression&lt;/li&gt;
&lt;li&gt;encoding&lt;/li&gt;
&lt;li&gt;train/test split&lt;/li&gt;
&lt;li&gt;scaling&lt;/li&gt;
&lt;li&gt;model evaluation&lt;/li&gt;
&lt;li&gt;hyperparameters&lt;/li&gt;
&lt;li&gt;ensemble models&lt;/li&gt;
&lt;li&gt;target transformation&lt;/li&gt;
&lt;li&gt;Gradio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next step is not to memorize more algorithms.&lt;/p&gt;

&lt;p&gt;The next step is to become comfortable answering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why am I doing this step?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can answer that question for every important line in your notebook, you are moving from "following an ML tutorial" to actually understanding machine learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  Appendix A — Notebook-by-notebook step map
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;11_Aug_mpg.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Notebook step&lt;/th&gt;
&lt;th&gt;Why it was done&lt;/th&gt;
&lt;th&gt;ML concept&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Import NumPy/Pandas/Matplotlib/Seaborn&lt;/td&gt;
&lt;td&gt;Load tools&lt;/td&gt;
&lt;td&gt;Python ML stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read_csv()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load data&lt;/td&gt;
&lt;td&gt;Data ingestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nunique()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand uniqueness&lt;/td&gt;
&lt;td&gt;Data exploration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect examples&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand dataset size&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;describe()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Summary statistics&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;info()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Types/non-null values&lt;/td&gt;
&lt;td&gt;Data quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;countplot()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect categorical distribution&lt;/td&gt;
&lt;td&gt;Visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hist()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect numerical distributions&lt;/td&gt;
&lt;td&gt;Visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isnull()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Detect actual missing values&lt;/td&gt;
&lt;td&gt;Data cleaning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pairplot()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Explore relationships&lt;/td&gt;
&lt;td&gt;EDA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sample()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect random examples&lt;/td&gt;
&lt;td&gt;Data quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identify &lt;code&gt;car name&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Recognize identifier-like field&lt;/td&gt;
&lt;td&gt;Feature selection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replace &lt;code&gt;?&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Convert fake missing values&lt;/td&gt;
&lt;td&gt;Data cleaning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;to_numeric()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Make horsepower numerical&lt;/td&gt;
&lt;td&gt;Data preparation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median imputation&lt;/td&gt;
&lt;td&gt;Fill missing horsepower&lt;/td&gt;
&lt;td&gt;Missing-value handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Train/test split&lt;/td&gt;
&lt;td&gt;Separate learning/evaluation data&lt;/td&gt;
&lt;td&gt;Generalization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logistic Regression&lt;/td&gt;
&lt;td&gt;Start classification experiment&lt;/td&gt;
&lt;td&gt;Supervised learning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Important caveat
&lt;/h3&gt;

&lt;p&gt;The notebook switches from Auto MPG to a &lt;code&gt;loan_prediction.csv&lt;/code&gt; dataset near the end. That appears to be a copied/reused modeling experiment rather than a continuation of the Auto MPG workflow. For a polished article, present these as separate experiments rather than one continuous Auto MPG pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;12th-Aug-Telco-Customer-churn.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load Telco CSV&lt;/td&gt;
&lt;td&gt;Get customer data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Understand size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;describe()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Statistical overview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop &lt;code&gt;customerID&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Remove identifier from features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;info()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check data types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sample()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect random rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot of Churn&lt;/td&gt;
&lt;td&gt;Check class distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Countplot of gender&lt;/td&gt;
&lt;td&gt;Explore category distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Histograms&lt;/td&gt;
&lt;td&gt;Explore numerical distributions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pairplot&lt;/td&gt;
&lt;td&gt;Explore relationships&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert TotalCharges&lt;/td&gt;
&lt;td&gt;Fix numeric type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fill missing TotalCharges&lt;/td&gt;
&lt;td&gt;Handle missing data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LabelEncoder&lt;/td&gt;
&lt;td&gt;Convert categories to numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Train/test split&lt;/td&gt;
&lt;td&gt;Evaluate on unseen data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logistic Regression&lt;/td&gt;
&lt;td&gt;Classification model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVC&lt;/td&gt;
&lt;td&gt;Alternative classifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision Tree&lt;/td&gt;
&lt;td&gt;Alternative classifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradio&lt;/td&gt;
&lt;td&gt;Turn model into interactive app&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Important caveat
&lt;/h3&gt;

&lt;p&gt;The notebook uses LabelEncoder on many categorical input columns. This is useful for learning encoding, but one-hot encoding is generally safer for nominal multi-category features.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;12-Aug-2.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This notebook is a more developed version of the Telco project.&lt;/p&gt;

&lt;p&gt;Important improvements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dropping &lt;code&gt;customerID&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;converting &lt;code&gt;TotalCharges&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;one-hot encoding multi-category variables&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;random_state=42&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;stratify=Y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scaling features&lt;/li&gt;
&lt;li&gt;training Logistic Regression&lt;/li&gt;
&lt;li&gt;building a Gradio prediction interface&lt;/li&gt;
&lt;li&gt;preserving training feature columns&lt;/li&gt;
&lt;li&gt;applying the same preprocessing to new input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the notebook that most clearly demonstrates the transition from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ML experiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;small ML application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;code&gt;13-Aug.ipynb&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Main steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load AutoInsurance
       ↓
Inspect dataset
       ↓
Drop Customer / date columns
       ↓
EDA
       ↓
Identify numerical/categorical columns
       ↓
Generate many visualizations
       ↓
Encode categorical variables
       ↓
Set CLV as target
       ↓
Train/test split
       ↓
Try multiple regressors
       ↓
Try log target
       ↓
Try scaling
       ↓
Tune tree/ensemble hyperparameters
       ↓
Generate predictions
       ↓
Save prediction CSVs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This notebook demonstrates the transition from classification to regression and from a single baseline model to model comparison and tuning.&lt;/p&gt;




&lt;h1&gt;
  
  
  Appendix B — A cleaner ML template to remember
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. Load
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Understand
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Clean
# handle missing values
# fix data types
# remove inappropriate identifiers
&lt;/span&gt;
&lt;span class="c1"&gt;# 4. Explore
# histograms
# boxplots
# countplots
# scatterplots
# correlation
&lt;/span&gt;
&lt;span class="c1"&gt;# 5. Prepare
&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 6. Split
&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 7. Preprocess
# encoding / scaling
&lt;/span&gt;
&lt;span class="c1"&gt;# 8. Train
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 9. Predict
&lt;/span&gt;&lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 10. Evaluate
# choose metrics appropriate to the problem
&lt;/span&gt;
&lt;span class="c1"&gt;# 11. Compare / improve
# try another model
# tune hyperparameters
# use cross-validation
&lt;/span&gt;
&lt;span class="c1"&gt;# 12. Final model
# train using the selected approach
&lt;/span&gt;
&lt;span class="c1"&gt;# 13. Predict new data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Closing thought for the article
&lt;/h1&gt;

&lt;p&gt;Five days ago, an ML notebook could easily look like a collection of unfamiliar commands.&lt;/p&gt;

&lt;p&gt;Now there is a structure behind those commands.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head()&lt;/code&gt; is not just a command — it is a way to understand the data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isnull()&lt;/code&gt; is not just a command — it is part of data quality.&lt;/p&gt;

&lt;p&gt;A histogram is not just a graph — it tells you about a distribution.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;train_test_split()&lt;/code&gt; is not just boilerplate — it protects your evaluation from simply measuring memorization.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fit()&lt;/code&gt; is not magic — it is the learning stage.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;predict()&lt;/code&gt; is the model applying what it learned.&lt;/p&gt;

&lt;p&gt;And model comparison is not about finding the fanciest algorithm — it is about finding an approach that generalizes well to data the model has never seen.&lt;/p&gt;

&lt;p&gt;That, more than anything else, is what I took away from my first five days of machine learning.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ML Foundations: A Complete Data Cleaning &amp; ML Pipeline</title>
      <dc:creator>yash-nigam</dc:creator>
      <pubDate>Tue, 25 Aug 2026 13:42:00 +0000</pubDate>
      <link>https://dev.to/yashnigam/ml-foundations-a-complete-data-cleaning-ml-pipeline-2o7o</link>
      <guid>https://dev.to/yashnigam/ml-foundations-a-complete-data-cleaning-ml-pipeline-2o7o</guid>
      <description>&lt;h1&gt;
  
  
  Fundamentals of Machine Learning
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Using Google Colab and Python Libraries to Run ML Models
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Find all the jupiter notebooks and datasets here: &lt;a href="https://github.com/yash-nigam/AI-ML-Foundations" rel="noopener noreferrer"&gt;https://github.com/yash-nigam/AI-ML-Foundations&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is Artificial Intelligence?&lt;/li&gt;
&lt;li&gt;
What is Machine Learning?

&lt;ul&gt;
&lt;li&gt;2.1 Types of Machine Learning
&lt;/li&gt;
&lt;li&gt;2.2 Supervised Learning
&lt;/li&gt;
&lt;li&gt;2.3 Unsupervised Learning
&lt;/li&gt;
&lt;li&gt;2.4 Reinforcement Learning
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
How Python Helps Implement Machine Learning

&lt;ul&gt;
&lt;li&gt;3.1 The Libraries and What Each One Handles
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Exploratory Data Analysis: Investigating the Dataset&lt;/li&gt;
&lt;li&gt;
Working with the Loan Prediction Dataset

&lt;ul&gt;
&lt;li&gt;5.1 Making the Dataset Ready for ML Models
&lt;/li&gt;
&lt;li&gt;5.2 What Should Be Cleaned Up
&lt;/li&gt;
&lt;li&gt;5.3 Cleanup Steps

&lt;ul&gt;
&lt;li&gt;5.3.1 Remove Unique/Identifier Columns
&lt;/li&gt;
&lt;li&gt;5.3.2 Handle Missing Values
&lt;/li&gt;
&lt;li&gt;5.3.3 Standardize &amp;amp; Encode Categorical Values
&lt;/li&gt;
&lt;li&gt;5.3.4 Outliers, Duplicates, Imbalance, Scaling, Split
&lt;/li&gt;
&lt;li&gt;5.3.5 Replace Non-Standard Placeholder Values
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Encoding

&lt;ul&gt;
&lt;li&gt;6.1 Why Does ML Need Encoding?
&lt;/li&gt;
&lt;li&gt;6.2 Label Encoding
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Train/Test Split

&lt;ul&gt;
&lt;li&gt;7.1 Why Not Train and Test on the Same Data?
&lt;/li&gt;
&lt;li&gt;7.2 Underfitting
&lt;/li&gt;
&lt;li&gt;7.3 Why &lt;code&gt;random_state&lt;/code&gt; Matters
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Machine Learning Models

&lt;ul&gt;
&lt;li&gt;8.1 Confusion Matrix
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Gradio: Turning a Model into an Application&lt;/li&gt;
&lt;li&gt;
What "Learning" Actually Means

&lt;ul&gt;
&lt;li&gt;10.1 What Happens During Prediction?
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Real ML Skill — Questions to Be Able to Answer&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. What is Artificial Intelligence?
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence (AI) is the broad idea of building systems that can perform tasks that normally require some form of human intelligence, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recognizing an image&lt;/li&gt;
&lt;li&gt;Generating text / writing an email&lt;/li&gt;
&lt;li&gt;Generating an image&lt;/li&gt;
&lt;li&gt;Recommending a movie&lt;/li&gt;
&lt;li&gt;Detecting fraud&lt;/li&gt;
&lt;li&gt;Predicting the price/value of something&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A useful mental model for the hierarchy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiw8x453jzek52q6gcn3p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiw8x453jzek52q6gcn3p.png" alt="AI Hierarchy" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What is Machine Learning?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Machine learning is teaching a computer to find patterns in examples, instead of telling it exact rules to follow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; The old way to predict if a customer will cancel their telecom subscription — you could try writing rules by hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF contract = month-to-month
AND monthly charges = high
AND tenure = low
THEN churn = yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The machine learning way:&lt;/strong&gt; show the ML algorithm many past customers along with what actually happened to them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Customer&lt;/th&gt;
&lt;th&gt;Contract type&lt;/th&gt;
&lt;th&gt;Monthly charges&lt;/th&gt;
&lt;th&gt;Tenure&lt;/th&gt;
&lt;th&gt;Did they churn?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Month-to-month&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Two year&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Month-to-month&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Month-to-month&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The algorithm studies this data and figures out the pattern on its own — no one told it "low tenure + high charges = risky."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using it to predict for a new customer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once trained, you can hand it a brand-new customer it has never seen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New customer's info
        ↓
   Trained model
        ↓
  Predicted: churn or not
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.1 Types of Machine Learning
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Supervised Learning&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Unsupervised Learning&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Reinforcement Learning&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Core idea&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Learn from examples with known answers&lt;/td&gt;
&lt;td&gt;Find hidden patterns with no answers given&lt;/td&gt;
&lt;td&gt;Learn by trial and error, guided by rewards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data needed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inputs + labels&lt;/td&gt;
&lt;td&gt;Inputs only, no labels&lt;/td&gt;
&lt;td&gt;No fixed dataset — agent generates its own data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Classification, Regression&lt;/td&gt;
&lt;td&gt;Clustering, dimensionality reduction, anomaly detection&lt;/td&gt;
&lt;td&gt;Choosing actions to maximize long-term reward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Common algorithms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logistic Regression, Decision Trees, Random Forest&lt;/td&gt;
&lt;td&gt;K-Means, DBSCAN, PCA&lt;/td&gt;
&lt;td&gt;Q-Learning, DQN, Policy Gradient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How it's evaluated&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Accuracy, precision, recall, MAE, RMSE&lt;/td&gt;
&lt;td&gt;No ground truth — silhouette score, human judgment&lt;/td&gt;
&lt;td&gt;Total reward earned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-world examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Churn prediction, spam filtering, price estimation&lt;/td&gt;
&lt;td&gt;Customer segmentation, topic discovery&lt;/td&gt;
&lt;td&gt;Game-playing agents, robotics, ad bidding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2.2 Supervised Learning
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84acxtl1dtmwla9h9x5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84acxtl1dtmwla9h9x5g.png" alt="Supervised Learning Hierarchy" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supervised learning is the case where &lt;strong&gt;you already know the right answers for your training data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model makes a guess, checks it against the known answer, sees how wrong it was, and adjusts. Repeat this thousands of times and it gets good at guessing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input (X)  →  Known answer (Y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;X is everything you know about a customer. Y is what actually happened to them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X = [tenure=2, contract=month-to-month, charges=95.5]   →   Y = churned
X = [tenure=48, contract=two-year, charges=45.2]        →   Y = stayed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model's job is to learn the &lt;em&gt;relationship&lt;/em&gt; between X and Y well enough that when a new X shows up with no Y attached, it can produce a sensible guess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key requirement:&lt;/strong&gt; you need historical data where the outcome is already recorded. No answer key, no supervised learning.&lt;/p&gt;

&lt;h4&gt;
  
  
  The only question that splits supervised learning in two
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Is the thing I'm predicting a category, or a number?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it. That single question decides whether you're doing classification or regression — and it changes your algorithms, your metrics, and how you evaluate success.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Classification&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Regression&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Question it answers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which category?&lt;/td&gt;
&lt;td&gt;How much?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type of answer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A fixed label (bucket)&lt;/td&gt;
&lt;td&gt;A number on a scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Spam or Not spam&lt;br&gt;Churn or No churn&lt;br&gt;Cat / Dog / Horse&lt;/td&gt;
&lt;td&gt;House price: ₹87,45,000&lt;br&gt;Temperature: 31.4°C&lt;br&gt;Fuel efficiency: 23.7 MPG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What the output means&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A label, not a quantity — &lt;code&gt;1&lt;/code&gt; isn't "more" than &lt;code&gt;0&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A real quantity — 6,000 truly is twice 3,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A probability → converted to a label&lt;br&gt;e.g. &lt;code&gt;0.91 → "Churn"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A direct number&lt;br&gt;e.g. &lt;code&gt;6,500&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Threshold involved?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes — usually 0.5, adjustable&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Being "wrong"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Binary — right label or wrong label&lt;/td&gt;
&lt;td&gt;A matter of degree — off by a little or a lot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Common metrics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Accuracy, Precision, Recall&lt;/td&gt;
&lt;td&gt;MAE, RMSE, R²&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Common algorithms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logistic Regression, SVC, Decision Tree Classifier&lt;/td&gt;
&lt;td&gt;Linear Regression, KNN Regressor, SVR, Random Forest Regressor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;In your project&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Telco churn (Yes/No)&lt;/td&gt;
&lt;td&gt;Customer Lifetime Value (a number)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Quick test for your own problems&lt;/strong&gt; — when you get a new dataset, look at the target column and ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Does averaging two values in this column produce something meaningful?

  Average of ₹5,000 and ₹7,000 = ₹6,000  ✓ meaningful  → regression
  Average of "spam" and "not spam"       ✗ meaningless → classification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Unsupervised Learning
&lt;/h3&gt;

&lt;p&gt;In unsupervised learning, we do not have a known target. Instead, the algorithm tries to discover structure in the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer data
     ↓
Find groups
     ↓
Group 1: high-value customers
Group 2: price-sensitive customers
Group 3: new customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;K-Means clustering&lt;/li&gt;
&lt;li&gt;Hierarchical clustering&lt;/li&gt;
&lt;li&gt;PCA&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.4 Reinforcement Learning
&lt;/h3&gt;

&lt;p&gt;Reinforcement learning is different. An agent interacts with an environment and receives rewards or penalties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓ action
Environment
  ↓
Reward / penalty
  ↓
Agent learns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game-playing agents&lt;/li&gt;
&lt;li&gt;Robotics&lt;/li&gt;
&lt;li&gt;Certain recommendation/control systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This was not part of the five-day practical work.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. How Python Helps Implement Machine Learning
&lt;/h2&gt;

&lt;p&gt;Machine learning is mostly mathematics — matrix operations, optimization, statistics. In principle you could write all of it yourself, but in practice nobody does. Python has become the default language for ML because a small set of mature libraries already implement those pieces, tested and optimized, so you can focus on the problem rather than the arithmetic.&lt;/p&gt;

&lt;p&gt;What makes Python work well here is that these libraries fit together as a &lt;strong&gt;pipeline&lt;/strong&gt;, not as isolated tools. Each one covers one stage of the journey, and they hand data to each other in a common format — a Pandas DataFrame or a NumPy array — so nothing needs translating in between.&lt;/p&gt;

&lt;p&gt;A typical project moves through the stack like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load and clean the data        →  Pandas (with NumPy underneath)
Explore and visualize it       →  Matplotlib + Seaborn
Prepare features and split     →  Scikit-learn
Train and predict              →  Scikit-learn
Evaluate the results           →  Scikit-learn (+ Seaborn to plot them)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that roughly the first half of that pipeline has nothing to do with modeling at all. In real projects, loading, cleaning, and understanding the data usually takes far more time than calling &lt;code&gt;.fit()&lt;/code&gt;. The libraries reflect that reality: Pandas and Seaborn get used constantly, while the actual model training is often two lines.&lt;/p&gt;

&lt;p&gt;The other thing Python gives you is a &lt;strong&gt;consistent interface&lt;/strong&gt;. Once you learn scikit-learn's &lt;code&gt;fit → predict&lt;/code&gt; pattern, it works the same way for logistic regression, random forests, and support vector machines alike. Swapping one algorithm for another is a one-line change, which makes it cheap to try several and compare.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 The Libraries and What Each One Handles
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Import&lt;/th&gt;
&lt;th&gt;Role in the Pipeline&lt;/th&gt;
&lt;th&gt;Key Functions/Methods&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NumPy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;import numpy as np&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The numerical foundation — fast array math that every other library is built on&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;np.nan&lt;/code&gt;, &lt;code&gt;np.log1p()&lt;/code&gt;, &lt;code&gt;np.expm1()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;np.nan&lt;/code&gt; = missing value. &lt;code&gt;log1p(x)&lt;/code&gt; = log(1+x), useful for skewed targets. &lt;code&gt;expm1(x)&lt;/code&gt; reverses it — used to convert log predictions back to the original CLV scale. You rarely use NumPy directly; it works underneath Pandas and scikit-learn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pandas&lt;/td&gt;
&lt;td&gt;&lt;code&gt;import pandas as pd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load and clean the data — a spreadsheet Python can manipulate&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;read_csv()&lt;/code&gt;, column selection/removal, dtype conversion, missing-value detection/fill, X/Y selection, encoding, saving predictions&lt;/td&gt;
&lt;td&gt;Where most of your time actually goes. Example: &lt;code&gt;df = pd.read_csv("Telco_Customer_Churn.csv")&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matplotlib&lt;/td&gt;
&lt;td&gt;&lt;code&gt;import matplotlib.pyplot as plt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The plotting engine — controls figures, titles, axes, display&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;plt.figure()&lt;/code&gt;, &lt;code&gt;plt.title()&lt;/code&gt;, &lt;code&gt;plt.show()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Rarely used alone; it's the layer Seaborn sits on top of&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Seaborn&lt;/td&gt;
&lt;td&gt;&lt;code&gt;import seaborn as sns&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Explore and understand the data through statistical plots&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;countplot&lt;/code&gt;, &lt;code&gt;boxplot&lt;/code&gt;, &lt;code&gt;histplot&lt;/code&gt;, &lt;code&gt;pairplot&lt;/code&gt;, &lt;code&gt;scatterplot&lt;/code&gt;, &lt;code&gt;heatmap&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;One line gives you a plot that would take many in raw Matplotlib. A graph is a tool for asking questions about the data, not decoration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scikit-learn&lt;/td&gt;
&lt;td&gt;&lt;code&gt;from sklearn... import ...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Everything modeling-related: splitting, preprocessing, scaling, encoding, training, prediction, evaluation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;train_test_split()&lt;/code&gt;, &lt;code&gt;StandardScaler()&lt;/code&gt;, &lt;code&gt;model.fit(X_train, Y_train)&lt;/code&gt;, &lt;code&gt;model.predict(X_test)&lt;/code&gt;, metrics functions&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;fit → predict&lt;/code&gt; pattern is identical across nearly every model, so trying a different algorithm is a one-line change&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The short version:&lt;/strong&gt; Pandas gets the data into shape, Seaborn helps you understand it, and scikit-learn learns from it — with NumPy doing the arithmetic underneath and Matplotlib drawing the pictures.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Exploratory Data Analysis: Investigating the Dataset
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What It Does &amp;amp; How to Use It&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;df.head()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shows the first few rows of the dataset. Run this right after loading data to confirm it loaded correctly and get a quick look at the columns and values.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;df.shape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the number of rows and columns, e.g. &lt;code&gt;(398, 9)&lt;/code&gt;. Use it to quickly gauge dataset size, which affects model choice and computation time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;df.info()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lists each column's data type and non-null count. Use it to spot missing values and type problems — e.g. a numeric column showing as &lt;code&gt;object&lt;/code&gt; usually means it contains hidden text like &lt;code&gt;"?"&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;df.describe()&lt;/code&gt; / &lt;code&gt;df.describe(include="all")&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Shows summary statistics (count, mean, min, max, etc.) for numeric columns, or all columns with &lt;code&gt;include="all"&lt;/code&gt;. Use it to check the scale of each variable and spot possible outliers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;df.sample(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shows &lt;code&gt;n&lt;/code&gt; random rows instead of just the first few. Use it after &lt;code&gt;head()&lt;/code&gt; to catch inconsistencies or unusual values that only appear later in the data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;df.isnull().sum()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Counts missing (&lt;code&gt;NaN&lt;/code&gt;) values per column. Use it to identify which columns need cleaning — note it only catches true &lt;code&gt;NaN&lt;/code&gt;s, not disguised placeholders like &lt;code&gt;"?"&lt;/code&gt;, which need to be checked separately.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  5. Working with the Loan Prediction Dataset
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Making the Dataset Ready for ML Models
&lt;/h3&gt;

&lt;p&gt;Raw data collected from forms, surveys, or real-world systems is almost never ready to feed straight into a machine learning model.&lt;/p&gt;

&lt;p&gt;ML models cannot by themselves guess around these problems, and these gaps could reduce the accuracy of your results.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 What Should Be Cleaned Up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NaN&lt;/code&gt; (missing values)&lt;/strong&gt; — ML models cannot handle these by themselves; they'll throw errors or silently produce garbage results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique-identifier columns&lt;/strong&gt; — Unique IDs create noise and aren't helpful for learning genuine patterns in the data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text/categorical values&lt;/strong&gt; — Numbers are expected by most ML models, not strings like "Yes"/"No".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imbalanced or skewed data&lt;/strong&gt; — If 70% of your data is one outcome, a lazy model can get 70% accuracy by always predicting that outcome, without actually learning anything useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outliers and skewed numeric columns&lt;/strong&gt; — A few extreme values can pull the mean far from what's "typical," making mean-based decisions misleading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.3 Cleanup Steps
&lt;/h3&gt;

&lt;h4&gt;
  
  
  5.3.1 Remove Unique/Identifier Columns
&lt;/h4&gt;

&lt;p&gt;Columns like IDs (e.g. &lt;code&gt;Loan_ID&lt;/code&gt;) don't carry predictive signal and should be dropped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loan_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Removes the &lt;code&gt;Loan_ID&lt;/code&gt; column. It's a unique identifier for each row (like a primary key) — it has no predictive value and would only confuse or overfit a model if left in.&lt;/p&gt;

&lt;h4&gt;
  
  
  5.3.2 Handle Missing Values
&lt;/h4&gt;

&lt;p&gt;Either drop rows/columns with too many nulls, or fill them in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;median&lt;/strong&gt; for numeric columns that are skewed (robust to outliers, e.g. income, loan amount).&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;mean&lt;/strong&gt; for numeric columns that are roughly symmetric/normally distributed.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;mode&lt;/strong&gt; (most frequent value) for categorical columns, since averaging text categories isn't meaningful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using Median&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;median_loanamount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LoanAmount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculates the median of &lt;code&gt;LoanAmount&lt;/code&gt;. Median is preferred over mean here because loan/income data is typically skewed by a few very high values, and median is more robust to outliers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;median_loanamount_term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loan_Amount_Term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same logic — computes the median loan term to use for filling its missing values later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;median_credit_history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Credit_History&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Computes the median of &lt;code&gt;Credit_History&lt;/code&gt; (a 0/1 flag). Even though it's binary, median is used instead of mean to avoid producing a non-integer/ambiguous fill value.&lt;/p&gt;

&lt;p&gt;Use the calculated values to fill:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LoanAmount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LoanAmount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;median_loanamount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loan_Amount_Term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loan_Amount_Term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;median_loanamount_term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Credit_History&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Credit_History&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;median_credit_history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fills missing values with the calculated medians. This avoids dropping rows (losing data) while keeping the columns usable for modeling, since most ML algorithms can't handle &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Calculates the &lt;strong&gt;mode&lt;/strong&gt; (most frequent value) for gender, married, dependents, and self_employed. Mode is used instead of median/mean because these are categorical columns — you can't average "Male" and "Female".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mode_gender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gender&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mode_married&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Married&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mode_dependents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dependents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mode_self_employed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Self_Employed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the missing entries with the most common category, which is a reasonable, low-bias guess for a categorical field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gender&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gender&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode_gender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Married&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Married&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode_married&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dependents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dependents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode_dependents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Self_Employed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Self_Employed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode_self_employed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.3.3 Standardize &amp;amp; Encode Categorical Values
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standardize categorical values&lt;/strong&gt; — fix inconsistent labels (e.g. "male", "Male", "MALE" should all become one consistent value).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encode categorical variables&lt;/strong&gt; — convert text categories into numbers using techniques like Label Encoding or One-Hot Encoding, since most ML models only accept numeric input.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;LabelEncoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# + loop over cat_cols
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Converts all text/categorical columns (&lt;code&gt;Loan_Status&lt;/code&gt;, &lt;code&gt;Married&lt;/code&gt;, &lt;code&gt;Gender&lt;/code&gt;, etc.) into numeric codes (e.g., "Yes"/"No" → 1/0). This step is &lt;strong&gt;required&lt;/strong&gt; because scikit-learn models only accept numeric input, not strings.&lt;/p&gt;

&lt;h4&gt;
  
  
  5.3.4 Outliers, Duplicates, Imbalance, Scaling, Split
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check and handle outliers&lt;/strong&gt; — identify extreme values (via boxplots, &lt;code&gt;.describe()&lt;/code&gt;, or z-scores) and decide whether to cap, remove, or transform them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for and remove duplicate rows&lt;/strong&gt; — duplicate records can bias the model toward those repeated patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Address class imbalance&lt;/strong&gt; — if one outcome dominates the target column, apply techniques like upsampling, downsampling, or SMOTE so the model doesn't just learn to predict the majority class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature scaling (when needed)&lt;/strong&gt; — normalize or standardize numeric ranges for models sensitive to scale (like SVM, KNN, or Logistic Regression with regularization).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split before further transformation&lt;/strong&gt; — separate train/test sets early so cleaning decisions (like fill values from training data) don't leak information from the test set.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5.3.5 Replace Non-Standard Placeholder Values
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This converts the placeholder &lt;code&gt;"?"&lt;/code&gt; into a real missing value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;horsepower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This then converts the column into a proper numeric type so it can be used in calculations and models.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Encoding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Why Does ML Need Encoding?
&lt;/h3&gt;

&lt;p&gt;Many ML algorithms work with numbers. But real-world data contains categories like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Male
Female

Yes
No

Month-to-month
One year
Two year

Fiber optic
DSL
No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model needs these values represented numerically. This is called &lt;strong&gt;encoding&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 Label Encoding
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LabelEncoder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a binary column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be reasonable for a binary variable. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn:
No  → 0
Yes → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes intuitive sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Train/Test Split
&lt;/h2&gt;

&lt;p&gt;Repeatedly used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important ML concepts.&lt;/p&gt;

&lt;p&gt;Suppose we have 1,000 examples. We might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;700 → training
300 → testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The training set is used to learn the model. The test set is held back to evaluate how the trained model performs on unseen data.&lt;/p&gt;

&lt;p&gt;Think of it like an exam:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training data = practice questions
Test data     = unseen exam questions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.1 Why Not Train and Test on the Same Data?
&lt;/h3&gt;

&lt;p&gt;Because the model could simply memorize the training examples. Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 99%
Test score     = 65%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a warning sign. The model learned the training data extremely well but does not generalize well. This is called:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Overfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7.2 Underfitting
&lt;/h3&gt;

&lt;p&gt;The opposite can happen. If the model is too simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training score = 60%
Test score     = 58%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may not have learned enough from the data. This is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Underfitting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A useful mental picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Underfitting
Model too simple
       ↓
misses important patterns

Good fit
Learns useful patterns
       ↓
works on unseen data

Overfitting
Model learns noise/details
       ↓
great training performance
poor unseen performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Why &lt;code&gt;random_state&lt;/code&gt; Matters
&lt;/h3&gt;

&lt;p&gt;In one Telco notebook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the improved notebook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A random state makes the split reproducible. Without it, the random split can change between runs — meaning your score may change between runs too. With &lt;code&gt;random_state=42&lt;/code&gt;, you can reproduce the same split every time. The number &lt;code&gt;42&lt;/code&gt; is not magical; any fixed integer can serve this purpose.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Machine Learning Models
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model / Concept&lt;/th&gt;
&lt;th&gt;What It Does &amp;amp; How to Use It&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Logistic Regression&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Despite the name, used for classification — estimates the probability of belonging to a class, then applies a threshold to assign a label. A simple, fast, interpretable baseline model — good starting point before trying complex models.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SVC (Support Vector Machine)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Finds a decision boundary that best separates classes, aiming for maximum margin between them. Sensitive to feature scale, so scale your data (e.g. with &lt;code&gt;StandardScaler&lt;/code&gt;) before using it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decision Tree&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Predicts by asking a sequence of yes/no questions, ending at a leaf with the prediction. Easy to visualize but prone to overfitting — control this with &lt;code&gt;max_depth&lt;/code&gt;, &lt;code&gt;min_samples_split&lt;/code&gt;, &lt;code&gt;min_samples_leaf&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Random Forest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Combines many decision trees and averages their predictions for a more robust result. An ensemble method — generally more reliable than a single decision tree.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bagging&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Trains multiple models on different random samples of the data, then combines their predictions. Reduces variance and makes predictions more stable; Random Forest is a specialized version of this.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AdaBoost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Builds models sequentially, where each new model focuses on the mistakes of the previous one. A boosting method — improves weak learners step by step rather than averaging independent ones.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;KNN (K-Nearest Neighbors)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Predicts by finding the most similar existing examples ("neighbors") and using their values. Relies on distance, so it needs feature scaling to avoid large-scale features dominating the result.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;StandardScaler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scales features to comparable ranges before training distance-sensitive models. Always &lt;code&gt;fit_transform&lt;/code&gt; on training data, then only &lt;code&gt;transform&lt;/code&gt; (not fit) on test data, to avoid data leakage.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Linear Regression&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Models the relationship between features and a numeric target as a straight-line equation (&lt;code&gt;Y = b0 + b1X1 + ...&lt;/code&gt;). Used for predicting continuous values, e.g. Customer Lifetime Value.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;R² Score (&lt;code&gt;.score()&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Measures how well the model explains variation in the target — 1 is perfect, 0 means no better than predicting the average. Report it as "R² of 0.90," not "90% accuracy" — they're not the same thing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accuracy Score&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The proportion of correct predictions out of all predictions made, used for classification. Easy to understand, but misleading when classes are imbalanced (e.g. 95% "no churn" data).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  8.1 Confusion Matrix
&lt;/h3&gt;

&lt;p&gt;A confusion matrix organizes classification predictions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Actual
                 No       Yes
Predicted No     TN       FN
Predicted Yes    FP       TP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Meaning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;True Positive&lt;/strong&gt; — model predicted positive and it was positive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;True Negative&lt;/strong&gt; — model predicted negative and it was negative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Positive&lt;/strong&gt; — model predicted positive but it was negative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Negative&lt;/strong&gt; — model predicted negative but it was positive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is much more informative than accuracy alone when the cost of errors differs.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Gradio: Turning a Model into an Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gradio&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;gr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Building a UI around your model is an important step because it changes the project from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Notebook experiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User input
    ↓
Preprocessing
    ↓
Model
    ↓
Prediction
    ↓
Human-readable result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gender: Female
Tenure: 12 months
Contract: Month-to-month
Monthly charges: $70
...
          ↓
    Predict Churn
          ↓
High Churn Risk
Probability: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates an important ML engineering concept:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A model is useful only when it can be integrated into a workflow where people or systems can use its predictions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. What "Learning" Actually Means
&lt;/h2&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model is not magically understanding the world. It is optimizing internal parameters so that its predictions match the training examples according to the algorithm's objective.&lt;/p&gt;

&lt;p&gt;For example, linear regression learns coefficients. A tree learns split rules. A neural network learns weights.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Training means finding model parameters that make the model perform well according to a defined objective.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  10.1 What Happens During Prediction?
&lt;/h3&gt;

&lt;p&gt;Once training is complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model does not learn again from the test examples. It applies what it learned during training.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Training:

X_train + y_train
        ↓
      model.fit()
        ↓
   learned model

Prediction:

X_test
   ↓
learned model
   ↓
prediction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. The Real ML Skill — Questions to Be Able to Answer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What problem are you solving?&lt;/li&gt;
&lt;li&gt;What is the target?&lt;/li&gt;
&lt;li&gt;What features are available?&lt;/li&gt;
&lt;li&gt;What does the data look like?&lt;/li&gt;
&lt;li&gt;What problems did you find?&lt;/li&gt;
&lt;li&gt;How did you clean them?&lt;/li&gt;
&lt;li&gt;How did you encode the data?&lt;/li&gt;
&lt;li&gt;Why did you choose the algorithm?&lt;/li&gt;
&lt;li&gt;How did you evaluate it?&lt;/li&gt;
&lt;li&gt;Does it generalize?&lt;/li&gt;
&lt;li&gt;What would you improve?&lt;/li&gt;
&lt;li&gt;Why was a specific algorithm chosen?&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Create a free static website using Github Pages and Jekyll</title>
      <dc:creator>yash-nigam</dc:creator>
      <pubDate>Fri, 03 Mar 2023 17:39:15 +0000</pubDate>
      <link>https://dev.to/yashnigam/create-a-free-static-website-using-github-pages-and-jekyll-41a9</link>
      <guid>https://dev.to/yashnigam/create-a-free-static-website-using-github-pages-and-jekyll-41a9</guid>
      <description>&lt;h2&gt;
  
  
  TOC
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why use GitHub Pages and Jekyll&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;1: Dev Machine Setup&lt;/li&gt;
&lt;li&gt;2: Use Chirpy Starter Template&lt;/li&gt;
&lt;li&gt;3: Install dependencies&lt;/li&gt;
&lt;li&gt;4: Modify config yaml and preview changes&lt;/li&gt;
&lt;li&gt;5: Using GitHub Actions&lt;/li&gt;
&lt;li&gt;6: Commit Changes to Repo&lt;/li&gt;
&lt;li&gt;7: View the website&lt;/li&gt;
&lt;li&gt;8: Personalize by Adding Avatar, favicon, sidebar link and create first post&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why use GitHub Pages and Jekyll ? &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt; allows us to host a static website(html, CSS, JavaScript) on GitHub repository for absolutely free which is ideal for personal websites. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A repository with the naming convention of &lt;strong&gt;{github-user-name}.github.io&lt;/strong&gt; makes that repository serve a static website with subdomain as {github-user-name} and domain name as github.io&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt; (static site generator tool) is integrated with GitHub pages providing professional looking themes and many free templates for your website.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When using Jekyll we do not have to code any HTML, CSS or JavaScript. Instead we only edit the markdown files to achieve the desired results in the templates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows/Linux developer machine&lt;/li&gt;
&lt;li&gt;GitHub Account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1: setup Ruby, Gem and Jekyll on developer machine &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If dev machine is windows, use Windows subsystem for Linux - which installs a ubuntu environment which is available from PowerShell terminal.

&lt;ul&gt;
&lt;li&gt;Open a PowerShell prompt as an Administrator and run:
&lt;code&gt;wsl --install&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Install Ruby and other prerequisites:
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github$ sudo apt-get install ruby-full build-essential zlib1g-dev
[sudo] password for yash:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
build-essential is already the newest version (12.9ubuntu3).
zlib1g-dev is already the newest version (1:1.2.11.dfsg-2ubuntu9.2).
The following additional packages will be installed:
  ri
The following NEW packages will be installed:
  ri ruby-full
0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
Need to get 6788 B of archives.
After this operation, 38.9 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 ri all 1:3.0~exp1 [4206 B]
Get:2 http://archive.ubuntu.com/ubuntu jammy/universe amd64 ruby-full all 1:3.0~exp1 [2582 B]
Fetched 6788 B in 1s (4970 B/s)
Selecting previously unselected package ri.
(Reading database ... 47201 files and directories currently installed.)
Preparing to unpack .../ri_1%3a3.0~exp1_all.deb ...
Unpacking ri (1:3.0~exp1) ...
Selecting previously unselected package ruby-full.
Preparing to unpack .../ruby-full_1%3a3.0~exp1_all.deb ...
Unpacking ruby-full (1:3.0~exp1) ...
Setting up ri (1:3.0~exp1) ...
Setting up ruby-full (1:3.0~exp1) ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add environment variables to your ~/.bashrc file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo '# Install Ruby Gems to ~/gems' &amp;gt;&amp;gt; ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' &amp;gt;&amp;gt; ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install Jekyll and Bundler
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github$ gem install jekyll bundler
Fetching jekyll-4.3.2.gem
Successfully installed jekyll-4.3.2
Parsing documentation for jekyll-4.3.2
Installing ri documentation for jekyll-4.3.2
Done installing documentation for jekyll after 3 seconds
Fetching bundler-2.4.7.gem
Successfully installed bundler-2.4.7
Parsing documentation for bundler-2.4.7
Installing ri documentation for bundler-2.4.7
Done installing documentation for bundler after 0 seconds
2 gems installed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2: Use chirpy-starter template to create new repo &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sign in to GitHub.com with your account, and go to &lt;a href="https://github.com/cotes2020/chirpy-starter/" rel="noopener noreferrer"&gt;chirpy-starter&lt;/a&gt;, click the button Use this template &amp;gt; Create a new repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffujl101qotj754h2761v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffujl101qotj754h2761v.png" alt="Use Chirpy Starter Template" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the next window type the repository name to be the same as your GitHub user name appended with .github.io
&lt;code&gt;
&amp;lt;GitHub User Name&amp;gt;.githubpages.io
&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fql6tf9k43ov5ri57mz97.png" alt="Create New repository(with same name as GH user) from Template" width="800" height="592"&gt;
This makes the repo. act as a source of static website, and the repo. name becomes the domain name website.&lt;/li&gt;
&lt;li&gt;Once this operation is complete all the contents of &lt;a href="https://github.com/cotes2020/chirpy-starter/" rel="noopener noreferrer"&gt;chirpy-starter&lt;/a&gt; will be present in our new site: &lt;a href="https://github.com/yash-nigam/yash-nigam.github.io" rel="noopener noreferrer"&gt;https://github.com/yash-nigam/yash-nigam.github.io&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3: Installing dependencies of chirpy-starter &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This site requires some GEM's to be installed before it can be used, the list of can be found in the Gemfile: &lt;a href="https://github.com/cotes2020/chirpy-starter/blob/main/Gemfile" rel="noopener noreferrer"&gt;https://github.com/cotes2020/chirpy-starter/blob/main/Gemfile&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;On your local development machine, clone the new repo
&lt;code&gt;git clone https://github.com/yash-nigam/yash-nigam.github.io.git
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;go to the repo root directory and run bundle command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;cd yash-nigam.github.io&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ bundle
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Using bundler 2.4.7
Using concurrent-ruby 1.2.2
Using rainbow 3.1.1
Using ffi 1.15.5
Using forwardable-extended 2.6.0
Using mercenary 0.4.0
Using parallel 1.22.1
Using rouge 4.1.0
Using eventmachine 1.2.7
Using unicode-display_width 2.4.2
Using racc 1.6.2
Using colorator 1.1.0
Using i18n 1.12.0
Using ethon 0.16.0
Using yell 2.2.2
Using pathutil 0.16.2
Using liquid 4.0.4
Using public_suffix 5.0.1
Using typhoeus 1.4.0
Using addressable 2.8.1
Using webrick 1.8.1
Using jekyll-paginate 1.1.0
Using http_parser.rb 0.8.0
Using rb-inotify 0.10.1
Using rb-fsevent 0.11.2
Using rexml 3.2.5
Using terminal-table 3.0.2
Using nokogiri 1.14.2 (x86_64-linux)
Using safe_yaml 1.0.5
Using google-protobuf 3.22.0 (x86_64-linux)
Using em-websocket 0.5.3
Using listen 3.8.0
Using sass-embedded 1.58.3 (x86_64-linux-gnu)
Using html-proofer 3.19.4
Using kramdown 2.4.0
Using jekyll-watch 2.2.1
Using jekyll-sass-converter 3.0.0
Using kramdown-parser-gfm 1.1.0
Using jekyll 4.3.2
Using jekyll-archives 2.2.1
Using jekyll-seo-tag 2.8.0
Using jekyll-redirect-from 0.16.0
Using jekyll-sitemap 1.4.0
Fetching jekyll-theme-chirpy 5.5.2
Installing jekyll-theme-chirpy 5.5.2
Bundle complete! 6 Gemfile dependencies, 44 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
1 installed gem you directly depend on is looking for funding.
  Run `bundle fund` for details
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4: Modify _config.yml and Preview the changes locally &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open _config.yml and modify the title and url
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;title: Yash Nigam

url: 'https://yash-nigam.github.io'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Preview the site contents locally:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ bundle exec jekyll s
Configuration file: /home/yash/github/yash-nigam.github.io/_config.yml
            Source: /home/yash/github/yash-nigam.github.io
       Destination: /home/yash/github/yash-nigam.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 1.634 seconds.
 Auto-regeneration: enabled for '/home/yash/github/yash-nigam.github.io'
    Server address: http://127.0.0.1:4000/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The local service will be published at &lt;a href="http://127.0.0.1:4000" rel="noopener noreferrer"&gt;http://127.0.0.1:4000&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82ip5bw1u9dtuwftt9sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82ip5bw1u9dtuwftt9sd.png" alt="Local Preview" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5: Configure to Deploy the Website using GitHub Actions &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Browse to your repository on GitHub, Select Settings &amp;gt; Pages. Then in the Source section (under Build and deployment), select GitHub Actions from the dropdown menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kpz6iqtvjf8bdvdewgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kpz6iqtvjf8bdvdewgv.png" alt="Select GitHub Actions" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6: Commit and push changes to repo&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check git status
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git restore &amp;lt;file&amp;gt;..." to discard changes in working directory)
        modified:   _config.yml

no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;add, Commit and push the _config.yaml file to repo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ git add _config.yml
yash@LearningPC:~/github/yash-nigam.github.io$ git commit -m "updated"
[main c30df68] updated
 1 file changed, 2 insertions(+), 2 deletions(-)
yash@LearningPC:~/github/yash-nigam.github.io$ git push
Username for 'https://github.com': yash-nigam
Password for 'https://yash-nigam@github.com':
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 334 bytes | 334.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/yash-nigam/yash-nigam.github.io.git
   aae12d1..c30df68  main -&amp;gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7: Check the Actions Workflow and view the final website &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Once the changes are pushed to the repo, a build and deploy workflow should be automatically triggered.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6tgd2lo23sia372ppc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6tgd2lo23sia372ppc.png" alt="Build and Deploy Workflow" width="800" height="826"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View the final website
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F913hc7e0538rpk7izevi.png" alt="Final Website" width="800" height="480"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8: Add Avatar, favicon, a new post and an sidebar tab.&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Add Avatar and favicon images
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a directory named img under assets in the root of repo
&lt;code&gt;yash-nigam.github.io/assets&lt;/code&gt; and favicons under img.&lt;/li&gt;
&lt;li&gt;Follow the steps to generate and add 
favicons&lt;a href="https://chirpy.cotes.page/posts/customize-the-favicon/" rel="noopener noreferrer"&gt;https://chirpy.cotes.page/posts/customize-the-favicon/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io/assets$ ls -ltr img/
total 96
drwxr-xr-x 2 yash yash  4096 Mar  3 23:28 favicons
-rw-r--r-- 1 yash yash    90 Mar  4  2023 favicon.ico:Zone.Identifier
-rw-r--r-- 1 yash yash 27019 Mar  4  2023 yn_small.jpg
-rw-r--r-- 1 yash yash 53754 Mar  4  2023 sidebar_bg.jpg
yash@LearningPC:~/github/yash-nigam.github.io$ ls -ltr assets/img/favicons/
total 168
-rw-r--r-- 1 yash yash 15531 Mar  4  2023 android-chrome-192x192.png
-rw-r--r-- 1 yash yash  8930 Mar  4  2023 mstile-150x150.png
-rw-r--r-- 1 yash yash   923 Mar  4  2023 favicon-16x16.png
-rw-r--r-- 1 yash yash   608 Mar  4  2023 safari-pinned-tab.svg
-rw-r--r-- 1 yash yash 15086 Mar  4  2023 favicon.ico
-rw-r--r-- 1 yash yash 66336 Mar  4  2023 android-chrome-512x512.png
-rw-r--r-- 1 yash yash 13736 Mar  4  2023 apple-touch-icon.png
-rw-r--r-- 1 yash yash  1270 Mar  4  2023 favicon-32x32.png

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Also put your personal photo to be used as avatar in the img folder.&lt;/li&gt;
&lt;li&gt;In the _config.yml file make following changes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;avatar: /assets/img/yn_small.jpg

github:
  username: yash-nigam
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Under the _posts folder create a file as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ ls -ltr _posts/
total 4
-rw-r--r-- 1 yash yash 446 Mar  4 00:14 2023-03-04-FirstPage.md
yash@LearningPC:~/github/yash-nigam.github.io$ cat _posts/2023-03-04-FirstPage.md
---
title: "First Post"
date: 2023-03-03 12:00:00 +0530
categories: [TOP_CATEGORIE, SUB_CATEGORIE]
tags: [TAG]    , TAG names should always be lowercase
---

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Under the _tabs folder create another markdown file of your choice.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ ls -ltr _tabs/
total 20
-rw-r--r-- 1 yash yash  47 Mar  3 15:00 tags.md
-rw-r--r-- 1 yash yash  56 Mar  3 15:00 categories.md
-rw-r--r-- 1 yash yash  55 Mar  3 15:00 archives.md
-rw-r--r-- 1 yash yash 194 Mar  3 15:00 about.md
-rw-r--r-- 1 yash yash 284 Mar  4 01:25 devto.md
yash@LearningPC:~/github/yash-nigam.github.io$ cat _tabs/devto.md
---
layout: page
title: dev.to Blog Posts
icon: fas fa-flask
order: 1
---
-----------
&amp;gt; &amp;lt;a href="https://dev.to/yashnigam/create-a-free-static-website-using-github-pages-and-jekyll-41a9" target="_blank"&amp;gt;create a personal website using Github Pages with the Jekyll Framework&amp;lt;/a&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Verify the site locally and view the changes in browser
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec jekyll s

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbzpm3ooj4oaki0k4vri.png" alt="changes" width="800" height="605"&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Commit and push the changes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git restore &amp;lt;file&amp;gt;..." to discard changes in working directory)
        modified:   _config.yml

Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
        _posts/2023-03-04-FirstPage.md
        _tabs/devto.md
        assets/css/
        assets/img/

no changes added to commit (use "git add" and/or "git commit -a")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ignore any Zone.Identifier files as they are autogenerated&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yash@LearningPC:~/github/yash-nigam.github.io$ git add --all
warning: CRLF will be replaced by LF in _tabs/devto.md.
The file will have its original line endings in your working directory

yash@LearningPC:~/github/yash-nigam.github.io$ git commit -m "Added changes"
[main 6eded15] Added changes
 24 files changed, 64 insertions(+), 8 deletions(-)
 create mode 100644 _posts/2023-03-04-FirstPage.md
 create mode 100644 _tabs/devto.md
 create mode 100644 assets/css/style.scss
 create mode 100644 assets/img/favicons/android-chrome-192x192.png
 create mode 100644 assets/img/favicons/android-chrome-512x512.png
 create mode 100644 assets/img/favicons/apple-touch-icon.png
 create mode 100644 assets/img/favicons/favicon-16x16.png
 create mode 100644 assets/img/favicons/favicon-32x32.png
 create mode 100644 assets/img/favicons/favicon.ico
 create mode 100644 assets/img/favicons/mstile-150x150.png
 create mode 100644 assets/img/favicons/safari-pinned-tab.svg
 create mode 100644 assets/img/sidebar_bg.jpg
 create mode 100644 assets/img/yn_small.jpg

yash@LearningPC:~/github/yash-nigam.github.io$ git push
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/yash-nigam/yash-nigam.github.io.git
   c30df68..6eded15  main -&amp;gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once changes are pushed, make sure GitHub build and deploy action is successful &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;https://github.com/yash-nigam/yash-nigam.github.io/actions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Added changes&lt;br&gt;
Build and Deploy #2: Commit 6eded15 pushed by yash-nigam&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now in the actual deployed site we can see that favicon, avatar, side bar tab and a new blog post is created successfully.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r1j003fep6fyimi6rtl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r1j003fep6fyimi6rtl.png" alt="Final Site" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://chirpy.cotes.page/posts/getting-started/" rel="noopener noreferrer"&gt;https://chirpy.cotes.page/posts/getting-started/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jekyllrb.com/docs/installation/" rel="noopener noreferrer"&gt;https://jekyllrb.com/docs/installation/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-11-with-gui-support#2-install-wsl" rel="noopener noreferrer"&gt;Install Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chirpy.cotes.page/posts/getting-started/#option-1-using-the-chirpy-starter" rel="noopener noreferrer"&gt;Chirpy Starter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow" rel="noopener noreferrer"&gt;Publishing with a custom GitHub Actions workflow
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chirpy.cotes.page/" rel="noopener noreferrer"&gt;https://chirpy.cotes.page/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  chirpy implementations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jamstackthemes.dev/demo/theme/jekyll-theme-chirpy/" rel="noopener noreferrer"&gt;https://jamstackthemes.dev/demo/theme/jekyll-theme-chirpy/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bpostance.github.io/" rel="noopener noreferrer"&gt;https://bpostance.github.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>fastapi</category>
      <category>django</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
