<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[emdeh’s Substack: Artificial Intelligence]]></title><description><![CDATA[Artificial Intelligence]]></description><link>https://www.emdeh.com/s/artificial-intelligence</link><image><url>https://substackcdn.com/image/fetch/$s_!ZFh2!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3ab64a-692c-4b46-903b-f8cbe66d9aba_144x144.png</url><title>emdeh’s Substack: Artificial Intelligence</title><link>https://www.emdeh.com/s/artificial-intelligence</link></image><generator>Substack</generator><lastBuildDate>Sat, 11 Apr 2026 08:08:41 GMT</lastBuildDate><atom:link href="https://www.emdeh.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[emdeh]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[emdeh@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[emdeh@substack.com]]></itunes:email><itunes:name><![CDATA[emdeh]]></itunes:name></itunes:owner><itunes:author><![CDATA[emdeh]]></itunes:author><googleplay:owner><![CDATA[emdeh@substack.com]]></googleplay:owner><googleplay:email><![CDATA[emdeh@substack.com]]></googleplay:email><googleplay:author><![CDATA[emdeh]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Regression Models and Evaluation Metrics in Machine Learning]]></title><description><![CDATA[A high-level overview of Linear Regression and common evaluation metrics.]]></description><link>https://www.emdeh.com/p/understanding-regression-models-and</link><guid isPermaLink="false">https://www.emdeh.com/p/understanding-regression-models-and</guid><dc:creator><![CDATA[emdeh]]></dc:creator><pubDate>Tue, 11 Jun 2024 09:10:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/712fa5e6-0aad-4927-95c4-27a79b4c9cae_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>What is Regression?</h1><p>Regression is a statistical method used in machine learning to predict a continuous numeric label (output) based on one or more input features. Regression analysis aims to establish a mathematical relationship between the dependent variable (label) and the independent variables (features). This relationship helps in predicting the label for new, unseen data.</p><p>In simple linear regression, the relationship between the dependent variable <em><strong>Y</strong></em> and the independent variable <em><strong>X</strong></em> is modelled as a linear function. The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;Y = \\beta_0 + \\beta_1X&quot;,&quot;id&quot;:&quot;TXORGCHYUQ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Where:</p><ul><li><p><strong>Y</strong>: The dependent variable (the output we are trying to predict).</p></li><li><p><strong>&#946;0</strong>: The intercept (the value of <strong>Y</strong> when <strong>X</strong> is 0).</p></li><li><p><strong>&#946;1</strong>: The slope (the change in <strong>Y</strong> for a one-unit change in <strong>X</strong>).</p></li><li><p><strong>X</strong>: The independent variable (the input feature used for prediction).</p></li></ul><p>Let's consider a very simple example: We use shoe size (<em><strong>x</strong></em>) to predict height (<em><strong>y</strong></em>).</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/BVd4M/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c25ed2af-7eb5-4925-ad52-266939bbbda5_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:271,&quot;title&quot;:&quot;| Created with Datawrapper&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/BVd4M/1/" width="730" height="271" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>Using linear regression on this data, we might find the following relationship:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=150+5x&quot;,&quot;id&quot;:&quot;MEHSGCGUVB&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Here:</p><ul><li><p><em><strong>y</strong></em>: The height of someone being predicted.</p></li><li><p><strong>150</strong>: Represents the intercept of y and x. That is, if the shoe size were hypothetically 0, the height would be 150cm.</p></li><li><p><strong>5</strong><em><strong>x</strong></em>: Represents the slope of the relationships. For each additional unit increase in shoe size, the height increases by 5 cm.</p></li></ul><p>To predict the height of someone with an 8.5 shoe size, we start with a base height of 150 and add 5cm for every value incremented in shoe size starting from 0. We then multiply 8.5 by 5.</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=150+5&#215;8.5&quot;,&quot;id&quot;:&quot;WMGHTGSKHH&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=150+42.5&quot;,&quot;id&quot;:&quot;ZMFEVTYKEW&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=192.5&quot;,&quot;id&quot;:&quot;AYESBZDFXO&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>So, the predicted height of someone with a shoe size of 8.5 is 192.5 cm.</p><p>Linear regression involves fitting the &#8220;line of best fit&#8221; to the data. In this case, it represents a perfect relationship: for every 5 cm increase in height, there is an increase of 1 in shoe size.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/uRI95/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c183b60-9e57-45ff-8431-f84be62d5217_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:353,&quot;title&quot;:&quot;| Created with Datawrapper&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/uRI95/1/" width="730" height="353" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>You can imagine that with less perfect data, not all of the data points would intercept with the line.</p><h2>Regression as a Type of Supervised Machine Learning</h2><p>Regression falls under the category of supervised machine learning. In supervised learning, the model is trained on a labelled dataset, meaning each training example consists of input features and the corresponding known output label. The model learns to map inputs to outputs by identifying patterns in the training data.</p><h3>Key Characteristics of Supervised Learning:</h3><ol><li><p><strong>Labelled Data</strong>: The training dataset includes input-output pairs where the output is a known value.</p></li><li><p><strong>Prediction Task</strong>: The goal is to predict the output label for new data based on the learned relationship from the training data.</p></li></ol><h2>Types of Regression</h2><p>There are various types of regression algorithms, each suitable for different types of data and relationships:</p><ol><li><p><strong>Linear Regression</strong>: Models the relationship between the input features and output as a straight line.</p></li><li><p><strong>Polynomial Regression</strong>: Models the relationship as a polynomial, suitable for more complex, non-linear data.</p></li><li><p><strong>Ridge and Lasso Regression</strong>: Regularised versions of linear regression that add penalty terms to prevent overfitting.</p></li></ol><h2>The Training Process for Regression Models</h2><ol><li><p><strong>Data Splitting</strong>: Randomly split the training data to create a dataset for training the model while holding back a subset of the data to validate the trained model.</p></li><li><p><strong>Model Training</strong>: Fit the training data to a model using an algorithm, such as linear regression.</p></li><li><p><strong>Model Validation</strong>: Test the model using the validation data by predicting labels for the features.</p></li><li><p><strong>Performance Evaluation</strong>: Compare the actual labels in the validation dataset to the predicted labels. Aggregate the differences between predicted and actual label values to calculate a metric indicating the model's accuracy.</p></li><li><p><strong>Iterative Refinement</strong>: Adjust the algorithm and parameters and repeat the training and validation process until the model achieves an acceptable level of predictive accuracy.</p></li></ol><div><hr></div><h1>Example: Predicting House Prices</h1><p>Let's explore regression with an example. We have a data set of house prices and their corresponding size</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/s0vFw/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99a4aa48-41e1-40ce-b0ad-3496b4a2066f_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:839,&quot;title&quot;:&quot;| Created with Datawrapper&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/s0vFw/1/" width="730" height="839" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>We split the dataset to form a training set, which will be used to train a model to predict house prices (<em><strong>y</strong></em>) based on house size (<em><strong>x</strong></em>) in square meters. The held-back data will be used during the evaluation.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/MhqQa/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39292d21-bdbd-4ed4-b76a-209a4e45db57_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:911,&quot;title&quot;:&quot;Training data&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/MhqQa/1/" width="730" height="911" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><h2>Applying Linear Regression</h2><p>We can plot the relationship between house size and price on a graph and fit a linear regression line to understand the relationship between the two variables.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/DJ2lp/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60dc168a-a766-4ac3-94b5-f15c59a8dc12_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:353,&quot;title&quot;:&quot;| Created with Datawrapper&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/DJ2lp/1/" width="730" height="353" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The function<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> derived by the linear regression algorithm for this data can be represented as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(x)=7595.42+3010.27x&quot;,&quot;id&quot;:&quot;PAHDOQKEJN&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Where:</p><ul><li><p><em><strong>f(x)</strong></em>: denotes the function <em><strong>f </strong></em>is evaluated at <em><strong>x. </strong></em>In this context, the function <em><strong>f(x)</strong></em> represents the independent variable (<em><strong>x</strong></em> = house size) and predicts the value of the dependent variable (<em><strong>y</strong></em> = house price).</p></li><li><p><strong>7595.42</strong>: This is the intercept term, which is the predicted house price (<em><strong>y</strong></em>) when the house size (<em><strong>x</strong></em>) is 0 square metres. </p></li><li><p><strong>+3010.27</strong><em><strong>x</strong></em>: This term represents the slope and indicates that for every one-unit increase in <em><strong>x</strong></em> (house size), the value of the function <em><strong>f(x) </strong></em>will increase by $3,010.27.</p></li></ul><p>How are the coefficients calculated? Check out the footnote.</p><p>In the context of predicting house prices based on house size:</p><ul><li><p><strong>House Size (</strong><em><strong>x</strong></em><strong>)</strong>: The independent variable (input feature) represents the size of the house in square meters.</p></li><li><p><strong>House Price function </strong><em><strong>f(x): </strong></em>The dependent variable (output) represents the house's predicted price.</p></li></ul><p>We can use this regression function to predict house prices for any given size. For example, if the house size is 85 square meters, the model predicts:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(x)=7595.42+3010.27x&quot;,&quot;id&quot;:&quot;KMZEPWBTOF&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(85)=7595.42+3010.27 \\times 85&quot;,&quot;id&quot;:&quot;XYYLRLYMQV&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(85)=7595.42+255872.95&quot;,&quot;id&quot;:&quot;NPTRHXHASG&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(85)=263468.37&quot;,&quot;id&quot;:&quot;CYJQASVSOS&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>So, the predicted price for a house size of 85 square meters is approximately $263,468.37.</p><div><hr></div><h2>Evaluating the Model</h2><p>To validate and evaluate the model's accuracy, we predict some values (<em><strong>&#375;</strong></em><strong>) </strong>based on the held-back data and compare them to the actual values (<em><strong>y</strong></em>) of the held-back data to evaluate performance.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/GsnO9/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e34da000-b740-43b3-80c4-c0fd04977178_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:268,&quot;title&quot;:&quot;Predicted house prices&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/GsnO9/1/" width="730" height="268" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/OBd0a/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9eb44611-865e-412b-b6ad-64dda44f3c76_1260x660.png&quot;,&quot;thumbnail_url_full&quot;:&quot;&quot;,&quot;height&quot;:233,&quot;title&quot;:&quot;| Created with Datawrapper&quot;,&quot;description&quot;:&quot;Create interactive, responsive &amp; beautiful charts &#8212; no code required.&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/OBd0a/1/" width="730" height="233" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p></p><p>We can measure the model's performance using various metrics by comparing the predicted values (&#375;) to the actual values (y) of the held-back data.</p><h2>Mean Absolute Error (MAE)</h2><p>Mean Absolute Error (MAE) measures the average magnitude of the errors in a set of predictions without considering their direction. It is the average of the absolute differences between prediction and actual observation over the test sample, where all individual differences have equal weight.</p><p>In this example, the variance indicates how many dollars each prediction was wrong. Importantly, it doesn&#8217;t matter if the prediction was over or under; it is simply a measure of variance.</p><p>In the house price example, the mean (average) of absolute errors is $8,207.36. </p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{MAE} = \\frac{1}{n} \\sum_{i=1}^{n} | y_i - \\hat{y}_i |&quot;,&quot;id&quot;:&quot;OWJXFQYFES&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h2>Mean Squared Error (MSE)</h2><p>Mean Squared Error (MSE) measures the average of the squares of the errors&#8212;that is, the average squared difference between the estimated values and the actual value.</p><p>This metric treats all discrepancies between predicted and actual labels equally. It may be preferable to have a model that is slightly off all the time rather than one that makes fewer but more significant errors. Squaring the individual errors and then calculating the mean of these squared values emphasizes the larger errors.</p><p>In the house price example, the MSE is 94,049,732.32.</p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{MSE} = \\frac{1}{n} \\sum_{i=1}^{n} ( y_i - \\hat{y}_i )^2&quot;,&quot;id&quot;:&quot;BKVJWYLKHM&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h2>Root Mean Squared Error (RMSE)</h2><p>Root Mean Squared Error (RMSE) is the square root of the MSE. It is a frequently used measure that quantifies the differences between values predicted by a model and the observed values. RMSE takes the magnitude of errors into account by squaring them, but as a result, the metric is in squared units of the original label. Thus, stating that the MSE of our model is XX does not provide a direct measure of the error in terms of the original units (dollars, in this case). The MSE is simply a numeric score indicating the overall error level in the validation predictions.</p><p>To express the error in terms of dollars, we take the square root of the MSE.</p><p>In the house price example, the RMSE is $9,699.99</p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{RMSE} = \\sqrt{ \\frac{1}{n} \\sum_{i=1}^{n} ( y_i - \\hat{y}_i )^2 }&quot;,&quot;id&quot;:&quot;CZQKMCXMNL&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h2>Coefficient of Determination (R&#178;)</h2><p>The Coefficient of Determination (R&#178;) is a statistical measure that explains how much of the variability in a dependent variable can be explained by its relationship with an independent variable. In regression, the R&#178; coefficient of determination measures how well the regression predictions approximate the actual data points. An R&#178; of 1 indicates that the regression predictions perfectly fit the data.</p><p>This metric compares the sum of squared differences between the predicted and actual labels (residual sum of squares) with the sum of squared differences between the actual label values and the mean of the actual values (total sum of squares).</p><p>The resulting value will be between 0 and 1. The closer the value is to 1, the better the model fits the validation data.</p><p>In the house price example, the R&#178; calculated from the validation data is 0.9996.</p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R^2 = 1 - \\frac{ \\sum_{i=1}^{n} ( y_i - \\hat{y}_i )^2 }{ \\sum_{i=1}^{n} ( y_i - \\bar{y} )^2 }&quot;,&quot;id&quot;:&quot;DACTBSRTKM&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h2>Adjusted R&#178;</h2><p>Adjusted R&#178; adjusts the R&#178; statistic based on the number of independent variables in the model. Unlike R&#178;, it does not always increase when adding a new predictor. This is because Adjusted R&#178; considers the number of predictors relative to the number of data points, penalizing the addition of predictors that do not significantly improve the model.</p><h3>Why Adjusted R&#178; is a Better Measure for Comparing Models</h3><ol><li><p><strong>Penalises Overfitting</strong>: R&#178; always increases or stays the same when more predictors are added to the model, regardless of whether the new predictors are actually useful. This can lead to overfitting, where the model fits the training data well but performs poorly on new, unseen data. Adjusted R&#178;, on the other hand, increases only if the new predictor improves the model more than would be expected by chance. If the new predictor does not provide a meaningful improvement, Adjusted R&#178; can decrease.</p></li><li><p><strong>Accounts for the Number of Predictors</strong>: Adjusted R&#178; incorporates the number of predictors (p) and the number of observations (n) into its calculation. This means that models with more predictors are not unfairly favoured. The formula for Adjusted R&#178; is:</p></li></ol><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{Adjusted } R^2 = 1 - \\left( \\frac{(1 - R^2)(n - 1)}{n - p - 1} \\right)\n&quot;,&quot;id&quot;:&quot;PNHCWPONWZ&quot;}" data-component-name="LatexBlockToDOM"></div><p>where R&#178; is the coefficient of determination, <em><strong>n </strong></em>is the number of observations, and <em><strong>p </strong></em>is the number of predictors.</p><ol start="3"><li><p><strong>Better Comparison</strong>: Because Adjusted R&#178; penalizes models for having unnecessary predictors, it provides a more accurate measure of model performance when comparing models with different numbers of predictors. This makes it a better tool for model selection, especially when dealing with complex models.</p></li></ol><p>Adjusted R&#178; is a more reliable statistic for comparing models because it adjusts for the number of predictors. This helps to avoid overfitting and provides a clearer picture of model performance. It also ensures that only predictors that genuinely improve the model are favoured.</p><p>In the house price example, the Adjusted R&#178; is 0.9996.</p><h3>Mean Bias Deviation (MBD)</h3><p>Mean Bias Deviation (MBD) measures the average bias in the model predictions. It provides an indication of whether the model tends to overpredict or underpredict. Unlike other error metrics that focus on the magnitude of errors, MBD specifically evaluates the direction of the errors, giving insights into the systematic bias present in the model.</p><p>In the house price example, the MBD is $8,207.36</p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{MBD} = \\frac{1}{n} \\sum_{i=1}^{n} ( y_i - \\hat{y}_i )&quot;,&quot;id&quot;:&quot;GMDMEGGYRM&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h3>Mean Absolute Percentage Error (MAPE)</h3><p>Mean Absolute Percentage Error (MAPE) measures a forecasting method's accuracy in terms of percentage error. It is a commonly used metric in regression analysis to assess a model's prediction accuracy. The MAPE is expressed as a percentage, which makes it easier to interpret and compare across different datasets and models.</p><p>In the house house price example, the MAPE is 2.02%</p><p>The formula is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{MAPE} = \\frac{100\\%}{n} \\sum_{i=1}^{n} \\left| \\frac{ y_i - \\hat{y}_i }{ y_i } \\right|&quot;,&quot;id&quot;:&quot;YHPBDKFBFW&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><div><hr></div><h1>Iterative Training</h1><p>The training process is typically iterative. Data scientists repeatedly train and evaluate a model, varying:</p><ul><li><p><strong>Feature Selection and Preparation</strong>: Choosing which features to include and how to preprocess them.</p></li><li><p><strong>Algorithm Selection</strong>: Exploring different regression algorithms.</p></li><li><p><strong>Hyperparameters</strong>: Adjusting the numeric settings that control algorithm behaviour.</p></li></ul><p>After multiple iterations, the model that yields the best evaluation metrics is selected for use.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><h3>Determining the regression algorithm</h3><p>To determine the regression algorithm for the dataset in question, we can use linear regression to fit a line that best describes the relationship between the house size (independent variable <em><strong>x</strong></em>) and the house price (dependent variable <em><strong>y</strong></em>).</p><h4>Steps to Find the Linear Regression Model</h4><ol><li><p><strong>Prepare the Data</strong>: List the house sizes and corresponding prices.</p></li><li><p><strong>Compute the Regression Coefficients</strong>: Find the slope (&#946;1)&#8203; and intercept (&#946;0&#8203;&#8203;) of the best-fit line.</p></li><li><p><strong>Construct the Regression Equation</strong>: Use the calculated coefficients to form the regression equation:</p></li></ol><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y= \\beta_0 + \\beta_1&#8203;x&quot;,&quot;id&quot;:&quot;MCYUBVMFWS&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h4>Using Python for Linear Regression</h4><p>We can use Python's <code>numpy</code> and <code>scikit-learn</code> libraries to perform linear regression and find the coefficients &#946;0 (intercept) and &#946;1 (slope)</p><pre><code>import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression

