<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ClassicML on davethehuman.com</title><link>https://davethehuman.com/tags/classicml/</link><description>Recent content in ClassicML on davethehuman.com</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026 Dave the human</copyright><lastBuildDate>Tue, 13 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://davethehuman.com/tags/classicml/index.xml" rel="self" type="application/rss+xml"/><item><title>gini index</title><link>https://davethehuman.com/notes/gini-index/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/gini-index/</guid><description>&lt;p&gt;&lt;em&gt;Gini Index&lt;/em&gt; or &lt;em&gt;Gini Impurity&lt;/em&gt; is a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;metric&lt;/a&gt; used to measure the frequency with which a randomly chosen element from a dataset would be incorrectly labeled if it were randomly labeled according to the distribution of labels in the subset.&lt;/p&gt;
&lt;p&gt;In Machine Learning, it is primarily used as a splitting criterion by the algorithm to build &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;decision trees&lt;/a&gt;.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Formula
 &lt;div id="formula" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#formula" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The Formula For a dataset with $C$ total classes, where $p_i$ is the probability of an item belonging to class $i$: &lt;/p&gt;</description></item><item><title>KNN from scratch</title><link>https://davethehuman.com/notes/knn-from-scratch/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/knn-from-scratch/</guid><description>&lt;h2 class="relative group"&gt;Algorithm and implementation
 &lt;div id="algorithm-and-implementation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#algorithm-and-implementation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/notes/knn/"&gt;KNN&lt;/a&gt; is a so-called &lt;em&gt;&lt;strong&gt;lazy learner&lt;/strong&gt;&lt;/em&gt; because it does not have a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;training&lt;/a&gt; step and it is immediately ready to predict, using &lt;a href="https://davethehuman.com/notes/euclidean-distance/"&gt;euclidean distance&lt;/a&gt; to find the &lt;code&gt;k&lt;/code&gt; points that are closest to the point we are predicting onto, and outputting a prediction based on these &lt;code&gt;k&lt;/code&gt; points (either using the most common &lt;code&gt;y&lt;/code&gt; class among them (&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;classification&lt;/a&gt;) or averaging those closest points&amp;rsquo; value of &lt;code&gt;y&lt;/code&gt; (&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;regression&lt;/a&gt;) ).&lt;/p&gt;</description></item><item><title>entropy</title><link>https://davethehuman.com/notes/entropy/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/entropy/</guid><description>&lt;p&gt;&lt;em&gt;Entropy&lt;/em&gt; is a statistics concept used to measure &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;disorder&lt;/a&gt; in a sample.&lt;br&gt;
It is applied to calculate the &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;information gain&lt;/a&gt; of a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;decision tree&lt;/a&gt;&amp;rsquo;s split through &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;node impurity&lt;/a&gt;, and can be described with the formula:&lt;/p&gt;
$$
E = -\sum_{i=1}^{n} P(X) \log_2 P(X)
$$&lt;p&gt;
In a decision tree&amp;rsquo;s &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;node&lt;/a&gt;, $P(X)$ is the number of times a given class has occurred in the node divided by the number of total examples $n$ in the node.&lt;br&gt;
It is basically the probability of encountering that class in the node&amp;rsquo;s sample. &lt;/p&gt;</description></item><item><title>K-means</title><link>https://davethehuman.com/notes/k-means/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/k-means/</guid><description>&lt;p&gt;&lt;em&gt;K-means&lt;/em&gt; is an &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;unsupervised learning&lt;/a&gt; algorithm that assigns labels to the data points (&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;clustering&lt;/a&gt;) with an iterative optimization that repeats until &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;convergence&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="low"
 alt=""
 src="k-means.png"
 &gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;h2 class="relative group"&gt;Optimization
 &lt;div id="optimization" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#optimization" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;initialize &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;clusters&lt;/a&gt; centers (also called &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;centroids&lt;/a&gt;) randomly&lt;/li&gt;
