【问题标题】:Python: How to handle outliers in a regression Q-Q plot?Python:如何处理回归 QQ 图中的异常值?
【发布时间】:2020-04-21 18:06:04
【问题描述】:

我画了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()

【问题讨论】:

    标签: python machine-learning regression data-science


    【解决方案1】:

    查看Understanding Q-Q Plots 以获得对 QQ 情节的简明描述。在您的情况下,此特定部分很重要:

    如果两组分位数来自同一分布,我们应该 查看形成一条大致笔直的线的点。

    这种理论上的一对一关系在您的图中用红线明确说明。

    关于你的问题...

    这点对我的模型有影响吗?

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


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


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

    1。 sepal_width 对 sepal_length 的线性回归

    情节 1:

    看起来不错!这里没有错。但是让我们通过向数据集添加一些极端值来混合一下。你会在最后找到完整的代码sn-p。

    2。引入异常值

    现在,让我们在数据框中添加一行,其中 ``sepal_width = 8instead of3`。 这会给你下面的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
    ==============================================================================
    

    那么为什么这是一个异常值?因为我们弄乱了数据集。我无法确定数据集中异常值的原因。在我们虚构的示例中,如果 8 可能很多,那么 setosa iris 具有萼片宽度的原因。也许科学家把它贴错了?也许它根本就不是setosa?或者也许它已经被转基因了?现在,与其仅仅从样本中丢弃这个观察结果,不如将它保留在原处通常会提供更多信息,接受这个观察结果有一些特别之处,并通过包含一个虚拟变量 1 来准确说明这一点和0 对于所有其他人。现在你的数据框的最后一部分应该是这样的:

    3。使用虚拟变量识别异常值

    现在,你的 qqplot 将如下所示:

    这是您的模型摘要:

    =================================================================================
                        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_widht 的系数估计值,以及SkewnessKurtosis 的值。这就是异常值对模型的影响的简短版本。

    完整代码:

    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()
    

    【讨论】:

    • 感谢韦斯特兰。我不清楚你的最后一句话““捕捉”这些异常值的一种方法通常是用一个或两个虚拟变量来表示它们。你能多解释一下这句话吗?这非常需要我。
    • @randunugalhena 我会尽量在周一回复你。同时,如果您可以在问题中包含您的代码和数据样本,那就太好了!
    • 感谢@vestland。对不起,我不能早点回复你的按摩。我的代码有问题。
    • @randunugalhena 你有数据样本吗?如果您使用的是 pandas 数据框,则可以运行,例如:x_train.head(10).to_dict() 并在问题中添加该字典。
    • 感谢您的帮助。我运行 [ x_train.head(10).to_dict() ] 但我的样本太大了。所以它不能在有问题的部分上传。你知道它是如何上传的吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多