Python:如何处理回归Q-Q图中的异常值?

Python:如何处理回归Q-Q图中的异常值?,python,machine-learning,regression,data-science,Python,Machine Learning,Regression,Data Science,我画了qq图多元回归,我得到了下图。有人能告诉我为什么红线下有两点吗?这些点对我的模型有影响吗 我使用下面的代码来绘制图表 from sklearn.linear_model import LinearRegression reg = LinearRegression() reg = reg.fit(x_train,y_train) pred_reg_GS = reg.predict(x_test) diff= y_test-pred_reg_GS import statsmodels.a

我画了qq图多元回归,我得到了下图。有人能告诉我为什么红线下有两点吗?这些点对我的模型有影响吗

我使用下面的代码来绘制图表

from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg = reg.fit(x_train,y_train)

pred_reg_GS = reg.predict(x_test)
diff= y_test-pred_reg_GS

import statsmodels.api as sm
sm.qqplot(diff,fit=True,line='45')
plt.show()
看看QQ情节的简明描述。在您的情况下,这一部分很重要:

如果两组分位数来自相同的分布,我们应该 请看形成大致直线的点

这种理论上的一对一关系在你的图中用红线清楚地说明了

关于你的问题

这对我的模型有什么影响

。。。远离红线的一个或两个点可能被视为异常值。这意味着,无论您试图在这里构建什么模型,都无法捕获这些观测值的属性。若我们在这里看到的是回归模型残差的QQ图,你们应该仔细看看这两个观测值。这两个是什么让它们从你的样本中脱颖而出的?“捕获”这些异常值的一种方法通常是用一个或两个虚拟变量来表示它们


编辑1:异常值和伪变量的基本方法


由于您没有明确标记您的问题
sklearn
,我冒昧地用
statsmodels
来说明这一点。我将使用内置的
iris
数据集来代替您的数据样本,其中我们将使用的最后一部分如下所示:

1.萼片宽度与萼片长度的线性回归 绘图1:

import numpy as np
import pandas as pd
import statsmodels.api as sm
from matplotlib import pyplot as plt
import seaborn as sns

# sample data
df = pd.DataFrame(sns.load_dataset('iris'))

# subset of sample data
df=df[df['species']=='setosa']

# add column for dummy variable
df['outlier_dummy']=0

# append line with extreme value for sepal width
# as well as a dummy variable = 1 for that row.
df.loc[len(df)] = [5,8,1.4, 0.3, 'setosa', 1]

# define independent variables
x=['sepal_width', 'outlier_dummy']

# run regression
mod_fit = sm.OLS(df['sepal_length'], df[x]).fit()
res = mod_fit.resid

fig = sm.qqplot(res)
plt.show()
mod_fit.summary()

看起来不错!这里没什么问题。但是,让我们通过向数据集添加一些极值来混合它。您将在末尾找到完整的代码段

2.引入异常值 现在,让我们在数据框中添加一行,其中``sepal_width=8
,而不是
3`。 这将为您提供以下带有非常明显异常值的qqplot:

以下是模型摘要的一部分:

===============================================================================
                  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.427
Prob(Omnibus):                  0.000   Jarque-Bera (JB):                7.909
Skew:                          -0.338   Prob(JB):                       0.0192
Kurtosis:                       2.101   Cond. No.                         1.00
==============================================================================
=================================================================================
                    coef    std err          t      P>|t|      [0.025      0.975]
---------------------------------------------------------------------------------
sepal_width       1.4512      0.015     94.613      0.000       1.420       1.482
outlier_dummy    -6.6097      0.394    -16.791      0.000      -7.401      -5.819
==============================================================================
Omnibus:                        1.917   Durbin-Watson:                   2.188
Prob(Omnibus):                  0.383   Jarque-Bera (JB):                1.066
Skew:                           0.218   Prob(JB):                        0.587
Kurtosis:                       3.558   Cond. No.                         27.0
==============================================================================
那么为什么这是一个异常值?因为我们弄乱了数据集。我无法确定数据集中出现异常值的原因。在我们编造的例子中,如果8可能是多个,则刚毛鸢尾具有萼片宽度的原因。也许科学家给它贴错了标签?也许它根本就不是一只刚毛?或者可能是转基因的?现在,不只是从样本中丢弃这个观察值,而是将它保留在原处,接受这个观察值有一些特殊之处,并通过包含一个虚拟变量(该观察值为
1
,其他所有观察值为
0
)来准确地说明这一点,通常会提供更多信息。现在,数据帧的最后一部分应该如下所示:

3.使用虚拟变量识别异常值 现在,您的qqplot将如下所示:

以下是您的模型摘要:

===============================================================================
                  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.427
Prob(Omnibus):                  0.000   Jarque-Bera (JB):                7.909
Skew:                          -0.338   Prob(JB):                       0.0192
Kurtosis:                       2.101   Cond. No.                         1.00
==============================================================================
=================================================================================
                    coef    std err          t      P>|t|      [0.025      0.975]
---------------------------------------------------------------------------------
sepal_width       1.4512      0.015     94.613      0.000       1.420       1.482
outlier_dummy    -6.6097      0.394    -16.791      0.000      -7.401      -5.819
==============================================================================
Omnibus:                        1.917   Durbin-Watson:                   2.188
Prob(Omnibus):                  0.383   Jarque-Bera (JB):                1.066
Skew:                           0.218   Prob(JB):                        0.587
Kurtosis:                       3.558   Cond. No.                         27.0
==============================================================================
请注意,包含虚拟变量会更改
sepal_widt
的系数估计值,以及
偏度
峰度
的值。这是异常值对模型影响的简短版本

完整代码:

import numpy as np
import pandas as pd
import statsmodels.api as sm
from matplotlib import pyplot as plt
import seaborn as sns

# sample data
df = pd.DataFrame(sns.load_dataset('iris'))

# subset of sample data
df=df[df['species']=='setosa']

# add column for dummy variable
df['outlier_dummy']=0

# append line with extreme value for sepal width
# as well as a dummy variable = 1 for that row.
df.loc[len(df)] = [5,8,1.4, 0.3, 'setosa', 1]

# define independent variables
x=['sepal_width', 'outlier_dummy']

# run regression
mod_fit = sm.OLS(df['sepal_length'], df[x]).fit()
res = mod_fit.resid

fig = sm.qqplot(res)
plt.show()
mod_fit.summary()

谢谢维斯特兰。我不清楚你的最后一句话“捕捉”这些异常值的一种方法通常是用一个或两个虚拟变量来表示它们。”你能再解释一下这句话吗?“我非常需要,”兰杜努加莱纳,“我会尽量在周一给你回复。同时,如果您能在问题中包含您的代码和数据示例,那就太好了!谢谢@vestland。很抱歉,我不能早点回复你的按摩。我质疑我的代码。@randunugalhena你有数据样本吗?如果您使用的是pandas数据帧,您可以运行,例如:x_train.head(10).to_dict(),并在问题中添加该词典。谢谢您的帮助。我运行[x_train.head(10).to_dict()],但是我的样本太大了。所以它不能上传有问题的部分。你知道怎么上传吗?