<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Think In Python</title><link>https://www.thinkinpython.com/</link><description>Jiangchuan's tech blog</description><generator>Hugo</generator><language>en-US</language><copyright>Think In Python</copyright><lastBuildDate>Tue, 31 Mar 2026 02:43:30 +0800</lastBuildDate><atom:link href="https://www.thinkinpython.com/en/index.xml" rel="self" type="application/rss+xml"/><item><title>Best Practices for Large Codebases with Claude Code: Building a Level-Structured Knowledge Base</title><link>https://www.thinkinpython.com/en/post/claude-code-large-codebase-best-practices.html</link><pubDate>Tue, 31 Mar 2026 02:43:30 +0800</pubDate><guid>https://www.thinkinpython.com/en/post/claude-code-large-codebase-best-practices.html</guid><description>&lt;h1 id="best-practices-for-large-codebases-with-claude-code-building-a-level-structured-knowledge-base"&gt;Best Practices for Large Codebases with Claude Code: Building a Level-Structured Knowledge Base&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;: The key to efficiently using Claude Code in large codebases lies in the principle of &amp;ldquo;Progressive Disclosure.&amp;rdquo; By building a three-tier hierarchical knowledge base, AI can access just the right amount of context when needed, avoiding token waste and context confusion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As AI-assisted programming tools become ubiquitous, developers face a new challenge: how to use Claude Code effectively in large codebases. Placing a massive README file at the root is far from optimal—it leads to token waste, context confusion, and maintenance difficulties.&lt;/p&gt;</description><content:encoded>&lt;h1 id="best-practices-for-large-codebases-with-claude-code-building-a-level-structured-knowledge-base"&gt;Best Practices for Large Codebases with Claude Code: Building a Level-Structured Knowledge Base&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;: The key to efficiently using Claude Code in large codebases lies in the principle of &amp;ldquo;Progressive Disclosure.&amp;rdquo; By building a three-tier hierarchical knowledge base, AI can access just the right amount of context when needed, avoiding token waste and context confusion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As AI-assisted programming tools become ubiquitous, developers face a new challenge: how to use Claude Code effectively in large codebases. Placing a massive README file at the root is far from optimal—it leads to token waste, context confusion, and maintenance difficulties.&lt;/p&gt;
&lt;p&gt;This article presents a &lt;strong&gt;hierarchical knowledge base&lt;/strong&gt; best practice, using a three-tier documentation structure to ensure Claude Code receives the right information at the right time.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="core-principle-progressive-disclosure"&gt;Core Principle: Progressive Disclosure&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Progressive Disclosure&lt;/strong&gt; means providing high-level rules at the root, then offering increasingly specific &amp;ldquo;why&amp;rdquo; and &amp;ldquo;how&amp;rdquo; details as AI drills down into subdirectories.&lt;/p&gt;
&lt;p&gt;Claude Code natively recognizes &lt;code&gt;CLAUDE.md&lt;/code&gt; files. We can extend this pattern into a hierarchical approach, aligning documentation structure with the directory tree.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-3-tier-hierarchy"&gt;The 3-Tier Hierarchy&lt;/h2&gt;
&lt;h3 id="tier-1-project-root-global-context"&gt;Tier 1: Project Root (Global Context)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;File Location&lt;/strong&gt;: &lt;code&gt;/CLAUDE.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: The &amp;ldquo;Constitution&amp;rdquo;—defining the tech stack, core commands, and non-negotiable standards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Content&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;markdown&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Build Commands
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Production build: &lt;span style="color:#f1fa8c"&gt;`pnpm build`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Development mode: &lt;span style="color:#f1fa8c"&gt;`pnpm dev`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Test Commands
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Unit tests: &lt;span style="color:#f1fa8c"&gt;`pnpm test:unit &amp;lt;file&amp;gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; E2E tests: &lt;span style="color:#f1fa8c"&gt;`pnpm test:e2e`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Code Style
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Functional components only
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; No default exports
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Use Tailwind CSS for styling
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Architecture
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Next.js monorepo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- Shared logic in &lt;span style="color:#f1fa8c"&gt;`/packages/shared`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id="tier-2-moduledomain-strategic-context"&gt;Tier 2: Module/Domain (Strategic Context)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;File Location&lt;/strong&gt;: &lt;code&gt;/src/features/billing/CONTEXT.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Explaining business logic and invisible data flows that code alone won&amp;rsquo;t reveal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Content&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;markdown&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Domain Logic
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;This module handles Stripe integration.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Data Flow
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;All payments must trigger the &lt;span style="color:#f1fa8c"&gt;`webhook-handler`&lt;/span&gt; before updating the DB.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Security
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Never expose Secret_Key to the frontend
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Use the proxy in &lt;span style="color:#f1fa8c"&gt;`/api/stripe`&lt;/span&gt; for backend calls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Dependencies
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Depends on UserStore for tax calculations
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- Bidirectional sync with OrderService&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id="tier-3-leafcomponent-tactical-context"&gt;Tier 3: Leaf/Component (Tactical Context)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;File Location&lt;/strong&gt;: &lt;code&gt;/src/components/DataGrid/NOTES.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Explaining &amp;ldquo;gotchas&amp;rdquo; and specific technical debt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Content&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;markdown&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Performance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Uses react-virtualized for virtual scrolling
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Do not remove the &lt;span style="color:#f1fa8c"&gt;`rowHeight`&lt;/span&gt; prop or it will crash on Safari
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Known Issues
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Sorting toggle has a race condition with the API
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Workaround: use &lt;span style="color:#f1fa8c"&gt;`isLoading`&lt;/span&gt; ref to debounce
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## TODO
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;- [ ]&lt;/span&gt; Extract sorting logic into a standalone Hook
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- [ ] Replace deprecated componentWillReceiveProps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="best-practices-for-ai-friendly-content"&gt;Best Practices for &amp;ldquo;AI-Friendly&amp;rdquo; Content&lt;/h2&gt;
&lt;h3 id="1-be-explicit-not-idiomatic"&gt;1. Be Explicit, Not Idiomatic&lt;/h3&gt;
&lt;p&gt;❌ Wrong: &lt;code&gt;Just run the tests&lt;/code&gt;&lt;br&gt;
✅ Right: &lt;code&gt;Use npm run test&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;AI models respond better to explicit instructions. Avoid developer &amp;ldquo;jargon.&amp;rdquo;&lt;/p&gt;
&lt;h3 id="2-use-dodont-lists"&gt;2. Use &amp;ldquo;Do/Don&amp;rsquo;t&amp;rdquo; Lists&lt;/h3&gt;
&lt;p&gt;AI models respond exceptionally well to negative constraints:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;markdown&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Type Safety
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; ❌ Don&amp;#39;t use &amp;#39;any&amp;#39; types
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; ✅ Use &amp;#39;unknown&amp;#39; if the type is truly ambiguous
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- ✅ Prefer TypeScript strict mode&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="3-reference-specific-files"&gt;3. Reference Specific Files&lt;/h3&gt;
&lt;p&gt;Let AI know where &amp;ldquo;The Truth&amp;rdquo; lives:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;markdown&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="font-weight:bold"&gt;## Data Models
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;-&lt;/span&gt; Master schema defined in &lt;span style="color:#f1fa8c"&gt;`/src/db/schema.ts`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- Type exports in &lt;span style="color:#f1fa8c"&gt;`/src/types/index.ts`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="4-keep-it-small"&gt;4. Keep It Small&lt;/h3&gt;
&lt;p&gt;Individual context files should be &lt;strong&gt;under 50 lines&lt;/strong&gt; of high-density information. If a file exceeds 10KB, AI may waste too many tokens reading it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="hierarchical-vs-flat-comparison"&gt;Hierarchical vs. Flat: Comparison&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Flat (One Big README)&lt;/th&gt;
&lt;th&gt;Hierarchical (Level-Structured)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token Usage&lt;/td&gt;
&lt;td&gt;High (Claude reads everything every time)&lt;/td&gt;
&lt;td&gt;Low (Claude only reads relevant folder&amp;rsquo;s notes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Precision&lt;/td&gt;
&lt;td&gt;Low (May confuse Webhook rules with UI rules)&lt;/td&gt;
&lt;td&gt;High (Specific rules for specific folders)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability&lt;/td&gt;
&lt;td&gt;Hard (One file becomes a &amp;ldquo;junk drawer&amp;rdquo;)&lt;/td&gt;
&lt;td&gt;Easy (Small files stay close to the code they describe)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Poor (Rapidly bloats as project grows)&lt;/td&gt;
&lt;td&gt;Good (New modules just add corresponding files)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="implementation-steps"&gt;Implementation Steps&lt;/h2&gt;
&lt;p&gt;You don&amp;rsquo;t have to write all of this at once. Adopt a progressive approach:&lt;/p&gt;
&lt;h3 id="phase-1-root-directory"&gt;Phase 1: Root Directory&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Create &lt;code&gt;/CLAUDE.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Define tech stack, build commands, code conventions&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="phase-2-core-modules"&gt;Phase 2: Core Modules&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Identify 3-5 core business modules&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;CONTEXT.md&lt;/code&gt; for each module&lt;/li&gt;
&lt;li&gt;Document data flows, security requirements, dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="phase-3-complex-components"&gt;Phase 3: Complex Components&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Identify components with technical debt or &amp;ldquo;gotchas&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;NOTES.md&lt;/code&gt; documenting known issues and workarounds&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="phase-4-let-claude-help"&gt;Phase 4: Let Claude Help&lt;/h3&gt;
&lt;p&gt;Use Claude Code itself to help generate documentation:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;bash&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6272a4"&gt;# Ask Claude to analyze a module and generate CONTEXT.md&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;claude &lt;span style="color:#f1fa8c"&gt;&amp;#34;Analyze the billing module and create a CONTEXT.md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f1fa8c"&gt; that explains the data flow and security requirements&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;The core value of a hierarchical knowledge base:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Saves tokens&lt;/strong&gt;: AI reads only relevant context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improves precision&lt;/strong&gt;: Specific rules apply to specific scopes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy maintenance&lt;/strong&gt;: Small files stay close to code, low update cost&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalable&lt;/strong&gt;: Grows naturally with the project&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When starting, begin with &lt;code&gt;/CLAUDE.md&lt;/code&gt; at the root, then expand downward. Remember: &lt;strong&gt;The value of documentation lies in being used, not in being finished.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.anthropic.com/claude-code"&gt;Claude Code Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nngroup.com/articles/progressive-disclosure/"&gt;Progressive Disclosure in Software Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>A Classic KNN Classifier Case — The Iris Flower</title><link>https://www.thinkinpython.com/en/post/KNN_classifier.html</link><pubDate>Sun, 17 Nov 2019 10:59:31 +0800</pubDate><guid>https://www.thinkinpython.com/en/post/KNN_classifier.html</guid><description>&lt;h1 id="recommended-book"&gt;Recommended book&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/10/04/1570157108105-1570157108134.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;This book (&lt;em&gt;Grokking Algorithms&lt;/em&gt;) was carefully picked from a large pile of algorithm books. It&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;focuses on understanding the principles behind algorithms,&lt;/li&gt;
&lt;li&gt;replaces obscure formula proofs with vivid examples,&lt;/li&gt;
&lt;li&gt;and has genuinely fun illustrations,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which makes it very friendly to non-specialist developers.
My own algorithm tutorial series is also built on &lt;em&gt;Grokking Algorithms&lt;/em&gt; as its blueprint.&lt;/p&gt;
&lt;h2 id="where-to-get-it"&gt;Where to get it&lt;/h2&gt;
&lt;p&gt;Besides buying the paper edition, you can also find it on WeRead (WeChat Reading), where unlimited reading cards make it a great deal.&lt;/p&gt;</description><content:encoded>&lt;h1 id="recommended-book"&gt;Recommended book&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/10/04/1570157108105-1570157108134.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;This book (&lt;em&gt;Grokking Algorithms&lt;/em&gt;) was carefully picked from a large pile of algorithm books. It&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;focuses on understanding the principles behind algorithms,&lt;/li&gt;
&lt;li&gt;replaces obscure formula proofs with vivid examples,&lt;/li&gt;
&lt;li&gt;and has genuinely fun illustrations,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which makes it very friendly to non-specialist developers.
My own algorithm tutorial series is also built on &lt;em&gt;Grokking Algorithms&lt;/em&gt; as its blueprint.&lt;/p&gt;
&lt;h2 id="where-to-get-it"&gt;Where to get it&lt;/h2&gt;
&lt;p&gt;Besides buying the paper edition, you can also find it on WeRead (WeChat Reading), where unlimited reading cards make it a great deal.&lt;/p&gt;
&lt;h1 id="getting-started"&gt;Getting started&lt;/h1&gt;
&lt;p&gt;This post follows chapter 10 of &lt;em&gt;Grokking Algorithms&lt;/em&gt;.
KNN is one of the entry-level algorithms in machine learning. KNN stands for K Nearest Neighbors, and the principle is very simple: classify by counting the elements nearby in the data&amp;rsquo;s spatial neighborhood. Our ancestors expressed a similar algorithm in one sentence: birds of a feather flock together.&lt;/p&gt;
&lt;p&gt;We will use scikit-learn, which you can install with&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;shell&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install scikit-learn &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id="the-iris-dataset"&gt;The iris dataset&lt;/h1&gt;
&lt;p&gt;The iris classification problem is a very classic case for the KNN algorithm. The scikit-learn library ships with a labeled iris dataset: 150 records in total, containing sepal and petal length and width.&lt;/p&gt;
&lt;p&gt;After shuffling the data, we split it 3:1 into two groups: one as training data, one as test data. The training data generates the KNN model. Since the computer worked hard to generate a model, we need to evaluate the result and confirm the model actually works — that is where the test data comes in. Run the test data through the model, compare the computed results with the data&amp;rsquo;s own labels, and you get the model&amp;rsquo;s accuracy.&lt;/p&gt;
&lt;p&gt;One point deserves special attention: both the training and test data are labeled, meaning the flowers were classified by human intelligence. I remember a village in Henan was dubbed an &amp;ldquo;AI village&amp;rdquo; — what it actually produces is exactly this kind of labeled data, not real &amp;ldquo;artificial intelligence&amp;rdquo; research.&lt;/p&gt;
&lt;p&gt;The iris dataset can be loaded with the following code:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;python&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;from&lt;/span&gt; sklearn.datasets &lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; load_iris
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;iris_dataset &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; load_iris()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Because the iris dataset is ordered, if we split it directly at a 3:1 ratio into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;training data&lt;/li&gt;
&lt;li&gt;test data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;the distributions would concentrate in specific regions and be uneven. So the data needs to be shuffled before splitting — scikit-learn already provides the tool:&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;python&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;from&lt;/span&gt; sklearn.model_selection &lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; train_test_split
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;X_train, X_test, y_train, y_test &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; train_test_split(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;iris_dataset[&lt;span style="color:#f1fa8c"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;], iris_dataset[&lt;span style="color:#f1fa8c"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;], random_state&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id="sharpening-the-knife"&gt;Sharpening the knife&lt;/h1&gt;
&lt;p&gt;The data is roughly ready. KNN requires the features themselves to be usable as classification conditions for the model to really work — the color of oranges and apples, for example, can serve as a classification feature, while their prices may not. In practice, we should also look at the data first.&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;python&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; pandas &lt;span style="color:#ff79c6"&gt;as&lt;/span&gt; pd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; mglearn
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;iris_dataframe &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; pd&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;DataFrame(X_train, columns&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;iris_dataset&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;feature_names)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6272a4"&gt;# color by y_train&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;grr &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; pd&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;plotting&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;scatter_matrix(iris_dataframe, c&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;y_train, figsize&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;(&lt;span style="color:#bd93f9"&gt;15&lt;/span&gt;, &lt;span style="color:#bd93f9"&gt;15&lt;/span&gt;), marker&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#39;o&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hist_kwds&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#f1fa8c"&gt;&amp;#39;bins&amp;#39;&lt;/span&gt;: &lt;span style="color:#bd93f9"&gt;20&lt;/span&gt;}, s&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;60&lt;/span&gt;, alpha&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;.8&lt;/span&gt;, cmap&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;mglearn&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;cm3)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/17/download-1573985692511.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;You can clearly see that the existing data basically separates the 3 kinds of flowers, so we can proceed to the next step with confidence.&lt;/p&gt;
&lt;h1 id="cutting-the-firewood"&gt;Cutting the firewood&lt;/h1&gt;
&lt;p&gt;Now that we have confirmed the data can produce a classifier, it is time to build a model. Thanks to the Python community, we don&amp;rsquo;t need to build one from scratch — scikit-learn already provides usable classifiers, including the KNN classifier. All we need to do is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;initialize the classifier&amp;rsquo;s parameters (only a few need to be specified; the rest can stay at their defaults),&lt;/li&gt;
&lt;li&gt;train the model,&lt;/li&gt;
&lt;li&gt;evaluate and predict.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The K in KNN means how many nearest neighbors — it can be 1, 2, 3, or more. Here we build a model with K = 3, and pass the training data X_train and y_train as parameters to build it.&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;python&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;from&lt;/span&gt; sklearn.neighbors &lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; KNeighborsClassifier
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;knn &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; KNeighborsClassifier(n_neighbors&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;knn&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;fit(X_train, y_train)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that knn is an object; the fit function actually modifies the internal data of the knn object. The KNN classifier is now ready.&lt;/p&gt;
&lt;p&gt;Using the knn.predict method, we can make predictions on data. To evaluate the classifier&amp;rsquo;s accuracy, we compare the predictions with the test data and compute the hit rate.&lt;/p&gt;
&lt;div class="codeblock"&gt;
&lt;div class="codeblock-head"&gt;
&lt;span class="dots" aria-hidden="true"&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span class="codeblock-lang"&gt;python&lt;/span&gt;
&lt;button class="copy-btn" type="button" data-copy-btn&gt;Copy&lt;/button&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;y_pred &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; knn&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;predict(X_test)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;Test set predictions:&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;\n&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt; &lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;{}&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;format(y_pred))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;Test set score: &lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;{:.2f}&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;format(np&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;mean(y_pred &lt;span style="color:#ff79c6"&gt;==&lt;/span&gt; y_test)))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/17/1573987366682-1573987366695.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;In the end, the accuracy reaches 97% — not bad. Your result should be about the same.&lt;/p&gt;
&lt;h1 id="from-knn-to-machine-learning"&gt;From KNN to machine learning&lt;/h1&gt;
&lt;p&gt;The KNN algorithm is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;very simple in theory,&lt;/li&gt;
&lt;li&gt;fast to train (it basically doesn&amp;rsquo;t learn at all),&lt;/li&gt;
&lt;li&gt;relatively accurate,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;while at the same time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;computationally heavy (it computes distances between samples and neighboring points),&lt;/li&gt;
&lt;li&gt;memory-hungry, because the KNN model relies on the training data itself as parameters,&lt;/li&gt;
&lt;li&gt;less accurate for rare categories when samples are imbalanced,&lt;/li&gt;
&lt;li&gt;hard to interpret, making it difficult to form explicit rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although KNN is very simple and brute-force, and quite different from today&amp;rsquo;s popular deep learning, its process of handling data, learning, and predicting — however simple — already contains the basic elements of machine learning.&lt;/p&gt;
&lt;p&gt;The code is here:
&lt;a href="https://github.com/JiangChuanGo/examples/blob/master/KNN/Iris.py"&gt;https://github.com/JiangChuanGo/examples/blob/master/KNN/Iris.py&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Godlike — The Fourier Transform</title><link>https://www.thinkinpython.com/en/post/Fourier_transform.html</link><pubDate>Wed, 13 Nov 2019 07:01:04 +0800</pubDate><guid>https://www.thinkinpython.com/en/post/Fourier_transform.html</guid><description>&lt;h1 id="godlike-not-an-exaggeration-at-all"&gt;Godlike? Not an exaggeration at all!&lt;/h1&gt;
&lt;p&gt;If we ranked every algorithm, the Fourier transform would absolutely take the crown. How powerful is it?! It basically gave humanity a third eye! It is honestly not something humans should have been able to come up with. Mortals, prepare to worship!&lt;/p&gt;
&lt;h1 id="recommended-book"&gt;Recommended book&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/10/04/1570157108105-1570157108134.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;This book (&lt;em&gt;Grokking Algorithms&lt;/em&gt;) was carefully picked from a large pile of algorithm books. It&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;focuses on understanding the principles behind algorithms,&lt;/li&gt;
&lt;li&gt;replaces obscure formula proofs with vivid examples,&lt;/li&gt;
&lt;li&gt;and has genuinely fun illustrations,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which makes it very friendly to non-specialist developers.
My own algorithm tutorial series is also built on &lt;em&gt;Grokking Algorithms&lt;/em&gt; as its blueprint.&lt;/p&gt;</description><content:encoded>&lt;h1 id="godlike-not-an-exaggeration-at-all"&gt;Godlike? Not an exaggeration at all!&lt;/h1&gt;
&lt;p&gt;If we ranked every algorithm, the Fourier transform would absolutely take the crown. How powerful is it?! It basically gave humanity a third eye! It is honestly not something humans should have been able to come up with. Mortals, prepare to worship!&lt;/p&gt;
&lt;h1 id="recommended-book"&gt;Recommended book&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/10/04/1570157108105-1570157108134.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;This book (&lt;em&gt;Grokking Algorithms&lt;/em&gt;) was carefully picked from a large pile of algorithm books. It&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;focuses on understanding the principles behind algorithms,&lt;/li&gt;
&lt;li&gt;replaces obscure formula proofs with vivid examples,&lt;/li&gt;
&lt;li&gt;and has genuinely fun illustrations,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which makes it very friendly to non-specialist developers.
My own algorithm tutorial series is also built on &lt;em&gt;Grokking Algorithms&lt;/em&gt; as its blueprint.&lt;/p&gt;
&lt;h2 id="where-to-get-it"&gt;Where to get it&lt;/h2&gt;
&lt;p&gt;Besides buying the paper edition, you can also find it on WeRead (WeChat Reading), where unlimited reading cards make it a great deal.&lt;/p&gt;
&lt;h1 id="getting-started"&gt;Getting started&lt;/h1&gt;
&lt;p&gt;This post expands on section 11.3 of &lt;em&gt;Grokking Algorithms&lt;/em&gt;. First, let&amp;rsquo;s meet Fourier: a handsome Frenchman who lived in the 18th century, fought wars alongside Napoleon, served as an official on the imperial payroll, then put down the gun for scholarship — and did rather well at it too, all the way to perpetual secretary of the French Academy of Sciences. A glittering résumé: he followed a big shot, and became one himself.&lt;/p&gt;
&lt;h1 id="the-principle"&gt;The principle&lt;/h1&gt;
&lt;p&gt;I really love drinking cola. The Coca-Cola recipe is supposedly a top secret. It is just sugary water — anyone can easily get a finished bottle — yet nobody can reproduce its taste one hundred percent. This process of analyzing a finished product back into its ingredients is called, in technical terms, reverse engineering. It is usually very hard, because it is an open problem.&lt;/p&gt;
&lt;p&gt;Sometimes we are interested not only in the ingredients of food, but also in the ingredients of signals: sound, images. Just like guessing the Coca-Cola formula, figuring out the recipe of a sound or an image is a very difficult piece of reverse engineering. But one man did it: Fourier.&lt;/p&gt;
&lt;p&gt;We normally look at signals in the time domain: whatever the signal, we observe it along a progress bar, and that seems to be the only way to look at it. Fourier successfully decomposed a signal into a series of simpler signals — sine waves of different frequencies. That gives us the signal&amp;rsquo;s recipe: once you know the recipe, you can mix signals of various frequencies together and reproduce the original signal. This recipe is the spectrum. Fourier took humanity&amp;rsquo;s understanding of signals into the frequency domain.&lt;/p&gt;
&lt;h1 id="an-interesting-property"&gt;An interesting property&lt;/h1&gt;
&lt;p&gt;Follow the same recipe, and shredded pork with garlic sauce tastes roughly the same everywhere. A time-domain signal can be converted to the frequency domain, and converted back, it is still the same signal as before (in practice there are tiny differences, but they don&amp;rsquo;t matter). If the Fourier transform only gave us the recipe of a signal, that would be a bit underwhelming — on top of it, we can do much more interesting things.&lt;/p&gt;
&lt;h1 id="high-pass-filtering"&gt;High-pass filtering&lt;/h1&gt;
&lt;p&gt;Very often we need to extract the edges of an image. How would you do it? Trace them with a pen? Let Papa Fourier take you flying — we use a high-pass filter.
This &amp;ldquo;high-pass&amp;rdquo; is not the company Qualcomm — it means &amp;ldquo;letting high frequencies pass&amp;rdquo;. The edges we see in an image are actually pixels that jump between two different color blocks; if you imagine them as sound, those parts are sharper — in other words, higher in frequency.
If we convert an image to the frequency domain, hold back the low-frequency signals, let the high-frequency signals through, and then convert back to the time domain, we get an interesting result.&lt;/p&gt;
&lt;p&gt;First, please welcome the image field&amp;rsquo;s famous model — Ms. Lena.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/13/1573580860818-1573580860856.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;What does her spectrum look like?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/13/1573581003200-1573581003203.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;The brighter a region, the more of that frequency component there is. The very center of the spectrum is the low-frequency region; the outer ring is the high-frequency region.&lt;/p&gt;
&lt;p&gt;We can see a fairly concentrated blob of information in the low-frequency area. Now we dig out the low-frequency information in the center of the spectrum, and the spectrum looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/13/1573581219917-1573581219920.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Convert the frequency-domain signal back to the time domain, and see what happened to Ms. &amp;ldquo;Lena&amp;rdquo;?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/alvendarthy/myimgs/master/gitnote/2019/11/13/1573581276845-1573581276848.png" alt="title" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;We get a &amp;ldquo;line drawing&amp;rdquo; — the edges of the image, extracted. All we did was a Fourier transform plus a high-pass filter. Magical, isn&amp;rsquo;t it!&lt;/p&gt;
&lt;p&gt;For audio signals, with the Fourier transform we can easily remove low-frequency noise in the frequency domain, or polish the sound. The principle is roughly the same.&lt;/p&gt;
&lt;h1 id="no-fourier-no-internet"&gt;No Fourier, no internet&lt;/h1&gt;
&lt;p&gt;Today, almost all information is eventually digitized, and digitization uses the Fourier transform and its variants. Only with the Fourier transform can signals be identified as concrete components and digitized.&lt;/p&gt;
&lt;p&gt;Next time you use a beauty camera or scroll through short videos, remember to give big boss Fourier a double tap!&lt;/p&gt;
&lt;p&gt;The code is &lt;a href="https://github.com/JiangChuanGo/examples/blob/master/FourierTransform/Fourier.py"&gt;here&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>