# Data
data = {
    'House Size (x)': [
        55, 65, 75, 80, 85, 95, 100, 110, 120, 135, 140, 50, 55, 70, 80, 85, 90, 95, 100, 105,
        110, 115, 120, 125, 130, 135, 140, 145, 65, 75, 125
    ],
    'House Price (y)': [
        158000, 182000, 230000, 245000, 248000, 285000, 297000, 340000, 360000, 400000, 430000, 
        155000, 158000, 220000, 245000, 248000, 280000, 285000, 297000, 310000, 340000, 345000, 
        360000, 375000, 395000, 400000, 430000, 435000, 182000, 230000, 375000
    ]
}

df = pd.DataFrame(data)

# Features and Labels
X = df[['House Size (x)']]
y = df['House Price (y)']

# Model
model = LinearRegression()
model.fit(X, y)

# Coefficients
intercept = model.intercept_
slope = model.coef_[0]

print(f"Intercept (&#946;&#8320;): {intercept}")
print(f"Slope (&#946;&#8321;): {slope}")

# Regression Equation
print(f"Regression Equation: y = {intercept} + {slope}x")</code></pre><h5>Output</h5><pre><code>Intercept (&#946;&#8320;): 7595.42
Slope (&#946;&#8321;): 3010.27
</code></pre><h4>Regression Equation</h4><p>Based on the linear regression model, the regression equation is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=7595.42+3010.27x&quot;,&quot;id&quot;:&quot;QCAEEOXTFF&quot;}" data-component-name="LatexBlockToDOM"></div><p>This equation means that:</p><ul><li><p>The intercept (&#946;0&#8203;) is approximately 93377.19, which is the predicted house price when the house size is 0 square meters.</p></li><li><p>The slope (&#946;1&#8203;) is approximately 2422.81, indicating that for each additional square meter of house size, the house price increases by about $2422.81.</p></li></ul><p>which can be expressed as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(x)=7595.42+3010.27x&quot;,&quot;id&quot;:&quot;GLCPLVKJPF&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>How are the coefficients actually calculated, you ask?</p><p>Below are the step-by-step calculations for finding the coefficients (intercept and slope)</p><h3>Computing coefficients</h3><h4>Definitions</h4><ul><li><p><em><strong>xi</strong></em>&#8203;: The <em>i-th</em> value of the independent variable (input feature).</p></li><li><p><em><strong>yi</strong></em>&#8203;: The <em>i-th</em> value of the dependent variable (output label).</p></li><li><p><em><strong>x&#772;</strong></em>: The mean of the independent variable values.</p></li><li><p><strong>y&#772;</strong>&#8203;: The mean of the dependent variable values.</p></li><li><p><em><strong>n</strong></em>: The number of observations.</p></li></ul><h4>Formulas for the Coefficients</h4><p> <strong>Slope (&#946;1)</strong></p><p> The slope &#946;1&#8203; is calculated as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\beta_1 = \\frac{\\sum_{i=1}^{n} (x_i - \\bar{x})(y_i - \\bar{y})}{\\sum_{i=1}^{n} (x_i - \\bar{x})^2}&quot;,&quot;id&quot;:&quot;ZMHMUOBYLU&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p><strong>Intercept (&#946;0)</strong></p><p>The intercept &#946;0&#8203; is calculated as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\beta_0 = \\bar{y} - \\beta_1 \\bar{x}&quot;,&quot;id&quot;:&quot;YJIVXYQIGX&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h4>Step-by-Step Calculation</h4><p><strong>1- Calculate the means</strong>:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\bar{x} = \\frac{1}{n} \\sum_{i=1}^{n} x_i\n&quot;,&quot;id&quot;:&quot;NBAAUMWMXF&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\bar{y} = \\frac{1}{n} \\sum_{i=1}^{n} y_i\n&quot;,&quot;id&quot;:&quot;QNVMORCOTB&quot;}" data-component-name="LatexBlockToDOM"></div><p>  </p><p><strong>2- Calculate the slope (&#946;1&#8203;)</strong>:</p><ul><li><p>Compute the numerator:</p></li></ul><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\sum_{i=1}^{n} (x_i - \\bar{x})(y_i - \\bar{y})\n&quot;,&quot;id&quot;:&quot;RMFWRNRNEY&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><ul><li><p>Compute the denominator:</p></li></ul><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\sum_{i=1}^{n} (x_i - \\bar{x})^2\n&quot;,&quot;id&quot;:&quot;ZBPOCCVXFO&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><ul><li><p>Divide the numerator by the denominator to get &#946;1&#8203;:</p></li></ul><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\beta_1 = \\frac{\\sum_{i=1}^{n} (x_i - \\bar{x})(y_i - \\bar{y})}{\\sum_{i=1}^{n} (x_i - \\bar{x})^2}\n&quot;,&quot;id&quot;:&quot;UZOYLHIHOU&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p><strong>3 - Calcualte the intercept (&#946;0&#8203;):</strong></p><ul><li><p>Use the mean values and the slope to find &#946;0&#8203;:</p></li></ul><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\beta_0 = \\bar{y} - \\beta_1 \\bar{x}&quot;,&quot;id&quot;:&quot;OMYSKMRNON&quot;}" data-component-name="LatexBlockToDOM"></div><p> </p></div></div>]]></content:encoded></item><item><title><![CDATA[Transformer architecture and self-attention]]></title><description><![CDATA[A brief overview]]></description><link>https://www.emdeh.com/p/transformer-architecture-and-self</link><guid isPermaLink="false">https://www.emdeh.com/p/transformer-architecture-and-self</guid><dc:creator><![CDATA[emdeh]]></dc:creator><pubDate>Mon, 18 Mar 2024 04:50:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/fd17eaba-9cb8-47e6-9ce1-6eddba474672_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Natural Language Processing (NLP), a transformer architecture is a type of deep learning model that has significantly improved the ability to understand and generate human language. Vaswani et al. introduced transformers in the paper &#8220;Attention is All You Need&#8221; in 2017 and distinguished them by their application of self-attention mechanisms. Self-attention mechanisms enable a model to weigh the importance of different words within a sentence, regardless of their positional distance from each other.</p><p><em><strong>Key Features of Transformers</strong></em></p><ul><li><p><strong>Self-Attention:</strong> allows the model to dynamically focus on different parts of an input as it processes information, enabling it to capture context and relationships between words effectively.</p></li><li><p><strong>Parallel Processing:</strong> Transformers can process entire data sequences in parallel, significantly speeding up training and improving the model&#8217;s ability to handle long sequences. Previous sequence models like RNNs (Recurrent Neural Networks) and LSTMs (Long-Short-Term Memory Networks) could only process data sequentially.</p></li><li><p><strong>Layered Structure:</strong> Transformers comprise multiple layers of self-attention and feed-forward neural networks. A layered structure enables Transformers to learn complex patterns and relationships in the data, which is critical to the depth of their performance on a broad range of NLP tasks.</p></li><li><p><strong>Scalability:</strong> Due to parallel processing and efficient training on large datasets, transformers are highly scalable, making them suitable for cases requiring an understanding of complex and nuanced language.</p></li></ul><p><em><strong>Applications</strong></em></p><p>Many state-of-the-art NLP models, such as BERT (Bidirectional Encoder Representations from Transformers) and GPT (Generative Pretrained Transformer), have a Transformer foundation. These models have set new benchmarks in various NLP tasks, such as text classification, machine translation, question answering, and text generation.</p><p>The transformer model&#8217;s ability to understand context and nuance in text has enabled the development of more sophisticated and interactive AI applications, and it is a cornerstone of modern NLP research.</p><h1>The architecture</h1><p>Transformer architectures have three broad models:</p><ul><li><p>Encoders</p></li><li><p>Decoders, and</p></li><li><p>Encoder-Decoders (Sequence-to-Sequence)</p></li></ul><h2>Encoders</h2><p>Encoders in transformers process input text into a format (vector representations) that captures the essence of the original information.</p><blockquote><p><em><strong>Encoder models are bidirectional.</strong></em></p></blockquote><p>Because encoders consider the context from both before and after a given word within the same layer, they are said to be <strong>bi-directional</strong>. Bi-directional capability contrasts with traditional models that process input in a strict uni-directional sequence (either left-to-right or right-to-left). Thus, it could only incorporate context from one direction at a time in their initial layers.</p><p>Imagine the sentence, <code>The cat sat on the mat.</code> Bidirectionality means that when processing the word <code>sat</code>, the encoder considers the context of <code>The cat</code> (words before <code>sat</code>) and <code>on the mat</code> (words after <code>sat</code>) simultaneously. This allows the encoder to understand that <code>sat</code> is an action performed by <code>the cat</code> and it occurred <code>on the mat</code>, integrating full-sentence context into its representation of <code>sat</code>.</p><p>In contrast, <strong>unidirectional</strong> models, such as decoders (see below), would only consider &#8220;<code>The cat</code> when first encountering <code>sat</code>, meaning it misses the contextual clues provided by <code>on the mat</code> until later layers, or not at all, depending on the model&#8217;s overall architecture.</p><p>Bi-directional processing enables transformers to capture a more nuanced and complete understanding of language, which makes them particularly effective for tasks that require a deep understanding of context, such as sentence classification, sentiment analysis, and named entity recognition.</p><blockquote><p><em><strong>Encoders use self-attention layers to understand relative context.</strong></em></p></blockquote><p>Encoders in transformer models aim to evaluate and understand each part of the input text relative to the entire text. This is achieved by first converting each word or part of the input into a vector representation using embeddings. For each of these vector representations, the model generates three distinct vectors: <em>Query </em><code>(Q)</code>, <em>Key </em><code>(K)</code>, and <em>Value </em><code>(V)</code>. The <code>Q</code>, <code>K</code>, and <code>V</code> vectors are then utilised to calculate attention scores, determining the weight each word&#8217;s representation should assign to every other word&#8217;s representation in the input. This weighting process enables the model to determine how much &#8216;attention&#8217; or importance each part of the input should give to other parts, effectively allowing each word to consider the context provided by the entire input. This mechanism, known as <strong>self-attention</strong>, is pivotal for the model&#8217;s ability to capture and utilise contextual information within the input.</p><p>Encoder-only models are often used in tasks that require understanding the input, like sentence classification or named entity recognition.</p><h2>Decoders</h2><blockquote><p><em><strong>Decoders use a masked self-attention layer.</strong></em></p></blockquote><p>Self-attention in decoders is said to be <strong>masked</strong>. Masking prevents a decoder from &#8216;seeing&#8217; future parts of the sequence during training, ensuring each word prediction is based only on already generated words. In other words, during generating an output sequence, each position can only attend to positions that preceded the current position in the sequence. This constraint is crucial for text generation, where models predict the next word based on the previous ones.</p><p>For example, imagine the decoder is generating the text <code>The quick brown fox.</code> When it&#8217;s predicting the word after <code>The quick,</code> the masked self-attention mechanism allows the decoder to consider <code>The</code> and <code>quick</code> but not <code>brown</code> or <code>fox</code> because those words are in the future relative to the predicted current position. This masking effectively enforces a uni-directional flow of information, ensuring that the model generates each word based solely on preceding words, preserving the natural order of text generation.</p><blockquote><p><em><strong>Because of masked self-attention, decoders are uni-directional.</strong></em></p></blockquote><p>They generate output one element at a time in a forward direction. In decoders, the future context is deliberately obscured to mimic the process of creating language one word at a time, making the decoding process fundamentally uni-directional.</p><p>If decoders were not uni-directional and could instead attend to the entire input sequence indiscriminately (similar to encoders), the integrity of the generated output sequence would be compromised. Specifically, the following issues could arise:</p><ul><li><p><em>Loss of Sequential Generation Logic:</em> Predicting the next word becomes moot if the decoder has access to future words, undermining the process of sequential text generation.</p></li><li><p><em>Incoherent or Circular Outputs:</em> Due to premature knowledge of future context, outputs might repeat or loop without a logical progression.</p></li><li><p><em>Compromised Learning Objective:</em> The model&#8217;s focus shifts from generating text based on learned structures to merely matching patterns, diluting the essence of language generation.</p></li></ul><blockquote><p><em><strong>The generation of each element of the output sequence one at a time is Auto-Regression.</strong></em></p></blockquote><p>Generating each element of the output one at a time, based on the previously generated elements, is known as <strong>Auto-Regression</strong>. The auto-regressive property necessitates the use of masked self-attention in the decoder, as it relies on the premise that each step in the generation process only has access to previous steps.</p><p>In summary, decoders are <em>uni-directional</em> because their <em>self-attention</em> layer is masked. Masking supports the <em>auto-regressive</em> nature of the generation process, ensuring that each step in generating the output can only use information from the steps that have already occurred.</p><p>Decoder-only models are particularly useful for generative tasks like text generation.</p><h2>Encoders-decoders</h2><p>Are also known as <strong>sequence-to-sequence</strong>. These models are good for generative tasks that are based on an input, such as translation or summarisation.</p><h1>Self-Attention Layers</h1><p><strong>Attention layers</strong> refer to any layer within a neural network that applies some form of the <em>attention mechanism</em>. Attention mechanisms allow models to focus on different parts of the input data with varying degrees of emphasis.</p><blockquote><p><em><strong>Self-Attention is one type of attention mechanism.</strong></em></p></blockquote><p>Self-Attention in transformer models enables each position in the input sequence to attend to all positions within the same sequence. Self-Attention enables transformers to process and interpret sequences of input data, such as sentences in natural language processing (NLP) and dynamically weigh the relevance of all parts of the input data against every other part when processing any single part, enabling the incorporation of relatively weighted context from the entire sequence.</p><p>In other words, self-attention allows a model to understand the relationships between words, regardless of their positional distance. Here&#8217;s a more detailed look at how self-attention works:</p><p>For example, imagine the sentence: <code>The cat purrs.</code></p><p><strong>Step 1 - Input representation</strong><br>First, each word in the sentence (<code>The</code>, <code>cat</code>, <code>purrs</code>) is converted into a vector using embeddings. These vectors contain each word&#8217;s initial context.</p><p><strong>Step 2 - Query, Key, and Value Vectors</strong><br>For each word, three vectors are generated from its embedding: a Query vector (<code>Q</code>), a Key vector (<code>K</code>), and a Value vector (<code>V</code>). This is done through linear transformations, which essentially means multiplying the word&#8217;s embedding by different weight matrices for <code>Q</code>, <code>K</code>, and <code>V</code>.</p><p><strong>Step 3 - Calculating attention scores</strong><br>The &#8220;dot product&#8221; of the Query vector for <code>purrs</code> is calculated with the Key vector of every word in the sentence, including itself. Calculating the dot product with the Key vector (<code>K</code>) of every other word produces scores that represent how much attention <code>purrs</code> should pay to each word in the sentence, including <code>The</code> and <code>cat</code>.</p><p><strong>Step 4 - Softmax to Determine Weights</strong><br>These scores are converted into weights that sum to 1 through a mathematical normalisation process (a softmax function). The weights quantify the relevance of each word&#8217;s information to the word <code>purrs</code>.</p><p><strong>Step 5 - Weighted Sum and Output</strong><br>The weights are used to create a weighted sum of the Value vectors, which incorporates information from the entire sentence into the representation of <code>purrs</code>. For instance, the high weight of <code>cat</code> (since it&#8217;s directly related to <code>purrs</code>) ensures that <code>purrs</code> is understood in the context of <code>The cat</code>, reinforcing that it&#8217;s the cat doing the purring.</p><blockquote><p><em><strong>The result is contextual representation.</strong></em></p></blockquote><p>Thanks to the self-attention mechanism, the output vector for &#8220;purrs&#8221; now contains information about the word itself and how it relates to the other words in the sentence.</p><p>This process is repeated for every word, enabling the encoder to understand and represent each word in the context of the entire sentence. Through this mechanism, transformers deeply understand the text, considering the meaning of individual words and their broader context within the sentence.</p><p>So clever.</p><h4>Sources</h4><ul><li><p>Self-Attention is all you need</p></li><li><p>Wikipedia</p></li><li><p>Huggingface.co NLP Course</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Optimising LLM Performance]]></title><description><![CDATA[A discussion on a few techniques to maximise LLM performance.]]></description><link>https://www.emdeh.com/p/optimising-llm-performance</link><guid isPermaLink="false">https://www.emdeh.com/p/optimising-llm-performance</guid><dc:creator><![CDATA[emdeh]]></dc:creator><pubDate>Tue, 05 Mar 2024 21:36:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XcF3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XcF3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XcF3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XcF3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XcF3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!XcF3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88d5fe5b-cc50-4fc9-918f-21c89b041f08_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Contents</h1><ul><li><p><a href="https://emdeh.substack.com/i/145145161/a-framework-for-understanding-optimisation">A framework for understanding optimisation</a></p></li><li><p><a href="https://emdeh.substack.com/i/145145161/using-the-framework-for-maximising-model-performance">Using the framework for maximising model performance</a></p><ul><li><p><a href="https://emdeh.substack.com/i/145145161/start-with-prompt-engineering">Start with prompt engineering</a></p></li><li><p><a href="https://emdeh.substack.com/i/145145161/is-it-a-context-issue">Is it a context issue?</a></p></li><li><p><a href="https://emdeh.substack.com/i/145145161/is-it-an-actions-issue">Is it an actions issue?</a></p></li></ul></li><li><p><a href="https://emdeh.substack.com/i/145145161/useful-resources">Useful resources</a></p></li></ul><h1>A Framework for understanding optimisation</h1><p>The recent developer conference hosted by OpenAI offered a deep dive into enhancing the capabilities of large language models (LLMs). The presenters, John and Colin, shared their insights on optimising LLMs. </p><p>You can watch the video <a href="https://youtu.be/ahnGLM-RC1Y?si=Y-Dfy5CPxGT79ZBQ">here</a> - I encourage you to do so!</p><p>Optimisation of base models can be a critical step on the path to Production. A base model may show promise in a specific application but may lack consistency in a desired behaviour or knowledge to warrant its deployment.</p><p>The optimisation approach will depend on which aspect of the model needs improvement. John and Colin from OpenAI propose two primary dimensions of optimisation. </p><div class="pullquote"><p>Is it the <strong>context</strong> that needs improvement&#8212;that is, what does the model <strong>need to know</strong>? Or is it <strong>the model itself</strong> that requires optimization&#8212;that is, how it <strong>needs to act</strong>?</p></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MMC5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MMC5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 424w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 848w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 1272w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MMC5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png" width="1000" height="633" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:633,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;graphic 1&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="graphic 1" title="graphic 1" srcset="https://substackcdn.com/image/fetch/$s_!MMC5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 424w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 848w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 1272w, https://substackcdn.com/image/fetch/$s_!MMC5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F419f0401-71dd-4da9-8d37-34b87ec65fd6_1000x633.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Graphic adapted from OpenAI&#8217;s presentation</em></p><p>For example, a base-model LLM will fail to generate a report on the most recent market trends because it doesn&#8217;t know them. Why? Because they were never present in its pre-trained knowledge. In cases like this, the model is said to need <em>context optimisation</em>.</p><p>Base models might not consistently follow instructions when the model is required to output particular formats or styles or requires multiple steps or complex reasoning. Some examples of these use cases are generating code from natural language or extracting structured data from unstructured text. In these cases, the <em>model itself requires optimisation</em>.</p><h1>Using the framework for maximising model performance</h1><p>Understanding model optimisation in this framework can help identify whether the issue is a context problem or an action problem. Once this is understood, appropriate techniques can be applied.</p><p>In the case of context optimisation, Retrieval Augmented Generation (RAG) is likely a good start. To optimise the LLM itself, consider fine-tuning.</p><p>Of course, in other cases, a combination of optimising how a model acts and what it knows will be required.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YJJC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YJJC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 424w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 848w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 1272w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YJJC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png" width="1000" height="632" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:632,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;graphic 2&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="graphic 2" title="graphic 2" srcset="https://substackcdn.com/image/fetch/$s_!YJJC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 424w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 848w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 1272w, https://substackcdn.com/image/fetch/$s_!YJJC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63e5de11-f9b5-4a26-936b-fc619819c880_1000x632.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Graphic adapted from OpenAI&#8217;s presentation</em></p><div><hr></div><h1>Start with prompt engineering.</h1><p>In either case, prompt engineering is the best approach to start with, as it offers a quick way to test and learn what dimensions should be optimised and sets a baseline for further improvements.</p><p>This stage is as simple as starting with a prompt. Then, consider adding a few shot examples (for context issues) or employing a few shot learning (for acting issues). If this yields improvements, you&#8217;ll have a good baseline from which to iterate further.</p><h2>What are few-shot examples?</h2><p>Few-shot examples refer to the specific instances or data points that are used in the process of few-shot learning. These are the actual samples from which the model is expected to learn or generalise. In a practical sense, if you were providing a machine learning model with few-shot examples, you would give it a very limited number of examples per class from which it needs to learn.</p><h2>What is few-shot learning?</h2><p>On the other hand, few-shot learning is the broader concept or methodology that involves training a model to accurately make predictions or understand new concepts with only a few examples. Few-shot learning is particularly relevant when the goal is to develop models that can generalise well from limited data&#8212;something that is especially challenging and important when large datasets are not available or when trying to improve model adaptability and efficiency.</p><div><hr></div><h1>Is it a context issue?</h1><p>Prompt engineering alone is unlikely to be sufficient in more complex use cases, and it doesn&#8217;t scale well (remember, we want a Production-grade solution).</p><p>If prompt engineering has revealed a context issue, optimising with RAG is a logical next step. For an overview of RAG, see this article the following article (or <a href="https://youtu.be/ahnGLM-RC1Y?si=QKwCMVozmxdPsBcU&amp;t=712">skip to this part of the video</a>).</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4fdb3dc0-d522-4761-8026-894f069b31af&quot;,&quot;caption&quot;:&quot;Introduction This project leverages a Retrieval Augmented Generation (RAG) implementation to create an intelligent question-answering system for a website. The project automates the collection of contextual data from the site, processes this data with an embeddings model to generate vector representations, and utilises these vectors to provide relevant a&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Using Retrieval Augmented Generation (RAG) for chatbots&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:239691080,&quot;name&quot;:&quot;emdeh&quot;,&quot;bio&quot;:&quot;/&#603;m di&#720; e&#618;t&#643;/&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf076eaf-1630-47e1-b7dd-6b1af2416b65_925x925.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-16T09:21:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://emdeh.substack.com/p/using-retrieval-augmented-generation&quot;,&quot;section_name&quot;:&quot;Artificial Intelligence&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:145121526,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;emdeh&#8217;s Substack&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3ab64a-692c-4b46-903b-f8cbe66d9aba_144x144.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h2>Retrieval Augmented Generation (RAG)</h2><p>RAG is typically good for introducing new information to the model, updating its knowledge, and reducing hallucinations by controlling content. If done correctly, the model will act as if it is explicitly amnesic to everything it was trained on while still retaining its implicit intelligence. In other words, the only knowledge it explicitly has is what has been provided in the RAG implementation.</p><h3>Simple retrieval</h3><p>Adding a simple RAG retrieval will ground the model in the desired context source. Embeddings and cosine similarity algorithms can provide the model with access to a repository from which it can pull data, for example.</p><blockquote><p><em>Cosine similarity algorithms measure the cosine of the angle between two non-zero vectors in a multi-dimensional space, providing a metric for how similar these vectors are.</em></p></blockquote><h3>Other RAG options</h3><p>Other, more advanced RAG options include Hypothetical Document Embeddings(HyDE) (with a fact-checking step). HyDE is essentially a technique where, instead of using the question&#8217;s vector to search for answers with an embedding similarity, a HyDE implementation will employ contrastive methods, generate a &#8220;hypothetical&#8221; answer in response to the prompt, and use that &#8220;made-up&#8221; answer to search for context instead.</p><p>HyDE techniques can be helpful in cases where the model will receive questions that lack specificity or easily identifiable elements, making it difficult to derive an answer from the integrated context source.</p><p>HyDE won&#8217;t always yield good results. For example, if the question is about a topic that the LLM is unfamiliar with - such as some new concept that was not present in the pre-trained knowledge - then it will likely lead to an increase in inaccurate results and hallucinations. The reason is that if it doesn&#8217;t know anything about the topic, the hypothetical answer it created to retrieve context will have no basis in reality&#8230;a hallucination, in other words.</p><p>This is probably why OpenAI presented HyDE in the video with the <em>+ fact-checking step</em>!</p><h3>RAG evaluation</h3><p>It&#8217;s important to remember that adding RAG to a solution creates an entirely new set of challenges. As John points out in the video, LLMs already hallucinate on their own. If the context the model uses to ground its responses is fundamentally or systematically flawed, understanding whether the solution fails because of the RAG integration or an inherently hallucinatory trait within the model will be challenging. For this reason, evaluation frameworks are crucial.</p><p>The video mentions an open-source evaluation framework called <a href="https://github.com/explodinggradients/ragas">Ragas from Exploding Gradients</a>. Ragas measures four metrics: two evaluate how well the model answered the question (Generation), and two measure how relevant the content retrieved is to the question (Retrieval).</p><p>The Generation metrics are:</p><ul><li><p><em>Faithfulness</em> - a measure of how factually accurate the answer is.</p></li><li><p><em>Answer relevancy</em> - how relevant the generated answer is to what was asked.</p></li></ul><p>The Retrieval metrics are:</p><ul><li><p><em>Context precision</em> - The signal-to-noise ratio of retrieved context.</p></li><li><p><em>Context recall</em> - Can it retrieve all the relevant information required to answer the question?</p></li></ul><p>Context precision is particularly useful because providing RAG implementation with more chunks of data potentially containing relevant context doesn&#8217;t always work. John mentions a paper, <em><a href="https://cs.stanford.edu/~nfliu/papers/lost-in-the-middle.arxiv2023.pdf">Lost in the Middle: How Language Models Use Large Contexts</a></em>, which explains that the more content given, the more likely the model is to hallucinate because LLMs tend to &#8220;forget&#8221; the content in the middle of a chunk. Not surprisingly, this is reminiscent of the Serial Position Effect observed in human cognition, which is the tendency to remember the first and last items in a list better than those in the middle. This effect has been well-researched in psychological science and can form part of the basis for various cognitive biases.</p><p>On the other hand, context recall helps to understand the utility of the search mechanism. A common misconception with RAG implementations is that it will always find the proper context. But there is a fundamental constraint to remember: how many tokens can that context window accept. If it were possible to pass the entire context source to the LLM for each prompt, then context recall would never be an issue. But the computing power required for even a modest context source would make this unviable.</p><p>The missing piece to consider is that the prompt is parsed into some search function, and it is the search function that surfaces the (ostensibly) relevant context. It is this surfaced context that the LLM relies on. So, evaluating context recall will help identify if the search process is surfacing up the most relevant context. If not, the search function may need optimising, such as re-ranking or fine-tuning the embeddings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MlhW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MlhW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 424w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 848w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 1272w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MlhW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png" width="1000" height="352" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:352,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;graphic 3&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="graphic 3" title="graphic 3" srcset="https://substackcdn.com/image/fetch/$s_!MlhW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 424w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 848w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 1272w, https://substackcdn.com/image/fetch/$s_!MlhW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe48e5273-cd29-479e-8c27-bab1f1abc195_1000x352.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Graphic adapted from OpenAI&#8217;s presentation</em></p><div><hr></div><h1>Is it an actions issue?</h1><p>If the required optimisation is related to how the model needs to act, then fine-tuning will likely be a good approach. Fine-tuning <em>&#8220;continues the training process on a smaller domain-specific dataset to optimise a model for a specific task&#8221;.</em></p><h2>Fine-tuning</h2><p>Fine-tuning is equivalent to teaching a general knowledge worker a specialised skill. It can drastically improve a model&#8217;s performance on a specific task while also making the fine-tuned model more efficient (on that specific task) than its corresponding base model.</p><p>Fine-tuning is often more effective than prompt engineering or few-shot learning because a much smaller token count inherently constrains these techniques. Only so much data can be put into the context window, whereas in fine-tuning, exposing the model to millions of tokens of specialised data is achieved relatively easily.</p><p>In terms of model efficiency, fine-tuning provides a way to reduce the number of tokens otherwise needed to get the model to perform the specialised task. Often, there is no need to offer in-context examples or explicit schemas, which translates into saved tokens. Sometimes, it can also distil the specialised task into a model smaller than the base one from which it was derived. Again, this ultimately translates into saved resources.</p><p>When fine-tuning, Colin suggests in the video that you start with a simple dataset without complex instructions, formal schemas, or in-context examples. All that is needed are natural language descriptions and the desired structure of the output.</p><h2>Where fine-tuning excels</h2><p>Fine-tuning works well when it emphasises pre-existing knowledge within the model, is used to customise the structure or tone of the desired output, or fine-tunes a highly complex set of instructions. The example given in the video is that of a text-to-SQL task. Base models like GPT-3.5 and GPT-4 already know everything there is to know about SQL, but they might perform poorly if asked about an obscure dialect of SQL. Fine-tuning is equivalent to telling the model to emphasise those aspects of its already present knowledge.</p><h3>Where it won&#8217;t excel</h3><p>Fine-tuning will not work to teach the model something new. And the reason can be thought of as the inverse of why fine-tuning excels in emphasising pre-existing knowledge. Consider the large datasets for some LLMs (like the-entirety-of-the-internet large). These training runs were so extensive that any attempt to use fine-tuning to inject new knowledge would be quickly lost in the pre-existing knowledge. If this is the objective, approaching the problem with RAG will be better.</p><p>Lastly, fine-tuning is a slow, iterative process. Preparing data and training requires a lot of investment, so it isn&#8217;t great for quick iterations.</p><h2>Quality over quantity</h2><p>It&#8217;s worth jumping to <a href="https://youtu.be/ahnGLM-RC1Y?si=mVBDUZtccM9RGH-t&amp;t=1929">this part of the video</a> for a humourous and cautionary tale on quality over quantity. In short, the takeaway from here is to ensure the fine-tuning data accurately represents the desired outcome; start small, confirm movement in the right direction, and then iterate from there.</p><p>And if you think fine-tuning a model on 200,000 of your Slack messages is a good place to start, maybe consider that a little longer.</p><div><hr></div><h2>Useful resources</h2><ul><li><p><a href="https://youtu.be/ahnGLM-RC1Y?si=Y-Dfy5CPxGT79ZBQ">A Survey of Techniques for Maximizing LLM Performance (Original OpenAI video on which this article is based)</a></p></li><li><p><a href="https://cs.stanford.edu/~nfliu/papers/lost-in-the-middle.arxiv2023.pdf">Lost in the Middle: How Language Models Use Large Contexts</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Using Retrieval Augmented Generation (RAG) for chatbots]]></title><description><![CDATA[A simple example of how RAG can be used for a website's chatbot.]]></description><link>https://www.emdeh.com/p/using-retrieval-augmented-generation</link><guid isPermaLink="false">https://www.emdeh.com/p/using-retrieval-augmented-generation</guid><dc:creator><![CDATA[emdeh]]></dc:creator><pubDate>Fri, 16 Feb 2024 09:21:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!D5__!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D5__!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D5__!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!D5__!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!D5__!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!D5__!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D5__!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ebfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D5__!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!D5__!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!D5__!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!D5__!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febfbbb8f-bf34-456f-b098-2edf1a546eb7_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Introduction</h1><p>This project leverages a Retrieval Augmented Generation (RAG) implementation to create an intelligent question-answering system for a website. The project automates the collection of contextual data from the site, processes this data with an embeddings model to generate vector representations, and utilises these vectors to provide relevant answers to user queries through a chatbot using a Language Model (LLM) to craft responses in a conservational tone.</p><p>You can find the code and a detailed overview in the <a href="https://github.com/emdeh/web-crawl-qna-blog-bot">Github repository</a>.</p><h2>Contents</h2><ul><li><p><a href="https://emdeh.substack.com/i/145121526/what-is-retrieval-augmented-generation-rag">What is RAG</a></p></li><li><p><a href="https://emdeh.substack.com/i/145121526/what-are-embeddings">Embeddings</a></p></li><li><p><a href="https://emdeh.substack.com/i/145121526/overview-of-a-rag-implementation">Implementation overview</a></p></li><li><p><a href="https://emdeh.substack.com/i/145121526/code-overview">Code overview</a></p></li></ul><div><hr></div><h1>What is Retrieval Augmented Generation (RAG)</h1><p>Retrieval Augmented Generation (RAG) is a sophisticated approach that enhances the capabilities of generative models, particularly Large Language Models (LLMs), by integrating an additional information retrieval step into the response generation process. This method involves dynamically sourcing relevant external information to augment the input provided to the generative model, thereby enriching its responses with details and insights not contained within its pre-trained knowledge base. Embeddings and vector representations typically facilitate the retrieval of additional information to identify content contextually similar to the user&#8217;s prompt.</p><h1>What are Embeddings</h1><p>Embeddings are a form of representation learning where words, sentences, or even entire documents are converted into real-valued vectors in a high-dimensional space. This process aims to capture the semantic meanings, relationships, and context of words or phrases, allowing machines to process natural language data more effectively. The vectors in the high-dimensional space represent the nuanced characteristics of the text, such as syntax, semantics, and usage patterns, in a form that can be quantitatively analysed. Each dimension could correspond to a latent feature that captures different aspects of the text&#8217;s meaning, not directly interpretable by humans but discernible through computational methods. By mapping textual information to a geometric space, embeddings enable the measurement of conceptual similarity between pieces of text based on their positions and distances within this space, facilitating tasks like search, classification, and contextual understanding in natural language processing applications. In the context of Retrieval-Augmented Generation (RAG), embeddings represent the queries (prompts) and the potential knowledge sources in a format that a computer can understand and compare.</p><h2>Vector Representations</h2><p>Vector representations are the outcome of converting text into embeddings, representing text as points or vectors in a multi-dimensional space. As described above, each dimension corresponds to a feature of the text, capturing various aspects of its meaning, context, or syntactical properties. Comparing vector representations involves calculating the similarity (often using cosine similarity or other metrics) between vectors to identify how closely related two pieces of text are. In RAG implementations that use embeddings, the vector representation of a user&#8217;s prompt is compared to the vector representations of various knowledge sources to identify the most relevant context. This relevant context is then retrieved and used to augment the response generated by a language model, enhancing the LLM&#8217;s ability to provide accurate and contextually enriched answers.</p><div class="pullquote"><p><strong>Credits<br></strong>This project was initially inspired by OpenAI&#8217;s Web Q&amp;A with Embeddings tutorial. Learn how to crawl your website and build a Q&amp;A bot with the OpenAI API. The full tutorial is available in the <a href="https://platform.openai.com/docs/tutorials/web-qa-embeddings">OpenAI documentation</a>.</p></div><h1>Overview of a RAG implementation</h1><p>The diagram below briefly outlines how a Retrieval-Augmented Generation (RAG) architecture leverages embeddings. In short, additional context is retrieved by comparing the prompt's vectors to the knowledge source's vectors. The related textual data is then appended to the prompt to <em>augment</em> the response <em>generated</em> by the LLM.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OhV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OhV6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 424w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 848w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 1272w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OhV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png" width="1245" height="641" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:641,&quot;width&quot;:1245,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;diagram&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="diagram" title="diagram" srcset="https://substackcdn.com/image/fetch/$s_!OhV6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 424w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 848w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 1272w, https://substackcdn.com/image/fetch/$s_!OhV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118fa27-3536-4a8a-b349-d8b8404f8ccb_1245x641.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Example implementation</h1><p><strong>Point 1:</strong> In the case of this particular implementation, the knowledge source is a blog. The knowledge is obtained by first extracting all the hyperlinks on the site and discarding any that point to other domains. Each unique hyperlink is then visited, and the content is extracted into text files. The text files are then used to create a data frame. Each row in the data frame is tokenised to facilitate analysing the length of documents, which is relevant for understanding the data&#8217;s distribution and optimising model input sizes.</p><p><strong>Point 2:</strong> After more processing to create smaller chunks (if required), the embeddings are generated and saved. In this case, to a <code>.csv</code> file.</p><pre><code><code>&lt;SNIP&gt;
https://emdeh.com/repositories
https://emdeh.com/news/announcement_7
https://emdeh.com/blog/2024/codify-walkthrough
Embeddings generated and saved to 'data/embeddings.csv'.
Preprocessing complete. Embeddings are ready.

# You can see the blog's links being iterated here.
</code></code></pre><p><strong>Points 3 - 5:</strong> When a user provides the prompt to the service, the embedding model will generate its vector representation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r9Pf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r9Pf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 424w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 848w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 1272w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r9Pf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png" width="1054" height="495" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/908195a6-5643-4dc4-b957-9888fe274527_1054x495.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:495,&quot;width&quot;:1054,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image of prompt&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image of prompt" title="image of prompt" srcset="https://substackcdn.com/image/fetch/$s_!r9Pf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 424w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 848w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 1272w, https://substackcdn.com/image/fetch/$s_!r9Pf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F908195a6-5643-4dc4-b957-9888fe274527_1054x495.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Point 6:</strong> The service then compares the prompt&#8217;s vector to the Vector DB (in this case, the <code>.csv</code> file containing the blog&#8217;s vector representations is loaded into another data frame).</p><blockquote><p><em>The comparision is done using Cosine function to calculate the distance between the question&#8217;s embedding and each row&#8217;s embedding in the data frame. Cosine distances is a measure used to determine the similarity between two vectors, with lower values indicating higher similarity.</em></p></blockquote><p>The service will then iterate over the data frame to accumulate the most similar text until it reaches a pre-defined token limit. This then forms the context for the original prompt.</p><p><strong>Points 7 - 9:</strong> The context and original prompt are now passed to the GPT model, which returns a generative completion. The end-user is presented with this completion.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!72y2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!72y2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 424w, https://substackcdn.com/image/fetch/$s_!72y2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 848w, https://substackcdn.com/image/fetch/$s_!72y2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 1272w, https://substackcdn.com/image/fetch/$s_!72y2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!72y2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png" width="1047" height="482" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:1047,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image of completion&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image of completion" title="image of completion" srcset="https://substackcdn.com/image/fetch/$s_!72y2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 424w, https://substackcdn.com/image/fetch/$s_!72y2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 848w, https://substackcdn.com/image/fetch/$s_!72y2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 1272w, https://substackcdn.com/image/fetch/$s_!72y2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964c150f-1eff-4172-a524-3a6f92e40507_1047x482.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1>Code overview</h1><h2>Data Collection and Preparation</h2><p><code>preprocess.py</code> crawls web pages within a specified domain and systematically navigates through the website, extracting text from each page it encounters. The collected text undergoes initial preprocessing to clean and organise the data, making it suitable for further analysis.</p><p>The script then employs OpenAI&#8217;s API to generate embeddings for each piece of text. These embeddings capture the semantic essence of the text in a high-dimensional space, facilitating the identification of contextual similarities between different texts. The processed data and its embeddings are saved for subsequent use, laying the groundwork for the system&#8217;s question-answering capabilities.</p><h2>Flask Application for Question Answering</h2><p>With the data prepared, <code>app.py</code> serves as the interface between the user and the system&#8217;s NLP engine. This script initiates a Flask web application, providing endpoints for users to submit their questions.</p><p>Upon receiving a query, the application leverages the previously generated embeddings to find the most relevant context within the collected data. It then formulates this context and the user&#8217;s question as input for an OpenAI GPT model. The model, trained on vast amounts of text from the internet, generates an answer that reflects the specific information in the crawled data and its understanding of the topic at large. The answer is then returned to the user through the web interface, completing the cycle of query and response.</p><h2>Integration and Workflow</h2><p>Integrating <code>preprocess.py</code> and <code>app.py</code> creates a workflow that bridges web crawling and NLP-driven question-answering. Initially, <code>preprocess.py</code> lays the foundation by collecting and preparing the data, which <code>app.py</code> subsequently utilises to offer real-time answers. This allows the system to provide contextually relevant answers informed by the specific context. Users interact with the system through a straightforward web interface, making complex NLP capabilities accessible to anyone with a question to ask.</p><h2>Use-cases</h2><p>Together, these scripts leverage sophisticated machine learning capabilities to demonstrate how existing website data can be harnessed to build robust and interactive AI-driven ways to retrieve and discover knowledge.</p><p>For example, the basic capabilities demonstrated in this project could be applied to create a contextually-aware chatbot on a website.</p>]]></content:encoded></item></channel></rss>