&lt;li&gt;update cluster labels by assigning points to the nearest cluster center&lt;/li&gt;
&lt;li&gt;update cluster centers by setting the center to the mean of the corresponding cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Loss function
 &lt;div id="loss-function" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#loss-function" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/notes/euclidean-distance/"&gt;Euclidean distance&lt;/a&gt; is the metric used to find the nearest centroids.&lt;/p&gt;</description></item><item><title>K-means from scratch</title><link>https://davethehuman.com/notes/k-means-from-scratch/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/k-means-from-scratch/</guid><description>&lt;h2 class="relative group"&gt;Algorithm and implementation
 &lt;div id="algorithm-and-implementation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#algorithm-and-implementation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/notes/k-means/"&gt;K-means&lt;/a&gt; algorithm assigns labels to data points by iteratively updating &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;centroids&lt;/a&gt; and &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;clusters&lt;/a&gt;&amp;rsquo; labels and using &lt;a href="https://davethehuman.com/notes/euclidean-distance/"&gt;euclidean distance&lt;/a&gt; to calculate their proximity until &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;convergence&lt;/a&gt; (or until a maximum number of iterations is reached).&lt;/p&gt;

&lt;h2 class="relative group"&gt;Class structure
 &lt;div id="class-structure" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#class-structure" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;main attributes&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;the number of clusters &lt;code&gt;K&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;n_iterations&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;clusters&lt;/code&gt;, which is the list of sample indices for each cluster initialized in the &lt;code&gt;__init__&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;centroid&lt;/code&gt; which is the center (or mean vector) for each cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;predict&lt;/code&gt; method
It is worth to note that &lt;strong&gt;there&amp;rsquo;s no &lt;code&gt;fit&lt;/code&gt; method&lt;/strong&gt; and we can do the &lt;code&gt;predict&lt;/code&gt; straight away.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-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:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np
&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="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;KMeans&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, K&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, n_iterations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;K &lt;span style="color:#f92672"&gt;=&lt;/span&gt; K
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;n_iterations &lt;span style="color:#f92672"&gt;=&lt;/span&gt; n_iterations
&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="color:#75715e"&gt;#list of sample indices for each cluster&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;clusters &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[] &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; _ &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;K)]
&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="color:#75715e"&gt;#mean vector for each cluster&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;centroids &lt;span style="color:#f92672"&gt;=&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="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;predict&lt;/span&gt;(self, X):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;pass&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 class="relative group"&gt;Inference
 &lt;div id="inference" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#inference" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;predict&lt;/code&gt; method consists of the following steps:&lt;/p&gt;</description></item><item><title>KNN</title><link>https://davethehuman.com/notes/knn/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/knn/</guid><description>&lt;p&gt;&lt;em&gt;K nearest neighbours&lt;/em&gt; is a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;supervised learning&lt;/a&gt; algorithm that, given a data point to predict onto, uses &lt;a href="https://davethehuman.com/notes/euclidean-distance/"&gt;euclidean distance&lt;/a&gt; to calculate the distance between that point and the &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;training&lt;/a&gt; data to make a prediction based on the closest $k$ points ($k$ is then an &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;hyperparameter&lt;/a&gt; defined by the user a-priori). &lt;br&gt;
