• 基于Python代码的相关性热力图,VIF共线性诊断图及残差四图的使用及解释


    注:热力图共线性诊断图易看易解释,这里不再阐述

    残差四图(Residuals vs Fitted Plot,Normal Q-Q Plot,Scale-Location Plot,Cook's Distance Plot)

    各种现象的相关解释如下:

    1. Residuals vs Fitted Plot(残差与拟合值散点图):
      这个图用于帮助检验回归模型的线性关系假设。在这个图中,我们会将模型的残差(观测值与预测值之间的差异)与模型的拟合值(预测值)进行比较,理想情况下,残差应该随着拟合值的增加而随机分布在0附近,没有明显的模式或趋势。如果残差呈现出某种趋势,可能意味着模型的线性关系假设不成立。

    2. Normal Q-Q Plot(正态概率图):
      这个图用于检验模型残差是否符合正态分布。在这个图中,残差的排序值会和一个理论的正态分布进行比较,理想情况下,残差点应该落在一条直线上,如果残差点偏离直线,可能表示残差不符合正态分布。

    3. Scale-Location Plot(标准化残差与拟合值的散点图):
      这个图也称为“Spread-Location”图,用于检验模型的同方差性假设。在这个图中,我们会将标准化残差的绝对值开方(以消除负值)与拟合值进行比较,理想情况下,点应该在一条水平线上分布,如果点呈现出聚集或特定的模式,可能意味着同方差性不成立。

    4. Cook’s Distance Plot(库克距离图):
      这个图用于识别在回归模型中对结果产生显著影响的个别观测值。Cook’s Distance是一种衡量数据点影响的统计量,这个图可以显示每个数据点的Cook’s Distance值,通常我们会关注那些Cook’s Distance远高于平均水平的数据点,它们可能是影响模型准确性的异常值或离群点。

    综合使用这四种图可以帮助分析师评估线性回归模型的准确性、假设是否成立以及是否存在异常值,从而提高建模的质量和可靠性。

    1>封装好的代码如下:

    import matplotlib.pyplot as plt
    import seaborn as sns
    import statsmodels.formula.api as smf
    import pandas as pd
    from statsmodels.formula.api import ols
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    
    def Corr_heatmap(data):
        # import matplotlib.pyplot as plt
        # import seaborn as sns
        #相关性分析
        print(data.corr())
        #画出热力图
        plt.figure(figsize=(7,5),dpi=128)
        sns.heatmap(data.corr().round(2), cmap='coolwarm', annot=True, annot_kws={"size": 10})
        plt.savefig('相关系数热力图.jpg')
        plt.show()
    
    def VIF_calculate(data, y_name):
        # import statsmodels.formula.api as smf
        # import pandas as pd
        x_cols = data.columns.to_list()
        x_cols.remove(y_name)
    
        def vif(df_exog, exog_name):
            exog_use = list(df_exog.columns)
            exog_use.remove(exog_name)
            model = smf.ols(f"{exog_name}~{'+'.join(list(exog_use))}", data=df_exog).fit()
            return 1. / (1. - model.rsquared)
    
        df_vif = pd.DataFrame()
        for x in x_cols:
            df_vif.loc['VIF', x] = vif(data[x_cols], x)
    
        df_vif.loc['tolerance'] = 1 / df_vif.loc['VIF']
        df_vif = df_vif.T.sort_values('VIF', ascending=False)
        df_vif.loc['mean_vif'] = df_vif.mean()
        # from statsmodels.formula.api import ols
        def vif(data, col_i):
            """
            df: 整份数据
            col_i:被检测的列名
            """
            cols = list(data.columns)
            cols.remove(col_i)
            cols_noti = cols
            formula = col_i + '~' + '+'.join(cols_noti)
            r2 = ols(formula, data).fit().rsquared
            # 其实就是多元线性回归建模步骤,只是取出了参数 R 平方而已
            test = 1. / (1. - r2)
            return test
    
        print('vif检验结果')
        print('  变量            vif检验值')
        vif_value = []
        for i in data:
            print(i.center(7) + '    ', str(vif(data=data, col_i=i)))
            vif_value.append(vif(data=data, col_i=i))
        plt.bar([x for x in data], vif_value, color='teal')
        plt.axhline(10, color='red', lw=2, label="参考线")
        plt.title("VIF检验结果")
        plt.xlabel("变量")
        plt.ylabel("VIF_value")
        plt.show()
        return print(df_vif)
    
    def Residuals_plot(predicts,residuals):
        import numpy as np
        import matplotlib.pyplot as plt
        import statsmodels.api as sm
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False
    
        plt.subplots(2, 2, figsize=(8, 8), dpi=128)
        plt.subplot(221)
        plt.scatter(predicts, residuals)
        plt.xlabel('Fitted Value')
        plt.ylabel('Residual')
        plt.title('(a)Residuals vs Fitted Plot', fontsize=15)
        plt.axhline(0, ls='--')
    
        ax2 = plt.subplot(222)
        pplot = sm.ProbPlot(residuals, fit=True)
        pplot.qqplot(line='r', ax=ax2, xlabel='Theoretical Quantiles', ylabel='Sample Quantiles')
        ax2.set_title('(b)Normal Q-Q Plot', fontsize=15)
    
        #创建一个序列来表示观测序号:
        obs = np.arange(1, len(residuals) + 1)
        #绘制scale-location图
        ax3 = plt.subplot(223)
        ax3.scatter(np.sqrt(obs), np.abs(residuals))
        ax3.set_xlabel("√Observation Number")
        ax3.set_ylabel("|Residuals|")
        ax3.set_title("(c)Scale-Location Plot")
    
        #计算库克距离并绘制库克距离图:
        model = sm.OLS(residuals, sm.add_constant(obs)).fit()  # 应用OLS回归模型
        influence = model.get_influence()
        cooks_dist = influence.cooks_distance[0]
    
        ax4=plt.subplot(224)
        ax4.scatter(obs, cooks_dist)
        ax4.axhline(y=4*cooks_dist.mean(), linestyle='dashed')
        ax4.set_xlabel("Observation")
        ax4.set_ylabel("Cook's Distance")
        ax4.set_title("(d)Cook's Distance Plot")
        plt.tight_layout()
        plt.show()
    Multivariable_statistics.py

     2>对上述代码进行简单调用:

    复制代码
    import Multivariable_statistics as Ms
    import numpy as np
    import pandas as pd
    p=np.linspace(20,60,100)   #预测值
    r=np.random.uniform(-1,1,100)   #残差值
    print(r)
    Ms.Residuals_plot(residuals=r,predicts=p)   #残差四图
    
    
    #对于其他两个图的使用教程,以p,r数据为例
    #得到一组100*2的数据
    df=pd.DataFrame(p,columns=['p'])
    df['r']=r
    df['y']=np.linspace(50,80,100)   #预测值
    print(df)
    
    Ms.Corr_heatmap(df)    #皮尔逊相关系数的热力图
    Ms.VIF_calculate(df,'y')        #VIF检验值以及图
    复制代码

    3>结果图如下:

     

  • 相关阅读:
    c++11:左值引用和右值引用《全家桶》
    代码随想录算法训练营第20天|654.最大二叉树、合并二叉树、700. 二叉搜索树中的搜索、98.验证二叉搜索树
    opengl动态修改vbo数据
    js---笔试题
    vscode+ESP-IDF:编译网友移植好的LVGL工程(ESP32+ili9341笔记)
    Ubuntu 20.04 固定内核,降低版本, 锁定内核
    (0 , _login.default) is not a function ES6,小程序浮点数精度问题
    Unity 点击UI(按钮)与点击屏幕冲突
    JVM的相关知识
    hdu 3549 Flow Problem(最大流模板题)
  • 原文地址:https://www.cnblogs.com/hongbao/p/18091668