Python:如何处理回归Q-Q图中的异常值?
我画了qq图多元回归,我得到了下图。有人能告诉我为什么红线下有两点吗?这些点对我的模型有影响吗 我使用下面的代码来绘制图表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
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()],但是我的样本太大了。所以它不能上传有问题的部分。你知道怎么上传吗?