In case of a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;classification&lt;/a&gt; task, it will assign a label with &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;majority voting&lt;/a&gt;; in case of a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;regression&lt;/a&gt; task it will compute the average of those closest points&amp;rsquo; value.&lt;/p&gt;</description></item><item><title>early stopping</title><link>https://davethehuman.com/notes/early-stopping/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/early-stopping/</guid><description>&lt;p&gt;&lt;em&gt;Early stopping&lt;/em&gt; is a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;regularization&lt;/a&gt; technique that stops training when performance on a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;held-out&lt;/a&gt; validation set stops improving, helping prevent &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;overfitting&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;Training loss&lt;/a&gt; may keep decreasing while &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;validation loss&lt;/a&gt; begins to rise: the model is increasingly fitting details that do not &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;generalize&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A typical procedure monitors validation loss, saves the best &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;model checkpoint&lt;/a&gt;, and stops after a chosen number of evaluations without meaningful improvement. This waiting period is called &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;patience&lt;/a&gt;. The best checkpoint is then restored.&lt;/p&gt;
&lt;p&gt;Another way to apply early stopping is to monitor the algorithm &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;convergence&lt;/a&gt;: if further iterations barely change the parameters, we can stop when the largest absolute update of &lt;code&gt;w&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; is below &lt;code&gt;tolerance&lt;/code&gt;. This is implemented in &lt;a href="https://davethehuman.com/notes/linear-regression-from-scratch/"&gt;Linear Regression from scratch&lt;/a&gt; and &lt;a href="https://davethehuman.com/notes/logistic-regression-from-scratch/"&gt;Logistic Regression from scratch&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Logistic Regression from scratch</title><link>https://davethehuman.com/notes/logistic-regression-from-scratch/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/logistic-regression-from-scratch/</guid><description>&lt;h2 class="relative group"&gt;Algorithm and implementation
 &lt;div id="algorithm-and-implementation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#algorithm-and-implementation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/notes/logistic-regression/"&gt;Logistic Regression&lt;/a&gt; formula is the same as the &lt;a href="https://davethehuman.com/notes/linear-regression/"&gt;Linear Regression&lt;/a&gt;&amp;rsquo;s one passed to a &lt;a href="https://davethehuman.com/notes/sigmoid/"&gt;sigmoid&lt;/a&gt; function to obtain a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;probability score&lt;/a&gt; from &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;logits&lt;/a&gt; and can be replicated on numpy with:&lt;br&gt;
