{
  "source_file": "0930",
  "source_platform": "Hashnode",
  "author": "Tharun",
  "title_listed": "Linear Regression: Fitting a Line Through Chaos ",
  "keywords": "",
  "domain": "机器学习",
  "content_type": "深度技术解析",
  "is_paid_flag": "否",
  "url": "https://tharunpandya.hashnode.dev/linear-regression-fitting-a-line-through-chaos",
  "publish_date": "2026-08-11",
  "corpus_stage": "",
  "notes": "",
  "id": "c50472126eeb",
  "collected_at": "2026-10-02T14:10:45",
  "title": "Linear Regression Explained: Fitting a Line Through Chaos",
  "body_markdown": "Linear Regression: Fitting a Line Through Chaos\nUpdated\nAugust 11, 2026\n•\n10\nmin read\n•\nView as Markdown\nT\nTharun\nA few days ago, I ordered food from an app, and right after placing the order, it showed: \"Arriving in 32 minutes.\" The delivery boy hadn't even picked up the order yet. He hadn't even started riding. But the app was already confident enough to give me an exact number.\nThat number wasn't pulled out of thin air. Somewhere behind that app, there's a model doing exactly what we talked about in the last post, looking at some inputs, and predicting an output. In this post, we're going to build the simplest possible version of that idea ourselves, with real numbers and a little bit of actual code.\nThe Simplest Possible Guessing Machine\nLet's stick with the delivery example, but simplify it down to just one input: distance.\nIf you had to guess how long a delivery takes, using only the distance in kilometers, what would your guess depend on? Probably two things. First, how far the food has to travel, more distance should mean more time. Second, some baseline time that exists no matter what, the time it takes to pack the order, hand it to the rider, and get the bike moving, even before a single kilometer is covered.\nLinear regression uses a formula to capture this:\nprediction = w × x + b\nHere's what each piece actually means, in plain terms:\nx is the input we already know. In our case, the distance in kilometers.\nw is called the weight. It tells us how much the prediction changes for every extra kilometer. If w is 5, every additional kilometer adds 5 minutes to the prediction. If you've seen the equation of a line before, this is just the slope.\nb is called the bias. It's the starting point, roughly, the time we'd predict at zero distance. Packing the order, handing it over, getting the bike out of the parking area, all of that lives inside b. In line terms, this is the intercept.\nWeight and bias, slope and intercept, same idea, different vocabulary depending on which room you're standing in. ML people say weight and bias. Math people say slope and intercept. Worth filing away, because you'll run into both.\nSo the formula is really just saying: start with a base time (b), then add a little more time for every kilometer of distance (w × x).\nOne clarification before we go further: this equation,\nw × x + b\n, is the model. It's the shape of the guess. Linear regression itself is the process of figuring out which w and b make that shape actually fit your data well. We haven't done that part yet. Right now we're just going to eyeball it.\nLet's Actually Look at Some Numbers\nSuppose we look at five past orders and their actual delivery times:\nDistance (km)\t    Actual Delivery Time (min)\n    1\t                      13\n    2\t                      16\n    3\t                      23\n    4\t                      26\n    5                         34\nLook at this table for a second before reading further. Notice anything?\nIt's roughly a straight line, but not exactly. Going from 1km to 2km only adds 3 minutes. Going from 2km to 3km adds 7. It's not a clean staircase. If you squint, though, the overall trend still climbs at something like 5 minutes per kilometer, with a starting point somewhere around 7 or 8 minutes.\nThis is actually closer to how real data behaves. Nothing about delivery times is going to line up perfectly: traffic, how busy the kitchen was, whether the rider hit every light red. That variation is what's usually called noise: the bumps in the data that don't come from distance at all, but from everything else going on around it. There's no single line that touches all five points exactly. What we're really looking for is a line that gets close to all of them, even if it doesn't nail any single one.\nHere's a scatter of those five points, with a rough straight line drawn through them:\nThe line doesn't pass through every point, and that's fine; it's not supposed to. It's just supposed to capture the trend.\nSo let's put a number on that trend. Looking at the table, the slope looks like it's somewhere around 5 minutes per kilometer, and the line looks like it would cross zero distance somewhere around 7 or 8 minutes. Nothing rigorous, just eyeballing it. Let's go with w = 5, b = 7 as a rough first guess and see how it holds up. Could a different pair of numbers fit these five points slightly better? Probably. That question, how do you find the best w and b, not just a decent one, is exactly what we're building toward.\nLet's check how our guess does for a distance of 3 km:\nprediction = w × x + b \nprediction = 5 × 3 + 7 \nprediction = 15 + 7 \nprediction = 22 minutes\nThe actual value in the table was 23. Close, but not a match. That one minute gap is the model being wrong by a little, and that's fine. It's actually the whole point: we're not looking for a formula that memorizes the table, we're looking for one that captures the general pattern well enough to be useful.\nWe can even write that gap down as a number:\nerror = prediction - actual\nerror = 22 - 23\nerror = -1 minute\nWe were off by one minute on this one. Nothing more to do with that number yet; just notice that every row in the table would give us a slightly different error, and we're going to need a way to turn all five of those into a single verdict on how good our line is. Hold that thought.\nNow here's the real test, what would this formula predict for a distance it has never seen before, say 6 km?\nprediction = 5 × 6 + 7\nprediction = 30 + 7\nprediction = 37 minutes\nNobody told the formula the answer for 6 km. We reused the same w and b we roughly guessed from the pattern, and it gave us an estimate based on that pattern. Whether 37 minutes is actually a good estimate isn't something we can say yet, we don't have a real 6 km order to check it against, and right now we don't even have a solid way to measure \"good.\" That's the idea we're building toward: a trained model shouldn't memorize the table, it should capture the pattern behind the data and reuse that pattern on new inputs. We're not there yet. We just picked numbers that looked about right.\nQuick side note on b: don't read too much into \"7 minutes at 0 km\" as a literal real-world fact. A delivery of zero distance isn't really a thing that happens. b is just where the line crosses the y-axis mathematically, a baseline the model implies, not a guarantee that any real order takes exactly 7 minutes.\nNow Let's Turn This Into Code\nWe just picked w and b by looking at a small table and estimating. That won't work on a real dataset with thousands of noisy orders, we'll fix that in the next two posts. But to be clear about what we actually did here: we chose w and b ourselves. Nothing was trained. The model didn't learn anything yet, we handed it the answer. Actually training it, so it finds w and b on its own, is what the next two posts are about.\nFor now, let's take the w and b we picked, and write actual code that does the same math.\nHere's the plain, no-shortcuts version first:\ndef predict(x, w, b):\n    return w * x + b\n\n# the values we picked by eye\nw = 5\nb = 7\n\n# a list of distances we want predictions for\ndistances = [1, 2, 3, 4, 5, 6]\n\n# predicting one by one, using a normal loop\npredictions = []\nfor x in distances:\n    predictions.append(predict(x, w, b))\n\nprint(predictions)\n# [12, 17, 22, 27, 32, 37]\nThere's nothing hidden inside\npredict()\n. It's literally the equation we just wrote out by hand, typed into Python.\nThis works fine, and honestly, for six numbers, a loop is perfectly readable. But real datasets don't have six rows, they have thousands or even millions. Running a Python loop over a million rows, one at a time, adds up. This is where a library called NumPy comes in, it lets us do the exact same calculation on an entire list of numbers at once, without writing a loop ourselves.\nimport numpy as np\n\ndistances = np.array([1, 2, 3, 4, 5, 6])\nw = 5\nb = 7\n\npredictions = w * distances + b\n\nprint(predictions)\n# [12 17 22 27 32 37]\nSame formula, same result. NumPy just lets us apply the operation to the whole array at once instead of looping through it ourselves; this is called vectorization, and it starts to matter once \"six numbers\" turns into a real dataset. We'll lean on this style for the rest of the series, so it's worth getting comfortable with it early.\nWhat We Built\nQuick recap before we move on:\nA linear model:\ny = wx + b w\ncontrols how much the prediction changes as x increases, the slope\nb is the baseline/intercept, the value the line implies at x = 0\nWe used the model to predict a distance it had never seen (6 km)\nWe picked w and b ourselves, by eye, nothing was actually trained\nThe model didn't perfectly match the data, and that's expected, not a bug\nThe Question We're Leaving Open\nWe cheated a bit in this post. We only landed on w = 5 and b = 7 because we stared at a small table and made a reasonable guess. It got close, not exact. Real data is messier than five rows, and no amount of staring at a spreadsheet is going to hand you the right w and b when you've got thousands of them.\nSo how does a machine find the right w and b on its own, without a human eyeballing anything?\nThat's exactly what the next two posts are about. First, we need a way to measure exactly how wrong a given w and b are, that's called the cost function. Then, we need a way for the machine to use that measurement to automatically improve its guess, step by step, that's gradient descent. Put those two together, and you've got the core mechanism a machine uses to find its own w and b, on data far messier than our little table.\nThe full code from this post, along with the dataset, is up on GitHub here:\nhttps://github.com/tharun-pandya/Machine-Learning-Blog-Series/blob/main/Linear_Regression.ipynb\nSee you in the next one.\n#\nlinear-regression\n#\nmachine-learning\n#\nnumpy\n#\nfood-delivery-app\n#\nartificial-intelligence\n#\npython\n16\nviews",
  "metadata": {
    "title": "Linear Regression Explained: Fitting a Line Through Chaos",
    "description": "Learn linear regression from scratch using a real delivery-time example, Python, and NumPy. Understand weights, bias, predictions, and errors.",
    "keywords": null,
    "author": null,
    "og:title": "Linear Regression Explained: Fitting a Line Through Chaos",
    "og:description": "Learn linear regression from scratch using a real delivery-time example, Python, and NumPy. Understand weights, bias, predictions, and errors.",
    "og:url": "https://tharunpandya.hashnode.dev/linear-regression-fitting-a-line-through-chaos",
    "og:site_name": "Machine Learing From scratch",
    "og:image": "https://cdn.hashnode.com/uploads/og-images/6a3f9a25a837e83b51cc8712/17c68eae-b606-49aa-8b34-00d8eeb5ce8f.png",
    "og:image:width": "1200",
    "og:image:height": "630",
    "og:type": "article",
    "twitter:card": "summary_large_image",
    "twitter:title": "Linear Regression Explained: Fitting a Line Through Chaos",
    "twitter:description": "Learn linear regression from scratch using a real delivery-time example, Python, and NumPy. Understand weights, bias, predictions, and errors.",
    "twitter:image": "https://cdn.hashnode.com/uploads/og-images/6a3f9a25a837e83b51cc8712/17c68eae-b606-49aa-8b34-00d8eeb5ce8f.png",
    "article:published_time": "2026-08-11T13:53:10.440Z",
    "article:modified_time": "2026-08-11T13:54:14.761Z",
    "article:author": "https://tharunpandya.hashnode.dev/@tharun-pandya"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/c50472126eeb/code/body-000.txt",
      "chars": 23,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-001.txt",
      "chars": 202,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-002.txt",
      "chars": 93,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-003.txt",
      "chars": 62,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-004.txt",
      "chars": 67,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-005.txt",
      "chars": 335,
      "language": "text"
    },
    {
      "file": "attachments/c50472126eeb/code/body-006.txt",
      "chars": 148,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/d30b815a-c1e2-4796-84de-7dfedfddcea3.png",
      "bytes": 1675109,
      "reused": true,
      "local_path": "attachments/c50472126eeb/images/002.png",
      "src": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/d30b815a-c1e2-4796-84de-7dfedfddcea3.png",
      "alt": "Linear Regression: Fitting a Line Through Chaos ",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/5b6ea2b5-ce31-4f13-92ad-7b5d156c00e7.png",
      "bytes": 51757,
      "reused": true,
      "local_path": "attachments/c50472126eeb/images/003.png",
      "src": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/5b6ea2b5-ce31-4f13-92ad-7b5d156c00e7.png",
      "alt": "",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://tharunpandya.hashnode.dev/linear-regression-fitting-a-line-through-chaos.md",
      "label": "View as Markdown",
      "type": "a"
    },
    {
      "href": "https://hashnode.com/@tharun-pandya",
      "label": "T",
      "type": "a"
    },
    {
      "href": "https://linkedin.com/in/tharun-pandya-kodi",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://github.com/tharun-pandya/Machine-Learning-Blog-Series/blob/main/Linear_Regression.ipynb",
      "label": "https://github.com/tharun-pandya/Machine-Learning-Blog-Series/blob/main/Linear_Regression.ipynb",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/linear-regression",
      "label": "# linear-regression",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/machine-learning",
      "label": "# machine-learning",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/numpy",
      "label": "# numpy",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/food-delivery-app",
      "label": "# food-delivery-app",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/artificial-intelligence",
      "label": "# artificial-intelligence",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/python",
      "label": "# python",
      "type": "a"
    }
  ],
  "retry_at": "2026-10-03T08:04:56",
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:50:29Z",
  "source_url": "https://tharunpandya.hashnode.dev/linear-regression-fitting-a-line-through-chaos",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 9913,
  "expected_body_images": 2,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/c50472126eeb/pages/source.html",
  "local_html": "attachments/c50472126eeb/pages/article.html",
  "body_base_path": "attachments/c50472126eeb/pages/",
  "body_markdown_path": "attachments/c50472126eeb/pages/article.md"
}