数据挖掘—— 线性回归
编写不易 如有不足望各位大佬即使指出 若有帮助请留下一个小赞👍
-
简单线性回归
-
简单线性回归是最基本的线性回归模型,它研究一个自变量(X)和一个因变量(Y)之间的线性关系。在数学表达式中,简单线性回归可以表示为:
其中:
- Y 是因变量。
- X 是自变量。
- 0β0 是截距项。
- 1β1 是斜率,表示X每变化一个单位,Y预期将如何变化。
- ϵ 是误差项,表示模型无法解释的随机变异。
-
多元线性回归
-
多元线性回归(Multiple Linear Regression)
多元线性回归是简单线性回归的扩展,它允许研究多个自变量(X1, X2, ..., Xn)与一个因变量(Y)之间的关系。数学表达式如下:
其中:
是因变量。
是自变量。
是截距项。
是各自变量的系数,表示相应自变量每变化一个单位,Y预期将如何变化。
是误差项。
- 简单线性回归 适用于研究单一因素对结果的影响,例如研究广告支出与销售额之间的关系。
- 多元线性回归 适用于研究多个因素对结果的综合影响,例如研究教育水平、工作经验和性别等因素对工资水平的影响。
- R-squared(决定系数):衡量模型解释的变异性的比例。
- Adjusted R-squared:对R-squared进行调整,考虑自变量的数量。
- F-statistic:检验模型中所有自变量的联合显著性。
- P-values:检验每个自变量的显著性。
- 线性回归假设自变量和因变量之间存在线性关系。
- 需要检查数据的正态性、线性、独立性和同方差性。
- 多重共线性可能会影响模型的稳定性和解释性。
- 模型诊断是必要的,以确保模型假设得到满足。
-
Python编程基础
- 1)
实验环境
Jupyter
-
2)准备工作
点击屏幕右上方的下载实验数据模块,选择下载linear_regression_details.tgz到指定目录下,然后再依次选择点击上方的File->Open->Upload,上传刚才下载的数据集压缩包,再使用如下命令解压:
!tar -zxvf linear_regression_details.tgz linear_regression_details/ linear_regression_details/Advertising.csv.bak linear_regression_details/Advertising.csv3)关于广告数据的问题
# read data into a DataFrame import pandas as pd import matplotlib.pyplot as plt import statsmodels.formula.api as smf data = pd.read_csv('linear_regression_details/Advertising.csv', index_col=0) print(data.head())TV radio newspaper sales
NO
1 230.1 37.8 69.2 22.1
2 44.5 39.3 45.1 10.4
3 17.2 45.9 69.3 9.3
4 151.5 41.3 58.5 18.5
5 180.8 10.8 58.4 12.9
可以看出数据具有以下特点:
电视:在特定市场中为单个产品花费在电视上的广告费(数千美元)
电台:在广播上花费的广告费
报纸:在报纸上花费的广告费
数据的回应为:
销售:在给定市场中销售单个产品的数目(以:千个小部件为单位)
打印散点图可以看出数据间的关系:
# visualize the relationship between the features and the response using scatterplots fig, axs = plt.subplots(1, 3, sharey=True) data.plot(kind='scatter', x='TV', y='sales', ax=axs[0], figsize=(16, 8)) data.plot(kind='scatter', x='radio', y='sales', ax=axs[1]) data.plot(kind='scatter', x='newspaper', y='sales', ax=axs[2])假如你是制造和营销这个小部件公司的产品分析师。根据这些数据,将如何使用广告费?
这个一般性问题可能会引导您提出更具体的问题:
广告和销售之间是否存在关系?
这种关系有多强?
哪种广告类型有助于销售?
每种广告类型的销售效果如何?
考虑到特定市场的广告支出,可以预测销售吗?
我们将用线性回归探讨这些问题!
6.简单线性回归
简单线性回归是使用单个特征(或“预测变量”或“输入变量”)预测定量响应的方法。它采用以下形式:
Y=β0+β1X
其中:Y是销售量,X是特征,β0是截距,β1是X的系数。其中β0和β1一起被称作模型系数。利用这些系数的值,可以创建模型来预测销售。
一般来说,使用最小二乘准则估计系数,这意味着我们要找到最小化残差平方和(或“平方误差之和”)的线(数学上):
在图中:
β0是截距(x=0时y的值)
β1是斜率(y的变化除以x的变化)
添加以下代码:
让我们使用Statsmodels估算广告数据的模型系数:
# create a fitted model in one line lm = smf.ols(formula='sales ~ TV', data=data).fit() # print the coefficients print(lm.params)Intercept 7.032594
TV 0.047537
dtype: float64
我们可以这样解释截距β1:电视广告支出的“单位”增长与销售额的0.047537“单位”增长有关。或者解释为电视广告花费的额外1,000美元与47.537小部件的销售额增长有关。需要注意的一点是,如果电视广告支出的增长与销售额下降相关,则β1会是负数的。
接下来我们可以利用模型进行预测了:如果有一个新的市场,电视广告支出是50,000美元。我们对该市场的销售情况有何预测?
Y=β0+β1X
Y=7.032594+0.047537*50
X_new = pd.DataFrame({'TV': [50]}) print(X_new) # use the model to make predictions on a new value print(lm.predict(X_new))0 9.409426
dtype: float64
因此,我们预测市场上将出售9,409个部件。然后让我们对x的最小和最大观测值进行预测,然后使用预测值绘制最小二乘线。
# create a DataFrame with the minimum and maximum values of TV X_new = pd.DataFrame({'TV': [data.TV.min(), data.TV.max()]}) X_new.head() # make predictions for those x values and store them preds = lm.predict(X_new) print("preds is") print(preds) # first, plot the observed data data.plot(kind='scatter', x='TV', y='sales') # then, plot the least squares line plt.plot(X_new, preds, c='red', linewidth=2)preds is
0 7.065869
1 21.122454
dtype: float64
[<matplotlib.lines.Line2D at 0x7f6479f3c390>]
模型评价
让我们来思考一下:线性回归是高偏差/低方差模型,还是低偏差/高方差模型?
正确答案是高偏差/低差异。在重复采样下,线将大致保持在同一位置(低方差),但这些模型的平均值不会很好地捕获真实关系(高偏差)。请注意,当没有大量训练数据时,低方差是一个有用的特性!
一个密切相关的概念是置信区间。Statsmodels计算我们的模型系数的95%置信区间,其解释如下:如果抽取该样本的人口被抽样100次,那么大约95个置信区间将包含“真实”系数。
# print the confidence intervals for the model coefficients print("\nconf is") print(lm.conf_int())conf is
0 1
Intercept 6.129719 7.935468
TV 0.042231 0.052843
记住,我们只有一个数据样本,而不是整个数据群。“真实”系数要么在这个区间内,要么不在,但是没有办法真正知道。我们用我们所拥有的数据估计系数,并通过给出系数可能在的范围来显示该估计的不确定性。使用95%置信区间只是一种惯例。也可以创建90%置信区间(更窄),99%置信区间(更宽)或任何间隔。
与置信区间密切相关的是假设检验。一般来说,从零假设和替代假设(与零相反)开始。然后,检查数据是否支持拒绝原假设或不能拒绝原假设。它与模型系数有关,这里是传统的假设检验:
零假设:电视广告和销售之间没有关系(因此β1等于零)
另类假设:电视广告与销售之间存在关联(因此β1不等于零)
我们如何测试这个假设呢?直观地,如果95%置信区间不包括零,我们拒绝null。相反,p值表示系数实际为零的概率:
# print the p-values for the model coefficients print("\npvalues are") print(lm.pvalues)pvalues are
Intercept 1.406300e-35
TV 1.467390e-42
dtype: float64
如果95%置信区间包括零,则该系数的p值将大于0.05。如果95%置信区间不包括零,则p值将小于0.05。因此,小于0.05的p值是决定特征和响应之间是否可能存在关系的一种方式。(同样,使用0.05作为截止值只是一种惯例。)在这种情况下,电视的p值远小于0.05,因此我们认为电视广告与销售之间存在关联。注意一点,我们通常会忽略截距的p值。
评估线性模型整体拟合的最常用方法是R平方值。R平方是解释的方差的比例,意味着由模型解释的观察数据中的方差比例,或者在空模型上的误差减少。(null模型只是预测观察到的响应的平均值,因此它有一个截距,没有斜率。)
R平方在0和1之间,并且更高更好,因为这意味着模型解释了更多的方差。这是一个R平方“looks like”的例子:
可以看到蓝线解释了数据中的一些方差(R平方= 0.54),绿线解释了更多的方差(R平方= 0.64),红线更符合训练数据( R平方= 0.66)。(红线看起来是否过度拟合?)让我们计算简单线性模型的R平方值:
# print the R-squared value for the model print("\nrsquared is") print(lm.rsquared)rsquared is
0.61187505085
这是一个“好”的R平方值吗?很难说。良好的R平方值的阈值在很大程度上取决于域。因此,它作为比较不同模型的工具最有用。
7.多元线性回归
简单的线性回归可以很容易地扩展到包含多个功能。这称为多元线性回归:
y = β0+ β1X1+ 。。。+ βñXñ
每个x表示不同的特征,每个特征都有自己的系数。在这种情况下:
y=β0+β1×TV+β2×Radio+β3×Newspapery
我们使用Statsmodels来估计这些系数:
# create a fitted model with all three features lm = smf.ols(formula='sales ~ TV + radio + newspaper', data=data).fit() # print the coefficients print("lm.params is") print(lm.params)lm.params is
Intercept 2.938889
TV 0.045765
radio 0.188530
newspaper -0.001037
dtype: float64
从系数可以看出,对于给定数量的广播和报纸广告支出,电视广告支出增加1000美元与销售额增加45.765小部件有关。
我们一直在审查的许多信息都可以在模型摘要输出中找到:
# print a summary of the fitted model print("lm summary") print(lm.summary())lm summary
OLS Regression Results
==============================================================================
Dep. Variable: sales R-squared: 0.897
Model: OLS Adj. R-squared: 0.896
Method: Least Squares F-statistic: 570.3
Date: Mon, 22 Jul 2019 Prob (F-statistic): 1.58e-96
Time: 10:13:59 Log-Likelihood: -386.18
No. Observations: 200 AIC: 780.4
Df Residuals: 196 BIC: 793.6
Df Model: 3
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 2.9389 0.312 9.422 0.000 2.324 3.554
TV 0.0458 0.001 32.809 0.000 0.043 0.049
radio 0.1885 0.009 21.893 0.000 0.172 0.206
newspaper -0.0010 0.006 -0.177 0.860 -0.013 0.011
==============================================================================
Omnibus: 60.414 Durbin-Watson: 2.084
Prob(Omnibus): 0.000 Jarque-Bera (JB): 151.241
Skew: -1.327 Prob(JB): 1.44e-33
Kurtosis: 6.332 Cond. No. 454.
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
我们从这个输出中学到了几个关键的东西:
电视和广播具有显着的p值,而报纸没有。因此,我们拒绝电视和广播的零假设(这些特征和销售之间没有关联),并且不能拒绝报纸的零假设。
电视和广播广告支出与销售额正相关,而报纸广告支出与销售额略有负相关。(但是,这是无关紧要的,因为我们未能拒绝报纸的零假设。)
该模型具有比先前模型更高的R平方(0.897),这意味着该模型比仅包括TV的模型更好地适合数据。
如何确定要在线性模型中包含哪些要素?这是一个想法:
尝试不同的模型,只有在p值较小的情况下才能在模型中保留预测变量。
添加新预测变量时,请检查R平方值是否上升。
这种方法哪些有缺点?
线性模型依赖于许多假设(例如特征是独立的),并且如果这些假设被违反(它们通常是这样),则R平方和p值不太可靠。
使用0.05的p值截止值意味着如果向模型中添加100个纯粹噪声的预测变量,其中5个(平均值)仍将被视为重要值。
R平方易受过度拟合影响,因此无法保证具有高R平方值的模型将推广。以下是一个例子:
# only include TV and Radio in the model lm = smf.ols(formula='sales ~ TV + radio', data=data).fit() print("lm.rsquared is") print(lm.rsquared)lm.rsquared is
0.897194261083
# add Newspaper to the model (which we believe has no association with Sales) lm = smf.ols(formula='sales ~ TV + radio + newspaper', data=data).fit() print("lm.rsquared is") print(lm.rsquared)lm.rsquared is
0.897210638179
当向模型添加更多功能时,R平方将始终增加,即使它们与响应无关。因此,选择具有最高R平方的模型不是选择最佳线性模型的可靠方法。R平方的替代方案称为调整后的R平方,它会惩罚模型的复杂性(控制过度拟合),但它通常会使复杂性不足。
那么有更好的特征选择方法吗?交叉验证。它提供了更可靠的样本外错误估计,因此是选择哪种模型最好地推广到样本外数据的更好方法。scikit-learn中有交叉验证的广泛功能,包括用于搜索不同参数集和不同模型的自动化方法。重要的是,交叉验证可以应用于任何模型,而上述方法仅适用于线性模型。
scikit-learn中的线性回归
import pandas as pd import matplotlib.pyplot as plt import statsmodels.formula.api as smf from sklearn.linear_model import LinearRegression import numpy as np data = pd.read_csv('linear_regression_details/Advertising.csv', index_col=0)让我们在scikit-learn中重做上面的一些Statsmodels代码:
# create X and y feature_cols = ['TV', 'radio', 'newspaper'] X = data[feature_cols] y = data.sales lm = LinearRegression() lm.fit(X, y) # print intercept and coefficients print(lm.intercept_) print(lm.coef_)2.93888936946
[ 0.04576465 0.18853002 -0.00103749]
# pair the feature names with the coefficients for each in zip(feature_cols, lm.coef_): print(each) ('TV', 0.045764645455397601) ('radio', 0.18853001691820448) ('newspaper', -0.0010374930424763285) # predict for a new observation print(lm.predict(np.asarray([100, 25, 25]).reshape(1,-1)))[ 12.20266701]
# calculate the R-squared print(lm.score(X, y))0.897210638179
请注意,p值和置信区间不能(轻松)通过scikit-learn访问。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)