&lt;code&gt;sigmoid(X @ w + b)&lt;/code&gt; (or &lt;code&gt;sigmoid(np.dot(X,w))&lt;/code&gt;.&lt;br&gt;
The implementation of &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;gradient descent&lt;/a&gt; as an &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;optimizer&lt;/a&gt; is the same of &lt;a href="https://davethehuman.com/notes/linear-regression-from-scratch/"&gt;Linear Regression from scratch&lt;/a&gt;, what changes is the &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;loss&lt;/a&gt; and the error since we deal with probabilities:&lt;/p&gt;</description></item><item><title>standardization</title><link>https://davethehuman.com/notes/standardization/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/standardization/</guid><description>&lt;p&gt;In several algorithms, &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;gradient descent&lt;/a&gt; uses one &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;learning rate&lt;/a&gt; for every &lt;a href="https://davethehuman.com/notes/weights/"&gt;weight&lt;/a&gt;; this means that if one &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;feature&lt;/a&gt; ranges from 0 to 1 and another from 0 to 100000 their gradients can have very different size, with &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;training&lt;/a&gt; that may zig-zag, diverge or require a very small learning rate.&lt;/p&gt;
&lt;p&gt;One solution is to add &lt;em&gt;standardization&lt;/em&gt; which means transforming each column on the training dataset so that its &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;mean&lt;/a&gt; is 0 and &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;standard deviation&lt;/a&gt; is 1: &lt;code&gt;X_scaled = (X - mean) / scale&lt;/code&gt;.&lt;br&gt;
The training &lt;code&gt;mean&lt;/code&gt; and &lt;code&gt;scale&lt;/code&gt; need to be saved and used for &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;validation&lt;/a&gt;, &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;test&lt;/a&gt; and future predictions too.&lt;/p&gt;</description></item><item><title>Linear Regression from scratch</title><link>https://davethehuman.com/notes/linear-regression-from-scratch/</link><pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/linear-regression-from-scratch/</guid><description>&lt;h2 class="relative group"&gt;Algorithm and implementation
 &lt;div id="algorithm-and-implementation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#algorithm-and-implementation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://davethehuman.com/notes/linear-regression/"&gt;Linear Regression&lt;/a&gt; formula can be replicated on numpy with &lt;code&gt;X @ w + b&lt;/code&gt; (or &lt;code&gt;np.dot(X,w)&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;To implement &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;gradient descent&lt;/a&gt; as an &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;optimizer&lt;/a&gt;, we need to calculate the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;errors = predictions - y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The loss is &lt;a href="https://davethehuman.com/notes/rss/"&gt;RSS&lt;/a&gt; , evaluated with &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;MSE&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;loss = np.mean(errors - y)**2&lt;/code&gt; In this case, we will actually be using the half-&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;MSE&lt;/a&gt; to have similarities with &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;Logistic Regression from scratch&lt;/a&gt;.
$$L=\frac{1}{2N}\sum_i(\hat y_i-y_i)^2.$$Half-MSE has the same minimizer as MSE and its &lt;code&gt;1/2&lt;/code&gt; cancels the &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;derivative&lt;/a&gt;&amp;rsquo;s &lt;code&gt;2&lt;/code&gt; giving the same gradient template as &lt;a href="https://davethehuman.com/notes/logistic-regression/"&gt;Logistic Regression&lt;/a&gt;:
$$dw=X^T errors/N, \qquad db=mean(errors).$$
Using &amp;ldquo;pure&amp;rdquo; MSE the derivative would have been:
$$dw=2X^T errors/N, \qquad db=mean(errors).$$&lt;/li&gt;
&lt;li&gt;weights &lt;code&gt;w&lt;/code&gt; and &lt;code&gt;biases&lt;/code&gt; are initialized as &lt;code&gt;np.zeros&lt;/code&gt; and &lt;code&gt;np.mean(y)&lt;/code&gt; respectively, since the &lt;a href="https://davethehuman.com/notes/weights/"&gt;weights&lt;/a&gt; act as a sort of &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;feature importance&lt;/a&gt; and the &lt;a href="https://davethehuman.com/notes/bias/"&gt;bias&lt;/a&gt; works as an &lt;a href="https://davethehuman.com/notes/intercept/"&gt;intercept&lt;/a&gt; .
After choosing a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;learning rate&lt;/a&gt;, at further steps &lt;code&gt;w&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; will be updated as:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;w-=dw * learning_rate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b-=db * learning_rate&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Class structure
 &lt;div id="class-structure" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#class-structure" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;main attributes&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;learning_rate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;n_iterations&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://davethehuman.com/notes/weights/"&gt;weights&lt;/a&gt; &lt;code&gt;w_&lt;/code&gt; and &lt;a href="https://davethehuman.com/notes/bias/"&gt;bias&lt;/a&gt; &lt;code&gt;b_&lt;/code&gt; initialized as &lt;code&gt;None&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fit&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;&lt;code&gt;predict&lt;/code&gt; method&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-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:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np
&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="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;LinearRegression&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, learning_rate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.05&lt;/span&gt;, n_iterations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;learning_rate &lt;span style="color:#f92672"&gt;=&lt;/span&gt; learning_rate
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;n_iterations &lt;span style="color:#f92672"&gt;=&lt;/span&gt; n_iterations
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;w_ &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;b_ &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&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="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fit&lt;/span&gt;(self, X, y):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;pass&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="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;predict&lt;/span&gt;(self, X):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;pass&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 class="relative group"&gt;Training
 &lt;div id="training" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#training" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;fit&lt;/code&gt; method can be implemented following these steps:&lt;/p&gt;</description></item><item><title>Logistic Regression</title><link>https://davethehuman.com/notes/logistic-regression/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/logistic-regression/</guid><description>&lt;h2 class="relative group"&gt;Formula
 &lt;div id="formula" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#formula" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Taking as a reference the &lt;a href="https://davethehuman.com/notes/linear-regression/"&gt;Linear Regression&lt;/a&gt;, in &lt;em&gt;Logistic Regression&lt;/em&gt; the linear output is converted into a probability between 0 and 1 using the &lt;a href="https://davethehuman.com/notes/sigmoid/"&gt;sigmoid&lt;/a&gt; function:&lt;/p&gt;
$$\sigma(z) = \frac{1}{1 + e^{-z}}$$&lt;p&gt;With \(z = \beta_0 + X\beta\) as the linear score, the model&amp;rsquo;s predicted probability is
\(\hat{p} = \sigma(z) = \sigma(\beta_0 + X\beta) = \frac{1}{1 + e^{-(\beta_0 + X\beta)}}\).&lt;/p&gt;</description></item><item><title>Random Forest</title><link>https://davethehuman.com/notes/random-forest/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/random-forest/</guid><description>&lt;p&gt;The &lt;em&gt;Random Forest&lt;/em&gt; is an &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;ensemble&lt;/a&gt; of &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;decision trees&lt;/a&gt; that reduces &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;overfitting&lt;/a&gt; by using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;bagging&lt;/a&gt; to reduce &lt;a href="https://davethehuman.com/notes/variance-ml/"&gt;variance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;random selection of &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;features&lt;/a&gt; from the full set of features at each &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;split&lt;/a&gt; to prevent the important features from always being present at the top of each tree&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is important to note that &lt;strong&gt;we can&amp;rsquo;t overfit by putting in too many trees&lt;/strong&gt; as they just reduce variance; at some point, variance reduction will just stop and we need to take into account computation time.&lt;/p&gt;</description></item><item><title>Linear Regression</title><link>https://davethehuman.com/notes/linear-regression/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/linear-regression/</guid><description>&lt;h2 class="relative group"&gt;Formula
 &lt;div id="formula" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#formula" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When using &lt;em&gt;Linear Regression&lt;/em&gt;, the goal is to estimate a function $f(x)$ such that each &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;feature&lt;/a&gt; has a &lt;strong&gt;linear relationship&lt;/strong&gt; to the target variable $y$.&lt;br&gt;
This is a &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;supervised learning&lt;/a&gt; model written as:
&lt;/p&gt;
$$
y = \beta_0 + X\beta
$$&lt;p&gt;with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\beta_0$ = &lt;a href="https://davethehuman.com/notes/intercept/"&gt;intercept&lt;/a&gt; (or &lt;a href="https://davethehuman.com/notes/bias/"&gt;bias&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;$X$ = matrix of &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;predictor&lt;/a&gt; variables&lt;/li&gt;
&lt;li&gt;$\beta$ = vector of parameters that determine the &lt;a href="https://davethehuman.com/notes/weights/"&gt;weights&lt;/a&gt; for each variable. For a single predictor, the sign of $\beta$ gives the direction of the relationship:
&lt;ul&gt;
&lt;li&gt;$\beta &gt; 0$ is positive&lt;/li&gt;
&lt;li&gt;$\beta &lt; 0$ is negative&lt;/li&gt;
&lt;li&gt;$\beta = 0$ means no linear effect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt="linear regression"
 width="2000"
 height="1300"
 src="https://davethehuman.com/attachments/linear_regression_hu_12905239a6b86b3e.png"
 srcset="https://davethehuman.com/attachments/linear_regression_hu_12905239a6b86b3e.png 800w, https://davethehuman.com/attachments/linear_regression_hu_1cb26931883e32fb.png 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://davethehuman.com/attachments/linear_regression.png"&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>intercept</title><link>https://davethehuman.com/notes/intercept/</link><pubDate>Sun, 20 Sep 2026 00:00:00 +0000</pubDate><guid>https://davethehuman.com/notes/intercept/</guid><description>&lt;p&gt;In &lt;a href="https://davethehuman.com/notes/linear-regression/"&gt;Linear Regression&lt;/a&gt;, the &lt;em&gt;intercept&lt;/em&gt; is the expected value of the &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;dependent variable&lt;/a&gt; $Y$ when all &lt;a href="https://davethehuman.com/coming-soon/" rel="nofollow"&gt;independent variable&lt;/a&gt;s are equal to zero. Graphically, it is represented by the intersection point between the regression line and the Y axis on a chart; its value shift the regression line up and down without affecting its tilt or slope.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt="intercept"
 width="2000"
 height="1300"
 src="https://davethehuman.com/attachments/intercept_hu_426627f0b6687085.png"
 srcset="https://davethehuman.com/attachments/intercept_hu_426627f0b6687085.png 800w, https://davethehuman.com/attachments/intercept_hu_bf603842d8e23f87.png 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://davethehuman.com/attachments/intercept.png"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;It can be interpreted as a &lt;strong&gt;baseline value&lt;/strong&gt;, since it acts as the starting point or baseline prediction for the linear regression model before any independent variables effect is added.&lt;/p&gt;</description></item></channel></rss>