我绘制了多元回归的Q-Q图,得到了下面的图表。有人能告诉我为什么有两个点在红线下方吗?这些点对我的模型有影响吗?
我使用以下代码绘制了图表。
from sklearn.linear_model import LinearRegressionreg = LinearRegression()reg = reg.fit(x_train,y_train)pred_reg_GS = reg.predict(x_test)diff= y_test-pred_reg_GSimport statsmodels.api as smsm.qqplot(diff,fit=True,line='45')plt.show()
回答:
请查看Understanding Q-Q Plots,以了解Q-Q图的简要描述。在你的情况下,这一部分尤为重要:
如果两组分位数来自相同的分布,我们应该看到点形成的线大致是直的。
你的图表中用红线明确展示了这种理论上的一对一关系。
关于你的问题…
这些点对我的模型有影响吗?
…离红线较远的一个或两个点可能被认为是异常值。这意味着你试图构建的模型未能捕捉到这两个观测值的特性。如果我们在这里看到的是回归模型残差的Q-Q图,你应该仔细查看这两个观测值。这两个观测值有什么特别之处,使它们与样本中的其他观测值不同?一种捕捉这些异常值的方法通常是用一个或两个虚拟变量来表示它们。
编辑1:处理异常值和虚拟变量的基本方法
由于你没有明确标记你的问题为sklearn
,我冒昧地使用statsmodels
来举例说明。并且由于没有你的数据样本,我将使用内置的iris
数据集,其中我们将使用的数据集的最后一部分看起来像这样:
1. 萼片宽度对萼片长度的线性回归
图表1:
看起来不错!这里没有问题。但让我们通过向数据集中添加一些极端值来改变一下。你将在最后找到完整的代码片段。
2. 引入一个异常值
现在,让我们在数据框中添加一行,“sepal_width = 8而不是
3`。这将给你一个非常明显的异常值的Q-Q图:
这是模型摘要的一部分:
=============================================================================== coef std err t P>|t| [0.025 0.975]-------------------------------------------------------------------------------sepal_width 1.8690 0.033 57.246 0.000 1.804 1.934==============================================================================Omnibus: 18.144 Durbin-Watson: 0.427Prob(Omnibus): 0.000 Jarque-Bera (JB): 7.909Skew: -0.338 Prob(JB): 0.0192Kurtosis: 2.101 Cond. No. 1.00==============================================================================
那么,为什么这是个异常值呢?因为我们篡改了数据集。你的数据集中异常值的原因我无法确定。在我们编造的例子中,一株setosa鸢尾花的萼片宽度为8的原因可能是多种多样的。可能是科学家标记错误了?也可能它根本不是setosa?或者它可能被基因改造过?现在,与其简单地从样本中丢弃这个观测值,通常更有信息价值的是保留它,接受这个观测值有某些特殊之处,并通过包含一个虚拟变量来明确这一点,该变量对于该观测值为1
,对于所有其他观测值为0
。现在,你的数据框的最后一部分应该看起来像这样:
3. 使用虚拟变量识别异常值
现在,你的Q-Q图将看起来像这样:
这是你的模型摘要:
================================================================================= coef std err t P>|t| [0.025 0.975]---------------------------------------------------------------------------------sepal_width 1.4512 0.015 94.613 0.000 1.420 1.482outlier_dummy -6.6097 0.394 -16.791 0.000 -7.401 -5.819==============================================================================Omnibus: 1.917 Durbin-Watson: 2.188Prob(Omnibus): 0.383 Jarque-Bera (JB): 1.066Skew: 0.218 Prob(JB): 0.587Kurtosis: 3.558 Cond. No. 27.0==============================================================================
请注意,包含一个虚拟变量会改变sepal_widht
的系数估计值,以及Skewness
和Kurtosis
的值。这就是异常值对你的模型产生影响的简短版本。
完整代码:
import numpy as npimport pandas as pdimport statsmodels.api as smfrom matplotlib import pyplot as pltimport seaborn as sns# 样本数据df = pd.DataFrame(sns.load_dataset('iris'))# 样本数据的子集df=df[df['species']=='setosa']# 添加列用于虚拟变量df['outlier_dummy']=0# 追加一行,包含萼片宽度的极端值# 以及该行的虚拟变量 = 1df.loc[len(df)] = [5,8,1.4, 0.3, 'setosa', 1]# 定义自变量x=['sepal_width', 'outlier_dummy']# 运行回归mod_fit = sm.OLS(df['sepal_length'], df[x]).fit()res = mod_fit.residfig = sm.qqplot(res)plt.show()mod_fit.summary()