{
  "source_file": "0930",
  "source_platform": "Hashnode",
  "author": "Tharun",
  "title_listed": "Multiple Linear Regression: When One Input Isn't Enough",
  "keywords": "",
  "domain": "机器学习",
  "content_type": "深度技术解析",
  "is_paid_flag": "否",
  "url": "https://tharunpandya.hashnode.dev/multiple-linear-regression-when-one-input-isn-t-enough",
  "publish_date": "2026-08-16",
  "corpus_stage": "",
  "notes": "",
  "id": "6e54559a951a",
  "collected_at": "2026-10-02T14:10:44",
  "title": "Multiple Linear Regression: When One Input Isn't Enough",
  "body_markdown": "Multiple Linear Regression: When One Input Isn't Enough\nUpdated\nAugust 16, 2026\n•\n9\nmin read\n•\nView as Markdown\nT\nTharun\nPicture two different orders. Both are exactly 3 kilometers away from the restaurant. One arrives in 18 minutes. The other takes 35 minutes.\nIf distance is the only thing our model looks at, it has no way to explain this. Both orders had the same distance, yet the actual times were nowhere close to each other. Something else must be affecting the delivery time, something our model from the last few posts never even considered.\nMaybe one order had 8 items in it, and the kitchen took longer to pack it all. Maybe the other order was placed during the evening rush, when every rider on the road is already carrying three deliveries at once. Distance alone was never going to capture any of this.\nThis post is about teaching our model to look at more than one thing at a time.\nNaming Our Inputs Properly\nSo far, we've only had one input, distance, and we called it x. Once we start using more than one input, calling everything x gets confusing fast. So we give each input a small number instead.\nLet's say we're now using three inputs to predict delivery time:\nx1 = distance in kilometers\nx2 = number of items in the order\nx3 = whether the order was placed during peak hours, written as 1 for yes and 0 for no\nEach past order in our dataset now has three numbers attached to it, not one. And just like before, each input needs its own weight, telling us how much that particular input matters:\nw1 = how much each kilometer of distance adds to the delivery time\nw2 = how much each extra item adds to the delivery time\nw3 = how much peak hours adds to the delivery time\nThe prediction formula extends very naturally from what we already know:\nprediction = w1 × x1 + w2 × x2 + w3 × x3 + b\nThis is exactly the same idea as w × x + b from our very first post, just with more terms added on. Multiply each input by its own weight, add them all together, then add the baseline b at the end.\nWriting This More Compactly, With a Dot Product\nAs the number of inputs grows, writing out w1 × x1 + w2 × x2 + w3 × x3 by hand every time gets tedious, especially once a real model has dozens or hundreds of inputs instead of three. So there's a shorter way to write this same operation, called a dot product.\nImagine you have two lists of numbers of the same length. A dot product simply means multiplying the numbers in matching positions, then adding up all those results into one single number. If w is the list of weights and x is the list of inputs, the dot product of w and x is written as w · x, and it means exactly what we did above: w1 × x1 + w2 × x2 + w3 × x3.\nSo our formula can now be written as:\nprediction = w · x + b\nNothing about the math has changed. This is purely a shorter way of writing the same sum, and it's the notation you'll see used almost everywhere once a model has more than a couple of inputs.\nWorking Through an Example, By Hand\nLet's build a small table using our three inputs.\nDistance (x1)\nItems (x2)\nPeak Hours (x3)\nActual Time (min)\n1\n2\n0\n16\n2\n1\n1\n29\n3\n3\n0\n28\n2\n4\n1\n35\n4\n2\n0\n31\nUnlike the earlier posts in this series, I'm not going to hand you a ready-made w1, w2, w3, and b this time and ask you to trust that they fit. That's a fair thing to be suspicious of, numbers that just appear from nowhere are exactly the kind of thing that should raise a question. So instead, let's actually find them the same way we found w and b for a single input a few posts ago, using gradient descent, just extended to handle three weights instead of one.\nExtending Gradient Descent to Multiple Weights\nThe good news here is that we don't need to relearn anything about how gradient descent works. We already know the idea from a couple of posts ago. Start with a bad guess, measure how wrong it is, take a small step against the slope, repeat. None of that changes.\nWhat changes is that instead of adjusting one w, we now adjust three of them, w1, w2, and w3, all at the same time, alongside b. Each weight gets nudged based on how much it personally contributed to the error, using the exact same update rule as before, just applied once per weight:\nnew w1 = old w1 - (learning rate times the slope of the cost with respect to w1)\nnew w2 = old w2 - (learning rate times the slope of the cost with respect to w2)\nnew w3 = old w3 - (learning rate times the slope of the cost with respect to w3)\nnew b = old b - (learning rate times the slope of the cost with respect to b)\nAnd the slope for each weight is calculated the same way it always was, the average of each error multiplied by that weight's own input. The only real difference from before is that we now do this once per input instead of just once.\nTurning This Into Code\nLet's write a predict function first, using the dot product idea from earlier in this post.\nimport numpy as np\n\ndef predict(X, w, b):\n    return X.dot(w) + b\nX.dot(w)\ncomputes the dot product for every row of X at once, exactly like\nnp.dot(w, x)\ndid for a single order, just applied to the whole table in one line.\nNow let's write gradient descent, extended to work with a whole vector of weights instead of just one number.\ndef gradient_descent(X, y, w, b, learning_rate, iterations):\n    m = len(y)\n\n    for _ in range(iterations):\n        predictions = X.dot(w) + b\n        errors = predictions - y\n\n        gradient_w = X.T.dot(errors) / m\n        gradient_b = np.sum(errors) / m\n\n        w = w - learning_rate * gradient_w\n        b = b - learning_rate * gradient_b\n\n    return w, b\nThe one new piece of code here is\nX.T.dot(errors)\n. Here's what it's actually doing, in plain words. For every input column, distance, items, and peak hours, it multiplies each row's error by that row's value for that particular column, then adds all of those up. That is exactly the same calculation we did by hand for a single weight in the gradient descent post, just done for all three weights simultaneously, using matrix multiplication instead of three separate loops.\nLet's run this on our table and see what it actually finds.\nX = np.array([\n    [1, 2, 0],\n    [2, 1, 1],\n    [3, 3, 0],\n    [2, 4, 1],\n    [4, 2, 0],\n])\n\nactual_times = np.array([16, 29, 28, 35, 31])\n\nw = np.zeros(3)\nb = 0.0\n\nfinal_w, final_b = gradient_descent(X, actual_times, w, b, learning_rate=0.05, iterations=10000)\n\nprint(\"Final weights:\", final_w)\nprint(\"Final bias:\", final_b)\n\n# Final weights: [ 5.  2. 10.]\n# Final bias: 7.0\nNobody handed the model those numbers. It started at all zeros, completely blind, and found w1 = 5, w2 = 2, w3 = 10, and b = 7 entirely on its own, using nothing but the table and the same downhill walking idea from before. Here's what that walk actually looked like, checked at a few points along the way:\nIterations\nw1\nw2\nw3\nb\n1\n3.52\n3.47\n0.64\n1.39\n10\n5.23\n4.73\n1.92\n2.37\n100\n5.32\n2.96\n7.74\n4.55\n1000\n5.02\n2.01\n10.03\n6.91\n10000\n5.00\n2.00\n10.00\n7.00\nNotice something interesting here. Early on, the weights are genuinely wrong, w3 in particular starts far too small compared to where it ends up. But with enough steps, every single weight settles exactly where it needs to be, without us ever telling the model which input mattered most.\nNow let's check this against the table by hand, the same way we did in earlier posts, using the fourth row, where the order had more items and was placed during peak hours:\nprediction = w1 × x1 + w2 × x2 + w3 × x3 + b \nprediction = 5 × 2 + 2 × 4 + 10 × 1 + 7 \nprediction = 10 + 8 + 10 + 7 \nprediction = 35\nThat matches the actual value in the table. Notice how much of the delivery time in that row came from peak hours alone, 10 full minutes, more than double what the distance itself contributed. This is exactly the kind of pattern a single-input model could never capture, since it never even had access to whether the order was placed during peak hours in the first place.\nOne Thing Worth Noticing Before We Move On\nLook closely at our three inputs again. Distance ranges from 1 to 4. Items range from 1 to 4 too. Peak hours only ever takes the value 0 or 1. These three inputs happen to sit on fairly similar scales, which is part of why gradient descent settled into the correct answer smoothly, without much fuss.\nNow imagine we added a fourth input, say the price of the order in rupees. That number could easily sit in the hundreds, while peak hours is still stuck at 0 or 1. When your inputs sit on wildly different scales like this, gradient descent starts behaving strangely, taking tiny steps in some directions and huge, unstable steps in others, even though we're using a single learning rate for all of them. Fixing that mismatch is called feature scaling, and that's exactly what the next post is about.\nThe full notebook for this post is up on GitHub here:\nhttps://github.com/tharun-pandya/Machine-Learning-Blog-Series/blob/main/Multi_Linear_Regression.ipynb\nSee you in the next one.\n#\nmachine-learning\n#\nai\n#\nlinearregression\n#\ngradient-descent\n#\npython\n#\nnumpy\n#\nmathematics\n9\nviews",
  "metadata": {
    "title": "Multiple Linear Regression: When One Input Isn't Enough",
    "description": "Picture two different orders. Both are exactly 3 kilometers away from the restaurant. One arrives in 18 minutes. The other takes 35 minutes.\nIf distance is the only thing our model looks at, it has no",
    "keywords": null,
    "author": null,
    "og:title": "Multiple Linear Regression: When One Input Isn't Enough",
    "og:description": "Picture two different orders. Both are exactly 3 kilometers away from the restaurant. One arrives in 18 minutes. The other takes 35 minutes.\nIf distance is the only thing our model looks at, it has no",
    "og:url": "https://tharunpandya.hashnode.dev/multiple-linear-regression-when-one-input-isn-t-enough",
    "og:site_name": "Machine Learing From scratch",
    "og:image": "https://cdn.hashnode.com/uploads/og-images/6a3f9a25a837e83b51cc8712/21e30ef9-1f94-4f7c-86bd-2f3d85e4c724.png",
    "og:image:width": "1200",
    "og:image:height": "630",
    "og:type": "article",
    "twitter:card": "summary_large_image",
    "twitter:title": "Multiple Linear Regression: When One Input Isn't Enough",
    "twitter:description": "Picture two different orders. Both are exactly 3 kilometers away from the restaurant. One arrives in 18 minutes. The other takes 35 minutes.\nIf distance is the only thing our model looks at, it has no",
    "twitter:image": "https://cdn.hashnode.com/uploads/og-images/6a3f9a25a837e83b51cc8712/21e30ef9-1f94-4f7c-86bd-2f3d85e4c724.png",
    "article:published_time": "2026-08-16T16:08:13.745Z",
    "article:modified_time": "2026-08-16T16:08:13.745Z",
    "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/6e54559a951a/code/body-000.txt",
      "chars": 45,
      "language": "text"
    },
    {
      "file": "attachments/6e54559a951a/code/body-001.txt",
      "chars": 23,
      "language": "text"
    },
    {
      "file": "attachments/6e54559a951a/code/body-002.txt",
      "chars": 66,
      "language": "text"
    },
    {
      "file": "attachments/6e54559a951a/code/body-003.txt",
      "chars": 363,
      "language": "text"
    },
    {
      "file": "attachments/6e54559a951a/code/body-004.txt",
      "chars": 377,
      "language": "text"
    },
    {
      "file": "attachments/6e54559a951a/code/body-005.txt",
      "chars": 133,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/7f995921-2762-44df-b20e-f70b90f3c2e3.png",
      "bytes": 1665460,
      "reused": true,
      "local_path": "attachments/6e54559a951a/images/002.png",
      "src": "https://cdn.hashnode.com/uploads/covers/6a3f9a25a837e83b51cc8712/7f995921-2762-44df-b20e-f70b90f3c2e3.png",
      "alt": "Multiple Linear Regression: When One Input Isn't Enough",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://tharunpandya.hashnode.dev/multiple-linear-regression-when-one-input-isn-t-enough.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/Multi_Linear_Regression.ipynb",
      "label": "https://github.com/tharun-pandya/Machine-Learning-Blog-Series/blob/main/Multi_Linear_Regression.ipynb",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/machine-learning",
      "label": "# machine-learning",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/ai",
      "label": "# ai",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/linearregression",
      "label": "# linearregression",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/gradient-descent",
      "label": "# gradient-descent",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/python",
      "label": "# python",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/numpy",
      "label": "# numpy",
      "type": "a"
    },
    {
      "href": "https://tharunpandya.hashnode.dev/tag/mathematics",
      "label": "# mathematics",
      "type": "a"
    }
  ],
  "retry_at": "2026-10-03T08:04:48",
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:50:28Z",
  "source_url": "https://tharunpandya.hashnode.dev/multiple-linear-regression-when-one-input-isn-t-enough",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 9003,
  "expected_body_images": 1,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/6e54559a951a/pages/source.html",
  "local_html": "attachments/6e54559a951a/pages/article.html",
  "body_base_path": "attachments/6e54559a951a/pages/",
  "body_markdown_path": "attachments/6e54559a951a/pages/article.md"
}