{
  "source_file": "0930",
  "source_platform": "Medium",
  "author": "James Andrew Godwin",
  "title_listed": "Multivariant Linear Regression",
  "keywords": "",
  "domain": "机器学习",
  "content_type": "深度技术解析",
  "is_paid_flag": "否",
  "url": "https://towardsdatascience.com/multivariant-linear-regression-e636a4f99b40/",
  "publish_date": "2021-03-12",
  "corpus_stage": "",
  "notes": "",
  "id": "c56372b116e4",
  "collected_at": "2026-10-02T08:43:16",
  "title": "Multivariant Linear Regression | Towards Data Science",
  "body_markdown": "![Revisit consent button](../images/body-df29beacd7496220cc94.svg)\nWe value your privacy\nWe use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking \"Accept All\", you consent to our use of cookies.\nCustomise Reject All Accept All\nCustomise Consent Preferences ![](../images/body-2159bb67f3de8ad870eb.svg)\nWe use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.\nThe cookies that are categorised as \"Necessary\" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... Show more\nNecessaryAlways Active\nNecessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.\n  * Cookie\nBCTempID\n  * Duration\n10 minutes\n  * Description\nNo description available.\n\n\n  * Cookie\n__cf_bm\n  * Duration\n1 hour\n  * Description\nThis cookie, set by Cloudflare, is used to support Cloudflare Bot Management. \n\n\n  * Cookie\nAWSALBCORS\n  * Duration\n7 days\n  * Description\nAmazon Web Services set this cookie for load balancing.\n\n\n  * Cookie\n_cfuvid\n  * Duration\nsession\n  * Description\nCloudflare sets this cookie to track users across sessions to optimize user experience by maintaining session consistency and providing personalized services\n\n\n  * Cookie\nli_gc\n  * Duration\n6 months\n  * Description\nLinkedin set this cookie for storing visitor's consent regarding using cookies for non-essential purposes.\n\n\n  * Cookie\n__hssrc\n  * Duration\nsession\n  * Description\nThis cookie is set by Hubspot whenever it changes the session cookie. The __hssrc cookie set to 1 indicates that the user has restarted the browser, and if the cookie does not exist, it is assumed to be a new session.\n\n\n  * Cookie\n__hssc\n  * Duration\n1 hour\n  * Description\nHubSpot sets this cookie to keep track of sessions and to determine if HubSpot should increment the session number and timestamps in the __hstc cookie.\n\n\n  * Cookie\nwpEmojiSettingsSupports\n  * Duration\nsession\n  * Description\nWordPress sets this cookie when a user interacts with emojis on a WordPress site. It helps determine if the user's browser can display emojis properly.\n\n\n  * Cookie\nBCSessionID\n  * Duration\n1 year 1 month 4 days\n  * Description\nBlueconic sets this cookie as a unique identifier for the BlueConic profile.\n\n\n  * Cookie\n_octo\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nlogged_in\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\n__Secure-YEC\n  * Duration\npast\n  * Description\nYouTube sets this cookie to stores the user's video player preferences using embedded YouTube video\n\n\n  * Cookie\n__eoi\n  * Duration\n6 months\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nAWSALBTGCORS\n  * Duration\n7 days\n  * Description\nNo description available.\n\n\n  * Cookie\nlogin-status-p\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nAWSALBTG\n  * Duration\n7 days\n  * Description\nNo description available.\n\n\n  * Cookie\ncsrf_token\n  * Duration\nsession\n  * Description\nNo description available.\n\n\n  * Cookie\ntoken_v2\n  * Duration\n1 day\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nD\n  * Duration\n1 year\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nPHPSESSID\n  * Duration\nsession\n  * Description\nThis cookie is native to PHP applications. The cookie stores and identifies a user's unique session ID to manage user sessions on the website. The cookie is a session cookie and will be deleted when all the browser windows are closed.\n\n\n  * Cookie\nVISITOR_PRIVACY_METADATA\n  * Duration\n6 months\n  * Description\nYouTube sets this cookie to store the user's cookie consent state for the current domain. \n\n\n  * Cookie\ncookietest\n  * Duration\nsession\n  * Description\nThe cookietest cookie is typically used to determine whether the user's browser accepts cookies, essential for website functionality and user experience.\n\n\n  * Cookie\n__Host-airtable-session\n  * Duration\n1 year\n  * Description\nThis cookie is used to enable us to integrate the services of Airtable.\n\n\n  * Cookie\n__Host-airtable-session.sig\n  * Duration\n1 year\n  * Description\nThis cookie is used to enable us to integrate the services of Airtable.\n\n\n  * Cookie\nm\n  * Duration\n1 year 1 month 4 days\n  * Description\nStripe sets this cookie for fraud prevention purposes. It identifies the device used to access the website, allowing the website to be formatted accordingly.\n\n\n  * Cookie\nBIGipServer*\n  * Duration\nsession\n  * Description\nMarketo sets this cookie to collect information about the user's online activity and build a profile about their interests to provide advertisements relevant to the user. \n\n\n  * Cookie\n__cfruid\n  * Duration\nsession\n  * Description\nCloudflare sets this cookie to identify trusted web traffic.\n\n\n  * Cookie\n_GRECAPTCHA\n  * Duration\n6 months\n  * Description\nGoogle Recaptcha service sets this cookie to identify bots to protect the website against malicious spam attacks.\n\n\n  * Cookie\n__Secure-YNID\n  * Duration\n6 months\n  * Description\nGoogle cookie used to protect user security and prevent fraud, especially during the login process.\n\n\n  * Cookie\ncookieyes-consent\n  * Duration\n1 year\n  * Description\nCookieYes sets this cookie to remember users' consent preferences so that their preferences are respected on subsequent visits to this site. It does not collect or store any personal information about the site visitors.\n\n\nFunctional\nFunctional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.\n  * Cookie\nlidc\n  * Duration\n1 day\n  * Description\nLinkedIn sets the lidc cookie to facilitate data center selection.\n\n\n  * Cookie\nbrw\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nbrwConsent\n  * Duration\n5 minutes\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nWMF-Uniq\n  * Duration\n1 year\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nloom_anon_comment\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nloom_referral_video\n  * Duration\nsession\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nVISITOR_INFO1_LIVE\n  * Duration\n6 months\n  * Description\nA cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.\n\n\n  * Cookie\nyt-remote-connected-devices\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to store the user's video preferences using embedded YouTube videos.\n\n\n  * Cookie\nytidb::LAST_RESULT_ENTRY_KEY\n  * Duration\nNever Expires\n  * Description\nThe cookie ytidb::LAST_RESULT_ENTRY_KEY is used by YouTube to store the last search result entry that was clicked by the user. This information is used to improve the user experience by providing more relevant search results in the future.\n\n\n  * Cookie\nyt-remote-device-id\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to store the user's video preferences using embedded YouTube videos.\n\n\n  * Cookie\nyt-remote-session-name\n  * Duration\nsession\n  * Description\nThe yt-remote-session-name cookie is used by YouTube to store the user's video player preferences using embedded YouTube video.\n\n\n  * Cookie\nyt-remote-fast-check-period\n  * Duration\nsession\n  * Description\nThe yt-remote-fast-check-period cookie is used by YouTube to store the user's video player preferences for embedded YouTube videos.\n\n\n  * Cookie\nyt-remote-session-app\n  * Duration\nsession\n  * Description\nThe yt-remote-session-app cookie is used by YouTube to store user preferences and information about the interface of the embedded YouTube video player.\n\n\n  * Cookie\nyt-remote-cast-available\n  * Duration\nsession\n  * Description\nThe yt-remote-cast-available cookie is used to store the user's preferences regarding whether casting is available on their YouTube video player.\n\n\n  * Cookie\nyt-remote-cast-installed\n  * Duration\nsession\n  * Description\nThe yt-remote-cast-installed cookie is used to store the user's video player preferences using embedded YouTube video.\n\n\n  * Cookie\ncp_session\n  * Duration\n3 months\n  * Description\nCodepen sets this cookie for Help systems found in the website.\n\n\n  * Cookie\nloid\n  * Duration\n1 year 1 month 4 days\n  * Description\nThis cookie is set by the Reddit. The cookie enables the sharing of content from the website onto the social media platform.\n\n\nAnalytics\nAnalytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.\n  * Cookie\n__hstc\n  * Duration\n6 months\n  * Description\nHubspot set this main cookie for tracking visitors. It contains the domain, initial timestamp (first visit), last timestamp (last visit), current timestamp (this visit), and session number (increments for each subsequent session).\n\n\n  * Cookie\nhubspotutk\n  * Duration\n6 months\n  * Description\nHubSpot sets this cookie to keep track of the visitors to the website. This cookie is passed to HubSpot on form submission and used when deduplicating contacts.\n\n\n  * Cookie\n_ga\n  * Duration\n1 year 1 month 4 days\n  * Description\nGoogle Analytics sets this cookie to calculate visitor, session and campaign data and track site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognise unique visitors.\n\n\n  * Cookie\n_ga_*\n  * Duration\n1 year 1 month 4 days\n  * Description\nGoogle Analytics sets this cookie to store and count page views.\n\n\n  * Cookie\n__Host-psifi.analyticsTrace\n  * Duration\n6 hours\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\n__Host-psifi.analyticsTraceV2\n  * Duration\n6 hours\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\n_gh_sess\n  * Duration\nsession\n  * Description\nGitHub sets this cookie for temporary application and framework state between pages like what step the user is on in a multiple step form.\n\n\n  * Cookie\nYSC\n  * Duration\nsession\n  * Description\nYSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.\n\n\n  * Cookie\najs_anonymous_id\n  * Duration\n1 year\n  * Description\nThis cookie is set by Segment to count the number of people who visit a certain site by tracking if they have visited before.\n\n\n  * Cookie\nvuid\n  * Duration\n1 year 1 month 4 days\n  * Description\nVimeo installs this cookie to collect tracking information by setting a unique ID to embed videos on the website. \n\n\nPerformance\nPerformance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.\n  * Cookie\nAWSALB\n  * Duration\n7 days\n  * Description\nAWSALB is an application load balancer cookie set by Amazon Web Services to map the session to the target.\n\n\n  * Cookie\nacq\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nacq.sig\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nptc\n  * Duration\n2 years\n  * Description\nNo description available.\n\n\nAdvertisement\nAdvertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.\n  * Cookie\nmuc_ads\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to collect user behaviour and interaction data to optimize the website.\n\n\n  * Cookie\nguest_id_marketing\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor.\n\n\n  * Cookie\nguest_id_ads\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor.\n\n\n  * Cookie\npersonalization_id\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to integrate and share features for social media and also store information about how the user uses the website, for tracking and targeting.\n\n\n  * Cookie\nguest_id\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor. It registers if a user is signed in to the Twitter platform and collects information about ad preferences.\n\n\n  * Cookie\nbcookie\n  * Duration\n1 year\n  * Description\nLinkedIn sets this cookie from LinkedIn share buttons and ad tags to recognize browser IDs.\n\n\n  * Cookie\n__Secure-ROLLOUT_TOKEN\n  * Duration\n6 months\n  * Description\nYouTube sets this cookie to manage feature rollout and experimentation. It helps Google control which new features or interface changes are shown to users as part of testing and staged rollouts, ensuring consistent experience for a given user during an experiment.\n\n\n  * Cookie\nyt.innertube::nextId\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to register a unique ID to store data on what videos from YouTube the user has seen.\n\n\n  * Cookie\nyt.innertube::requests\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to register a unique ID to store data on what videos from YouTube the user has seen.\n\n\n  * Cookie\nsession_tracker\n  * Duration\nsession\n  * Description\nThis cookie is set by the Reddit. This cookie is used to identify trusted web traffic. It also helps in adverstising on the website.\n\n\n  * Cookie\nedgebucket\n  * Duration\nsession\n  * Description\nReddit sets this cookie to save the information about a log-on Reddit user, for the purpose of advertisement recommendations and updating the content.\n\n\n  * Cookie\ndid\n  * Duration\n1 year\n  * Description\nArbor sets this cookie to show targeted ads to site visitors.This cookie expires after 2 months or 1 year.\n\n\nUncategorised\nOther uncategorised cookies are those that are being analysed and have not been classified into a category as yet.\nNo cookies to display.\nReject All Save My Preferences Accept All\nToggle Search[](https://towardsdatascience.com/)Toggle Mobile Navigation\n[](https://towardsdatascience.com/)\nPublish AI, ML & data-science insights to a global community of data professionals.\nSign in[Submit an Article](https://write.insightmediagroup.io)\n[Latest](https://towardsdatascience.com/latest/)[Editor's Picks](https://towardsdatascience.com/tag/editors-pick/)[Newsletter](https://towardsdatascience.com/tag/the-variable/)[ShipAI](https://towardsdatascience.com/shipai/)\n* * *\n[Write For TDS](https://towardsdatascience.com/submissions/)\n[LinkedIn](https://www.linkedin.com/company/towards-data-science/)[X](https://x.com/TDataScience)Toggle Search\n[Data Science](https://towardsdatascience.com/category/data-science/)\n# Multivariant Linear Regression\nOh boy, homoscedasticity!\n[James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\nMarch 12, 202111 min read\n### Oh boy, homoscedasticity\n![Multivariant Regression | Photo by Paweł Czerwiński](../images/000.jpeg)\nMultivariant Regression | Photo by [Paweł Czerwiński](https://unsplash.com/@pawel_czerwinski)\nThis article is a continuation of my previous one on [Linear Regression](https://towardsdatascience.com/an-introduction-to-linear-regression-9cbb64b52d23).\nIt is important to reiterate from my last article about the error formulae in least-squares regression.\n![Least-squares regression selects the line with the lowest total SSE](../images/001.jpeg)\nLeast-squares regression selects the line with the lowest total SSE\nThe sum of this sum of squares error here is the discrepancy between the theoretical value on the line and the actual observed value, which is the point which is the blue dots. Those discrepancies squared and then sum up those squares that hold total area is the **SSE** , sum of squared error.\n![Sum of Squares Regression \\(SSR\\)](../images/002.jpeg)\nSum of Squares Regression (SSR)\nHere is the sum of squares regression (**SSR**). This basically says how much variance there is; what is basically the amount of effect that we see between the predictive values, how much the model has to do. If this is a very large number, it does not by itself mean that the model is good or bad. But if this SSR is substantially larger than it, or the sum of squares of the regression is substantially larger than the sum of squares of these discrepancies (SSE), then it is a good model. The measurement is between the predicted values and the mean.\nThe sum of squares total (**SST**)is sometimes equal to SSR + SSE. The primary sometimes is if you use the least-squares regression, to begin with, which sort of makes sense - we are summing up squares here so you are doing a least-squares regression. And the other more important thing is, and this is the one that people forget all the time, is that this equation, **SST = SSR +SSE is only true for the training data**. It is not true for the test data. **The reason why is the SSE can be arbitrarily large with test data**. And if it gets too large then things can go wrong. SSE can get arbitrarily large, so even larger than SST, it can become a lot larger than SST. SST is based on only the training data while SSE is based on your test data.\n![SSE can be bigger than SST](../images/003.png)\nSSE can be bigger than SST\nTherefore it is very possible to have a negative value for R². And as we all know, R² cannot be negative if it were truly a square of something. But as you see, this formula here is not a squaring of any Pearson's R or anything like that.\nAnother accuracy measure of the line is using the Root Mean Squared Error (RMSE). Using this as an estimate of the error means we are losing one more degree of freedom than the standard deviation, so we write the RSE as:\n![Defined in terms of SSE](../images/004.png)\nDefined in terms of SSE\ntext\n\n```\n# mean squared error\n```\n\ntext\n\n```\nmse = np.sum((y_pred - y_actual)**2)\n```\n\ntext\n\n```\n# root mean squared error, m is number of training samples\nrmse = np.sqrt(mse/m)\n# results.mse_resid\n```\n\n### Assumptions\nHere are some important assumptions of linear regression.\n  * Linear relationship between the dependent variable and independent variables\n  * Measurement error is random\n  * Residuals are homoscedastic\n\n\nThe primary assumption is **residuals are homoscedastic**. Homoscedasticity means that they are roughly the same throughout, which means your residuals do not suddenly get larger. And this is often not the case, often things are not homoscedastic. What do you do then? Well, if you can do one of those tricks, like changing the y values, transforming them before you do any linear regression, then great! Otherwise, what can be done when the assumption is not valid? This is the dirty secret: they do nothing. They just pretend that their residuals are homoscedastic in spite of the fact that they are heteroscedastic, which means that the error is not consistent throughout.\n![Our assumed homoscedastic model](../images/005.jpeg)\nOur assumed homoscedastic model\nN.B: The errors do not be normally distributed to be homoscedastic, the errors just need to be roughly the same throughout. They do need to be centered about zero, however.\n### Outliers\n![Susceptible to outliers: an outlier is an observation with a large residual](../images/006.jpeg)\nSusceptible to outliers: an outlier is an observation with a large residual\nLinear regressions are susceptible to outliers. Here, you have a nice linear relationship, this line going through these data points perfectly. The second image is not because that one data point up in the top right is pulling the regression line way up there. Outliers like this can really be a problem, you can get rid of outliers and like that in a variety of ways, like leverage and Cook's Distance.\nLinear regression fits a line based on the means of the x and y values. It fits a line that goes through the means of both values. This line pivots around the point relative to the pull of each point. Points that are farther away from the mean pull harder on the slope - this is leverage. Another way to quantify the 'pull' of each point, is to fit the line to the data without each point and see how the parameters move: this is Cook's Distance.\n### Coefficients and p-values\nWhen the regression line is linear the **regression coefficient** is the constant that represents the rate of change of one variable as a function of the other - it is the **slope of the regression line**.\n  * The p-values for the coefficients indicate whether these relationships are statistically significant.\n  * The **t statistic is the coefficient divided by its standard error.**\n\n\n### Checking the residuals\nThis is important! You should always check for trends in the residuals.\n![You should not see any pattern](../images/007.jpeg)\nYou should not see any pattern\nThere are more data points on the right than the left, and that is ok, that is just the shape of the data. The predicted values on the x-axis and the residuals, the error from the predicted value, on the y-axis.\n  * Residuals = Obsevered (actual data) - Predicted (where the data moves to the regression line)\n\n\nPositive values for the residual (on the y-axis) indicate that the prediction was too low, and negative values indicate that the prediction was too high. A zero means that the guess was exactly correct!\n**THERE SHOULD BE NO PATTERN IN THE RESIDUALS!**\nThe question is, are the residuals closer to this dotted line on the right-hand side than they are on the left-hand side overall? Or even worse - do you see more residuals beneath the dotted line than above the dotted line? What is the dotted line, the dotted line is zero where you have zero residual. The residual again is the discrepancy between your predicted y value and your actual y value. They should all hover around zero because well, the point of the fact of having a predicted y value was to explain your data. And the predicted y value should be generally close to your y value.\nWhen this is not the case you have residuals. Sometimes, seeing an obvious trend in your residuals is an opportunity. That means that you can then use that trend in your residuals to add another model only to your residuals.\nAlways plot the residuals to check for trends. Check the residuals versus y, and make sure that they are, say, always positively correlated, the higher the correlation, the worse the fit. The reason is that if there is a high correlation to the residuals with y, that means that as y gets larger, your residuals get larger. And this actually happens a lot. Testing the normality of the residuals is also important.\nA common sign that your residuals are **heteroscedastic** is the \"fan-shaped\" errors, whereby the errors are larger on the right-hand side than the left-hand side.\n![Note the &quot;fan-shape&quot; in the raw data, the errors are much larger on RHS than LHS](../images/008.jpeg)\nNote the \"fan-shape\" in the raw data, the errors are much larger on RHS than LHS\nAgain, there should be no trends apparent in the residuals. But oftentimes the residuals can be assumed to be homoscedastic when they are not, like the fan-shape below. The third outcome, the nonlinear one, is a really bad one that cannot be assumed to be homoscedastic, the error trend is parabolic.\n![](../images/body-230947deae826a4c2bd5.png)\nThis nonlinear error trend is likely an indication that the data has a relationship that is not best captured with the parameters used; **the residuals have information** in them. It looks as if we could actually fit a polynomial to these residuals. Or we could simply add the polynomial to our linear model in the first place and overall we would have fewer errors after doing this.\n### Multiple linear regression\n![All these regressions are linear in parameters](../images/009.jpeg)\nAll these regressions are linear in parameters\nAs mentioned in my previous article, why not make the variables in the last formula linear by saying the exponent is a different variable, like z? These are the new variables that we then have a linear setup for and the equation becomes a multivariant linear regression.\n![Multiple independent variables make this an example of multivariant linear regression](../images/010.jpeg)\nMultiple independent variables make this an example of multivariant linear regression\n### One hot encoding vs dummy variables\nThis is commonly misunderstood. There is one-hot encoding (OHE) as one way of doing things, then there is the dummy variable way of encoding for linear regression. The dummy variable is basically the same as OHE, you just do n-1 of the variables. Gender is not OHE when all you have is a column labeled \"gender\" with a 1 being \"male\" and a 0 being \"female\", this here is actually a dummy variable. This is not one hot encoding because there is no column for females, there is only a column for males. So the column should not be called gender, because there exists no such gender as one and zero, this column should be called is male.\nWith the dummy variable, you drop columns, with OHE you never drop columns. That is the definition of what one-hot encoding is. **One hot encoding is not a data science term** , rather it comes from a very different area of engineering. Imparting dummy variables is statistically more useful because you will not have colinearity. But you probably will not have colinearity anyway, probably not for certain. Using OHE allows for better model interpretation. Remember that with OHE, you never drop columns, doing so is imparting a dummy variable.\n## Multiple linear regression in python\nWith the following example, we want to predict the stock price index, just like everyone else.\nN.B: For simplicity, and this is a big no-no, this model just uses the test data for fitting - there is no train/tune/test split.\ntext\n\n```\n# imports\nfrom pandas import DataFrame\nfrom sklearn import linear_model\nimport statsmodels.api as sm\nfrom sklearn.metrics import mean_squared_error, r2_score\nimport matplotlib.pyplot as plt\n```\n\ntext\n\n```\n# create dataframe from stock data\nStock_Market = {'Year': [2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016],\n 'Month': [12, 11,10,9,8,7,6,5,4,3,2,1,12,11,10,9,8,7,6,5,4,3,2,1],\n 'Interest_Rate': [2.75,2.5,2.5,2.5,2.5,2.5,2.5,2.25,2.25,2.25,2,2,2,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75],\n 'Unemployment_Rate': [5.3,5.3,5.3,5.3,5.4,5.6,5.5,5.5,5.5,5.6,5.7,5.9,6,5.9,5.8,6.1,6.2,6.1,6.1,6.1,5.9,6.2,6.2,6.1],\n 'Stock_Index_Price': [1464,1394,1357,1293,1256,1254,1234,1195,1159,1167,1130,1075,1047,965,943,958,971,949,884,866,876,822,704,719] \n }\n```\n\ntext\n\n```\n# inputs\ndf = DataFrame(Stock_Market,\n columns=['Year','Month','Interest_Rate','Unemployment_Rate','Stock_Index_Price'])\n```\n\ntext\n\n```\n# check that the data is well imported\ndf.head()\n```\n\n![Data looks well imported](../images/011.png)\nData looks well imported\nIdentify variables that are interesting and scale them. Scale your data to be safe! You will not have a different outcome if you scale your data in spite of what anyone will tell you - this you can prove mathematically. **My statement is true, as long as you do not consider floating-point stuff**. **If you have very large or very small numbers, then you have floating-point inaccuracy**. And this can then lead to a lot of problems. And you get very large numbers and very small numbers by not scaling, to begin with. If you scale everything, to begin with, then everything looks the same. Everything is between minus two and plus two, everything is centered around zero. The reason why that is that most people will scale according will scale on use what is called a standard scaler, which is your normal or your Gaussian distribution. What you do is subtract away the mean, and then you divide by the standard deviation.\nAnother benefit to scaling is that if you use an iterative methodology, your data will generally converge faster if you have scaled it. But, as long as you have a linear system - there is a mathematical proof (this is a so-called convex problem) and if it is such, there is a specific solution in all cases, regardless of data scaling. In principle, you will not get more or less accuracy if you scale - however floating point inaccuracies are a thing to watch out for!\nWe keep \"Interest_Rate\" and \"Unemployment_Rate\" for further analysis:\ntext\n\n```\nx = df[['Interest_Rate','Unemployment_Rate']]\ny = df['Stock_Index_Price']\n```\n\ntext\n\n```\n# scale the data\nfrom sklearn.preprocessing import StandardScaler\nscaler = StandardScaler()\nscaler.fit(x)\nx = scaler.transform(x)\n```\n\ntext\n\n```\nfrom sklearn.linear_model import LinearRegression\nregression_model = LinearRegression()\n# Fit the data(train the model)\nregression_model.fit(x, y)\n```\n\ntext\n\n```\n# predict\ny_predicted = regression_model.predict(x)\n```\n\ntext\n\n```\nprint('Intercept: n', regression_model.intercept_) # pull out intercept\nprint('Coefficients: n', regression_model.coef_) # pull out coeffeicients\n```\n\n![](../images/body-6ed4bacd727bc86b60b7.png)\nThis output includes the intercept and coefficients to build the multiple linear regression equation.\nN.B: We scaled the data, so the coefficients above reflect that. Nonetheless, there is a correlation between high-interest rates and stock prices rising and a smaller correlated effect with prices rising as unemployment falls. We can see that the scaled coefficients are roughly the same and are therefore directly comparable.\ntext\n\n```\nStock_Index_Price = (Intercept) + (Interest_Rate coef)*X1 + (Unemployment_Rate coef)*X2\n```\n\nPlugging in new numbers:\ntext\n\n```\nStock_Index_Price = (1070.083) + (118.233)*X1 + (-80.815)*X2\n```\n\ntext\n\n```\n# prediction with sklearn\nNew_Interest_Rate = 2.75\nNew_Unemployment_Rate = 5.3\n# create a scaled feature array and make the prediction\nfeature_array = scaler.transform([[New_Interest_Rate ,New_Unemployment_Rate]])\nprint ('Predicted Stock Index Price: n', regression_model.predict(feature_array))\n```\n\n![Given the new interest and unemployment rates, we expect the stock to be this price](../images/012.jpeg)\nGiven the new interest and unemployment rates, we expect the stock to be this price\n### Stats models\nSame analysis but this time with `sm`. Again I stress the more important package to know is `sklearn`\ntext\n\n```\n# with statsmodels\nX = sm.add_constant(x) # adding a constant\n\nmodel = sm.OLS(y, X).fit()\npredictions = model.predict(X) \n\nprint_model = model.summary()\nprint(print_model)\n```\n\n![Adj R² is always lower than R² | We lose 2 degrees of freedom thanks to the multiple inputs](../images/013.jpeg)\nAdj R² is always lower than R² | We lose 2 degrees of freedom thanks to the multiple inputs\ntext\n\n```\n# Summary graphs:\nimport scipy.stats as stats\nimport statsmodels.api as statsmodels\nfrom statsmodels.graphics.regressionplots import *\nimport seaborn as sns\nimport numpy as np\n```\n\ntext\n\n```\nsns.distplot(model.resid, hist=True)\nplt.grid(True)\nplt.xlabel('Residual')\nplt.ylabel('Frequency')\nplt.title('Residual Histogram')\nplt.show()\n```\n\ntext\n\n```\n# Residuals vs Fitted Values\nresiduals = model.resid # outlier_linear = name of linear model on #our dataset\nfitted_vals = model.predict(X) # making predictions from our fit #model\n```\n\ntext\n\n```\nplt.plot(fitted_vals, residuals, 'o') # plotting predictions from #fit model vs residuals\n```\n\ntext\n\n```\nplt.xlabel('Fitted Values')\nplt.ylabel('Residuals')\nplt.title('Residuals vs. Fitted Values (w/ 1 outlier)')\nplt.show()\n```\n\ntext\n\n```\n# create Q-Q plot to ensure normality\nstatsmodels.qqplot(residuals, stats.norm, fit=True, line='45')\n```\n\ntext\n\n```\n# leverage Plot (Cook's Distance)\ninfluence_plot(model) # from statsmodels.graphics.regressionplots #import *\n```\n\n![Residuals appear reasonably normally distributed](../images/body-fb62c5e44d63018ac8e6.jpeg)\nResiduals appear reasonably normally distributed\n![Residual plot, no apparent trend - residuals appear reasonably homoscedastic](../images/body-5e9a20387309856c377f.jpeg)\nResidual plot, no apparent trend - residuals appear reasonably homoscedastic\n![As expected, larger residual = larger influence on the fitted line | residuals are normalized \\(studentized\\)](../images/body-fb80f13a6cc3919f276b.jpeg)\nAs expected, larger residual = larger influence on the fitted line | residuals are normalized (studentized)\n![Data appears normally distributed, histogram confirmed](../images/body-4226342bed092da033fa.jpeg)\nData appears normally distributed, histogram confirmed\n### Conclusion\nWe have explored linear models in depth and run some Jupyter Notebook code cells to explore least-squares linear regression. Remember linear refers to the parameters - in the above stock example the data is multivariant: we used interest rates AND unemployment rates to predict a numeric outcome: the stock price GIVEN those inputs. The importance of homoscedasticity of the residuals was emphasized as was, albeit briefly, leverage and outliers.\nIn my next article, I will expand these concepts and explore using [bootstrap with regression models](https://towardsdatascience.com/linear-regression-with-bootstrapping-4924c05d2a9)!\nFind me on [Linkedin](https://www.linkedin.com/in/james-a-w-godwin/)\n_Physicist cum Data Scientist- Available for new opportunity | SaaS | Sports | Start-ups | Scale-ups_\n## Register Now to Continue Reading\n### Unlock Towards Data Science with a Free Account\nAll articles on Towards Data Science are available to registered users. Create a free account today to access this article and thousands more.\nRegister for freeSign in to your account\n* * *\n![](../images/body-92fdfcb3140ff02db487.jpeg)\nWritten By\n## [James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\n[See all from James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\n[Data Science](https://towardsdatascience.com/tag/data-science/)[Linear Regression Python](https://towardsdatascience.com/tag/linear-regression-python/)[Multiple Linearregression](https://towardsdatascience.com/tag/multiple-linearregression/)[Towards Data Science](https://towardsdatascience.com/tag/towards-data-science/)\nShare This Article\n  * [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&title=Multivariant%20Linear%20Regression)\n  * [](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&title=Multivariant%20Linear%20Regression)\n  * [](https://x.com/share?url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&text=Multivariant%20Linear%20Regression)\n\n\nTowards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.\n[Write for TDS](https://towardsdatascience.com/submissions/)\n## Related Articles\n  * [![](../images/014.jpg)](https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3/)\n## [4 Powerful Rules for Better Data Science](https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3/)\n[Data Science](https://towardsdatascience.com/category/data-science/)\nFollowing these rules has drastically improved my effectiveness as a data scientist to deliver more value from my work\n[Adam Sroka](https://towardsdatascience.com/author/aesroka/)\nJune 27, 20229 min read\n  * [![](../images/015.jpg)](https://towardsdatascience.com/the-power-of-ensemble-learning-and-data-augmentation-435c62e13c57/)\n## [The Power of Ensemble Learning and Data Augmentation](https://towardsdatascience.com/the-power-of-ensemble-learning-and-data-augmentation-435c62e13c57/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nFull code examples on the MNIST dataset with VGG16 | ResNet50 | FG-UNET | Majority Voting | Single Transferable Vote | Instant-Runoff...\n[Cathie So, PhD](https://towardsdatascience.com/author/cathieso/)\nJuly 1, 20219 min read\n  * [![](../images/016.jpg)](https://towardsdatascience.com/building-a-rules-engine-from-first-principles/)\n## [Building a Rules Engine from First Principles](https://towardsdatascience.com/building-a-rules-engine-from-first-principles/)\n[Algorithms](https://towardsdatascience.com/category/algorithms/)\nHow recasting propositional logic as sparse algebra leads to an elegant and efficient design\n[Dmitry Lesnik](https://towardsdatascience.com/author/dmitry.lesnik/)\nOctober 30, 202516 min read\n  * [![](../images/017.jpg)](https://towardsdatascience.com/why-are-southern-californians-obsessed-with-guns-c80ae281f1e8/)\n## [Which American City has the Most Gun Shops?](https://towardsdatascience.com/why-are-southern-californians-obsessed-with-guns-c80ae281f1e8/)\n[Data Science](https://towardsdatascience.com/category/data-science/)\nYelp data reveals cities with the most gun shops per capita\n[William Chon](https://towardsdatascience.com/author/williamchon/)\nDecember 26, 20203 min read\n  * [![](../images/018.png)](https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-kmeans-clustering-pca-b7ba6fafa74/)\n## [Andrew Ng's Machine Learning Course in Python (Kmeans-Clustering, PCA)](https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-kmeans-clustering-pca-b7ba6fafa74/)\n[Machine Learning](https://towardsdatascience.com/category/artificial-intelligence/machine-learning/)\nKmeans-Clustering, PCA\n[Benjamin Lau](https://towardsdatascience.com/author/ben_lau93/)\nJanuary 8, 20197 min read\n  * [![](../images/019.jpeg)](https://towardsdatascience.com/6-pandas-tricks-that-you-might-not-know-but-should-6f766dfdb2c2/)\n## [6 Pandas Tricks That You Might Not Know, But Should](https://towardsdatascience.com/6-pandas-tricks-that-you-might-not-know-but-should-6f766dfdb2c2/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nHelpful for your daily tasks\n[Pranjal Saxena](https://towardsdatascience.com/author/pranjalai/)\nAugust 23, 20214 min read\n  * [![](../images/020.jpeg)](https://towardsdatascience.com/serverless-model-hosting-with-docker-aws-lambda-and-api-gateway-2d79382ecb45/)\n## [Serverless Model Hosting with Docker, AWS Lambda and API Gateway](https://towardsdatascience.com/serverless-model-hosting-with-docker-aws-lambda-and-api-gateway-2d79382ecb45/)\n[Machine Learning](https://towardsdatascience.com/category/artificial-intelligence/machine-learning/)\nMake the most of Docker support in Lambda to host your models without the need for dedicated servers.\n[Jonathan Readshaw](https://towardsdatascience.com/author/readshawjonathan/)\nJune 20, 20213 min read\n  * [![](../images/021.png)](https://towardsdatascience.com/location-analytics-use-cases-that-every-data-scientist-should-know-740b708a2504/)\n## [Location Analytics Use-Cases that Every Data Scientist Should Know](https://towardsdatascience.com/location-analytics-use-cases-that-every-data-scientist-should-know-740b708a2504/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nPowerful ways to use location analytics\n[Pranay Dave](https://towardsdatascience.com/author/pranay-dave9/)\nFebruary 22, 20225 min read\n  * [![](../images/022.jpg)](https://towardsdatascience.com/comprehending-python-list-comprehensions-ii-lost-in-new-york-e8af27038f4b/)\n## [Comprehending Python Lists](https://towardsdatascience.com/comprehending-python-list-comprehensions-ii-lost-in-new-york-e8af27038f4b/)\n[Programming](https://towardsdatascience.com/category/programming/)\nA beginner's guide to Python object comprehensions and protecting your home from a Joe Pesci-type burglar\n[Joe Marx](https://towardsdatascience.com/author/joebrowz/)\nDecember 10, 20207 min read\n\n\n  * [YouTube](https://www.youtube.com/c/TowardsDataScience)\n  * [X](https://x.com/TDataScience)\n  * [LinkedIn](https://www.linkedin.com/company/towards-data-science/)\n  * [Threads](https://www.threads.net/@towardsdatascience)\n  * [Bluesky](https://bsky.app/profile/towardsdatascience.com)\n\n\n[](https://towardsdatascience.com/)\nYour home for data science and AI. The world's leading publication for data science, data analytics, data engineering, machine learning, and artificial intelligence professionals.\nSubscribe to Our Newsletter[Write For TDS](https://towardsdatascience.com/submissions/)•[About](https://towardsdatascience.com/about-towards-data-science-d691af11cc2f/)•[Advertise](https://contact.towardsdatascience.com/advertise-with-towards-data-science)•[Privacy Policy](https://towardsdatascience.com/privacy-policy/)•[Terms of Use](https://towardsdatascience.com/website-terms-of-use/)\n© Insight Media Group, LLC 2026•[The New Stack](https://thenewstack.io)•[roadmap.sh](https://roadmap.sh)•[Creator Network](https://insightmediagroup.io/creator-network)\n####  Recommended Articles \nClose\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607686/image?etag=1782161464448&width=500&height=500) How Relevance Models Foreshadowed Transformers for NLP ](https://towardsdatascience.com/how-relevance-models-foreshadowed-transformers-for-nlp/ \"How Relevance Models Foreshadowed Transformers for NLP\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607639/image?etag=1781250125848&width=500&height=500) Javascript Fatigue: HTMX Is All You Need to Build ChatGPT — Part 1 ](https://towardsdatascience.com/javascript-fatigue-you-dont-need-js-to-build-chatgpt/ \"Javascript Fatigue: HTMX Is All You Need to Build ChatGPT — Part 1\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607930/image?etag=1782124566054&width=500&height=500) The Subset Sum Problem Solved in Linear Time for Dense Enough Inputs ](https://towardsdatascience.com/subset-sum-problem-solved-in-linear-time-for-dense-enough-inputs/ \"The Subset Sum Problem Solved in Linear Time for Dense Enough Inputs\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/3660/image?etag=1780176246070&width=500&height=500) Does Your Company Have a Data Strategy? ](https://towardsdatascience.com/does-your-company-have-a-data-strategy-e8944dbec4ae/ \"Does Your Company Have a Data Strategy?\")\n\n\n",
  "metadata": {
    "title": "Multivariant Linear Regression | Towards Data Science",
    "description": "Oh boy, homoscedasticity!",
    "keywords": null,
    "author": "James Andrew Godwin",
    "og:locale": "en_US",
    "og:type": "article",
    "og:title": "Multivariant Linear Regression",
    "og:description": "Oh boy, homoscedasticity!",
    "og:url": "https://towardsdatascience.com/multivariant-linear-regression-e636a4f99b40/",
    "og:site_name": "Towards Data Science",
    "og:image": "https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/17wg90gBhLpasFt4Np3Uwug.jpeg",
    "og:image:width": "640",
    "og:image:height": "427",
    "og:image:type": "image/jpeg",
    "twitter:card": "summary_large_image",
    "twitter:site": "@TDataScience",
    "twitter:creator": "@TDataScience",
    "twitter:label1": "Written by",
    "twitter:data1": "James Andrew Godwin",
    "twitter:label2": "Est. reading time",
    "twitter:data2": "11 min read",
    "article:published_time": "2021-03-12T07:00:34.000Z",
    "article:modified_time": "2021-03-12T07:00:34.000Z",
    "article:author": "https://towardsdatascience.com/author/james-andrew/"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_000.txt",
      "chars": 21
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_001.txt",
      "chars": 37
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_002.txt",
      "chars": 101
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_003.txt",
      "chars": 190
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_004.txt",
      "chars": 632
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_005.txt",
      "chars": 121
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_006.txt",
      "chars": 49
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_007.txt",
      "chars": 74
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_008.txt",
      "chars": 130
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_009.txt",
      "chars": 147
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_010.txt",
      "chars": 52
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_011.txt",
      "chars": 146
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_012.txt",
      "chars": 88
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_013.txt",
      "chars": 61
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_014.txt",
      "chars": 296
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_015.txt",
      "chars": 172
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_016.txt",
      "chars": 176
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_017.txt",
      "chars": 142
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_018.txt",
      "chars": 181
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_019.txt",
      "chars": 90
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_020.txt",
      "chars": 119
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_021.txt",
      "chars": 101
    },
    {
      "language": "txt",
      "file": "attachments/c56372b116e4/code/block_022.txt",
      "chars": 110
    }
  ],
  "images": [
    {
      "status": "http_404",
      "url": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607686/image?etag=1782161464448&width=500&height=500",
      "src": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607686/image?etag=1782161464448&width=500&height=500",
      "alt": "",
      "downloaded": false,
      "discovery": "saved_markdown",
      "retried_at": "2026-10-20T17:50:39Z"
    },
    {
      "status": "http_404",
      "url": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607639/image?etag=1781250125848&width=500&height=500",
      "src": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607639/image?etag=1781250125848&width=500&height=500",
      "alt": "",
      "downloaded": false,
      "discovery": "saved_markdown",
      "retried_at": "2026-10-20T17:50:39Z"
    },
    {
      "status": "http_404",
      "url": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607930/image?etag=1782124566054&width=500&height=500",
      "src": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607930/image?etag=1782124566054&width=500&height=500",
      "alt": "",
      "downloaded": false,
      "discovery": "saved_markdown",
      "retried_at": "2026-10-20T17:50:39Z"
    },
    {
      "status": "http_404",
      "url": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/3660/image?etag=1780176246070&width=500&height=500",
      "src": "https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/3660/image?etag=1780176246070&width=500&height=500",
      "alt": "",
      "downloaded": false,
      "discovery": "saved_markdown",
      "retried_at": "2026-10-20T17:50:39Z"
    }
  ],
  "audio": [],
  "videos": [
    {
      "url": "https://www.youtube.com/c/TowardsDataScience",
      "kind": "channel_reference",
      "status": "reference_only"
    }
  ],
  "links": [
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/latest/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/editors-pick/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/the-variable/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/shipai/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/submissions/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/category/data-science/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/author/james-andrew/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/an-introduction-to-linear-regression-9cbb64b52d23"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/linear-regression-with-bootstrapping-4924c05d2a9"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/data-science/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/linear-regression-python/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/multiple-linearregression/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/tag/towards-data-science/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/author/aesroka/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/the-power-of-ensemble-learning-and-data-augmentation-435c62e13c57/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/category/artificial-intelligence/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/author/cathieso/"
    },
    {
      "type": "internal",
      "href": "https://towardsdatascience.com/building-a-rules-engine-from-first-principles/"
    },
    {
      "type": "external",
      "href": "https://write.insightmediagroup.io"
    },
    {
      "type": "external",
      "href": "https://www.linkedin.com/company/towards-data-science/"
    },
    {
      "type": "external",
      "href": "https://x.com/TDataScience"
    },
    {
      "type": "external",
      "href": "https://unsplash.com/@pawel_czerwinski"
    },
    {
      "type": "external",
      "href": "https://www.linkedin.com/in/james-a-w-godwin/"
    },
    {
      "type": "external",
      "href": "https://www.facebook.com/sharer/sharer.php?title=Multivariant+Linear+Regression&u=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F"
    },
    {
      "type": "external",
      "href": "https://www.linkedin.com/shareArticle?mini=true&title=Multivariant+Linear+Regression&url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F"
    },
    {
      "type": "external",
      "href": "https://x.com/share?text=Multivariant+Linear+Regression&url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F"
    },
    {
      "type": "external",
      "href": "https://www.youtube.com/c/TowardsDataScience"
    },
    {
      "type": "external",
      "href": "https://www.threads.net/@towardsdatascience"
    },
    {
      "type": "external",
      "href": "https://bsky.app/profile/towardsdatascience.com"
    },
    {
      "type": "external",
      "href": "https://thenewstack.io"
    },
    {
      "type": "external",
      "href": "https://roadmap.sh"
    },
    {
      "type": "external",
      "href": "https://insightmediagroup.io/creator-network"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-20T17:27:04Z",
  "source_url": "https://towardsdatascience.com/multivariant-linear-regression-e636a4f99b40/",
  "delivery_status": "unverified",
  "discovery_status": "http_403",
  "missing_reason": "源页面未重新核验:http_403；已按保留正文补采图片",
  "repair_error": "",
  "actual_video_files": [],
  "expected_saved_body_images": 4,
  "image_discovery": "saved_markdown",
  "source_body_markdown": "![Revisit consent button](https://cdn-cookieyes.com/assets/images/revisit.svg)\nWe value your privacy\nWe use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking \"Accept All\", you consent to our use of cookies.\nCustomise Reject All Accept All\nCustomise Consent Preferences ![](https://cdn-cookieyes.com/assets/images/close.svg)\nWe use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.\nThe cookies that are categorised as \"Necessary\" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... Show more\nNecessaryAlways Active\nNecessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.\n  * Cookie\nBCTempID\n  * Duration\n10 minutes\n  * Description\nNo description available.\n\n\n  * Cookie\n__cf_bm\n  * Duration\n1 hour\n  * Description\nThis cookie, set by Cloudflare, is used to support Cloudflare Bot Management. \n\n\n  * Cookie\nAWSALBCORS\n  * Duration\n7 days\n  * Description\nAmazon Web Services set this cookie for load balancing.\n\n\n  * Cookie\n_cfuvid\n  * Duration\nsession\n  * Description\nCloudflare sets this cookie to track users across sessions to optimize user experience by maintaining session consistency and providing personalized services\n\n\n  * Cookie\nli_gc\n  * Duration\n6 months\n  * Description\nLinkedin set this cookie for storing visitor's consent regarding using cookies for non-essential purposes.\n\n\n  * Cookie\n__hssrc\n  * Duration\nsession\n  * Description\nThis cookie is set by Hubspot whenever it changes the session cookie. The __hssrc cookie set to 1 indicates that the user has restarted the browser, and if the cookie does not exist, it is assumed to be a new session.\n\n\n  * Cookie\n__hssc\n  * Duration\n1 hour\n  * Description\nHubSpot sets this cookie to keep track of sessions and to determine if HubSpot should increment the session number and timestamps in the __hstc cookie.\n\n\n  * Cookie\nwpEmojiSettingsSupports\n  * Duration\nsession\n  * Description\nWordPress sets this cookie when a user interacts with emojis on a WordPress site. It helps determine if the user's browser can display emojis properly.\n\n\n  * Cookie\nBCSessionID\n  * Duration\n1 year 1 month 4 days\n  * Description\nBlueconic sets this cookie as a unique identifier for the BlueConic profile.\n\n\n  * Cookie\n_octo\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nlogged_in\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\n__Secure-YEC\n  * Duration\npast\n  * Description\nYouTube sets this cookie to stores the user's video player preferences using embedded YouTube video\n\n\n  * Cookie\n__eoi\n  * Duration\n6 months\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nAWSALBTGCORS\n  * Duration\n7 days\n  * Description\nNo description available.\n\n\n  * Cookie\nlogin-status-p\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nAWSALBTG\n  * Duration\n7 days\n  * Description\nNo description available.\n\n\n  * Cookie\ncsrf_token\n  * Duration\nsession\n  * Description\nNo description available.\n\n\n  * Cookie\ntoken_v2\n  * Duration\n1 day\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nD\n  * Duration\n1 year\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nPHPSESSID\n  * Duration\nsession\n  * Description\nThis cookie is native to PHP applications. The cookie stores and identifies a user's unique session ID to manage user sessions on the website. The cookie is a session cookie and will be deleted when all the browser windows are closed.\n\n\n  * Cookie\nVISITOR_PRIVACY_METADATA\n  * Duration\n6 months\n  * Description\nYouTube sets this cookie to store the user's cookie consent state for the current domain. \n\n\n  * Cookie\ncookietest\n  * Duration\nsession\n  * Description\nThe cookietest cookie is typically used to determine whether the user's browser accepts cookies, essential for website functionality and user experience.\n\n\n  * Cookie\n__Host-airtable-session\n  * Duration\n1 year\n  * Description\nThis cookie is used to enable us to integrate the services of Airtable.\n\n\n  * Cookie\n__Host-airtable-session.sig\n  * Duration\n1 year\n  * Description\nThis cookie is used to enable us to integrate the services of Airtable.\n\n\n  * Cookie\nm\n  * Duration\n1 year 1 month 4 days\n  * Description\nStripe sets this cookie for fraud prevention purposes. It identifies the device used to access the website, allowing the website to be formatted accordingly.\n\n\n  * Cookie\nBIGipServer*\n  * Duration\nsession\n  * Description\nMarketo sets this cookie to collect information about the user's online activity and build a profile about their interests to provide advertisements relevant to the user. \n\n\n  * Cookie\n__cfruid\n  * Duration\nsession\n  * Description\nCloudflare sets this cookie to identify trusted web traffic.\n\n\n  * Cookie\n_GRECAPTCHA\n  * Duration\n6 months\n  * Description\nGoogle Recaptcha service sets this cookie to identify bots to protect the website against malicious spam attacks.\n\n\n  * Cookie\n__Secure-YNID\n  * Duration\n6 months\n  * Description\nGoogle cookie used to protect user security and prevent fraud, especially during the login process.\n\n\n  * Cookie\ncookieyes-consent\n  * Duration\n1 year\n  * Description\nCookieYes sets this cookie to remember users' consent preferences so that their preferences are respected on subsequent visits to this site. It does not collect or store any personal information about the site visitors.\n\n\nFunctional\nFunctional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.\n  * Cookie\nlidc\n  * Duration\n1 day\n  * Description\nLinkedIn sets the lidc cookie to facilitate data center selection.\n\n\n  * Cookie\nbrw\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nbrwConsent\n  * Duration\n5 minutes\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nWMF-Uniq\n  * Duration\n1 year\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nloom_anon_comment\n  * Duration\n1 year\n  * Description\nNo description available.\n\n\n  * Cookie\nloom_referral_video\n  * Duration\nsession\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nVISITOR_INFO1_LIVE\n  * Duration\n6 months\n  * Description\nA cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.\n\n\n  * Cookie\nyt-remote-connected-devices\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to store the user's video preferences using embedded YouTube videos.\n\n\n  * Cookie\nytidb::LAST_RESULT_ENTRY_KEY\n  * Duration\nNever Expires\n  * Description\nThe cookie ytidb::LAST_RESULT_ENTRY_KEY is used by YouTube to store the last search result entry that was clicked by the user. This information is used to improve the user experience by providing more relevant search results in the future.\n\n\n  * Cookie\nyt-remote-device-id\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to store the user's video preferences using embedded YouTube videos.\n\n\n  * Cookie\nyt-remote-session-name\n  * Duration\nsession\n  * Description\nThe yt-remote-session-name cookie is used by YouTube to store the user's video player preferences using embedded YouTube video.\n\n\n  * Cookie\nyt-remote-fast-check-period\n  * Duration\nsession\n  * Description\nThe yt-remote-fast-check-period cookie is used by YouTube to store the user's video player preferences for embedded YouTube videos.\n\n\n  * Cookie\nyt-remote-session-app\n  * Duration\nsession\n  * Description\nThe yt-remote-session-app cookie is used by YouTube to store user preferences and information about the interface of the embedded YouTube video player.\n\n\n  * Cookie\nyt-remote-cast-available\n  * Duration\nsession\n  * Description\nThe yt-remote-cast-available cookie is used to store the user's preferences regarding whether casting is available on their YouTube video player.\n\n\n  * Cookie\nyt-remote-cast-installed\n  * Duration\nsession\n  * Description\nThe yt-remote-cast-installed cookie is used to store the user's video player preferences using embedded YouTube video.\n\n\n  * Cookie\ncp_session\n  * Duration\n3 months\n  * Description\nCodepen sets this cookie for Help systems found in the website.\n\n\n  * Cookie\nloid\n  * Duration\n1 year 1 month 4 days\n  * Description\nThis cookie is set by the Reddit. The cookie enables the sharing of content from the website onto the social media platform.\n\n\nAnalytics\nAnalytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.\n  * Cookie\n__hstc\n  * Duration\n6 months\n  * Description\nHubspot set this main cookie for tracking visitors. It contains the domain, initial timestamp (first visit), last timestamp (last visit), current timestamp (this visit), and session number (increments for each subsequent session).\n\n\n  * Cookie\nhubspotutk\n  * Duration\n6 months\n  * Description\nHubSpot sets this cookie to keep track of the visitors to the website. This cookie is passed to HubSpot on form submission and used when deduplicating contacts.\n\n\n  * Cookie\n_ga\n  * Duration\n1 year 1 month 4 days\n  * Description\nGoogle Analytics sets this cookie to calculate visitor, session and campaign data and track site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognise unique visitors.\n\n\n  * Cookie\n_ga_*\n  * Duration\n1 year 1 month 4 days\n  * Description\nGoogle Analytics sets this cookie to store and count page views.\n\n\n  * Cookie\n__Host-psifi.analyticsTrace\n  * Duration\n6 hours\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\n__Host-psifi.analyticsTraceV2\n  * Duration\n6 hours\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\n_gh_sess\n  * Duration\nsession\n  * Description\nGitHub sets this cookie for temporary application and framework state between pages like what step the user is on in a multiple step form.\n\n\n  * Cookie\nYSC\n  * Duration\nsession\n  * Description\nYSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.\n\n\n  * Cookie\najs_anonymous_id\n  * Duration\n1 year\n  * Description\nThis cookie is set by Segment to count the number of people who visit a certain site by tracking if they have visited before.\n\n\n  * Cookie\nvuid\n  * Duration\n1 year 1 month 4 days\n  * Description\nVimeo installs this cookie to collect tracking information by setting a unique ID to embed videos on the website. \n\n\nPerformance\nPerformance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.\n  * Cookie\nAWSALB\n  * Duration\n7 days\n  * Description\nAWSALB is an application load balancer cookie set by Amazon Web Services to map the session to the target.\n\n\n  * Cookie\nacq\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nacq.sig\n  * Duration\npast\n  * Description\nDescription is currently not available.\n\n\n  * Cookie\nptc\n  * Duration\n2 years\n  * Description\nNo description available.\n\n\nAdvertisement\nAdvertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.\n  * Cookie\nmuc_ads\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to collect user behaviour and interaction data to optimize the website.\n\n\n  * Cookie\nguest_id_marketing\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor.\n\n\n  * Cookie\nguest_id_ads\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor.\n\n\n  * Cookie\npersonalization_id\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to integrate and share features for social media and also store information about how the user uses the website, for tracking and targeting.\n\n\n  * Cookie\nguest_id\n  * Duration\n1 year 1 month 4 days\n  * Description\nTwitter sets this cookie to identify and track the website visitor. It registers if a user is signed in to the Twitter platform and collects information about ad preferences.\n\n\n  * Cookie\nbcookie\n  * Duration\n1 year\n  * Description\nLinkedIn sets this cookie from LinkedIn share buttons and ad tags to recognize browser IDs.\n\n\n  * Cookie\n__Secure-ROLLOUT_TOKEN\n  * Duration\n6 months\n  * Description\nYouTube sets this cookie to manage feature rollout and experimentation. It helps Google control which new features or interface changes are shown to users as part of testing and staged rollouts, ensuring consistent experience for a given user during an experiment.\n\n\n  * Cookie\nyt.innertube::nextId\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to register a unique ID to store data on what videos from YouTube the user has seen.\n\n\n  * Cookie\nyt.innertube::requests\n  * Duration\nNever Expires\n  * Description\nYouTube sets this cookie to register a unique ID to store data on what videos from YouTube the user has seen.\n\n\n  * Cookie\nsession_tracker\n  * Duration\nsession\n  * Description\nThis cookie is set by the Reddit. This cookie is used to identify trusted web traffic. It also helps in adverstising on the website.\n\n\n  * Cookie\nedgebucket\n  * Duration\nsession\n  * Description\nReddit sets this cookie to save the information about a log-on Reddit user, for the purpose of advertisement recommendations and updating the content.\n\n\n  * Cookie\ndid\n  * Duration\n1 year\n  * Description\nArbor sets this cookie to show targeted ads to site visitors.This cookie expires after 2 months or 1 year.\n\n\nUncategorised\nOther uncategorised cookies are those that are being analysed and have not been classified into a category as yet.\nNo cookies to display.\nReject All Save My Preferences Accept All\nToggle Search[](https://towardsdatascience.com/)Toggle Mobile Navigation\n[](https://towardsdatascience.com/)\nPublish AI, ML & data-science insights to a global community of data professionals.\nSign in[Submit an Article](https://write.insightmediagroup.io)\n[Latest](https://towardsdatascience.com/latest/)[Editor's Picks](https://towardsdatascience.com/tag/editors-pick/)[Newsletter](https://towardsdatascience.com/tag/the-variable/)[ShipAI](https://towardsdatascience.com/shipai/)\n* * *\n[Write For TDS](https://towardsdatascience.com/submissions/)\n[LinkedIn](https://www.linkedin.com/company/towards-data-science/)[X](https://x.com/TDataScience)Toggle Search\n[Data Science](https://towardsdatascience.com/category/data-science/)\n# Multivariant Linear Regression\nOh boy, homoscedasticity!\n[James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\nMarch 12, 202111 min read\n### Oh boy, homoscedasticity\n![Multivariant Regression | Photo by Paweł Czerwiński](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/17wg90gBhLpasFt4Np3Uwug.jpeg)\nMultivariant Regression | Photo by [Paweł Czerwiński](https://unsplash.com/@pawel_czerwinski)\nThis article is a continuation of my previous one on [Linear Regression](https://towardsdatascience.com/an-introduction-to-linear-regression-9cbb64b52d23).\nIt is important to reiterate from my last article about the error formulae in least-squares regression.\n![Least-squares regression selects the line with the lowest total SSE](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1eVfmcZIshneeRhnfbFJPQQ.jpeg)\nLeast-squares regression selects the line with the lowest total SSE\nThe sum of this sum of squares error here is the discrepancy between the theoretical value on the line and the actual observed value, which is the point which is the blue dots. Those discrepancies squared and then sum up those squares that hold total area is the **SSE** , sum of squared error.\n![Sum of Squares Regression \\(SSR\\)](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1KHbl4lUegclXIk9kCLhZog.jpeg)\nSum of Squares Regression (SSR)\nHere is the sum of squares regression (**SSR**). This basically says how much variance there is; what is basically the amount of effect that we see between the predictive values, how much the model has to do. If this is a very large number, it does not by itself mean that the model is good or bad. But if this SSR is substantially larger than it, or the sum of squares of the regression is substantially larger than the sum of squares of these discrepancies (SSE), then it is a good model. The measurement is between the predicted values and the mean.\nThe sum of squares total (**SST**)is sometimes equal to SSR + SSE. The primary sometimes is if you use the least-squares regression, to begin with, which sort of makes sense - we are summing up squares here so you are doing a least-squares regression. And the other more important thing is, and this is the one that people forget all the time, is that this equation, **SST = SSR +SSE is only true for the training data**. It is not true for the test data. **The reason why is the SSE can be arbitrarily large with test data**. And if it gets too large then things can go wrong. SSE can get arbitrarily large, so even larger than SST, it can become a lot larger than SST. SST is based on only the training data while SSE is based on your test data.\n![SSE can be bigger than SST](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/0-Q_LZ609msZwx2dS.png)\nSSE can be bigger than SST\nTherefore it is very possible to have a negative value for R². And as we all know, R² cannot be negative if it were truly a square of something. But as you see, this formula here is not a squaring of any Pearson's R or anything like that.\nAnother accuracy measure of the line is using the Root Mean Squared Error (RMSE). Using this as an estimate of the error means we are losing one more degree of freedom than the standard deviation, so we write the RSE as:\n![Defined in terms of SSE](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/0rqkMQy14mFA4ax7F.png)\nDefined in terms of SSE\ntext\n\n```\n# mean squared error\n```\n\ntext\n\n```\nmse = np.sum((y_pred - y_actual)**2)\n```\n\ntext\n\n```\n# root mean squared error, m is number of training samples\nrmse = np.sqrt(mse/m)\n# results.mse_resid\n```\n\n### Assumptions\nHere are some important assumptions of linear regression.\n  * Linear relationship between the dependent variable and independent variables\n  * Measurement error is random\n  * Residuals are homoscedastic\n\n\nThe primary assumption is **residuals are homoscedastic**. Homoscedasticity means that they are roughly the same throughout, which means your residuals do not suddenly get larger. And this is often not the case, often things are not homoscedastic. What do you do then? Well, if you can do one of those tricks, like changing the y values, transforming them before you do any linear regression, then great! Otherwise, what can be done when the assumption is not valid? This is the dirty secret: they do nothing. They just pretend that their residuals are homoscedastic in spite of the fact that they are heteroscedastic, which means that the error is not consistent throughout.\n![Our assumed homoscedastic model](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1BWwVKrbta2XOOPv2BcQaKg.jpeg)\nOur assumed homoscedastic model\nN.B: The errors do not be normally distributed to be homoscedastic, the errors just need to be roughly the same throughout. They do need to be centered about zero, however.\n### Outliers\n![Susceptible to outliers: an outlier is an observation with a large residual](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1qhS91fwy3MOZ7wUrqp-0MQ.jpeg)\nSusceptible to outliers: an outlier is an observation with a large residual\nLinear regressions are susceptible to outliers. Here, you have a nice linear relationship, this line going through these data points perfectly. The second image is not because that one data point up in the top right is pulling the regression line way up there. Outliers like this can really be a problem, you can get rid of outliers and like that in a variety of ways, like leverage and Cook's Distance.\nLinear regression fits a line based on the means of the x and y values. It fits a line that goes through the means of both values. This line pivots around the point relative to the pull of each point. Points that are farther away from the mean pull harder on the slope - this is leverage. Another way to quantify the 'pull' of each point, is to fit the line to the data without each point and see how the parameters move: this is Cook's Distance.\n### Coefficients and p-values\nWhen the regression line is linear the **regression coefficient** is the constant that represents the rate of change of one variable as a function of the other - it is the **slope of the regression line**.\n  * The p-values for the coefficients indicate whether these relationships are statistically significant.\n  * The **t statistic is the coefficient divided by its standard error.**\n\n\n### Checking the residuals\nThis is important! You should always check for trends in the residuals.\n![You should not see any pattern](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/11qR89DAIfzo_oDvipFzIoA.jpeg)\nYou should not see any pattern\nThere are more data points on the right than the left, and that is ok, that is just the shape of the data. The predicted values on the x-axis and the residuals, the error from the predicted value, on the y-axis.\n  * Residuals = Obsevered (actual data) - Predicted (where the data moves to the regression line)\n\n\nPositive values for the residual (on the y-axis) indicate that the prediction was too low, and negative values indicate that the prediction was too high. A zero means that the guess was exactly correct!\n**THERE SHOULD BE NO PATTERN IN THE RESIDUALS!**\nThe question is, are the residuals closer to this dotted line on the right-hand side than they are on the left-hand side overall? Or even worse - do you see more residuals beneath the dotted line than above the dotted line? What is the dotted line, the dotted line is zero where you have zero residual. The residual again is the discrepancy between your predicted y value and your actual y value. They should all hover around zero because well, the point of the fact of having a predicted y value was to explain your data. And the predicted y value should be generally close to your y value.\nWhen this is not the case you have residuals. Sometimes, seeing an obvious trend in your residuals is an opportunity. That means that you can then use that trend in your residuals to add another model only to your residuals.\nAlways plot the residuals to check for trends. Check the residuals versus y, and make sure that they are, say, always positively correlated, the higher the correlation, the worse the fit. The reason is that if there is a high correlation to the residuals with y, that means that as y gets larger, your residuals get larger. And this actually happens a lot. Testing the normality of the residuals is also important.\nA common sign that your residuals are **heteroscedastic** is the \"fan-shaped\" errors, whereby the errors are larger on the right-hand side than the left-hand side.\n![Note the &quot;fan-shape&quot; in the raw data, the errors are much larger on RHS than LHS](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1uSWhoX_tT662IuBAggQdxg.jpeg)\nNote the \"fan-shape\" in the raw data, the errors are much larger on RHS than LHS\nAgain, there should be no trends apparent in the residuals. But oftentimes the residuals can be assumed to be homoscedastic when they are not, like the fan-shape below. The third outcome, the nonlinear one, is a really bad one that cannot be assumed to be homoscedastic, the error trend is parabolic.\n![](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/14uzXaZ2vNHwmZMTY_TSCMQ.png)\nThis nonlinear error trend is likely an indication that the data has a relationship that is not best captured with the parameters used; **the residuals have information** in them. It looks as if we could actually fit a polynomial to these residuals. Or we could simply add the polynomial to our linear model in the first place and overall we would have fewer errors after doing this.\n### Multiple linear regression\n![All these regressions are linear in parameters](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1a7GtN7B1ZpUG7PZm3hVujQ.jpeg)\nAll these regressions are linear in parameters\nAs mentioned in my previous article, why not make the variables in the last formula linear by saying the exponent is a different variable, like z? These are the new variables that we then have a linear setup for and the equation becomes a multivariant linear regression.\n![Multiple independent variables make this an example of multivariant linear regression](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1Uw7olcHUG9moIA191UPadQ.jpeg)\nMultiple independent variables make this an example of multivariant linear regression\n### One hot encoding vs dummy variables\nThis is commonly misunderstood. There is one-hot encoding (OHE) as one way of doing things, then there is the dummy variable way of encoding for linear regression. The dummy variable is basically the same as OHE, you just do n-1 of the variables. Gender is not OHE when all you have is a column labeled \"gender\" with a 1 being \"male\" and a 0 being \"female\", this here is actually a dummy variable. This is not one hot encoding because there is no column for females, there is only a column for males. So the column should not be called gender, because there exists no such gender as one and zero, this column should be called is male.\nWith the dummy variable, you drop columns, with OHE you never drop columns. That is the definition of what one-hot encoding is. **One hot encoding is not a data science term** , rather it comes from a very different area of engineering. Imparting dummy variables is statistically more useful because you will not have colinearity. But you probably will not have colinearity anyway, probably not for certain. Using OHE allows for better model interpretation. Remember that with OHE, you never drop columns, doing so is imparting a dummy variable.\n## Multiple linear regression in python\nWith the following example, we want to predict the stock price index, just like everyone else.\nN.B: For simplicity, and this is a big no-no, this model just uses the test data for fitting - there is no train/tune/test split.\ntext\n\n```\n# imports\nfrom pandas import DataFrame\nfrom sklearn import linear_model\nimport statsmodels.api as sm\nfrom sklearn.metrics import mean_squared_error, r2_score\nimport matplotlib.pyplot as plt\n```\n\ntext\n\n```\n# create dataframe from stock data\nStock_Market = {'Year': [2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016],\n 'Month': [12, 11,10,9,8,7,6,5,4,3,2,1,12,11,10,9,8,7,6,5,4,3,2,1],\n 'Interest_Rate': [2.75,2.5,2.5,2.5,2.5,2.5,2.5,2.25,2.25,2.25,2,2,2,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75,1.75],\n 'Unemployment_Rate': [5.3,5.3,5.3,5.3,5.4,5.6,5.5,5.5,5.5,5.6,5.7,5.9,6,5.9,5.8,6.1,6.2,6.1,6.1,6.1,5.9,6.2,6.2,6.1],\n 'Stock_Index_Price': [1464,1394,1357,1293,1256,1254,1234,1195,1159,1167,1130,1075,1047,965,943,958,971,949,884,866,876,822,704,719] \n }\n```\n\ntext\n\n```\n# inputs\ndf = DataFrame(Stock_Market,\n columns=['Year','Month','Interest_Rate','Unemployment_Rate','Stock_Index_Price'])\n```\n\ntext\n\n```\n# check that the data is well imported\ndf.head()\n```\n\n![Data looks well imported](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1dcyy_0cFpcdi9ADnIaKcvw.png)\nData looks well imported\nIdentify variables that are interesting and scale them. Scale your data to be safe! You will not have a different outcome if you scale your data in spite of what anyone will tell you - this you can prove mathematically. **My statement is true, as long as you do not consider floating-point stuff**. **If you have very large or very small numbers, then you have floating-point inaccuracy**. And this can then lead to a lot of problems. And you get very large numbers and very small numbers by not scaling, to begin with. If you scale everything, to begin with, then everything looks the same. Everything is between minus two and plus two, everything is centered around zero. The reason why that is that most people will scale according will scale on use what is called a standard scaler, which is your normal or your Gaussian distribution. What you do is subtract away the mean, and then you divide by the standard deviation.\nAnother benefit to scaling is that if you use an iterative methodology, your data will generally converge faster if you have scaled it. But, as long as you have a linear system - there is a mathematical proof (this is a so-called convex problem) and if it is such, there is a specific solution in all cases, regardless of data scaling. In principle, you will not get more or less accuracy if you scale - however floating point inaccuracies are a thing to watch out for!\nWe keep \"Interest_Rate\" and \"Unemployment_Rate\" for further analysis:\ntext\n\n```\nx = df[['Interest_Rate','Unemployment_Rate']]\ny = df['Stock_Index_Price']\n```\n\ntext\n\n```\n# scale the data\nfrom sklearn.preprocessing import StandardScaler\nscaler = StandardScaler()\nscaler.fit(x)\nx = scaler.transform(x)\n```\n\ntext\n\n```\nfrom sklearn.linear_model import LinearRegression\nregression_model = LinearRegression()\n# Fit the data(train the model)\nregression_model.fit(x, y)\n```\n\ntext\n\n```\n# predict\ny_predicted = regression_model.predict(x)\n```\n\ntext\n\n```\nprint('Intercept: n', regression_model.intercept_) # pull out intercept\nprint('Coefficients: n', regression_model.coef_) # pull out coeffeicients\n```\n\n![](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1Htvn4DylPQrhQD1_C9cLCA.png)\nThis output includes the intercept and coefficients to build the multiple linear regression equation.\nN.B: We scaled the data, so the coefficients above reflect that. Nonetheless, there is a correlation between high-interest rates and stock prices rising and a smaller correlated effect with prices rising as unemployment falls. We can see that the scaled coefficients are roughly the same and are therefore directly comparable.\ntext\n\n```\nStock_Index_Price = (Intercept) + (Interest_Rate coef)*X1 + (Unemployment_Rate coef)*X2\n```\n\nPlugging in new numbers:\ntext\n\n```\nStock_Index_Price = (1070.083) + (118.233)*X1 + (-80.815)*X2\n```\n\ntext\n\n```\n# prediction with sklearn\nNew_Interest_Rate = 2.75\nNew_Unemployment_Rate = 5.3\n# create a scaled feature array and make the prediction\nfeature_array = scaler.transform([[New_Interest_Rate ,New_Unemployment_Rate]])\nprint ('Predicted Stock Index Price: n', regression_model.predict(feature_array))\n```\n\n![Given the new interest and unemployment rates, we expect the stock to be this price](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1mQbbLU6qF3i7pqMblxLChg.jpeg)\nGiven the new interest and unemployment rates, we expect the stock to be this price\n### Stats models\nSame analysis but this time with `sm`. Again I stress the more important package to know is `sklearn`\ntext\n\n```\n# with statsmodels\nX = sm.add_constant(x) # adding a constant\n\nmodel = sm.OLS(y, X).fit()\npredictions = model.predict(X) \n\nprint_model = model.summary()\nprint(print_model)\n```\n\n![Adj R² is always lower than R² | We lose 2 degrees of freedom thanks to the multiple inputs](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1sYoXMGDYEeliloVrjD7A-g.jpeg)\nAdj R² is always lower than R² | We lose 2 degrees of freedom thanks to the multiple inputs\ntext\n\n```\n# Summary graphs:\nimport scipy.stats as stats\nimport statsmodels.api as statsmodels\nfrom statsmodels.graphics.regressionplots import *\nimport seaborn as sns\nimport numpy as np\n```\n\ntext\n\n```\nsns.distplot(model.resid, hist=True)\nplt.grid(True)\nplt.xlabel('Residual')\nplt.ylabel('Frequency')\nplt.title('Residual Histogram')\nplt.show()\n```\n\ntext\n\n```\n# Residuals vs Fitted Values\nresiduals = model.resid # outlier_linear = name of linear model on #our dataset\nfitted_vals = model.predict(X) # making predictions from our fit #model\n```\n\ntext\n\n```\nplt.plot(fitted_vals, residuals, 'o') # plotting predictions from #fit model vs residuals\n```\n\ntext\n\n```\nplt.xlabel('Fitted Values')\nplt.ylabel('Residuals')\nplt.title('Residuals vs. Fitted Values (w/ 1 outlier)')\nplt.show()\n```\n\ntext\n\n```\n# create Q-Q plot to ensure normality\nstatsmodels.qqplot(residuals, stats.norm, fit=True, line='45')\n```\n\ntext\n\n```\n# leverage Plot (Cook's Distance)\ninfluence_plot(model) # from statsmodels.graphics.regressionplots #import *\n```\n\n![Residuals appear reasonably normally distributed](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1c4E7u20JlGw28r5FlORzdg.jpeg)\nResiduals appear reasonably normally distributed\n![Residual plot, no apparent trend - residuals appear reasonably homoscedastic](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1oh8dA0yZnmrtETdQoYG0MQ.jpeg)\nResidual plot, no apparent trend - residuals appear reasonably homoscedastic\n![As expected, larger residual = larger influence on the fitted line | residuals are normalized \\(studentized\\)](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/1_sB6lzxQkGdnIo8NCREGQA.jpeg)\nAs expected, larger residual = larger influence on the fitted line | residuals are normalized (studentized)\n![Data appears normally distributed, histogram confirmed](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/03/17vW5IpTiL1UlH_OkEPixDg.jpeg)\nData appears normally distributed, histogram confirmed\n### Conclusion\nWe have explored linear models in depth and run some Jupyter Notebook code cells to explore least-squares linear regression. Remember linear refers to the parameters - in the above stock example the data is multivariant: we used interest rates AND unemployment rates to predict a numeric outcome: the stock price GIVEN those inputs. The importance of homoscedasticity of the residuals was emphasized as was, albeit briefly, leverage and outliers.\nIn my next article, I will expand these concepts and explore using [bootstrap with regression models](https://towardsdatascience.com/linear-regression-with-bootstrapping-4924c05d2a9)!\nFind me on [Linkedin](https://www.linkedin.com/in/james-a-w-godwin/)\n_Physicist cum Data Scientist- Available for new opportunity | SaaS | Sports | Start-ups | Scale-ups_\n## Register Now to Continue Reading\n### Unlock Towards Data Science with a Free Account\nAll articles on Towards Data Science are available to registered users. Create a free account today to access this article and thousands more.\nRegister for freeSign in to your account\n* * *\n![](https://assets.insightmediagroup.io/media/1787657234707_1wi608.jpeg)\nWritten By\n## [James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\n[See all from James Andrew Godwin](https://towardsdatascience.com/author/james-andrew/)\n[Data Science](https://towardsdatascience.com/tag/data-science/)[Linear Regression Python](https://towardsdatascience.com/tag/linear-regression-python/)[Multiple Linearregression](https://towardsdatascience.com/tag/multiple-linearregression/)[Towards Data Science](https://towardsdatascience.com/tag/towards-data-science/)\nShare This Article\n  * [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&title=Multivariant%20Linear%20Regression)\n  * [](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&title=Multivariant%20Linear%20Regression)\n  * [](https://x.com/share?url=https%3A%2F%2Ftowardsdatascience.com%2Fmultivariant-linear-regression-e636a4f99b40%2F&text=Multivariant%20Linear%20Regression)\n\n\nTowards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.\n[Write for TDS](https://towardsdatascience.com/submissions/)\n## Related Articles\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2022/06/0Ik0KicQBZHAUyzxi-scaled.jpg)](https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3/)\n## [4 Powerful Rules for Better Data Science](https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3/)\n[Data Science](https://towardsdatascience.com/category/data-science/)\nFollowing these rules has drastically improved my effectiveness as a data scientist to deliver more value from my work\n[Adam Sroka](https://towardsdatascience.com/author/aesroka/)\nJune 27, 20229 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/07/0kjDqAHZTKKH6VIpp-scaled.jpg)](https://towardsdatascience.com/the-power-of-ensemble-learning-and-data-augmentation-435c62e13c57/)\n## [The Power of Ensemble Learning and Data Augmentation](https://towardsdatascience.com/the-power-of-ensemble-learning-and-data-augmentation-435c62e13c57/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nFull code examples on the MNIST dataset with VGG16 | ResNet50 | FG-UNET | Majority Voting | Single Transferable Vote | Instant-Runoff...\n[Cathie So, PhD](https://towardsdatascience.com/author/cathieso/)\nJuly 1, 20219 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2025/10/Philosopher-1.jpg)](https://towardsdatascience.com/building-a-rules-engine-from-first-principles/)\n## [Building a Rules Engine from First Principles](https://towardsdatascience.com/building-a-rules-engine-from-first-principles/)\n[Algorithms](https://towardsdatascience.com/category/algorithms/)\nHow recasting propositional logic as sparse algebra leads to an elegant and efficient design\n[Dmitry Lesnik](https://towardsdatascience.com/author/dmitry.lesnik/)\nOctober 30, 202516 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2020/12/0haZOojvbcQ9PAeO4-scaled.jpg)](https://towardsdatascience.com/why-are-southern-californians-obsessed-with-guns-c80ae281f1e8/)\n## [Which American City has the Most Gun Shops?](https://towardsdatascience.com/why-are-southern-californians-obsessed-with-guns-c80ae281f1e8/)\n[Data Science](https://towardsdatascience.com/category/data-science/)\nYelp data reveals cities with the most gun shops per capita\n[William Chon](https://towardsdatascience.com/author/williamchon/)\nDecember 26, 20203 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2019/01/1F0p2WOAM3CGCZBy6lKhM7g.png)](https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-kmeans-clustering-pca-b7ba6fafa74/)\n## [Andrew Ng's Machine Learning Course in Python (Kmeans-Clustering, PCA)](https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-kmeans-clustering-pca-b7ba6fafa74/)\n[Machine Learning](https://towardsdatascience.com/category/artificial-intelligence/machine-learning/)\nKmeans-Clustering, PCA\n[Benjamin Lau](https://towardsdatascience.com/author/ben_lau93/)\nJanuary 8, 20197 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/08/1nLI9YUORiLbHELG4rAwLrw-scaled.jpeg)](https://towardsdatascience.com/6-pandas-tricks-that-you-might-not-know-but-should-6f766dfdb2c2/)\n## [6 Pandas Tricks That You Might Not Know, But Should](https://towardsdatascience.com/6-pandas-tricks-that-you-might-not-know-but-should-6f766dfdb2c2/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nHelpful for your daily tasks\n[Pranjal Saxena](https://towardsdatascience.com/author/pranjalai/)\nAugust 23, 20214 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2021/06/1lovxQO12mwBmO3mhK2QeIg-scaled.jpeg)](https://towardsdatascience.com/serverless-model-hosting-with-docker-aws-lambda-and-api-gateway-2d79382ecb45/)\n## [Serverless Model Hosting with Docker, AWS Lambda and API Gateway](https://towardsdatascience.com/serverless-model-hosting-with-docker-aws-lambda-and-api-gateway-2d79382ecb45/)\n[Machine Learning](https://towardsdatascience.com/category/artificial-intelligence/machine-learning/)\nMake the most of Docker support in Lambda to host your models without the need for dedicated servers.\n[Jonathan Readshaw](https://towardsdatascience.com/author/readshawjonathan/)\nJune 20, 20213 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2022/02/1KaGHjdDf4pBHY3uXKFGveg.png)](https://towardsdatascience.com/location-analytics-use-cases-that-every-data-scientist-should-know-740b708a2504/)\n## [Location Analytics Use-Cases that Every Data Scientist Should Know](https://towardsdatascience.com/location-analytics-use-cases-that-every-data-scientist-should-know-740b708a2504/)\n[Artificial Intelligence](https://towardsdatascience.com/category/artificial-intelligence/)\nPowerful ways to use location analytics\n[Pranay Dave](https://towardsdatascience.com/author/pranay-dave9/)\nFebruary 22, 20225 min read\n  * [![](https://assets.insightmediagroup.io/media/wp-content/uploads/2020/12/0lsM6IHNmCpJqAMJv-scaled.jpg)](https://towardsdatascience.com/comprehending-python-list-comprehensions-ii-lost-in-new-york-e8af27038f4b/)\n## [Comprehending Python Lists](https://towardsdatascience.com/comprehending-python-list-comprehensions-ii-lost-in-new-york-e8af27038f4b/)\n[Programming](https://towardsdatascience.com/category/programming/)\nA beginner's guide to Python object comprehensions and protecting your home from a Joe Pesci-type burglar\n[Joe Marx](https://towardsdatascience.com/author/joebrowz/)\nDecember 10, 20207 min read\n\n\n  * [YouTube](https://www.youtube.com/c/TowardsDataScience)\n  * [X](https://x.com/TDataScience)\n  * [LinkedIn](https://www.linkedin.com/company/towards-data-science/)\n  * [Threads](https://www.threads.net/@towardsdatascience)\n  * [Bluesky](https://bsky.app/profile/towardsdatascience.com)\n\n\n[](https://towardsdatascience.com/)\nYour home for data science and AI. The world's leading publication for data science, data analytics, data engineering, machine learning, and artificial intelligence professionals.\nSubscribe to Our Newsletter[Write For TDS](https://towardsdatascience.com/submissions/)•[About](https://towardsdatascience.com/about-towards-data-science-d691af11cc2f/)•[Advertise](https://contact.towardsdatascience.com/advertise-with-towards-data-science)•[Privacy Policy](https://towardsdatascience.com/privacy-policy/)•[Terms of Use](https://towardsdatascience.com/website-terms-of-use/)\n© Insight Media Group, LLC 2026•[The New Stack](https://thenewstack.io)•[roadmap.sh](https://roadmap.sh)•[Creator Network](https://insightmediagroup.io/creator-network)\n####  Recommended Articles \nClose\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607686/image?etag=1782161464448&width=500&height=500) How Relevance Models Foreshadowed Transformers for NLP ](https://towardsdatascience.com/how-relevance-models-foreshadowed-transformers-for-nlp/ \"How Relevance Models Foreshadowed Transformers for NLP\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607639/image?etag=1781250125848&width=500&height=500) Javascript Fatigue: HTMX Is All You Need to Build ChatGPT — Part 1 ](https://towardsdatascience.com/javascript-fatigue-you-dont-need-js-to-build-chatgpt/ \"Javascript Fatigue: HTMX Is All You Need to Build ChatGPT — Part 1\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/607930/image?etag=1782124566054&width=500&height=500) The Subset Sum Problem Solved in Linear Time for Dense Enough Inputs ](https://towardsdatascience.com/subset-sum-problem-solved-in-linear-time-for-dense-enough-inputs/ \"The Subset Sum Problem Solved in Linear Time for Dense Enough Inputs\")\n  * [ ![](https://h030.towardsdatascience.com/rest/v2/contentStores/d7d3a4ab-7caf-4383-bbd2-fbf7fb4f1787/items/3660/image?etag=1780176246070&width=500&height=500) Does Your Company Have a Data Strategy? ](https://towardsdatascience.com/does-your-company-have-a-data-strategy-e8944dbec4ae/ \"Does Your Company Have a Data Strategy?\")\n\n\n",
  "body_base_path": "attachments/c56372b116e4/pages/",
  "body_markdown_path": "attachments/c56372b116e4/pages/archived-body.md",
  "local_html": "attachments/c56372b116e4/pages/archived-body.html",
  "body_source": "prior_capture"
}